Changed cell selection/reselection to avoid stopping/restarting radio. Fixed SIB message search

master
Ismael Gomez 7 years ago
parent 56455b31ef
commit 42ece73453

@ -104,7 +104,7 @@ private:
bool set_cell(); bool set_cell();
void cell_search_inc(); void cell_search_inc();
void resync_sfn(bool is_connected = false, bool rx_now = false); void resync_sfn(bool restart_radio, bool restart_now = false);
bool stop_sync(); bool stop_sync();
void stop_rx(); void stop_rx();
@ -307,7 +307,6 @@ private:
IDLE = 0, IDLE = 0,
CELL_SEARCH, CELL_SEARCH,
CELL_SELECT, CELL_SELECT,
CELL_RESELECT,
CELL_MEASURE, CELL_MEASURE,
CELL_CAMP, CELL_CAMP,
IDLE_RX IDLE_RX

@ -33,6 +33,7 @@ namespace srsue {
// RRC states (3GPP 36.331 v10.0.0) // RRC states (3GPP 36.331 v10.0.0)
typedef enum { typedef enum {
RRC_STATE_IDLE = 0, RRC_STATE_IDLE = 0,
RRC_STATE_PLMN_START,
RRC_STATE_PLMN_SELECTION, RRC_STATE_PLMN_SELECTION,
RRC_STATE_CELL_SELECTING, RRC_STATE_CELL_SELECTING,
RRC_STATE_CELL_SELECTED, RRC_STATE_CELL_SELECTED,
@ -44,11 +45,14 @@ typedef enum {
RRC_STATE_N_ITEMS, RRC_STATE_N_ITEMS,
} rrc_state_t; } rrc_state_t;
static const char rrc_state_text[RRC_STATE_N_ITEMS][100] = {"IDLE", static const char rrc_state_text[RRC_STATE_N_ITEMS][100] = {"IDLE",
"PLMN SELECTED",
"PLMN SELECTION", "PLMN SELECTION",
"CELL SELECTING", "CELL SELECTING",
"CELL SELECTED", "CELL SELECTED",
"CONNECTING", "CONNECTING",
"CONNECTED", "CONNECTED",
"HO PREPARE",
"HO PROCESS",
"LEAVE CONNECTED"}; "LEAVE CONNECTED"};
} // namespace srsue } // namespace srsue

@ -265,17 +265,22 @@ bool phch_recv::set_cell() {
return cell_is_set; return cell_is_set;
} }
void phch_recv::resync_sfn(bool is_connected, bool now) { void phch_recv::resync_sfn(bool restart_radio, bool restart_now) {
if (!now) { if (restart_radio) {
wait_radio_reset(); wait_radio_reset();
stop_rx(); stop_rx();
usleep(100000);
} }
start_rx(now);
sfn_p.reset(); sfn_p.reset();
Info("SYNC: Starting SFN synchronization\n"); search_p.reset();
srslte_ue_sync_reset(&ue_sync);
phy_state = is_connected?CELL_RESELECT:CELL_SELECT; if (restart_radio) {
start_rx(restart_now);
}
phy_state = CELL_SELECT;
} }
void phch_recv::set_earfcn(std::vector<uint32_t> earfcn) { void phch_recv::set_earfcn(std::vector<uint32_t> earfcn) {
@ -294,7 +299,7 @@ bool phch_recv::stop_sync() {
if (phy_state == IDLE && is_in_idle) { if (phy_state == IDLE && is_in_idle) {
return true; return true;
} else { } else {
Info("SYNC: Going to IDLE\n"); Info("SYNC: Going to IDLE (state=%d)\n", phy_state);
phy_state = IDLE; phy_state = IDLE;
int cnt = 0; int cnt = 0;
while (!is_in_idle && cnt < 100) { while (!is_in_idle && cnt < 100) {
@ -302,7 +307,7 @@ bool phch_recv::stop_sync() {
cnt++; cnt++;
} }
if (!is_in_idle) { if (!is_in_idle) {
Warning("SYNC: Could not go to IDLE\n"); Warning("SYNC: Could not go to IDLE (state=%d)\n", phy_state);
} }
return is_in_idle; return is_in_idle;
} }
@ -310,11 +315,12 @@ bool phch_recv::stop_sync() {
void phch_recv::reset_sync() { void phch_recv::reset_sync() {
Warning("SYNC: Resetting sync, cell_search_in_progress=%s\n", cell_search_in_progress?"yes":"no"); if (phy_state != CELL_SELECT) {
Warning("SYNC: Resetting sync, cell_search_in_progress=%s\n", cell_search_in_progress?"yes":"no");
search_p.reset(); resync_sfn(false);
srslte_ue_sync_reset(&ue_sync); } else {
resync_sfn(true, true); Warning("SYNC: Trying to reset sync while in cell reselection\n");
}
} }
void phch_recv::cell_search_inc() void phch_recv::cell_search_inc()
@ -323,6 +329,8 @@ void phch_recv::cell_search_inc()
if (cur_earfcn_index >= 0) { if (cur_earfcn_index >= 0) {
if (cur_earfcn_index >= (int) earfcn.size()) { if (cur_earfcn_index >= (int) earfcn.size()) {
cur_earfcn_index = 0; cur_earfcn_index = 0;
cell_search_in_progress = false;
phy_state = IDLE;
rrc->earfcn_end(); rrc->earfcn_end();
} else { } else {
Info("SYNC: Cell Search idx %d/%d\n", cur_earfcn_index, earfcn.size()); Info("SYNC: Cell Search idx %d/%d\n", cur_earfcn_index, earfcn.size());
@ -338,7 +346,7 @@ void phch_recv::cell_search_next(bool reset) {
if (cell_search_in_progress || reset) { if (cell_search_in_progress || reset) {
cell_search_in_progress = false; cell_search_in_progress = false;
if (!stop_sync()) { if (!stop_sync()) {
log_h->warning("SYNC: Couldn't stop PHY\n"); log_h->warning("SYNC: Couldn't stop PHY (state=%d)\n", phy_state);
} }
if (reset) { if (reset) {
cur_earfcn_index = -1; cur_earfcn_index = -1;
@ -393,9 +401,7 @@ bool phch_recv::cell_handover(srslte_cell_t cell)
if (is_in_idle_rx) { if (is_in_idle_rx) {
Info("Cell HO: Reconfiguring cell\n"); Info("Cell HO: Reconfiguring cell\n");
if (set_cell()) { if (set_cell()) {
//resync_sfn(true, true); resync_sfn(false);
sfn_p.reset();
phy_state = CELL_RESELECT;
Info("Cell HO: Synchronizing with new cell\n"); Info("Cell HO: Synchronizing with new cell\n");
ret = true; ret = true;
} else { } else {
@ -419,7 +425,7 @@ bool phch_recv::cell_select(uint32_t earfcn, srslte_cell_t cell) {
set_sampling_rate(); set_sampling_rate();
} }
if (phy_state < CELL_SELECT) { if (phy_state < CELL_SELECT) {
resync_sfn(); resync_sfn(true, false);
} }
return true; return true;
} else { } else {
@ -444,9 +450,7 @@ bool phch_recv::cell_select(uint32_t earfcn, srslte_cell_t cell) {
if (set_cell()) { if (set_cell()) {
log_h->info("Cell Select: Synchronizing on cell...\n"); log_h->info("Cell Select: Synchronizing on cell...\n");
resync_sfn(); resync_sfn(true, false);
usleep(500000); // Time offset we set start_rx to start receiving samples
return true; return true;
} }
return false; return false;
@ -616,13 +620,14 @@ void phch_recv::run_thread()
} }
if (set_cell()) { if (set_cell()) {
set_sampling_rate(); set_sampling_rate();
resync_sfn(); resync_sfn(true, false);
} }
break; break;
case search::CELL_NOT_FOUND: case search::CELL_NOT_FOUND:
if (cell_search_in_progress) { if (cell_search_in_progress) {
cell_search_inc(); cell_search_inc();
} }
phy_state = IDLE;
break; break;
default: default:
radio_error(); radio_error();
@ -630,7 +635,6 @@ void phch_recv::run_thread()
} }
} }
break; break;
case CELL_RESELECT:
case CELL_SELECT: case CELL_SELECT:
switch (sfn_p.run_subframe(&cell, &tti)) switch (sfn_p.run_subframe(&cell, &tti))
{ {
@ -650,7 +654,7 @@ void phch_recv::run_thread()
phy_state = CELL_SEARCH; phy_state = CELL_SEARCH;
} else { } else {
log_h->warning("SYNC: Timeout while synchronizing SFN. Reselecting cell\n"); log_h->warning("SYNC: Timeout while synchronizing SFN. Reselecting cell\n");
resync_sfn(true, true); resync_sfn(false);
} }
break; break;
case sfn_sync::IDLE: case sfn_sync::IDLE:
@ -666,6 +670,7 @@ void phch_recv::run_thread()
case measure::MEASURE_OK: case measure::MEASURE_OK:
log_h->info("SYNC: Measured OK. Camping on cell PCI=%d...\n", cell.id); log_h->info("SYNC: Measured OK. Camping on cell PCI=%d...\n", cell.id);
phy_state = CELL_CAMP; phy_state = CELL_CAMP;
cell_search_in_progress = false;
rrc->cell_found(earfcn[cur_earfcn_index], cell, measure_p.rsrp()); rrc->cell_found(earfcn[cur_earfcn_index], cell, measure_p.rsrp());
break; break;
case measure::IDLE: case measure::IDLE:

@ -171,7 +171,10 @@ void nas::plmn_search_end() {
rrc->plmn_select(known_plmns[0]); rrc->plmn_select(known_plmns[0]);
} else { } else {
nas_log->debug("Finished searching PLMN in current EARFCN set but no networks were found.\n"); nas_log->info("Finished searching PLMN in current EARFCN set but no networks were found.\n");
if (state == EMM_STATE_REGISTERED_INITIATED && plmn_selection == PLMN_NOT_SELECTED) {
rrc->plmn_search();
}
} }
} }

@ -202,6 +202,12 @@ void rrc::run_thread() {
// If not attached, PLMN selection will be triggered from higher layers // If not attached, PLMN selection will be triggered from higher layers
} }
break; break;
case RRC_STATE_PLMN_START:
rrc_log->info("RRC PLMN Search: Starting cell search\n");
plmn_select_timeout = 0;
phy->cell_search_start();
state = RRC_STATE_PLMN_SELECTION;
break;
case RRC_STATE_PLMN_SELECTION: case RRC_STATE_PLMN_SELECTION:
plmn_select_timeout++; plmn_select_timeout++;
if (plmn_select_timeout >= RRC_PLMN_SELECT_TIMEOUT) { if (plmn_select_timeout >= RRC_PLMN_SELECT_TIMEOUT) {
@ -209,8 +215,7 @@ void rrc::run_thread() {
phy->cell_search_stop(); phy->cell_search_stop();
sleep(1); sleep(1);
rrc_log->console("\nRRC PLMN Search: timeout expired. Searching again\n"); rrc_log->console("\nRRC PLMN Search: timeout expired. Searching again\n");
plmn_select_timeout = 0;
phy->cell_search_start();
} }
break; break;
case RRC_STATE_CELL_SELECTING: case RRC_STATE_CELL_SELECTING:
@ -230,7 +235,7 @@ void rrc::run_thread() {
state = RRC_STATE_CELL_SELECTED; state = RRC_STATE_CELL_SELECTED;
} }
} }
// Don't time out during restablishment (T311 running) // Don't time out during reestablishment (T311 running)
if (!mac_timers->timer_get(t311)->is_running()) { if (!mac_timers->timer_get(t311)->is_running()) {
select_cell_timeout++; select_cell_timeout++;
if (select_cell_timeout >= RRC_SELECT_CELL_TIMEOUT) { if (select_cell_timeout >= RRC_SELECT_CELL_TIMEOUT) {
@ -351,7 +356,7 @@ void rrc::run_si_acquisition_procedure()
tti = mac->get_current_tti(); tti = mac->get_current_tti();
si_win_start = sib_start_tti(tti, 2, 0, 5); si_win_start = sib_start_tti(tti, 2, 0, 5);
if (last_win_start == 0 || if (last_win_start == 0 ||
(srslte_tti_interval(last_win_start, tti) > 20 && srslte_tti_interval(last_win_start, tti) < 1000)) (srslte_tti_interval(tti, last_win_start) >= 20 && srslte_tti_interval(tti, last_win_start) < 1000))
{ {
last_win_start = si_win_start; last_win_start = si_win_start;
@ -384,12 +389,12 @@ void rrc::run_si_acquisition_procedure()
si_win_len = liblte_rrc_si_window_length_num[serving_cell->sib1ptr()->si_window_length]; si_win_len = liblte_rrc_si_window_length_num[serving_cell->sib1ptr()->si_window_length];
if (last_win_start == 0 || if (last_win_start == 0 ||
(srslte_tti_interval(last_win_start, tti) > period*10 && srslte_tti_interval(last_win_start, tti) < 1000)) (srslte_tti_interval(tti, last_win_start) > period*10 && srslte_tti_interval(tti, last_win_start) < 1000))
{ {
last_win_start = si_win_start; last_win_start = si_win_start;
mac->bcch_start_rx(si_win_start, si_win_len); mac->bcch_start_rx(si_win_start, si_win_len);
rrc_log->info("Instructed MAC to search for system info, win_start=%d, win_len=%d\n", rrc_log->debug("Instructed MAC to search for system info, win_start=%d, win_len=%d\n",
si_win_start, si_win_len); si_win_start, si_win_len);
} }
@ -433,10 +438,7 @@ uint16_t rrc::get_mnc() {
} }
void rrc::plmn_search() { void rrc::plmn_search() {
rrc_log->info("Starting PLMN search procedure\n"); state = RRC_STATE_PLMN_START;
state = RRC_STATE_PLMN_SELECTION;
phy->cell_search_start();
plmn_select_timeout = 0;
} }
/* This is the NAS interface. When NAS requests to select a PLMN we have to /* This is the NAS interface. When NAS requests to select a PLMN we have to
@ -576,7 +578,8 @@ void rrc::new_phy_meas(float rsrp, float rsrq, uint32_t tti, int earfcn_i, int p
} }
// Verify cell selection criteria with strongest neighbour cell (always first) // Verify cell selection criteria with strongest neighbour cell (always first)
if (cell_selection_eval(neighbour_cells[0]->get_rsrp()) && if (neighbour_cells.size() > 1 &&
cell_selection_eval(neighbour_cells[0]->get_rsrp()) &&
neighbour_cells[0]->get_rsrp() > serving_cell->get_rsrp() + 5) neighbour_cells[0]->get_rsrp() > serving_cell->get_rsrp() + 5)
{ {
set_serving_cell(0); set_serving_cell(0);
@ -761,10 +764,6 @@ void rrc::earfcn_end() {
// If searching for PLMN, indicate NAS we scanned all frequencies // If searching for PLMN, indicate NAS we scanned all frequencies
if (state == RRC_STATE_PLMN_SELECTION) { if (state == RRC_STATE_PLMN_SELECTION) {
nas->plmn_search_end(); nas->plmn_search_end();
} else if (state == RRC_STATE_CELL_SELECTING) {
select_cell_timeout = 0;
rrc_log->info("Starting cell search again\n");
phy->cell_search_start();
} }
} }
@ -825,11 +824,11 @@ void rrc::out_of_sync() {
if (!mac_timers->timer_get(t311)->is_running() && !mac_timers->timer_get(t310)->is_running()) { if (!mac_timers->timer_get(t311)->is_running() && !mac_timers->timer_get(t310)->is_running()) {
n310_cnt++; n310_cnt++;
if (n310_cnt == N310) { if (n310_cnt == N310) {
rrc_log->info("Detected %d out-of-sync from PHY. Trying to resync. Starting T310 timer %d ms\n",
N310, mac_timers->timer_get(t310)->get_timeout());
mac_timers->timer_get(t310)->reset(); mac_timers->timer_get(t310)->reset();
mac_timers->timer_get(t310)->run(); mac_timers->timer_get(t310)->run();
n310_cnt = 0; n310_cnt = 0;
phy->sync_reset();
rrc_log->info("Detected %d out-of-sync from PHY. Trying to resync. Starting T310 timer\n", N310);
} }
} }
} else { } else {
@ -856,7 +855,6 @@ void rrc::in_sync() {
void rrc::radio_link_failure() { void rrc::radio_link_failure() {
// TODO: Generate and store failure report // TODO: Generate and store failure report
phy->sync_reset();
rrc_log->warning("Detected Radio-Link Failure\n"); rrc_log->warning("Detected Radio-Link Failure\n");
rrc_log->console("Warning: Detected Radio-Link Failure\n"); rrc_log->console("Warning: Detected Radio-Link Failure\n");
if (state != RRC_STATE_CONNECTED) { if (state != RRC_STATE_CONNECTED) {
@ -1016,6 +1014,7 @@ void rrc::send_con_restablish_request(LIBLTE_RRC_CON_REEST_REQ_CAUSE_ENUM cause,
set_phy_default(); set_phy_default();
mac->reset(); mac->reset();
set_mac_default(); set_mac_default();
phy->sync_reset();
state = RRC_STATE_CELL_SELECTING; state = RRC_STATE_CELL_SELECTING;
} }

Loading…
Cancel
Save