From 58a9610efaac3a6cd88a51486529c3452c2f8dbe Mon Sep 17 00:00:00 2001 From: Francisco Paisana Date: Wed, 8 Jul 2020 11:45:26 +0100 Subject: [PATCH] use of stack event loop to propagate cell search and selection results --- srsue/hdr/stack/rrc/phy_controller.h | 68 ++++++++++++++------------- srsue/src/stack/rrc/phy_controller.cc | 49 +++++++++---------- srsue/src/stack/rrc/rrc_procedures.cc | 6 +-- srsue/test/upper/rrc_phy_ctrl_test.cc | 11 ++++- 4 files changed, 74 insertions(+), 60 deletions(-) diff --git a/srsue/hdr/stack/rrc/phy_controller.h b/srsue/hdr/stack/rrc/phy_controller.h index ef49e0355..69f15daf1 100644 --- a/srsue/hdr/stack/rrc/phy_controller.h +++ b/srsue/hdr/stack/rrc/phy_controller.h @@ -41,19 +41,23 @@ public: cell_search_ret_t cs_ret; phy_cell_t found_cell; }; - using cell_sel_res = bool; - struct cell_sel_cmd { - phy_cell_t phy_cell; - srslte::event_callback callback; + struct cell_sel_res { + bool result; + }; + struct cell_sel_cmd { + phy_cell_t phy_cell; + srslte::event_callback callback; + }; + struct cell_search_cmd { + srslte::event_callback callback; }; - using cell_search_cmd = srslte::event_callback; struct in_sync_ev {}; struct out_sync_ev {}; explicit phy_controller(phy_interface_rrc_lte* phy_, stack_interface_rrc* stack_); // PHY procedures interfaces - bool start_cell_select(const phy_cell_t& phy_cell, const srslte::event_callback& on_complete); + bool start_cell_select(const phy_cell_t& phy_cell, const srslte::event_callback& on_complete); bool start_cell_search(const srslte::event_callback& on_complete); bool cell_search_completed(cell_search_ret_t cs_ret, phy_cell_t found_cell); bool cell_selection_completed(bool outcome); @@ -71,7 +75,7 @@ public: struct selecting_cell : public subfsm_t { struct timeout_ev {}; - struct wait_result {}; + struct wait_csel_res {}; struct wait_in_sync { void enter(selecting_cell* f, const cell_sel_res& ev); }; @@ -82,24 +86,25 @@ public: srslte::timer_handler::unique_timer wait_in_sync_timer; phy_cell_t target_cell = {}; - cell_sel_res result = {}; + cell_sel_res csel_res = {}; + srslte::event_callback csel_callback; protected: // guard functions - bool is_cell_selected(wait_result& s, const cell_sel_res& ev) { return ev; } + bool is_cell_selected(wait_csel_res& s, const cell_sel_res& ev) { return ev.result; } // event handlers - void set_success(wait_in_sync& s, const in_sync_ev& ev) { result = true; } + void set_success(wait_in_sync& s, const in_sync_ev& ev) { csel_res.result = true; } - state_list states{this}; + state_list states{this}; // clang-format off using c = selecting_cell; using transitions = transition_table< // Start Target Event Action Guard // +----------------+---------------+--------------+------------------+----------------------+ - row< wait_result, wait_in_sync, cell_sel_res, nullptr, &c::is_cell_selected >, - row< wait_result, unknown_st, cell_sel_res >, + row< wait_csel_res, wait_in_sync, cell_sel_res, nullptr, &c::is_cell_selected >, + row< wait_csel_res, unknown_st, cell_sel_res >, // +----------------+---------------+--------------+------------------+----------------------+ row< wait_in_sync, in_sync_st, in_sync_ev, &c::set_success >, row< wait_in_sync, unknown_st, timeout_ev > @@ -116,7 +121,6 @@ private: stack_interface_rrc* stack = nullptr; std::vector > csearch_callbacks; - srslte::event_callback csel_callback; protected: state_list states{this, @@ -133,24 +137,24 @@ protected: // clang-format off using c = phy_controller; using transitions = transition_table< - // Start Target Event Action Guard - // +----------------+-----------------+------------------+------------------------------+---------------------+ - row< unknown_st, selecting_cell, cell_sel_cmd >, - row< unknown_st, searching_cell, cell_search_cmd >, - row< unknown_st, in_sync_st, in_sync_ev >, - row< unknown_st, out_sync_st, out_sync_ev >, - // +----------------+-----------------+------------------+------------------------------+---------------------+ - row< in_sync_st, selecting_cell, cell_sel_cmd >, - row< in_sync_st, searching_cell, cell_search_cmd >, - row< in_sync_st, out_sync_st, out_sync_ev >, - // +----------------+-----------------+------------------+------------------------------+---------------------+ - row< out_sync_st, selecting_cell, cell_sel_cmd >, - row< out_sync_st, searching_cell, cell_search_cmd >, - row< out_sync_st, in_sync_st, in_sync_ev >, - // +----------------+-----------------+------------------+------------------------------+---------------------+ - row< searching_cell, unknown_st, cell_srch_res, &c::handle_cell_search_res >, - upd< searching_cell, cell_search_cmd, &c::share_cell_search_res > - // +----------------+-----------------+------------------+------------------------------+---------------------+ + // Start Target Event Action + // +----------------+-----------------+------------------+------------------------------+ + row< unknown_st, selecting_cell, cell_sel_cmd >, + row< unknown_st, searching_cell, cell_search_cmd >, + row< unknown_st, in_sync_st, in_sync_ev >, + row< unknown_st, out_sync_st, out_sync_ev >, + // +----------------+-----------------+------------------+------------------------------+ + row< in_sync_st, selecting_cell, cell_sel_cmd >, + row< in_sync_st, searching_cell, cell_search_cmd >, + row< in_sync_st, out_sync_st, out_sync_ev >, + // +----------------+-----------------+------------------+------------------------------+ + row< out_sync_st, selecting_cell, cell_sel_cmd >, + row< out_sync_st, searching_cell, cell_search_cmd >, + row< out_sync_st, in_sync_st, in_sync_ev >, + // +----------------+-----------------+------------------+------------------------------+ + row< searching_cell, unknown_st, cell_srch_res, &c::handle_cell_search_res >, + upd< searching_cell, cell_search_cmd, &c::share_cell_search_res > + // +----------------+-----------------+------------------+------------------------------+ >; // clang-format on }; diff --git a/srsue/src/stack/rrc/phy_controller.cc b/srsue/src/stack/rrc/phy_controller.cc index c0215bf25..d406a9e4a 100644 --- a/srsue/src/stack/rrc/phy_controller.cc +++ b/srsue/src/stack/rrc/phy_controller.cc @@ -40,8 +40,7 @@ phy_controller::phy_controller(srsue::phy_interface_rrc_lte* phy_, srsue::stack_ * PHY Cell Select Procedure *************************************/ -bool phy_controller::start_cell_select(const phy_cell_t& phy_cell, - const srslte::event_callback& on_complete) +bool phy_controller::start_cell_select(const phy_cell_t& phy_cell, const srslte::event_callback& on_complete) { trigger(cell_sel_cmd{phy_cell, on_complete}); if (not is_in_state()) { @@ -53,17 +52,12 @@ bool phy_controller::start_cell_select(const phy_cell_t& bool phy_controller::cell_selection_completed(bool outcome) { - return trigger(outcome); + return trigger(cell_sel_res{outcome}); } void phy_controller::in_sync() { - bool is_selecting_cell = is_in_state(); trigger(in_sync_ev{}); - if (is_selecting_cell and not is_in_state()) { - // Signal result back to FSM that called cell selection - csel_callback(get_state()->result); - } } phy_controller::selecting_cell::selecting_cell(phy_controller* parent_) : nested_fsm_t(parent_) @@ -73,9 +67,9 @@ phy_controller::selecting_cell::selecting_cell(phy_controller* parent_) : nested void phy_controller::selecting_cell::enter(phy_controller* f, const cell_sel_cmd& ev) { - target_cell = ev.phy_cell; - f->csel_callback = ev.callback; - result = false; + target_cell = ev.phy_cell; + csel_callback = ev.callback; + csel_res.result = false; f->log_h->info("Starting \"%s\" for pci=%d, earfcn=%d\n", srslte::get_type_name(*this).c_str(), @@ -88,21 +82,21 @@ void phy_controller::selecting_cell::exit(phy_controller* f) { wait_in_sync_timer.stop(); - if (result) { + if (csel_res.result) { log_h->info("Cell %s successfully selected\n", to_string(target_cell).c_str()); } else { log_h->warning("Failed to select cell %s\n", to_string(target_cell).c_str()); } + + // Signal result back to FSM that called cell selection + auto& copied_callback = csel_callback; + bool result = csel_res.result; + f->stack->defer_task([copied_callback, result]() { copied_callback(result); }); } void phy_controller::selecting_cell::wait_in_sync::enter(selecting_cell* f, const cell_sel_res& ev) { - f->wait_in_sync_timer.set(wait_sync_timeout_ms, [f](uint32_t tid) { - f->parent_fsm()->trigger(timeout_ev{}); - if (not f->parent_fsm()->is_in_state()) { - f->parent_fsm()->csel_callback(false); - } - }); + f->wait_in_sync_timer.set(wait_sync_timeout_ms, [f](uint32_t tid) { f->parent_fsm()->trigger(timeout_ev{}); }); f->wait_in_sync_timer.run(); } @@ -113,7 +107,7 @@ void phy_controller::selecting_cell::wait_in_sync::enter(selecting_cell* f, cons //! Searches for a cell in the current frequency and retrieves SIB1 if not retrieved yet bool phy_controller::start_cell_search(const srslte::event_callback& on_complete) { - trigger(on_complete); + trigger(cell_search_cmd{on_complete}); if (not is_in_state()) { log_h->warning("Failed to launch cell search\n"); return false; @@ -138,7 +132,7 @@ bool phy_controller::cell_search_completed(cell_search_ret_t cs_ret, phy_cell_t void phy_controller::searching_cell::enter(phy_controller* f, const cell_search_cmd& cmd) { f->log_h->info("Initiated Cell search\n"); - f->csearch_callbacks.emplace_back(cmd); + f->csearch_callbacks.emplace_back(cmd.callback); f->stack->start_cell_search(); } @@ -156,14 +150,21 @@ void phy_controller::handle_cell_search_res(searching_cell& s, const cell_srch_r // TODO: check what errors can happen (currently not handled in our code) } - // Forward cell search result to be handled in next state - // trigger(result); + // Signal result back to FSM that called cell search + auto& moved_callbacks = csearch_callbacks; + stack->defer_task(std::bind( + [result](std::vector >& callbacks) { + for (auto& f : callbacks) { + f(result); + } + }, + std::move(moved_callbacks))); } -void phy_controller::share_cell_search_res(searching_cell& s, const cell_search_cmd& callback) +void phy_controller::share_cell_search_res(searching_cell& s, const cell_search_cmd& cmd) { log_h->info("Cell Search already running. Re-utilizing result.\n"); - csearch_callbacks.emplace_back(callback); + csearch_callbacks.emplace_back(cmd.callback); } } // namespace srsue diff --git a/srsue/src/stack/rrc/rrc_procedures.cc b/srsue/src/stack/rrc/rrc_procedures.cc index 119d2308f..8498bb00a 100644 --- a/srsue/src/stack/rrc/rrc_procedures.cc +++ b/srsue/src/stack/rrc/rrc_procedures.cc @@ -45,9 +45,9 @@ 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; - rrc_ptr->phy_ctrl->start_cell_search( - [this](const phy_controller::cell_srch_res& res) { rrc_ptr->cell_searcher.trigger(res); }); + 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); if (not rrc_ptr->phy_ctrl->is_in_state()) { Warning("Failed to initiate Cell Search.\n"); 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 e493d8a04..26bf28784 100644 --- a/srsue/test/upper/rrc_phy_ctrl_test.cc +++ b/srsue/test/upper/rrc_phy_ctrl_test.cc @@ -59,7 +59,7 @@ int test_phy_ctrl_fsm() TESTASSERT(phy_ctrl.start_cell_search(cell_sel_callback)); TESTASSERT(not phy_ctrl.is_in_sync()); - // TEST: Cell Search only listens to a cell search result event and calls provided callback on completion + // TEST: Cell Search only listens to a cell search result event phy_ctrl.in_sync(); TESTASSERT(not phy_ctrl.is_in_sync()); phy_ctrl.out_sync(); @@ -72,6 +72,9 @@ int test_phy_ctrl_fsm() found_cell.earfcn = 2; phy_ctrl.cell_search_completed(cs_ret, found_cell); TESTASSERT(phy_ctrl.current_state_name() != "searching_cell"); + + // 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); @@ -105,6 +108,9 @@ int test_phy_ctrl_fsm() 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); // TEST: Cell Selection with timeout being reached @@ -120,6 +126,9 @@ int test_phy_ctrl_fsm() stack.run_tti(); } TESTASSERT(phy_ctrl.current_state_name() != "selecting_cell"); + + // TEST: Propagation of cell selection result to caller + stack.run_tti(); TESTASSERT(cell_select_success == 0); test_log->info("Finished RRC PHY controller test successfully\n");