From 48138b5281f0c47435f4d9684e5b33d8463de68f Mon Sep 17 00:00:00 2001 From: Francisco Paisana Date: Tue, 7 Jul 2020 18:42:57 +0100 Subject: [PATCH] removal of phy cell selection procedure as it now it is replaced by phy controller --- srsue/hdr/stack/rrc/rrc.h | 9 +- srsue/hdr/stack/rrc/rrc_procedures.h | 32 ++---- srsue/src/stack/rrc/phy_controller.cc | 2 +- srsue/src/stack/rrc/rrc.cc | 12 ++- srsue/src/stack/rrc/rrc_procedures.cc | 144 ++++++++------------------ srsue/test/upper/rrc_phy_ctrl_test.cc | 4 +- 6 files changed, 65 insertions(+), 138 deletions(-) diff --git a/srsue/hdr/stack/rrc/rrc.h b/srsue/hdr/stack/rrc/rrc.h index 9a173dbe9..55d595b4f 100644 --- a/srsue/hdr/stack/rrc/rrc.h +++ b/srsue/hdr/stack/rrc/rrc.h @@ -66,6 +66,9 @@ using srslte::byte_buffer_t; namespace srsue { + +class phy_controller; + class rrc : public rrc_interface_nas, public rrc_interface_phy_lte, public rrc_interface_mac, @@ -191,8 +194,8 @@ 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; + // PHY controller state machine + std::unique_ptr phy_ctrl; rrc_args_t args = {}; @@ -290,7 +293,6 @@ private: enum class cs_result_t { changed_cell, same_cell, no_cell }; // RRC procedures (fwd declared) - class phy_cell_select_proc; class cell_search_proc; class si_acquire_proc; class serving_cell_config_proc; @@ -302,7 +304,6 @@ private: class cell_reselection_proc; class connection_reest_proc; class ho_proc; - srslte::proc_t phy_cell_selector; srslte::proc_t cell_searcher; srslte::proc_t si_acquirer; srslte::proc_t serv_cell_cfg; diff --git a/srsue/hdr/stack/rrc/rrc_procedures.h b/srsue/hdr/stack/rrc/rrc_procedures.h index bb660b7f8..57775eba9 100644 --- a/srsue/hdr/stack/rrc/rrc_procedures.h +++ b/srsue/hdr/stack/rrc/rrc_procedures.h @@ -19,6 +19,7 @@ * */ +#include "phy_controller.h" #include "srslte/common/log.h" #include "srsue/hdr/stack/rrc/rrc.h" #include @@ -43,36 +44,16 @@ struct cell_select_event_t { * Procedures *******************************/ -class rrc::phy_cell_select_proc -{ -public: - explicit phy_cell_select_proc(rrc* parent_); - srslte::proc_outcome_t init(const cell_t& target_cell); - srslte::proc_outcome_t react(cell_select_event_t ev); - void then(const srslte::proc_state_t& result); - srslte::proc_outcome_t step() { return srslte::proc_outcome_t::yield; } - static const char* name() { return "PHY Cell Select"; } - -private: - // args - rrc* rrc_ptr; - const cell_t* target_cell; -}; - class rrc::cell_search_proc { public: - struct cell_search_event_t { - phy_interface_rrc_lte::cell_search_ret_t cs_ret; - phy_interface_rrc_lte::phy_cell_t found_cell; - }; enum class state_t { phy_cell_search, si_acquire, wait_measurement, phy_cell_select }; explicit cell_search_proc(rrc* parent_); srslte::proc_outcome_t init(); srslte::proc_outcome_t step(); srslte::proc_outcome_t step_si_acquire(); - srslte::proc_outcome_t react(const cell_search_event_t& event); + srslte::proc_outcome_t react(const phy_controller::cell_srch_res& event); srslte::proc_outcome_t react(const cell_select_event_t& event); srslte::proc_outcome_t step_wait_measurement(); @@ -86,9 +67,9 @@ private: rrc* rrc_ptr; // state vars - cell_search_event_t search_result; - srslte::proc_future_t si_acquire_fut; - state_t state; + phy_controller::cell_srch_res search_result; + srslte::proc_future_t si_acquire_fut; + state_t state; }; /**************************************************************** @@ -164,7 +145,6 @@ private: srslte::proc_outcome_t start_cell_selection(); srslte::proc_outcome_t step_cell_selection(const cell_select_event_t& event); srslte::proc_outcome_t step_serv_cell_camp(const cell_select_event_t& event); - srslte::proc_outcome_t step_wait_in_sync(); srslte::proc_outcome_t step_cell_search(); srslte::proc_outcome_t step_cell_config(); @@ -172,7 +152,7 @@ private: rrc* rrc_ptr; // state variables - enum class search_state_t { cell_selection, serv_cell_camp, wait_in_sync, cell_config, cell_search }; + enum class search_state_t { cell_selection, serv_cell_camp, cell_config, cell_search }; cs_result_t cs_result; search_state_t state; uint32_t neigh_index; diff --git a/srsue/src/stack/rrc/phy_controller.cc b/srsue/src/stack/rrc/phy_controller.cc index 90e37b230..3c4328461 100644 --- a/srsue/src/stack/rrc/phy_controller.cc +++ b/srsue/src/stack/rrc/phy_controller.cc @@ -126,7 +126,7 @@ void phy_controller::handle_cell_search_res(searching_cell& s, const cell_srch_r log_h->info("PHY cell search completed. Found cell %s\n", to_string(result.found_cell).c_str()); break; case cell_search_ret_t::CELL_NOT_FOUND: - log_h->warning("PHY cell search completed. No cells found\n"); + log_h->warning("PHY cell search completed. No cells found.\n"); break; default: log_h->error("Invalid cell search result\n"); diff --git a/srsue/src/stack/rrc/rrc.cc b/srsue/src/stack/rrc/rrc.cc index b54f90146..2b64f6dc6 100644 --- a/srsue/src/stack/rrc/rrc.cc +++ b/srsue/src/stack/rrc/rrc.cc @@ -23,6 +23,7 @@ #include "srslte/asn1/rrc_asn1.h" #include "srslte/common/bcd_helpers.h" #include "srslte/common/security.h" +#include "srsue/hdr/stack/rrc/phy_controller.h" #include "srsue/hdr/stack/rrc/rrc_meas.h" #include "srsue/hdr/stack/rrc/rrc_procedures.h" #include @@ -57,7 +58,6 @@ rrc::rrc(stack_interface_rrc* stack_, srslte::task_sched_handle task_sched_) : drb_up(false), rrc_log("RRC"), measurements(new rrc_meas()), - phy_cell_selector(this), cell_searcher(this), si_acquirer(this), serv_cell_cfg(this), @@ -116,6 +116,8 @@ void rrc::init(phy_interface_rrc_lte* phy_, args = args_; + phy_ctrl.reset(new phy_controller{phy, stack}); + state = RRC_STATE_IDLE; plmn_is_selected = false; @@ -382,7 +384,7 @@ void rrc::out_of_sync() { // CAUTION: We do not lock in this function since they are called from real-time threads if (meas_cells.serving_cell().is_valid() && rrc_log) { - phy_sync_state = phy_out_of_sync; + phy_ctrl->out_sync(); // upon receiving N310 consecutive "out-of-sync" indications for the PCell from lower layers while neither T300, // T301, T304 nor T311 is running: @@ -412,7 +414,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 - phy_sync_state = phy_in_sync; + phy_ctrl->in_sync(); if (t310.is_running()) { n311_cnt++; if (n311_cnt == N311) { @@ -1008,12 +1010,12 @@ void rrc::start_con_restablishment(reest_cause_e cause) 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) { - cell_searcher.trigger(cell_search_proc::cell_search_event_t{cs_ret, found_cell}); + phy_ctrl->cell_search_completed(cs_ret, found_cell); } void rrc::cell_select_completed(bool cs_ret) { - phy_cell_selector.trigger(cell_select_event_t{cs_ret}); + phy_ctrl->cell_selection_completed(cs_ret); } /** diff --git a/srsue/src/stack/rrc/rrc_procedures.cc b/srsue/src/stack/rrc/rrc_procedures.cc index 75c7a79cd..399341475 100644 --- a/srsue/src/stack/rrc/rrc_procedures.cc +++ b/srsue/src/stack/rrc/rrc_procedures.cc @@ -35,42 +35,6 @@ namespace srsue { using srslte::proc_outcome_t; using srslte::tti_point; -/************************************** - * PHY Cell Select Procedure - *************************************/ - -rrc::phy_cell_select_proc::phy_cell_select_proc(rrc* parent_) : rrc_ptr(parent_) {} - -srslte::proc_outcome_t rrc::phy_cell_select_proc::init(const cell_t& target_cell_) -{ - target_cell = &target_cell_; - Info("Starting for %s\n", target_cell->to_string().c_str()); - rrc_ptr->start_phy_cell_select(&target_cell->phy_cell); - return proc_outcome_t::yield; -} - -srslte::proc_outcome_t rrc::phy_cell_select_proc::react(cell_select_event_t ev) -{ - if (not ev.cs_ret) { - Error("Couldn't select new serving cell\n"); - return proc_outcome_t::error; - } - return proc_outcome_t::success; -} - -void rrc::phy_cell_select_proc::then(const srslte::proc_state_t& result) -{ - Info("Finished %s\n", result.is_success() ? "successfully" : "with error"); - // Warn other procedures that depend on this procedure - if (rrc_ptr->cell_searcher.is_busy()) { - rrc_ptr->cell_searcher.trigger(cell_select_event_t{result.is_success()}); - } else if (rrc_ptr->cell_selector.is_busy()) { - rrc_ptr->cell_selector.trigger(cell_select_event_t{result.is_success()}); - } else { - rrc_ptr->ho_handler.trigger(cell_select_event_t{result.is_success()}); - } -} - /************************************** * Cell Search Procedure *************************************/ @@ -82,7 +46,11 @@ proc_outcome_t rrc::cell_search_proc::init() { Info("Starting...\n"); state = state_t::phy_cell_search; - rrc_ptr->start_phy_cell_search(); + if (not rrc_ptr->phy_ctrl->start_cell_search( + [this](const phy_controller::cell_srch_res& res) { rrc_ptr->cell_searcher.trigger(res); })) { + Warning("Failed to initiate Cell Search.\n"); + return proc_outcome_t::error; + } return proc_outcome_t::yield; } @@ -129,8 +97,9 @@ proc_outcome_t rrc::cell_search_proc::handle_cell_found(const phy_interface_rrc_ rrc_ptr->meas_cells.set_serving_cell(new_cell, false); // set new serving cell in PHY - state = state_t::phy_cell_select; - if (not rrc_ptr->phy_cell_selector.launch(rrc_ptr->meas_cells.serving_cell())) { + state = state_t::phy_cell_select; + auto on_complete = [this](const bool& result) { rrc_ptr->cell_searcher.trigger(cell_select_event_t{result}); }; + if (not rrc_ptr->phy_ctrl->start_cell_select(rrc_ptr->meas_cells.serving_cell().phy_cell, on_complete)) { Error("Couldn't start phy cell selection\n"); return proc_outcome_t::error; } @@ -183,7 +152,7 @@ proc_outcome_t rrc::cell_search_proc::react(const cell_select_event_t& event) return proc_outcome_t::yield; } -proc_outcome_t rrc::cell_search_proc::react(const cell_search_event_t& event) +proc_outcome_t rrc::cell_search_proc::react(const phy_controller::cell_srch_res& event) { if (state != state_t::phy_cell_search) { Error("Received unexpected cell search result\n"); @@ -191,22 +160,14 @@ proc_outcome_t rrc::cell_search_proc::react(const cell_search_event_t& event) } search_result = event; - Info("PHY cell search completed.\n"); // Transition to SI Acquire or finish - switch (search_result.cs_ret.found) { - case phy_interface_rrc_lte::cell_search_ret_t::CELL_FOUND: - 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; - case phy_interface_rrc_lte::cell_search_ret_t::ERROR: - Error("Error while performing cell search\n"); - // TODO: check what errors can happen (currently not handled in our code) - return proc_outcome_t::error; + if (search_result.cs_ret.found == phy_interface_rrc_lte::cell_search_ret_t::CELL_FOUND) { + return handle_cell_found(search_result.found_cell); + } else if (search_result.cs_ret.found == phy_interface_rrc_lte::cell_search_ret_t::CELL_NOT_FOUND) { + // No cells found. Do nothing + return proc_outcome_t::success; } - return proc_outcome_t::yield; + return proc_outcome_t::error; } /**************************************************************** @@ -495,7 +456,7 @@ rrc::cell_selection_proc::cell_selection_proc(rrc* parent_) : rrc_ptr(parent_) { */ proc_outcome_t rrc::cell_selection_proc::init() { - if (rrc_ptr->meas_cells.nof_neighbours() == 0 and rrc_ptr->phy_sync_state == phy_in_sync and + if (rrc_ptr->meas_cells.nof_neighbours() == 0 and rrc_ptr->phy_ctrl->is_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 as there are no neighbour and cell is camping.\n"); @@ -505,7 +466,7 @@ proc_outcome_t rrc::cell_selection_proc::init() Info("Starting...\n"); Info("Current neighbor cells: [%s]\n", rrc_ptr->meas_cells.print_neighbour_cells().c_str()); - Info("Current PHY state: %s\n", rrc_ptr->phy_sync_state == phy_in_sync ? "in-sync" : "out-of-sync"); + Info("Current PHY state: %s\n", rrc_ptr->phy_ctrl->is_in_sync() ? "in-sync" : "out-of-sync"); if (rrc_ptr->meas_cells.serving_cell().has_sib3()) { Info("Cell selection criteria: Qrxlevmin=%f, Qrxlevminoffset=%f\n", rrc_ptr->cell_resel_cfg.Qrxlevmin, @@ -542,15 +503,16 @@ proc_outcome_t rrc::cell_selection_proc::react(const cell_select_event_t& event) proc_outcome_t rrc::cell_selection_proc::start_serv_cell_selection() { - if (rrc_ptr->phy_sync_state == phy_in_sync and rrc_ptr->phy->cell_is_camping()) { + if (rrc_ptr->phy_ctrl->is_in_sync() and rrc_ptr->phy->cell_is_camping()) { cs_result = cs_result_t::same_cell; return proc_outcome_t::success; } Info("Not camping on serving cell %s. Selecting it...\n", rrc_ptr->meas_cells.serving_cell().to_string().c_str()); - state = search_state_t::serv_cell_camp; - if (not rrc_ptr->phy_cell_selector.launch(rrc_ptr->meas_cells.serving_cell())) { + state = search_state_t::serv_cell_camp; + auto on_complete = [this](const bool& result) { rrc_ptr->cell_selector.trigger(cell_select_event_t{result}); }; + if (not rrc_ptr->phy_ctrl->start_cell_select(rrc_ptr->meas_cells.serving_cell().phy_cell, on_complete)) { Error("Failed to launch PHY Cell Selection\n"); return proc_outcome_t::error; } @@ -574,7 +536,7 @@ proc_outcome_t rrc::cell_selection_proc::start_cell_selection() // Matches S criteria float rsrp = rrc_ptr->meas_cells.at(neigh_index).get_rsrp(); - if (rrc_ptr->phy_sync_state != phy_in_sync or + if (not rrc_ptr->phy_ctrl->is_in_sync() or (rrc_ptr->cell_selection_criteria(rsrp) and rsrp > rrc_ptr->meas_cells.serving_cell().get_rsrp() + 5)) { // currently connected and verifies cell selection criteria // Try to select Cell @@ -582,8 +544,9 @@ proc_outcome_t rrc::cell_selection_proc::start_cell_selection() discard_serving = false; Info("Selected cell: %s\n", rrc_ptr->meas_cells.serving_cell().to_string().c_str()); - state = search_state_t::cell_selection; - if (not rrc_ptr->phy_cell_selector.launch(rrc_ptr->meas_cells.serving_cell())) { + state = search_state_t::cell_selection; + auto on_complete = [this](const bool& result) { rrc_ptr->cell_selector.trigger(cell_select_event_t{result}); }; + if (not rrc_ptr->phy_ctrl->start_cell_select(rrc_ptr->meas_cells.serving_cell().phy_cell, on_complete)) { Error("Failed to launch PHY Cell Selection\n"); return proc_outcome_t::error; } @@ -610,17 +573,23 @@ proc_outcome_t rrc::cell_selection_proc::start_cell_selection() proc_outcome_t rrc::cell_selection_proc::step_cell_selection(const cell_select_event_t& event) { - rrc_ptr->phy_sync_state = phy_unknown_sync; - if (event.cs_ret) { // successful selection - Info("Wait PHY to be in-synch\n"); - state = search_state_t::wait_in_sync; - return step(); + if (rrc_ptr->cell_selection_criteria(rrc_ptr->meas_cells.serving_cell().get_rsrp())) { + Info("PHY is in SYNC and cell selection passed\n"); + if (not rrc_ptr->serv_cell_cfg.launch(&serv_cell_cfg_fut, rrc_ptr->ue_required_sibs)) { + return proc_outcome_t::error; + } + state = search_state_t::cell_config; + return proc_outcome_t::yield; + } + Info("PHY is in SYNC but cell selection did not pass. Go back to select step.\n"); + cs_result = cs_result_t::no_cell; + } else { + Error("Could not camp on serving cell.\n"); } - Error("Could not camp on serving cell.\n"); - discard_serving = true; + discard_serving = true; // Discard this cell // Continue to next neighbour cell ++neigh_index; return start_cell_selection(); @@ -635,32 +604,11 @@ srslte::proc_outcome_t rrc::cell_selection_proc::step_serv_cell_camp(const cell_ return proc_outcome_t::success; } - rrc_ptr->phy_sync_state = phy_unknown_sync; rrc_ptr->meas_cells.serving_cell().set_rsrp(-INFINITY); Warning("Could not camp on serving cell.\n"); return neigh_index >= rrc_ptr->meas_cells.nof_neighbours() ? proc_outcome_t::error : proc_outcome_t::yield; } -proc_outcome_t rrc::cell_selection_proc::step_wait_in_sync() -{ - if (rrc_ptr->phy_sync_state == phy_in_sync) { - if (rrc_ptr->cell_selection_criteria(rrc_ptr->meas_cells.serving_cell().get_rsrp())) { - Info("PHY is in SYNC and cell selection passed\n"); - if (not rrc_ptr->serv_cell_cfg.launch(&serv_cell_cfg_fut, rrc_ptr->ue_required_sibs)) { - return proc_outcome_t::error; - } - state = search_state_t::cell_config; - } else { - Info("PHY is in SYNC but cell selection did not pass. Go back to select step.\n"); - cs_result = cs_result_t::no_cell; - neigh_index++; - discard_serving = true; // Discard this cell - return start_cell_selection(); - } - } - return proc_outcome_t::yield; -} - proc_outcome_t rrc::cell_selection_proc::step_cell_search() { if (rrc_ptr->cell_searcher.run()) { @@ -703,8 +651,6 @@ proc_outcome_t rrc::cell_selection_proc::step() case search_state_t::serv_cell_camp: // this state waits for phy event return proc_outcome_t::yield; - 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: @@ -955,11 +901,9 @@ 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->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->phy_sync_state = phy_unknown_sync; break; default: log_h->warning("Could not find any suitable cell to connect\n"); @@ -1132,7 +1076,7 @@ rrc::cell_reselection_proc::cell_reselection_proc(srsue::rrc* rrc_) : rrc_ptr(rr proc_outcome_t rrc::cell_reselection_proc::init() { - if (rrc_ptr->meas_cells.nof_neighbours() == 0 and rrc_ptr->phy_sync_state == phy_in_sync and + if (rrc_ptr->meas_cells.nof_neighbours() == 0 and rrc_ptr->phy_ctrl->is_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; @@ -1171,7 +1115,6 @@ 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->phy_sync_state = phy_unknown_sync; } break; } @@ -1274,7 +1217,7 @@ srslte::proc_outcome_t rrc::connection_reest_proc::step_cell_reselection() } // Cell reselection finished or not started - if (rrc_ptr->phy_sync_state == phy_in_sync) { + if (rrc_ptr->phy_ctrl->is_in_sync()) { // In-sync, check SIBs if (rrc_ptr->meas_cells.serving_cell().has_sib1() && rrc_ptr->meas_cells.serving_cell().has_sib2() && rrc_ptr->meas_cells.serving_cell().has_sib3()) { @@ -1318,7 +1261,7 @@ proc_outcome_t rrc::connection_reest_proc::step_cell_configuration() } // SIBs adquisition not started or finished - if (rrc_ptr->phy_sync_state == phy_in_sync) { + if (rrc_ptr->phy_ctrl->is_in_sync()) { // In-sync if (rrc_ptr->meas_cells.serving_cell().has_sib1() && rrc_ptr->meas_cells.serving_cell().has_sib2() && rrc_ptr->meas_cells.serving_cell().has_sib3()) { @@ -1541,9 +1484,10 @@ srslte::proc_outcome_t rrc::ho_proc::step() rrc_ptr->apply_rr_config_dedicated(&recfg_r8.rr_cfg_ded); } - cell_t* target_cell = + cell_t* target_cell = rrc_ptr->meas_cells.get_neighbour_cell_handle(target_earfcn, recfg_r8.mob_ctrl_info.target_pci); - if (not rrc_ptr->phy_cell_selector.launch(*target_cell)) { + auto on_complete = [this](const bool& result) { rrc_ptr->ho_handler.trigger(cell_select_event_t{result}); }; + if (not rrc_ptr->phy_ctrl->start_cell_select(target_cell->phy_cell, on_complete)) { Error("Failed to launch the selection of target cell %s\n", target_cell->to_string().c_str()); return proc_outcome_t::error; } diff --git a/srsue/test/upper/rrc_phy_ctrl_test.cc b/srsue/test/upper/rrc_phy_ctrl_test.cc index bc4c61731..f855d5055 100644 --- a/srsue/test/upper/rrc_phy_ctrl_test.cc +++ b/srsue/test/upper/rrc_phy_ctrl_test.cc @@ -84,7 +84,7 @@ int test_phy_ctrl_fsm() // TEST: Cell Selection state ignores events other than the cell selection result, and callback is called phy_ctrl.in_sync(); TESTASSERT(not phy_ctrl.is_in_sync()); - phy_ctrl.cell_selection_completed(true); + TESTASSERT(phy_ctrl.cell_selection_completed(true)); // Note: Still in cell selection, but now waiting for the first in_sync TESTASSERT(phy_ctrl.current_state_name() == "selecting_cell"); TESTASSERT(not phy_ctrl.is_in_sync()); @@ -96,7 +96,7 @@ int test_phy_ctrl_fsm() // TEST: Cell Selection with timeout being reached cell_select_success = -1; - phy_ctrl.start_cell_select(found_cell, csel_callback); + TESTASSERT(phy_ctrl.start_cell_select(found_cell, csel_callback)); TESTASSERT(not phy_ctrl.is_in_sync()); phy_ctrl.cell_selection_completed(true); TESTASSERT(phy_ctrl.current_state_name() == "selecting_cell");