From 9c5471b0942a7f32b0432f7c06416ce78caea548 Mon Sep 17 00:00:00 2001 From: Francisco Paisana Date: Wed, 8 Jul 2020 12:36:55 +0100 Subject: [PATCH] more ergonomic event callback --- lib/include/srslte/common/fsm.h | 14 +++- srsue/hdr/stack/rrc/rrc_procedures.h | 20 ++---- srsue/src/stack/rrc/rrc_procedures.cc | 47 +++++++------- srsue/test/upper/rrc_phy_ctrl_test.cc | 92 ++++++++++++++++----------- 4 files changed, 96 insertions(+), 77 deletions(-) diff --git a/lib/include/srslte/common/fsm.h b/lib/include/srslte/common/fsm.h index 7bcb6c63b..0a044b580 100644 --- a/lib/include/srslte/common/fsm.h +++ b/lib/include/srslte/common/fsm.h @@ -682,7 +682,19 @@ private: }; template -using event_callback = std::function; +struct event_callback { + event_callback() = default; + template + explicit event_callback(FSM* f) + { + callback = [f](const Event& ev) { f->trigger(ev); }; + } + + void operator()(const Event& ev) { callback(ev); } + void operator()(const Event& ev) const { callback(ev); } + + std::function callback; +}; } // namespace srslte diff --git a/srsue/hdr/stack/rrc/rrc_procedures.h b/srsue/hdr/stack/rrc/rrc_procedures.h index 57775eba9..fc2f27336 100644 --- a/srsue/hdr/stack/rrc/rrc_procedures.h +++ b/srsue/hdr/stack/rrc/rrc_procedures.h @@ -30,16 +30,6 @@ namespace srsue { -/******************************** - * Events - *******************************/ - -// background workers use this event to signal the result of a cell select phy procedure -struct cell_select_event_t { - explicit cell_select_event_t(bool c_) : cs_ret(c_) {} - bool cs_ret; -}; - /******************************** * Procedures *******************************/ @@ -54,7 +44,7 @@ public: srslte::proc_outcome_t step(); srslte::proc_outcome_t step_si_acquire(); 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 react(const bool& event); srslte::proc_outcome_t step_wait_measurement(); phy_interface_rrc_lte::cell_search_ret_t get_result() const { return search_result.cs_ret; } @@ -138,13 +128,13 @@ public: void then(const srslte::proc_result_t& proc_result) const; cs_result_t get_result() const { return cs_result; } static const char* name() { return "Cell Selection"; } - srslte::proc_outcome_t react(const cell_select_event_t& event); + srslte::proc_outcome_t react(const bool& event); private: srslte::proc_outcome_t start_serv_cell_selection(); 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_cell_selection(const bool& event); + srslte::proc_outcome_t step_serv_cell_camp(const bool& event); srslte::proc_outcome_t step_cell_search(); srslte::proc_outcome_t step_cell_config(); @@ -299,7 +289,7 @@ public: explicit ho_proc(rrc* rrc_); srslte::proc_outcome_t init(const asn1::rrc::rrc_conn_recfg_s& rrc_reconf); - srslte::proc_outcome_t react(cell_select_event_t ev); + srslte::proc_outcome_t react(const bool& ev); srslte::proc_outcome_t react(t304_expiry ev); srslte::proc_outcome_t react(ra_completed_ev ev); srslte::proc_outcome_t step(); diff --git a/srsue/src/stack/rrc/rrc_procedures.cc b/srsue/src/stack/rrc/rrc_procedures.cc index 8498bb00a..12ab5641c 100644 --- a/srsue/src/stack/rrc/rrc_procedures.cc +++ b/srsue/src/stack/rrc/rrc_procedures.cc @@ -45,9 +45,8 @@ rrc::cell_search_proc::cell_search_proc(rrc* parent_) : rrc_ptr(parent_) {} proc_outcome_t rrc::cell_search_proc::init() { Info("Starting...\n"); - state = state_t::phy_cell_search; - auto on_complete = [this](const phy_controller::cell_srch_res& res) { rrc_ptr->cell_searcher.trigger(res); }; - rrc_ptr->phy_ctrl->start_cell_search(on_complete); + state = state_t::phy_cell_search; + rrc_ptr->phy_ctrl->start_cell_search(srslte::event_callback{&rrc_ptr->cell_searcher}); if (not rrc_ptr->phy_ctrl->is_in_state()) { Warning("Failed to initiate Cell Search.\n"); return proc_outcome_t::error; @@ -98,9 +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; - 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)) { + state = state_t::phy_cell_select; + if (not rrc_ptr->phy_ctrl->start_cell_select(rrc_ptr->meas_cells.serving_cell().phy_cell, + srslte::event_callback{&rrc_ptr->cell_searcher})) { Error("Couldn't start phy cell selection\n"); return proc_outcome_t::error; } @@ -129,14 +128,14 @@ proc_outcome_t rrc::cell_search_proc::step_wait_measurement() return step(); } -proc_outcome_t rrc::cell_search_proc::react(const cell_select_event_t& event) +proc_outcome_t rrc::cell_search_proc::react(const bool& cs_ret) { if (state != state_t::phy_cell_select) { Warning("Received unexpected cell search result\n"); return proc_outcome_t::yield; } - if (not event.cs_ret) { + if (not cs_ret) { Error("Couldn't select new serving cell\n"); return proc_outcome_t::error; } @@ -484,7 +483,7 @@ proc_outcome_t rrc::cell_selection_proc::init() return start_cell_selection(); } -proc_outcome_t rrc::cell_selection_proc::react(const cell_select_event_t& event) +proc_outcome_t rrc::cell_selection_proc::react(const bool& event) { switch (state) { case search_state_t::cell_selection: { @@ -511,9 +510,9 @@ proc_outcome_t rrc::cell_selection_proc::start_serv_cell_selection() 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; - 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)) { + state = search_state_t::serv_cell_camp; + if (not rrc_ptr->phy_ctrl->start_cell_select(rrc_ptr->meas_cells.serving_cell().phy_cell, + srslte::event_callback{&rrc_ptr->cell_selector})) { Error("Failed to launch PHY Cell Selection\n"); return proc_outcome_t::error; } @@ -545,9 +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; - auto on_complete = [this](const bool& result) { rrc_ptr->cell_selector.trigger(cell_select_event_t{result}); }; - rrc_ptr->phy_ctrl->start_cell_select(rrc_ptr->meas_cells.serving_cell().phy_cell, on_complete); + state = search_state_t::cell_selection; + rrc_ptr->phy_ctrl->start_cell_select(rrc_ptr->meas_cells.serving_cell().phy_cell, + srslte::event_callback{&rrc_ptr->cell_selector}); if (not rrc_ptr->phy_ctrl->is_in_state()) { Error("Failed to launch PHY Cell Selection\n"); return proc_outcome_t::error; @@ -573,9 +572,9 @@ proc_outcome_t rrc::cell_selection_proc::start_cell_selection() return step(); } -proc_outcome_t rrc::cell_selection_proc::step_cell_selection(const cell_select_event_t& event) +proc_outcome_t rrc::cell_selection_proc::step_cell_selection(const bool& cs_ret) { - if (event.cs_ret) { + if (cs_ret) { // successful selection if (rrc_ptr->cell_selection_criteria(rrc_ptr->meas_cells.serving_cell().get_rsrp())) { Info("PHY is in SYNC and cell selection passed\n"); @@ -597,10 +596,10 @@ proc_outcome_t rrc::cell_selection_proc::step_cell_selection(const cell_select_e return start_cell_selection(); } -srslte::proc_outcome_t rrc::cell_selection_proc::step_serv_cell_camp(const cell_select_event_t& event) +srslte::proc_outcome_t rrc::cell_selection_proc::step_serv_cell_camp(const bool& cs_ret) { // if we are now camping, the proc was successful - if (event.cs_ret) { + if (cs_ret) { Info("Selected serving cell OK.\n"); cs_result = cs_result_t::same_cell; return proc_outcome_t::success; @@ -1392,7 +1391,7 @@ srslte::proc_outcome_t rrc::ho_proc::init(const asn1::rrc::rrc_conn_recfg_s& rrc return proc_outcome_t::yield; } -srslte::proc_outcome_t rrc::ho_proc::react(srsue::cell_select_event_t ev) +srslte::proc_outcome_t rrc::ho_proc::react(const bool& cs_ret) { if (state != wait_phy_cell_select_complete) { Warning("Received unexpected PHY Cell Selection event\n"); @@ -1405,7 +1404,7 @@ srslte::proc_outcome_t rrc::ho_proc::react(srsue::cell_select_event_t ev) return proc_outcome_t::error; } - if (not ev.cs_ret) { + if (not cs_ret) { Error("Could not synchronize with target cell %s. Removing cell and trying to return to source %s\n", target_cell->to_string().c_str(), rrc_ptr->meas_cells.serving_cell().to_string().c_str()); @@ -1486,10 +1485,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); - auto on_complete = [this](const bool& result) { rrc_ptr->ho_handler.trigger(cell_select_event_t{result}); }; - rrc_ptr->phy_ctrl->start_cell_select(rrc_ptr->meas_cells.serving_cell().phy_cell, on_complete); + rrc_ptr->phy_ctrl->start_cell_select(rrc_ptr->meas_cells.serving_cell().phy_cell, + srslte::event_callback{&rrc_ptr->ho_handler}); if (not rrc_ptr->phy_ctrl->is_in_state()) { 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 26bf28784..f1bc80c8d 100644 --- a/srsue/test/upper/rrc_phy_ctrl_test.cc +++ b/srsue/test/upper/rrc_phy_ctrl_test.cc @@ -25,12 +25,51 @@ namespace srsue { +struct cell_search_result_test { + cell_search_result_test(phy_controller* phy_ctrl_) : phy_ctrl(phy_ctrl_) {} + + void trigger(const phy_controller::cell_srch_res& result_) + { + trigger_called = true; + result = result_; + + if (phy_ctrl->current_state_name() == "searching_cell" or phy_ctrl->is_trigger_locked()) { + phy_ctrl->get_log()->error( + "When caller is signalled with cell search result, cell search state cannot be active\n"); + exit(1); + } + } + + bool trigger_called = false; + phy_controller::cell_srch_res result = {}; + phy_controller* phy_ctrl = nullptr; +}; + +struct cell_select_result_test { + cell_select_result_test(phy_controller* phy_ctrl_) : phy_ctrl(phy_ctrl_) {} + + void trigger(const bool& result_) + { + result = result_ ? 1 : 0; + if (phy_ctrl->current_state_name() == "selecting_cell" or phy_ctrl->is_trigger_locked()) { + phy_ctrl->get_log()->error( + "When caller is signalled with cell select result, cell select state cannot be active\n"); + exit(1); + } + } + + int result = -1; + phy_controller* phy_ctrl = nullptr; +}; + int test_phy_ctrl_fsm() { - srslte::log_ref test_log{"TEST"}; - stack_test_dummy stack; - phy_dummy_interface phy; - phy_controller phy_ctrl{&phy, &stack}; + srslte::log_ref test_log{"TEST"}; + stack_test_dummy stack; + phy_dummy_interface phy; + phy_controller phy_ctrl{&phy, &stack}; + cell_search_result_test csearch_tester{&phy_ctrl}; + cell_select_result_test csel_tester{&phy_ctrl}; TESTASSERT(not phy_ctrl.is_in_sync()); TESTASSERT(not phy_ctrl.cell_is_camping()); @@ -44,19 +83,7 @@ int test_phy_ctrl_fsm() TESTASSERT(phy_ctrl.is_in_sync()); // TEST: Correct initiation of Cell Search state - bool csearch_res_present = false; - phy_controller::cell_srch_res csearch_res = {}; - auto cell_sel_callback = - [&csearch_res_present, &csearch_res, &phy_ctrl](const phy_controller::cell_srch_res& result) { - csearch_res_present = true; - csearch_res = result; - if (phy_ctrl.current_state_name() == "searching_cell" or phy_ctrl.is_trigger_locked()) { - phy_ctrl.get_log()->error( - "When caller is signalled with cell search result, cell search state cannot be active\n"); - exit(1); - } - }; - TESTASSERT(phy_ctrl.start_cell_search(cell_sel_callback)); + TESTASSERT(phy_ctrl.start_cell_search(srslte::event_callback{&csearch_tester})); TESTASSERT(not phy_ctrl.is_in_sync()); // TEST: Cell Search only listens to a cell search result event @@ -75,25 +102,16 @@ int test_phy_ctrl_fsm() // TEST: Check propagation of cell search result to caller stack.run_tti(); - TESTASSERT(csearch_res_present); - TESTASSERT(csearch_res.cs_ret.found == cs_ret.found); - TESTASSERT(csearch_res.found_cell.pci == found_cell.pci); - TESTASSERT(csearch_res.found_cell.earfcn == found_cell.earfcn); + TESTASSERT(csearch_tester.trigger_called); + TESTASSERT(csearch_tester.result.cs_ret.found == cs_ret.found); + TESTASSERT(csearch_tester.result.found_cell.pci == found_cell.pci); + TESTASSERT(csearch_tester.result.found_cell.earfcn == found_cell.earfcn); phy_ctrl.in_sync(); TESTASSERT(phy_ctrl.is_in_sync()); phy_ctrl.out_sync(); // TEST: Correct initiation of Cell Select state - int cell_select_success = -1; - auto csel_callback = [&cell_select_success, &phy_ctrl](const bool& res) { - cell_select_success = res ? 1 : 0; - if (phy_ctrl.current_state_name() == "selecting_cell" or phy_ctrl.is_trigger_locked()) { - phy_ctrl.get_log()->error( - "When caller is signalled with cell selection result, cell selection state cannot be active\n"); - exit(1); - } - }; - phy_ctrl.start_cell_select(found_cell, csel_callback); + phy_ctrl.start_cell_select(found_cell, srslte::event_callback{&csel_tester}); TESTASSERT(not phy_ctrl.is_in_sync()); TESTASSERT(phy_ctrl.current_state_name() == "selecting_cell"); @@ -104,22 +122,22 @@ int test_phy_ctrl_fsm() // 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()); - TESTASSERT(cell_select_success < 0); + TESTASSERT(csel_tester.result < 0); phy_ctrl.in_sync(); TESTASSERT(phy_ctrl.is_in_sync()); TESTASSERT(phy_ctrl.current_state_name() != "selecting_cell"); // TEST: Propagation of cell selection result to caller stack.run_tti(); - TESTASSERT(cell_select_success == 1); + TESTASSERT(csel_tester.result == 1); // TEST: Cell Selection with timeout being reached - cell_select_success = -1; - TESTASSERT(phy_ctrl.start_cell_select(found_cell, csel_callback)); + csel_tester.result = -1; + TESTASSERT(phy_ctrl.start_cell_select(found_cell, srslte::event_callback{&csel_tester})); TESTASSERT(not phy_ctrl.is_in_sync()); phy_ctrl.cell_selection_completed(true); TESTASSERT(phy_ctrl.current_state_name() == "selecting_cell"); - TESTASSERT(cell_select_success < 0); + TESTASSERT(csel_tester.result < 0); for (uint32_t i = 0; i < phy_controller::wait_sync_timeout_ms; ++i) { TESTASSERT(phy_ctrl.current_state_name() == "selecting_cell"); @@ -129,7 +147,7 @@ int test_phy_ctrl_fsm() // TEST: Propagation of cell selection result to caller stack.run_tti(); - TESTASSERT(cell_select_success == 0); + TESTASSERT(csel_tester.result == 0); test_log->info("Finished RRC PHY controller test successfully\n"); return SRSLTE_SUCCESS;