diff --git a/srsue/hdr/stack/rrc/rrc.h b/srsue/hdr/stack/rrc/rrc.h index a84792ff5..949d257df 100644 --- a/srsue/hdr/stack/rrc/rrc.h +++ b/srsue/hdr/stack/rrc/rrc.h @@ -260,7 +260,6 @@ class cell_t } phy_interface_rrc_lte::phy_cell_t phy_cell = {}; - bool in_sync = false; bool has_mcch = false; asn1::rrc::sib_type1_s sib1; asn1::rrc::sib_type2_s sib2; @@ -328,9 +327,9 @@ public: void paging_completed(bool outcome) final; // PHY interface - void in_sync(); - void out_of_sync(); - void new_phy_meas(float rsrp, float rsrq, uint32_t tti, int earfcn, int pci); + void in_sync() final; + void out_of_sync() final; + void new_phy_meas(float rsrp, float rsrq, uint32_t tti, int earfcn, int pci) final; // MAC interface void ho_ra_completed(bool ra_successful); @@ -390,6 +389,9 @@ private: bool drb_up = false; + typedef enum { phy_unknown_sync = 0, phy_in_sync, phy_out_of_sync } phy_sync_state_t; + phy_sync_state_t phy_sync_state = phy_unknown_sync; + rrc_args_t args = {}; uint32_t cell_clean_cnt = 0; diff --git a/srsue/hdr/stack/rrc/rrc_procedures.h b/srsue/hdr/stack/rrc/rrc_procedures.h index 7618d982f..e76f84df1 100644 --- a/srsue/hdr/stack/rrc/rrc_procedures.h +++ b/srsue/hdr/stack/rrc/rrc_procedures.h @@ -117,6 +117,7 @@ public: private: srslte::proc_outcome_t step_cell_selection(); + srslte::proc_outcome_t step_wait_in_sync(); srslte::proc_outcome_t step_cell_search(); srslte::proc_outcome_t step_cell_config(); @@ -124,7 +125,7 @@ private: rrc* rrc_ptr; // state variables - enum class search_state_t { cell_selection, cell_config, cell_search }; + enum class search_state_t { cell_selection, wait_in_sync, cell_config, cell_search }; cs_result_t cs_result; search_state_t state; uint32_t neigh_index; diff --git a/srsue/src/phy/sync.cc b/srsue/src/phy/sync.cc index 62854410d..35dae9655 100644 --- a/srsue/src/phy/sync.cc +++ b/srsue/src/phy/sync.cc @@ -330,6 +330,7 @@ bool sync::cell_select(phy_interface_rrc_lte::phy_cell_t* new_cell) phy_state.run_sfn_sync(); if (phy_state.is_camping()) { Info("Cell Select: SFN synchronized. CAMPING...\n"); + stack->in_sync(); ret = true; } else { Info("Cell Select: Could not synchronize SFN\n"); diff --git a/srsue/src/stack/rrc/rrc.cc b/srsue/src/stack/rrc/rrc.cc index 913b0f093..ffefbdd14 100644 --- a/srsue/src/stack/rrc/rrc.cc +++ b/srsue/src/stack/rrc/rrc.cc @@ -201,6 +201,8 @@ void rrc::run_tti(uint32_t tti) return; } + rrc_log->step(tti); + if (simulate_rlf) { radio_link_failure(); simulate_rlf = false; @@ -425,7 +427,7 @@ void rrc::out_of_sync() { // CAUTION: We do not lock in this function since they are called from real-time threads if (serving_cell && timers && rrc_log) { - serving_cell->in_sync = false; + phy_sync_state = phy_out_of_sync; // upon receiving N310 consecutive "out-of-sync" indications for the PCell from lower layers while neither T300, // T301, T304 nor T311 is running: @@ -452,7 +454,7 @@ void rrc::out_of_sync() void rrc::in_sync() { // CAUTION: We do not lock in this function since they are called from real-time threads - serving_cell->in_sync = true; + phy_sync_state = phy_in_sync; if (t310.is_running()) { n311_cnt++; if (n311_cnt == N311) { @@ -1346,7 +1348,7 @@ void rrc::start_con_restablishment(asn1::rrc::reest_cause_e cause) void rrc::start_cell_reselection() { - if (neighbour_cells.empty() and serving_cell->in_sync and phy->cell_is_camping()) { + if (neighbour_cells.empty() and phy_sync_state == phy_in_sync and phy->cell_is_camping()) { // don't bother with cell selection if there are no neighbours and we are already camping return; } diff --git a/srsue/src/stack/rrc/rrc_procedures.cc b/srsue/src/stack/rrc/rrc_procedures.cc index 3e7b51fad..47cc57920 100644 --- a/srsue/src/stack/rrc/rrc_procedures.cc +++ b/srsue/src/stack/rrc/rrc_procedures.cc @@ -116,6 +116,7 @@ proc_outcome_t rrc::cell_search_proc::react(const cell_search_event_t& event) return handle_cell_found(search_result.found_cell); } case phy_interface_rrc_lte::cell_search_ret_t::CELL_NOT_FOUND: + rrc_ptr->phy_sync_state = phy_unknown_sync; Info("No cells found.\n"); // do nothing return proc_outcome_t::success; @@ -329,7 +330,7 @@ rrc::cell_selection_proc::cell_selection_proc(rrc* parent_) : rrc_ptr(parent_) { */ proc_outcome_t rrc::cell_selection_proc::init() { - if (rrc_ptr->neighbour_cells.empty() and rrc_ptr->serving_cell->in_sync and rrc_ptr->phy->cell_is_camping()) { + if (rrc_ptr->neighbour_cells.empty() and rrc_ptr->phy_sync_state == phy_in_sync and rrc_ptr->phy->cell_is_camping()) { // don't bother with cell selection if there are no neighbours and we are already camping Debug("Skipping Cell Selection Procedure ..\n"); cs_result = cs_result_t::same_cell; @@ -350,35 +351,30 @@ proc_outcome_t rrc::cell_selection_proc::step_cell_selection() for (; neigh_index < rrc_ptr->neighbour_cells.size(); ++neigh_index) { /*TODO: CHECK that PLMN matches. Currently we don't receive SIB1 of neighbour cells * neighbour_cells[i]->plmn_equals(selected_plmn_id) && */ - if (rrc_ptr->neighbour_cells.at(neigh_index)->in_sync) { - // Matches S criteria - float rsrp = rrc_ptr->neighbour_cells.at(neigh_index)->get_rsrp(); - - if (not rrc_ptr->serving_cell->in_sync or - (rrc_ptr->cell_selection_criteria(rsrp) and rsrp > rrc_ptr->serving_cell->get_rsrp() + 5)) { - // currently connected and verifies cell selection criteria - // Try to select Cell - rrc_ptr->set_serving_cell(rrc_ptr->neighbour_cells.at(neigh_index)->phy_cell); - Info("Selected cell: %s\n", rrc_ptr->serving_cell->print().c_str()); - rrc_ptr->rrc_log->console("Selected cell: %s\n", rrc_ptr->serving_cell->print().c_str()); - - /* BLOCKING CALL */ - if (rrc_ptr->phy->cell_select(&rrc_ptr->serving_cell->phy_cell)) { - serv_cell_cfg_fut = rrc_ptr->serv_cell_cfg.get_future(); - if (not rrc_ptr->serv_cell_cfg.launch(rrc_ptr->ue_required_sibs)) { - return proc_outcome_t::error; - } - state = search_state_t::cell_config; - return proc_outcome_t::repeat; - } else { - rrc_ptr->serving_cell->in_sync = false; - Error("Could not camp on serving cell.\n"); - // Continue to next neighbour cell - } + // Matches S criteria + float rsrp = rrc_ptr->neighbour_cells.at(neigh_index)->get_rsrp(); + + if (rrc_ptr->phy_sync_state != phy_in_sync or + (rrc_ptr->cell_selection_criteria(rsrp) and rsrp > rrc_ptr->serving_cell->get_rsrp() + 5)) { + // currently connected and verifies cell selection criteria + // Try to select Cell + rrc_ptr->set_serving_cell(rrc_ptr->neighbour_cells.at(neigh_index)->phy_cell); + Info("Selected cell: %s\n", rrc_ptr->serving_cell->print().c_str()); + rrc_ptr->rrc_log->console("Selected cell: %s\n", rrc_ptr->serving_cell->print().c_str()); + + /* BLOCKING CALL */ + if (rrc_ptr->phy->cell_select(&rrc_ptr->serving_cell->phy_cell)) { + Info("Wait PHY to be in-synch\n"); + state = search_state_t::wait_in_sync; + return proc_outcome_t::repeat; + } else { + rrc_ptr->phy_sync_state = phy_unknown_sync; + Error("Could not camp on serving cell.\n"); + // Continue to next neighbour cell } } } - if (rrc_ptr->serving_cell->in_sync) { + if (rrc_ptr->phy_sync_state == phy_in_sync) { if (not rrc_ptr->phy->cell_is_camping()) { Info("Serving cell %s is in-sync but not camping. Selecting it...\n", rrc_ptr->serving_cell->print().c_str()); @@ -386,7 +382,7 @@ proc_outcome_t rrc::cell_selection_proc::step_cell_selection() if (rrc_ptr->phy->cell_select(&rrc_ptr->serving_cell->phy_cell)) { Info("Selected serving cell OK.\n"); } else { - rrc_ptr->serving_cell->in_sync = false; + rrc_ptr->phy_sync_state = phy_unknown_sync; Error("Could not camp on serving cell.\n"); return proc_outcome_t::error; } @@ -405,6 +401,19 @@ proc_outcome_t rrc::cell_selection_proc::step_cell_selection() return proc_outcome_t::repeat; } +proc_outcome_t rrc::cell_selection_proc::step_wait_in_sync() +{ + if (rrc_ptr->phy_sync_state == phy_in_sync) { + Info("PHY is in SYNC\n"); + serv_cell_cfg_fut = rrc_ptr->serv_cell_cfg.get_future(); + if (not rrc_ptr->serv_cell_cfg.launch(rrc_ptr->ue_required_sibs)) { + return proc_outcome_t::error; + } + state = search_state_t::cell_config; + } + return proc_outcome_t::yield; +} + proc_outcome_t rrc::cell_selection_proc::step_cell_search() { if (rrc_ptr->cell_searcher.run()) { @@ -443,6 +452,8 @@ proc_outcome_t rrc::cell_selection_proc::step() switch (state) { case search_state_t::cell_selection: return step_cell_selection(); + case search_state_t::wait_in_sync: + return step_wait_in_sync(); case search_state_t::cell_config: return step_cell_config(); case search_state_t::cell_search: @@ -684,11 +695,11 @@ srslte::proc_outcome_t rrc::connection_request_proc::react(const cell_selection_ switch (cs_ret) { case cs_result_t::same_cell: log_h->warning("Did not reselect cell but serving cell is out-of-sync.\n"); - rrc_ptr->serving_cell->in_sync = false; + rrc_ptr->phy_sync_state = phy_unknown_sync; break; case cs_result_t::changed_cell: log_h->warning("Selected a new cell but could not camp on. Setting out-of-sync.\n"); - rrc_ptr->serving_cell->in_sync = false; + rrc_ptr->phy_sync_state = phy_unknown_sync; break; default: log_h->warning("Could not find any suitable cell to connect\n"); @@ -861,7 +872,7 @@ proc_outcome_t rrc::cell_reselection_proc::step() case cs_result_t::same_cell: if (!rrc_ptr->phy->cell_is_camping()) { Warning("Did not reselect cell but serving cell is out-of-sync.\n"); - rrc_ptr->serving_cell->in_sync = false; + rrc_ptr->phy_sync_state = phy_unknown_sync; } break; } @@ -945,7 +956,7 @@ srslte::proc_outcome_t rrc::connection_reest_proc::step_cell_reselection() // Run cell reselection if (not rrc_ptr->cell_reselector.run()) { // Cell reselection finished or not started - if (rrc_ptr->serving_cell->in_sync) { + if (rrc_ptr->phy_sync_state == phy_in_sync) { // In-sync, check SIBs if (rrc_ptr->serving_cell->has_sib1() && rrc_ptr->serving_cell->has_sib2() && rrc_ptr->serving_cell->has_sib3()) { Info("In-sync, SIBs available. Going to cell criteria\n"); @@ -978,7 +989,7 @@ proc_outcome_t rrc::connection_reest_proc::step_cell_configuration() { if (not rrc_ptr->serv_cell_cfg.run()) { // SIBs adquisition not started or finished - if (rrc_ptr->serving_cell->in_sync) { + if (rrc_ptr->phy_sync_state == phy_in_sync) { // In-sync if (rrc_ptr->serving_cell->has_sib1() && rrc_ptr->serving_cell->has_sib2() && rrc_ptr->serving_cell->has_sib3()) { // All SIBs are available