From 42ece73453274f064b15ba450a59578397dbef35 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Sat, 24 Feb 2018 21:33:13 +0100 Subject: [PATCH] Changed cell selection/reselection to avoid stopping/restarting radio. Fixed SIB message search --- srsue/hdr/phy/phch_recv.h | 3 +-- srsue/hdr/upper/rrc_common.h | 4 +++ srsue/src/phy/phch_recv.cc | 51 ++++++++++++++++++++---------------- srsue/src/upper/nas.cc | 5 +++- srsue/src/upper/rrc.cc | 35 ++++++++++++------------- 5 files changed, 54 insertions(+), 44 deletions(-) diff --git a/srsue/hdr/phy/phch_recv.h b/srsue/hdr/phy/phch_recv.h index bc7255ac9..a14f8e9fa 100644 --- a/srsue/hdr/phy/phch_recv.h +++ b/srsue/hdr/phy/phch_recv.h @@ -104,7 +104,7 @@ private: bool set_cell(); 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(); void stop_rx(); @@ -307,7 +307,6 @@ private: IDLE = 0, CELL_SEARCH, CELL_SELECT, - CELL_RESELECT, CELL_MEASURE, CELL_CAMP, IDLE_RX diff --git a/srsue/hdr/upper/rrc_common.h b/srsue/hdr/upper/rrc_common.h index 6d1186812..259d08fd7 100644 --- a/srsue/hdr/upper/rrc_common.h +++ b/srsue/hdr/upper/rrc_common.h @@ -33,6 +33,7 @@ namespace srsue { // RRC states (3GPP 36.331 v10.0.0) typedef enum { RRC_STATE_IDLE = 0, + RRC_STATE_PLMN_START, RRC_STATE_PLMN_SELECTION, RRC_STATE_CELL_SELECTING, RRC_STATE_CELL_SELECTED, @@ -44,11 +45,14 @@ typedef enum { RRC_STATE_N_ITEMS, } rrc_state_t; static const char rrc_state_text[RRC_STATE_N_ITEMS][100] = {"IDLE", + "PLMN SELECTED", "PLMN SELECTION", "CELL SELECTING", "CELL SELECTED", "CONNECTING", "CONNECTED", + "HO PREPARE", + "HO PROCESS", "LEAVE CONNECTED"}; } // namespace srsue diff --git a/srsue/src/phy/phch_recv.cc b/srsue/src/phy/phch_recv.cc index 5e2ec4dee..4a8fef5bf 100644 --- a/srsue/src/phy/phch_recv.cc +++ b/srsue/src/phy/phch_recv.cc @@ -265,17 +265,22 @@ bool phch_recv::set_cell() { 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(); stop_rx(); + usleep(100000); } - start_rx(now); 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 earfcn) { @@ -294,7 +299,7 @@ bool phch_recv::stop_sync() { if (phy_state == IDLE && is_in_idle) { return true; } else { - Info("SYNC: Going to IDLE\n"); + Info("SYNC: Going to IDLE (state=%d)\n", phy_state); phy_state = IDLE; int cnt = 0; while (!is_in_idle && cnt < 100) { @@ -302,7 +307,7 @@ bool phch_recv::stop_sync() { cnt++; } 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; } @@ -310,11 +315,12 @@ bool phch_recv::stop_sync() { void phch_recv::reset_sync() { - Warning("SYNC: Resetting sync, cell_search_in_progress=%s\n", cell_search_in_progress?"yes":"no"); - - search_p.reset(); - srslte_ue_sync_reset(&ue_sync); - resync_sfn(true, true); + if (phy_state != CELL_SELECT) { + Warning("SYNC: Resetting sync, cell_search_in_progress=%s\n", cell_search_in_progress?"yes":"no"); + resync_sfn(false); + } else { + Warning("SYNC: Trying to reset sync while in cell reselection\n"); + } } 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 >= (int) earfcn.size()) { cur_earfcn_index = 0; + cell_search_in_progress = false; + phy_state = IDLE; rrc->earfcn_end(); } else { 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) { cell_search_in_progress = false; 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) { cur_earfcn_index = -1; @@ -393,9 +401,7 @@ bool phch_recv::cell_handover(srslte_cell_t cell) if (is_in_idle_rx) { Info("Cell HO: Reconfiguring cell\n"); if (set_cell()) { - //resync_sfn(true, true); - sfn_p.reset(); - phy_state = CELL_RESELECT; + resync_sfn(false); Info("Cell HO: Synchronizing with new cell\n"); ret = true; } else { @@ -419,7 +425,7 @@ bool phch_recv::cell_select(uint32_t earfcn, srslte_cell_t cell) { set_sampling_rate(); } if (phy_state < CELL_SELECT) { - resync_sfn(); + resync_sfn(true, false); } return true; } else { @@ -444,9 +450,7 @@ bool phch_recv::cell_select(uint32_t earfcn, srslte_cell_t cell) { if (set_cell()) { log_h->info("Cell Select: Synchronizing on cell...\n"); - resync_sfn(); - - usleep(500000); // Time offset we set start_rx to start receiving samples + resync_sfn(true, false); return true; } return false; @@ -616,13 +620,14 @@ void phch_recv::run_thread() } if (set_cell()) { set_sampling_rate(); - resync_sfn(); + resync_sfn(true, false); } break; case search::CELL_NOT_FOUND: if (cell_search_in_progress) { cell_search_inc(); } + phy_state = IDLE; break; default: radio_error(); @@ -630,7 +635,6 @@ void phch_recv::run_thread() } } break; - case CELL_RESELECT: case CELL_SELECT: switch (sfn_p.run_subframe(&cell, &tti)) { @@ -650,7 +654,7 @@ void phch_recv::run_thread() phy_state = CELL_SEARCH; } else { log_h->warning("SYNC: Timeout while synchronizing SFN. Reselecting cell\n"); - resync_sfn(true, true); + resync_sfn(false); } break; case sfn_sync::IDLE: @@ -666,6 +670,7 @@ void phch_recv::run_thread() case measure::MEASURE_OK: log_h->info("SYNC: Measured OK. Camping on cell PCI=%d...\n", cell.id); phy_state = CELL_CAMP; + cell_search_in_progress = false; rrc->cell_found(earfcn[cur_earfcn_index], cell, measure_p.rsrp()); break; case measure::IDLE: diff --git a/srsue/src/upper/nas.cc b/srsue/src/upper/nas.cc index 04b5f4869..7f5683867 100644 --- a/srsue/src/upper/nas.cc +++ b/srsue/src/upper/nas.cc @@ -171,7 +171,10 @@ void nas::plmn_search_end() { rrc->plmn_select(known_plmns[0]); } 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(); + } } } diff --git a/srsue/src/upper/rrc.cc b/srsue/src/upper/rrc.cc index 9e26436ae..0760ccb7e 100644 --- a/srsue/src/upper/rrc.cc +++ b/srsue/src/upper/rrc.cc @@ -202,6 +202,12 @@ void rrc::run_thread() { // If not attached, PLMN selection will be triggered from higher layers } 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: plmn_select_timeout++; if (plmn_select_timeout >= RRC_PLMN_SELECT_TIMEOUT) { @@ -209,8 +215,7 @@ void rrc::run_thread() { phy->cell_search_stop(); sleep(1); rrc_log->console("\nRRC PLMN Search: timeout expired. Searching again\n"); - plmn_select_timeout = 0; - phy->cell_search_start(); + } break; case RRC_STATE_CELL_SELECTING: @@ -230,7 +235,7 @@ void rrc::run_thread() { 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()) { 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(); si_win_start = sib_start_tti(tti, 2, 0, 5); 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; @@ -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]; 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; 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); } @@ -433,10 +438,7 @@ uint16_t rrc::get_mnc() { } void rrc::plmn_search() { - rrc_log->info("Starting PLMN search procedure\n"); - state = RRC_STATE_PLMN_SELECTION; - phy->cell_search_start(); - plmn_select_timeout = 0; + state = RRC_STATE_PLMN_START; } /* 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) - 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) { set_serving_cell(0); @@ -761,10 +764,6 @@ void rrc::earfcn_end() { // If searching for PLMN, indicate NAS we scanned all frequencies if (state == RRC_STATE_PLMN_SELECTION) { 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()) { n310_cnt++; 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)->run(); 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 { @@ -856,7 +855,6 @@ void rrc::in_sync() { void rrc::radio_link_failure() { // TODO: Generate and store failure report - phy->sync_reset(); rrc_log->warning("Detected Radio-Link Failure\n"); rrc_log->console("Warning: Detected Radio-Link Failure\n"); 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(); mac->reset(); set_mac_default(); + phy->sync_reset(); state = RRC_STATE_CELL_SELECTING; }