diff --git a/srsue/hdr/stack/rrc/rrc.h b/srsue/hdr/stack/rrc/rrc.h index bd24627d3..2b13b4596 100644 --- a/srsue/hdr/stack/rrc/rrc.h +++ b/srsue/hdr/stack/rrc/rrc.h @@ -579,7 +579,6 @@ private: void leave_connected(); void stop_timers(); void start_con_restablishment(asn1::rrc::reest_cause_e cause); - void start_cell_reselection(); void log_rr_config_common(); void log_phy_config_dedicated(); diff --git a/srsue/hdr/stack/rrc/rrc_procedures.h b/srsue/hdr/stack/rrc/rrc_procedures.h index 6ca66cb2f..bb660b7f8 100644 --- a/srsue/hdr/stack/rrc/rrc_procedures.h +++ b/srsue/hdr/stack/rrc/rrc_procedures.h @@ -259,6 +259,7 @@ public: srslte::proc_outcome_t step(); srslte::proc_outcome_t react(bool timeout); static const char* name() { return "Go Idle"; } + void then(const srslte::proc_state_t& result); private: static const uint32_t rlc_flush_timeout_ms = 60; // TS 36.331 Sec 5.3.8.3 @@ -270,15 +271,19 @@ private: class rrc::cell_reselection_proc { public: + const static uint32_t cell_reselection_periodicity_ms = 20; + cell_reselection_proc(rrc* rrc_); srslte::proc_outcome_t init(); srslte::proc_outcome_t step(); static const char* name() { return "Cell Reselection"; } + void then(const srslte::proc_state_t& result); private: rrc* rrc_ptr; - srslte::proc_future_t cell_selection_fut; + srslte::timer_handler::unique_timer reselection_timer; + srslte::proc_future_t cell_selection_fut; }; class rrc::connection_reest_proc diff --git a/srsue/src/stack/rrc/rrc.cc b/srsue/src/stack/rrc/rrc.cc index ee976a11b..4624839d3 100644 --- a/srsue/src/stack/rrc/rrc.cc +++ b/srsue/src/stack/rrc/rrc.cc @@ -253,16 +253,6 @@ void rrc::run_tti() // Run state machine switch (state) { case RRC_STATE_IDLE: - - /* CAUTION: The execution of cell_search() and cell_selection() take more than 1 ms - * and will slow down MAC TTI ticks. This has no major effect at the moment because - * the UE is in IDLE but we could consider splitting MAC and RRC threads to avoid this - */ - - // If attached but not camping on the cell, perform cell reselection - if (nas->is_attached()) { - start_cell_reselection(); - } break; case RRC_STATE_CONNECTED: measurements->run_tti(); @@ -1251,24 +1241,6 @@ void rrc::start_con_restablishment(reest_cause_e cause) callback_list.add_proc(connection_reest); } -void rrc::start_cell_reselection() -{ - 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; - } - - if (cell_reselector.is_busy()) { - // it is already running - return; - } - - if (not cell_reselector.launch()) { - rrc_log->error("Failed to initiate a Cell Reselection procedure...\n"); - } - callback_list.add_proc(cell_reselector); -} - void rrc::cell_search_completed(const phy_interface_rrc_lte::cell_search_ret_t& cs_ret, const phy_interface_rrc_lte::phy_cell_t& found_cell) { diff --git a/srsue/src/stack/rrc/rrc_procedures.cc b/srsue/src/stack/rrc/rrc_procedures.cc index fd5e2ea51..d5a6ee1d3 100644 --- a/srsue/src/stack/rrc/rrc_procedures.cc +++ b/srsue/src/stack/rrc/rrc_procedures.cc @@ -1101,14 +1101,44 @@ proc_outcome_t rrc::go_idle_proc::step() return proc_outcome_t::yield; } +void rrc::go_idle_proc::then(const srslte::proc_state_t& result) +{ + if (not rrc_ptr->cell_reselector.launch()) { + rrc_ptr->rrc_log->error("Failed to initiate a Cell Reselection procedure...\n"); + return; + } + rrc_ptr->callback_list.add_proc(rrc_ptr->cell_reselector); +} + /************************************** * Cell Reselection procedure *************************************/ -rrc::cell_reselection_proc::cell_reselection_proc(srsue::rrc* rrc_) : rrc_ptr(rrc_) {} +rrc::cell_reselection_proc::cell_reselection_proc(srsue::rrc* rrc_) : rrc_ptr(rrc_) +{ + // Timer for cell reselection procedure to self-relaunch periodically + reselection_timer = rrc_ptr->stack->get_unique_timer(); + reselection_timer.set(cell_reselection_periodicity_ms, [this](uint32_t tid) { + if (not rrc_ptr->cell_reselector.launch()) { + rrc_ptr->rrc_log->error("Failed to initiate a Cell Reselection procedure...\n"); + return; + } + rrc_ptr->callback_list.add_proc(rrc_ptr->cell_reselector); + }); +} proc_outcome_t rrc::cell_reselection_proc::init() { + if (not rrc_ptr->nas->is_attached() or rrc_ptr->is_connected()) { + // check if rrc is still idle + return proc_outcome_t::success; + } + + 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 + return proc_outcome_t::success; + } + Info("Starting...\n"); if (not rrc_ptr->cell_selector.launch(&cell_selection_fut)) { Error("Failed to initiate a Cell Selection procedure...\n"); @@ -1150,6 +1180,14 @@ proc_outcome_t rrc::cell_reselection_proc::step() return srslte::proc_outcome_t::success; } +void rrc::cell_reselection_proc::then(const srslte::proc_state_t& result) +{ + // Schedule cell reselection periodically, while rrc is idle + if (not rrc_ptr->is_connected() and rrc_ptr->nas->is_attached()) { + reselection_timer.run(); + } +} + /************************************** * RRC Connection Re-establishment procedure *************************************/