From 13efa740e846dea1b0b559d1229418d8bd1b1f39 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Tue, 6 Mar 2018 22:20:38 +0100 Subject: [PATCH] Changed logic in RRC/NAS/PHY for cell/plmn search to avoid stucking in IDLE --- lib/include/srslte/interfaces/ue_interfaces.h | 4 +- srsue/hdr/phy/phch_recv.h | 2 +- srsue/hdr/upper/nas.h | 3 +- srsue/hdr/upper/rrc.h | 7 +- srsue/src/phy/phch_recv.cc | 6 +- srsue/src/phy/phch_worker.cc | 4 +- srsue/src/upper/nas.cc | 24 +- srsue/src/upper/rrc.cc | 212 ++++++++++-------- srsue/test/upper/nas_test.cc | 2 +- 9 files changed, 140 insertions(+), 124 deletions(-) diff --git a/lib/include/srslte/interfaces/ue_interfaces.h b/lib/include/srslte/interfaces/ue_interfaces.h index 923111371..b1251c0bb 100644 --- a/lib/include/srslte/interfaces/ue_interfaces.h +++ b/lib/include/srslte/interfaces/ue_interfaces.h @@ -119,7 +119,7 @@ public: virtual uint32_t get_ul_count() = 0; virtual bool get_s_tmsi(LIBLTE_RRC_S_TMSI_STRUCT *s_tmsi) = 0; virtual bool get_k_asme(uint8_t *k_asme_, uint32_t n) = 0; - virtual void plmn_found(LIBLTE_RRC_PLMN_IDENTITY_STRUCT plmn_id, uint16_t tracking_area_code) = 0; + virtual bool plmn_found(LIBLTE_RRC_PLMN_IDENTITY_STRUCT plmn_id, uint16_t tracking_area_code) = 0; virtual void plmn_search_end() = 0; }; @@ -173,7 +173,7 @@ public: virtual uint16_t get_mnc() = 0; virtual void enable_capabilities() = 0; virtual void plmn_search() = 0; - virtual void plmn_select(LIBLTE_RRC_PLMN_IDENTITY_STRUCT plmn_id) = 0; + virtual void plmn_select(LIBLTE_RRC_PLMN_IDENTITY_STRUCT plmn_id, bool connect_request = false) = 0; virtual std::string get_rb_name(uint32_t lcid) = 0; }; diff --git a/srsue/hdr/phy/phch_recv.h b/srsue/hdr/phy/phch_recv.h index 861d58229..d77e489ae 100644 --- a/srsue/hdr/phy/phch_recv.h +++ b/srsue/hdr/phy/phch_recv.h @@ -150,7 +150,7 @@ private: srslte_ue_mib_t ue_mib; uint32_t cnt; uint32_t timeout; - const static uint32_t SYNC_SFN_TIMEOUT = 500; + const static uint32_t SYNC_SFN_TIMEOUT = 80; }; // Class to perform cell measurements diff --git a/srsue/hdr/upper/nas.h b/srsue/hdr/upper/nas.h index 6038993e0..8a1fd6ae3 100644 --- a/srsue/hdr/upper/nas.h +++ b/srsue/hdr/upper/nas.h @@ -88,9 +88,10 @@ public: uint32_t get_ul_count(); bool is_attached(); bool is_attaching(); + bool is_data_requested(); bool get_s_tmsi(LIBLTE_RRC_S_TMSI_STRUCT *s_tmsi); bool get_k_asme(uint8_t *k_asme_, uint32_t n); - void plmn_found(LIBLTE_RRC_PLMN_IDENTITY_STRUCT plmn_id, uint16_t tracking_area_code); + bool plmn_found(LIBLTE_RRC_PLMN_IDENTITY_STRUCT plmn_id, uint16_t tracking_area_code); void plmn_search_end(); // UE interface diff --git a/srsue/hdr/upper/rrc.h b/srsue/hdr/upper/rrc.h index 55ee21097..904ae59db 100644 --- a/srsue/hdr/upper/rrc.h +++ b/srsue/hdr/upper/rrc.h @@ -249,7 +249,7 @@ public: void enable_capabilities(); void plmn_search(); - void plmn_select(LIBLTE_RRC_PLMN_IDENTITY_STRUCT plmn_id); + void plmn_select(LIBLTE_RRC_PLMN_IDENTITY_STRUCT plmn_id, bool connect_request); // PHY interface void in_sync(); @@ -324,9 +324,6 @@ private: uint32_t plmn_select_timeout; static const uint32_t RRC_PLMN_SELECT_TIMEOUT = 10000; - uint32_t select_cell_timeout; - static const uint32_t RRC_SELECT_CELL_TIMEOUT = 1000; - uint8_t k_rrc_enc[32]; uint8_t k_rrc_int[32]; uint8_t k_up_enc[32]; @@ -401,7 +398,7 @@ private: uint16_t sysinfo_index; uint32_t last_win_start; - void select_next_cell_in_plmn(); + bool select_next_cell_in_plmn(); LIBLTE_RRC_PLMN_IDENTITY_STRUCT selected_plmn_id; bool thread_running; diff --git a/srsue/src/phy/phch_recv.cc b/srsue/src/phy/phch_recv.cc index ecd2cf241..ca6a35772 100644 --- a/srsue/src/phy/phch_recv.cc +++ b/srsue/src/phy/phch_recv.cc @@ -565,8 +565,8 @@ void phch_recv::run_thread() } break; case sfn_sync::TIMEOUT: - log_h->warning("SYNC: Timeout while synchronizing SFN. Going back to cell search\n"); - phy_state = CELL_SEARCH; + log_h->warning("SYNC: Timeout while synchronizing SFN\n"); + rrc->out_of_sync(); break; case sfn_sync::IDLE: break; @@ -1271,7 +1271,7 @@ int phch_recv::scell_recv::find_cells(cf_t *input_buffer, float rx_gain_offset, for (uint32_t sf5_cnt=0;sf5_cnt max_peak && sync_res == SRSLTE_SYNC_FOUND) { diff --git a/srsue/src/phy/phch_worker.cc b/srsue/src/phy/phch_worker.cc index 4546788ec..2d1b67c48 100644 --- a/srsue/src/phy/phch_worker.cc +++ b/srsue/src/phy/phch_worker.cc @@ -529,7 +529,9 @@ bool phch_worker::decode_pdcch_dl(srsue::mac_interface_phy::mac_grant_t* grant) if (srslte_ue_dl_find_dl_dci_type(&ue_dl, phy->config->dedicated.antenna_info_explicit_value.tx_mode, cfi, tti%10, dl_rnti, type, &dci_msg) != 1) { if (type == SRSLTE_RNTI_RAR) { - Info("RAR not found, SNR=%.1f dB\n", 10*log10(srslte_chest_dl_get_snr(&ue_dl.chest))); + Info("RAR not found, SNR=%.1f dB, tti=%d, cfi=%d, tx_mode=%d, cell_id=%d\n", + 10*log10(srslte_chest_dl_get_snr(&ue_dl.chest)), tti, cfi, + phy->config->dedicated.antenna_info_explicit_value.tx_mode, cell.id); } return false; } diff --git a/srsue/src/upper/nas.cc b/srsue/src/upper/nas.cc index 0a5b597e4..c25a05125 100644 --- a/srsue/src/upper/nas.cc +++ b/srsue/src/upper/nas.cc @@ -107,8 +107,8 @@ void nas::attach_request() { selecting_plmn = current_plmn; } } else if (state == EMM_STATE_REGISTERED) { - nas_log->info("NAS state is registered, connecting to same PLMN\n"); - rrc->plmn_select(current_plmn); + nas_log->info("NAS state is registered, selecting current PLMN\n"); + rrc->plmn_select(current_plmn, true); } else { nas_log->info("Attach request ignored. State = %s\n", emm_state_text[state]); } @@ -123,12 +123,7 @@ void nas::deattach_request() { * RRC interface ******************************************************************************/ -void nas::plmn_found(LIBLTE_RRC_PLMN_IDENTITY_STRUCT plmn_id, uint16_t tracking_area_code) { - - // Do not process new PLMN if already selected - if (plmn_selection == PLMN_SELECTED) { - return; - } +bool nas::plmn_found(LIBLTE_RRC_PLMN_IDENTITY_STRUCT plmn_id, uint16_t tracking_area_code) { // Check if already registered for (uint32_t i=0;iinfo("Found known PLMN Id=%s\n", plmn_id_to_string(plmn_id).c_str()); if (plmn_id.mcc == home_plmn.mcc && plmn_id.mnc == home_plmn.mnc) { nas_log->info("Connecting Home PLMN Id=%s\n", plmn_id_to_string(plmn_id).c_str()); - rrc->plmn_select(plmn_id); + rrc->plmn_select(plmn_id, state == EMM_STATE_REGISTERED_INITIATED); selecting_plmn = plmn_id; + return true; } - return; + return false; } } @@ -152,10 +148,11 @@ void nas::plmn_found(LIBLTE_RRC_PLMN_IDENTITY_STRUCT plmn_id, uint16_t tracking_ tracking_area_code); if (plmn_id.mcc == home_plmn.mcc && plmn_id.mnc == home_plmn.mnc) { - rrc->plmn_select(plmn_id); + rrc->plmn_select(plmn_id, state == EMM_STATE_REGISTERED_INITIATED); selecting_plmn = plmn_id; + return true; } - + return false; } // RRC indicates that the UE has gone through all EARFCN and finished PLMN selection @@ -170,7 +167,7 @@ void nas::plmn_search_end() { plmn_id_to_string(home_plmn).c_str(), plmn_id_to_string(known_plmns[0]).c_str()); } - rrc->plmn_select(known_plmns[0]); + rrc->plmn_select(known_plmns[0], state == EMM_STATE_REGISTERED_INITIATED); } else { 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) { @@ -538,6 +535,7 @@ void nas::parse_attach_accept(uint32_t lcid, byte_buffer_t *pdu) { state = EMM_STATE_REGISTERED; current_plmn = selecting_plmn; + plmn_selection = PLMN_SELECTED; ctxt.rx_count++; diff --git a/srsue/src/upper/rrc.cc b/srsue/src/upper/rrc.cc index 37ae14e8c..875785093 100644 --- a/srsue/src/upper/rrc.cc +++ b/srsue/src/upper/rrc.cc @@ -126,6 +126,8 @@ void rrc::init(phy_interface_rrc *phy_, pending_mob_reconf = false; + connection_requested = false; + // Set default values for all layers set_rrc_default(); set_phy_default(); @@ -184,10 +186,8 @@ void rrc::run_thread() { if (phy->sync_status()) { // If attempting to attach, reselect cell if (nas->is_attaching()) { - sleep(1); - rrc_log->info("RRC IDLE: NAS is attaching and camping on cell, reselecting...\n"); + rrc_log->info("RRC IDLE: NAS has pending data and camping on cell, connecting...\n"); plmn_select_rrc(selected_plmn_id); - connection_requested = true; } // If not camping on a cell } else { @@ -196,7 +196,6 @@ void rrc::run_thread() { rrc_log->info("RRC IDLE: NAS is attached, PHY not synchronized. Re-selecting cell...\n"); plmn_select_rrc(selected_plmn_id); } else if (nas->is_attaching()) { - sleep(1); rrc_log->info("RRC IDLE: NAS is attaching, searching again PLMN\n"); plmn_search(); } @@ -234,16 +233,6 @@ void rrc::run_thread() { state = RRC_STATE_CELL_SELECTED; } } - // Don't time out during reestablishment (T311 running) - if (!mac_timers->timer_get(t311)->is_running() || !phy->sync_status()) { - select_cell_timeout++; - if (select_cell_timeout >= RRC_SELECT_CELL_TIMEOUT) { - rrc_log->info("RRC Cell Selecting: timeout expired. Starting Cell Search...\n"); - select_cell_timeout = 0; - state = RRC_STATE_PLMN_START; - serving_cell->in_sync = false; - } - } break; case RRC_STATE_CELL_SELECTED: @@ -258,9 +247,9 @@ void rrc::run_thread() { con_restablish_cell_reselected(); state = RRC_STATE_CONNECTING; connecting_timeout = 0; - } else if (connection_requested) { - connection_requested = false; + } else if (nas->is_attaching() || connection_requested) { rrc_log->info("RRC Cell Selected: Sending connection request...\n"); + connection_requested = false; send_con_request(); state = RRC_STATE_CONNECTING; connecting_timeout = 0; @@ -442,8 +431,8 @@ void rrc::plmn_search() { /* This is the NAS interface. When NAS requests to select a PLMN we have to * connect to either register or because there is pending higher layer traffic. */ -void rrc::plmn_select(LIBLTE_RRC_PLMN_IDENTITY_STRUCT plmn_id) { - connection_requested = true; +void rrc::plmn_select(LIBLTE_RRC_PLMN_IDENTITY_STRUCT plmn_id, bool connect_request) { + connection_requested = connect_request; plmn_select_rrc(plmn_id); } @@ -451,37 +440,41 @@ void rrc::plmn_select(LIBLTE_RRC_PLMN_IDENTITY_STRUCT plmn_id) { * selected PLMN */ void rrc::plmn_select_rrc(LIBLTE_RRC_PLMN_IDENTITY_STRUCT plmn_id) { + pthread_mutex_lock(&mutex); + // If already camping on the selected PLMN, select this cell if (state == RRC_STATE_IDLE || state == RRC_STATE_CONNECTED || state == RRC_STATE_PLMN_SELECTION) { if (phy->sync_status() && selected_plmn_id.mcc == plmn_id.mcc && selected_plmn_id.mnc == plmn_id.mnc) { - rrc_log->info("Already camping on selected PLMN, connecting...\n"); + rrc_log->info("Already camping on selected PLMN\n"); } else { selected_plmn_id = plmn_id; - if (serving_cell->plmn_equals(selected_plmn_id)) { - phy->cell_select(serving_cell->get_earfcn(), serving_cell->phy_cell); + if (serving_cell->plmn_equals(selected_plmn_id) && serving_cell->in_sync) { + rrc_log->info("PLMN Id=%s selected, Selecting serving cell earfcn=%d, pci=%d\n", + plmn_id_to_string(plmn_id).c_str(), serving_cell->get_earfcn(), serving_cell->phy_cell.id); } else { bool found = false; for (uint32_t i=0;iplmn_equals(selected_plmn_id)) { - rrc_log->info("PLMN Id=%s selected, PCI=%d\n", plmn_id_to_string(plmn_id).c_str(), neighbour_cells[i]->get_pci()); + rrc_log->info("PLMN Id=%s selected, Selecting neighbour cell PCI=%d\n", plmn_id_to_string(plmn_id).c_str(), neighbour_cells[i]->get_pci()); phy->cell_select(neighbour_cells[i]->get_earfcn(), neighbour_cells[i]->phy_cell); found = true; } } if (!found) { - rrc_log->warning("Could not find any cell for the selected PLMN\n"); - state = RRC_STATE_IDLE; + rrc_log->warning("Could not find any cell for the selected PLMN. Searching another PLMN\n"); + plmn_search(); + pthread_mutex_unlock(&mutex); return; } } } state = RRC_STATE_CELL_SELECTING; - select_cell_timeout = 0; } else { rrc_log->warning("Requested PLMN select in incorrect state %s\n", rrc_state_text[state]); } + pthread_mutex_unlock(&mutex); } void rrc::set_serving_cell(uint32_t earfcn, uint32_t pci) { @@ -494,6 +487,7 @@ void rrc::set_serving_cell(uint32_t earfcn, uint32_t pci) { } void rrc::set_serving_cell(uint32_t cell_idx) { + if (cell_idx < neighbour_cells.size()) { // Remove future serving cell from neighbours to make space for current serving cell @@ -529,29 +523,37 @@ void rrc::set_serving_cell(uint32_t cell_idx) { } } -void rrc::select_next_cell_in_plmn() { +bool rrc::select_next_cell_in_plmn() { // Neighbour cells are sorted in descending order of RSRP for (uint32_t i = 0; i < neighbour_cells.size(); i++) { - if (neighbour_cells[i]->plmn_equals(selected_plmn_id) && + if (/*TODO: CHECK that PLMN matches. Currently we don't receive SIB1 of neighbour cells + * neighbour_cells[i]->plmn_equals(selected_plmn_id) && */ neighbour_cells[i]->in_sync) // matches S criteria { - // Try to select Cell - phy->cell_select(neighbour_cells[i]->get_earfcn(), neighbour_cells[i]->phy_cell); - set_serving_cell(i); - rrc_log->info("Selected cell PCI=%d, EARFCN=%d, Cell ID=0x%x\n", - serving_cell->phy_cell.id, serving_cell->get_earfcn(), - serving_cell->get_cell_id()); - rrc_log->console("Selected cell PCI=%d, EARFCN=%d, Cell ID=0x%x\n", - serving_cell->phy_cell.id, serving_cell->get_earfcn(), - serving_cell->get_cell_id()); - return; + // If currently connected, verify cell selection criteria + if (!serving_cell->in_sync || + (cell_selection_eval(neighbour_cells[i]->get_rsrp()) && + neighbour_cells[i]->get_rsrp() > serving_cell->get_rsrp() + 5)) + { + // Try to select Cell + set_serving_cell(i); + rrc_log->info("Selected cell idx=%d, PCI=%d, EARFCN=%d\n", + i, serving_cell->phy_cell.id, serving_cell->get_earfcn()); + rrc_log->console("Selected cell PCI=%d, EARFCN=%d\n", + serving_cell->phy_cell.id, serving_cell->get_earfcn()); + phy->cell_select(serving_cell->get_earfcn(), serving_cell->phy_cell); + state = RRC_STATE_CELL_SELECTING; + return true; + } } } - rrc_log->info("No more known cells. Starting again\n"); + return false; } void rrc::new_phy_meas(float rsrp, float rsrq, uint32_t tti, int earfcn_i, int pci_i) { + pthread_mutex_lock(&mutex); + if (earfcn_i < 0 || pci_i < 0) { earfcn_i = serving_cell->get_earfcn(); pci_i = serving_cell->phy_cell.id; @@ -582,16 +584,22 @@ 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 (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); - rrc_log->info("Selecting best neighbour cell PCI=%d, rsrp=%.1f dBm\n", serving_cell->phy_cell.id, serving_cell->get_rsrp()); - state = RRC_STATE_CELL_SELECTING; - phy->cell_select(serving_cell->get_earfcn(), serving_cell->phy_cell); - } + // Evaluate if we need to select a new cell + select_next_cell_in_plmn(); + } + pthread_mutex_unlock(&mutex); +} + +// PHY indicates that has gone through all known EARFCN +void rrc::earfcn_end() { + rrc_log->info("Finished searching cells in EARFCN set while in state %s\n", rrc_state_text[state]); + + // If searching for PLMN, indicate NAS we scanned all frequencies + if (state == RRC_STATE_PLMN_SELECTION) { + nas->plmn_search_end(); + } else { + rrc_log->info("Restarting Cell search...\n"); + phy->cell_search_start(); } } @@ -600,51 +608,53 @@ void rrc::new_phy_meas(float rsrp, float rsrq, uint32_t tti, int earfcn_i, int p * new cell as current serving cell */ void rrc::cell_camping(uint32_t earfcn, srslte_cell_t phy_cell, float rsrp) { - bool found = false; - int cell_idx = -1; - + int cell_idx = -1; + bool found = true; + + pthread_mutex_lock(&mutex); + if (serving_cell->equals(earfcn, phy_cell.id)) { serving_cell->set_rsrp(rsrp); - found = true; } else { // Check if cell is in our list of neighbour cells cell_idx = find_neighbour_cell(earfcn, phy_cell.id); if (cell_idx >= 0) { set_serving_cell(cell_idx); serving_cell->set_rsrp(rsrp); - found = true; + } else { + found = false; + if (!add_neighbour_cell(earfcn, phy_cell, rsrp)) { + rrc_log->info( + "No more space for neighbour cells (detected cell RSRP=%.1f dBm worse than current %d neighbours)\n", + rsrp, + NOF_NEIGHBOUR_CELLS); + } else { + set_serving_cell(earfcn, phy_cell.id); + serving_cell->set_rsrp(rsrp); + } } } - if (found) { - if (!serving_cell->has_sib1()) { - si_acquire_state = SI_ACQUIRE_SIB1; - } else if (state == RRC_STATE_PLMN_SELECTION) { - for (uint32_t j = 0; j < serving_cell->sib1ptr()->N_plmn_ids; j++) { - nas->plmn_found(serving_cell->sib1ptr()->plmn_id[j].id, serving_cell->sib1ptr()->tracking_area_code); - } - usleep(5000); - phy->cell_search_next(); + pthread_mutex_unlock(&mutex); + + if (!serving_cell->has_sib1()) { + si_acquire_state = SI_ACQUIRE_SIB1; + } else if (state == RRC_STATE_PLMN_SELECTION) { + bool ret = false; + for (uint32_t j = 0; j < serving_cell->sib1ptr()->N_plmn_ids; j++) { + ret |= nas->plmn_found(serving_cell->sib1ptr()->plmn_id[j].id, serving_cell->sib1ptr()->tracking_area_code); } - } else { - // add to list of known cells and set current_cell - if (!add_neighbour_cell(earfcn, phy_cell, rsrp)) { - rrc_log->info("No more space for neighbour cells (detected cell RSRP=%.1f dBm worse than current %d neighbours)\n", - rsrp, NOF_NEIGHBOUR_CELLS); - usleep(5000); + // If any of the PLMNs in this cell is selected, search next cell + if (!ret) { phy->cell_search_next(); - } else { - set_serving_cell(earfcn, phy_cell.id); - si_acquire_state = SI_ACQUIRE_SIB1; } } rrc_log->info("%s %s cell EARFCN=%d, PCI=%d, RSRP=%.1f dBm\n", found?"Updating":"Adding", - cell_idx>=0?"neighbour":"serving", - serving_cell->get_earfcn(), - serving_cell->phy_cell.id, - serving_cell->get_rsrp()); + cell_idx>=0?"neighbour":"serving", earfcn, phy_cell.id, rsrp); + + } bool sort_rsrp(cell_t *u1, cell_t *u2) { @@ -668,6 +678,8 @@ void rrc::clean_neighbours() struct timeval now; gettimeofday(&now, NULL); + pthread_mutex_lock(&mutex); + std::vector::iterator it = neighbour_cells.begin(); while(it != neighbour_cells.end()) { if ((*it)->timeout_secs(now) > NEIGHBOUR_TIMEOUT) { @@ -677,6 +689,7 @@ void rrc::clean_neighbours() ++it; } } + pthread_mutex_unlock(&mutex); } // Sort neighbour cells by decreasing order of RSRP @@ -695,13 +708,17 @@ void rrc::sort_neighbour_cells() std::sort(neighbour_cells.begin(), neighbour_cells.end(), sort_rsrp); - char ordered[512]; - int n=0; - n += snprintf(ordered, 512, "[pci=%d, rsrsp=%.2f", neighbour_cells[0]->phy_cell.id, neighbour_cells[0]->get_rsrp()); - for (uint32_t i=1;iget_pci(), neighbour_cells[i]->get_rsrp()); + if (neighbour_cells.size() > 0) { + char ordered[512]; + int n=0; + n += snprintf(ordered, 512, "[pci=%d, rsrsp=%.2f", neighbour_cells[0]->phy_cell.id, neighbour_cells[0]->get_rsrp()); + for (uint32_t i=1;iget_pci(), neighbour_cells[i]->get_rsrp()); + } + rrc_log->info("Neighbours: %s]\n", ordered); + } else { + rrc_log->info("Neighbours: Empty\n"); } - rrc_log->info("Neighbours: %s]\n", ordered); } bool rrc::add_neighbour_cell(cell_t *new_cell) { @@ -744,7 +761,7 @@ bool rrc::add_neighbour_cell(uint32_t earfcn, srslte_cell_t phy_cell, float rsrp if (cell_idx >= 0) { neighbour_cells[cell_idx]->set_rsrp(rsrp); sort_neighbour_cells(); - return true; + return true; } // If not, create a new one @@ -762,18 +779,6 @@ int rrc::find_neighbour_cell(uint32_t earfcn, uint32_t pci) { return -1; } -// PHY indicates that has gone through all known EARFCN -void rrc::earfcn_end() { - rrc_log->info("Finished searching cells in EARFCN set while in state %s\n", rrc_state_text[state]); - - // If searching for PLMN, indicate NAS we scanned all frequencies - if (state >= RRC_STATE_PLMN_SELECTION && state < RRC_STATE_CONNECTING) { - nas->plmn_search_end(); - } else if (state >= RRC_STATE_CONNECTING && state < RRC_STATE_LEAVE_CONNECTED) { - leave_connected(); - } -} - // Cell reselection in IDLE Section 5.2.4 of 36.304 void rrc::cell_reselection_eval(float rsrp, float rsrq) { @@ -826,7 +831,6 @@ float rrc::get_squal(float Qqualmeas) { // Detection of physical layer problems in RRC_CONNECTED (5.3.11.1) void rrc::out_of_sync() { - serving_cell->in_sync = false; if (state == RRC_STATE_CONNECTED) { if (!mac_timers->timer_get(t311)->is_running() && !mac_timers->timer_get(t310)->is_running()) { n310_cnt++; @@ -838,9 +842,23 @@ void rrc::out_of_sync() { n310_cnt = 0; } } - } else { - phy->sync_reset(); + } else if (state != RRC_STATE_LEAVE_CONNECTED) { + if (!mac_timers->timer_get(t311)->is_running()) { + if (serving_cell->in_sync) { + rrc_log->info("Detected out-of-sync while in IDLE. Resetting sync\n"); + phy->sync_reset(); + } else { + rrc_log->info("Detected out-of-sync while in IDLE. Selecting another cell in the PLMN\n"); + if (!select_next_cell_in_plmn()) { + rrc_log->info("Could not find any available cell in this PLMN. Searching PLMN again.\n"); + plmn_search(); + } + } + } else { + rrc_log->info("Detected out-of-sync while T311 is running\n"); + } } + serving_cell->in_sync = false; } // Recovery of physical layer problems (5.3.11.2) diff --git a/srsue/test/upper/nas_test.cc b/srsue/test/upper/nas_test.cc index 4f4ffb687..5a4a082ba 100644 --- a/srsue/test/upper/nas_test.cc +++ b/srsue/test/upper/nas_test.cc @@ -81,7 +81,7 @@ public: uint32_t get_last_sdu_len() { return last_sdu_len; } void plmn_search() {}; - void plmn_select(LIBLTE_RRC_PLMN_IDENTITY_STRUCT plmn_id) {}; + void plmn_select(LIBLTE_RRC_PLMN_IDENTITY_STRUCT plmn_id, bool con_req) {}; uint16_t get_mcc() { return mcc; } uint16_t get_mnc() { return mnc; }