moved cell selection/search complete event signalling out of phy_controller

This commit is contained in:
Francisco Paisana 2020-07-07 23:49:24 +01:00
parent 48138b5281
commit d48a45976e
5 changed files with 87 additions and 49 deletions

View File

@ -239,7 +239,7 @@ struct apply_first_guard_pass<FSM, type_list<> > {
template <typename SrcState, typename Event> template <typename SrcState, typename Event>
static bool trigger(FSM* f, SrcState& s, const Event& ev) static bool trigger(FSM* f, SrcState& s, const Event& ev)
{ {
f->log_fsm_activity("FSM \"%s\": Unhandled event caught: \"%s\"\n", f->get_log()->debug("FSM \"%s\": Unhandled event caught: \"%s\"\n",
get_type_name<typename FSM::derived_t>().c_str(), get_type_name<typename FSM::derived_t>().c_str(),
get_type_name<Event>().c_str()); get_type_name<Event>().c_str());
return false; return false;
@ -492,6 +492,8 @@ public:
srslte::log_ref get_log() const { return log_h; } srslte::log_ref get_log() const { return log_h; }
bool is_trigger_locked() const { return trigger_locked; }
//! Log FSM activity method, e.g. state transitions //! Log FSM activity method, e.g. state transitions
template <typename... Args> template <typename... Args>
void log_fsm_activity(const char* format, Args&&... args) void log_fsm_activity(const char* format, Args&&... args)

View File

@ -49,7 +49,6 @@ public:
using cell_search_cmd = srslte::event_callback<cell_srch_res>; using cell_search_cmd = srslte::event_callback<cell_srch_res>;
struct in_sync_ev {}; struct in_sync_ev {};
struct out_sync_ev {}; struct out_sync_ev {};
struct timeout_ev {};
explicit phy_controller(phy_interface_rrc_lte* phy_, stack_interface_rrc* stack_); explicit phy_controller(phy_interface_rrc_lte* phy_, stack_interface_rrc* stack_);
@ -58,18 +57,13 @@ public:
bool start_cell_search(const srslte::event_callback<cell_srch_res>& on_complete); bool start_cell_search(const srslte::event_callback<cell_srch_res>& on_complete);
bool cell_search_completed(cell_search_ret_t cs_ret, phy_cell_t found_cell); bool cell_search_completed(cell_search_ret_t cs_ret, phy_cell_t found_cell);
bool cell_selection_completed(bool outcome); bool cell_selection_completed(bool outcome);
void in_sync() { trigger(in_sync_ev{}); } void in_sync();
void out_sync() { trigger(out_sync_ev{}); } void out_sync() { trigger(out_sync_ev{}); }
// state getters // state getters
bool cell_is_camping() { return phy->cell_is_camping(); } bool cell_is_camping() { return phy->cell_is_camping(); }
bool is_in_sync() const { return is_in_state<in_sync_st>(); } bool is_in_sync() const { return is_in_state<in_sync_st>(); }
private:
phy_interface_rrc_lte* phy = nullptr;
stack_interface_rrc* stack = nullptr;
protected:
// states // states
struct unknown_st {}; struct unknown_st {};
struct in_sync_st {}; struct in_sync_st {};
@ -86,10 +80,9 @@ protected:
void enter(phy_controller* f, const cell_sel_cmd& ev); void enter(phy_controller* f, const cell_sel_cmd& ev);
void exit(phy_controller* f); void exit(phy_controller* f);
srslte::timer_handler::unique_timer wait_in_sync_timer; srslte::timer_handler::unique_timer wait_in_sync_timer;
phy_cell_t target_cell = {}; phy_cell_t target_cell = {};
cell_sel_res result = {}; cell_sel_res result = {};
srslte::event_callback<cell_sel_res> csel_callback;
protected: protected:
// guard functions // guard functions
@ -109,16 +102,23 @@ protected:
row< wait_result, unknown_st, cell_sel_res >, row< wait_result, unknown_st, cell_sel_res >,
// +----------------+---------------+--------------+------------------+----------------------+ // +----------------+---------------+--------------+------------------+----------------------+
row< wait_in_sync, in_sync_st, in_sync_ev, &c::set_success >, row< wait_in_sync, in_sync_st, in_sync_ev, &c::set_success >,
row< wait_in_sync, out_sync_st, timeout_ev > row< wait_in_sync, unknown_st, timeout_ev >
// +----------------+---------------+--------------+------------------+----------------------+ // +----------------+---------------+--------------+------------------+----------------------+
>; >;
// clang-format on // clang-format on
}; };
struct searching_cell { struct searching_cell {
void enter(phy_controller* f, const cell_search_cmd& cmd); void enter(phy_controller* f, const cell_search_cmd& cmd);
std::vector<srslte::event_callback<cell_srch_res> > csearch_callbacks;
}; };
private:
phy_interface_rrc_lte* phy = nullptr;
stack_interface_rrc* stack = nullptr;
std::vector<srslte::event_callback<cell_srch_res> > csearch_callbacks;
srslte::event_callback<cell_sel_res> csel_callback;
protected:
state_list<unknown_st, in_sync_st, out_sync_st, searching_cell, selecting_cell> states{this, state_list<unknown_st, in_sync_st, out_sync_st, searching_cell, selecting_cell> states{this,
unknown_st{}, unknown_st{},
in_sync_st{}, in_sync_st{},
@ -148,8 +148,8 @@ protected:
row< out_sync_st, searching_cell, cell_search_cmd >, row< out_sync_st, searching_cell, cell_search_cmd >,
row< out_sync_st, in_sync_st, in_sync_ev >, row< out_sync_st, in_sync_st, in_sync_ev >,
// +----------------+-----------------+------------------+------------------------------+---------------------+ // +----------------+-----------------+------------------+------------------------------+---------------------+
row< searching_cell, unknown_st, cell_srch_res, &c::handle_cell_search_res >, row< searching_cell, unknown_st, cell_srch_res, &c::handle_cell_search_res >,
upd< searching_cell, cell_search_cmd, &c::share_cell_search_res > upd< searching_cell, cell_search_cmd, &c::share_cell_search_res >
// +----------------+-----------------+------------------+------------------------------+---------------------+ // +----------------+-----------------+------------------+------------------------------+---------------------+
>; >;
// clang-format on // clang-format on

View File

@ -43,13 +43,29 @@ phy_controller::phy_controller(srsue::phy_interface_rrc_lte* phy_, srsue::stack_
bool phy_controller::start_cell_select(const phy_cell_t& phy_cell, bool phy_controller::start_cell_select(const phy_cell_t& phy_cell,
const srslte::event_callback<cell_sel_res>& on_complete) const srslte::event_callback<cell_sel_res>& on_complete)
{ {
if (not trigger(cell_sel_cmd{phy_cell, on_complete})) { trigger(cell_sel_cmd{phy_cell, on_complete});
log_h->warning("Failed to launch cell selection\n"); if (not is_in_state<selecting_cell>()) {
log_h->warning("Failed to launch cell selection. Current state: %s\n", current_state_name().c_str());
return false; return false;
} }
return true; return true;
} }
bool phy_controller::cell_selection_completed(bool outcome)
{
return trigger(outcome);
}
void phy_controller::in_sync()
{
bool is_selecting_cell = is_in_state<selecting_cell>();
trigger(in_sync_ev{});
if (is_selecting_cell and not is_in_state<selecting_cell>()) {
// Signal result back to FSM that called cell selection
csel_callback(get_state<selecting_cell>()->result);
}
}
phy_controller::selecting_cell::selecting_cell(phy_controller* parent_) : nested_fsm_t(parent_) phy_controller::selecting_cell::selecting_cell(phy_controller* parent_) : nested_fsm_t(parent_)
{ {
wait_in_sync_timer = parent_fsm()->stack->get_unique_timer(); wait_in_sync_timer = parent_fsm()->stack->get_unique_timer();
@ -57,9 +73,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) void phy_controller::selecting_cell::enter(phy_controller* f, const cell_sel_cmd& ev)
{ {
target_cell = ev.phy_cell; target_cell = ev.phy_cell;
csel_callback = ev.callback; f->csel_callback = ev.callback;
result = false; result = false;
f->log_h->info("Starting \"%s\" for pci=%d, earfcn=%d\n", f->log_h->info("Starting \"%s\" for pci=%d, earfcn=%d\n",
srslte::get_type_name(*this).c_str(), srslte::get_type_name(*this).c_str(),
@ -77,14 +93,16 @@ void phy_controller::selecting_cell::exit(phy_controller* f)
} else { } else {
log_h->warning("Failed to select cell %s\n", to_string(target_cell).c_str()); log_h->warning("Failed to select cell %s\n", to_string(target_cell).c_str());
} }
// Signal result back to FSM that called cell selection
csel_callback(result);
} }
void phy_controller::selecting_cell::wait_in_sync::enter(selecting_cell* f, const cell_sel_res& ev) 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->trigger(timeout_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<selecting_cell>()) {
f->parent_fsm()->csel_callback(false);
}
});
f->wait_in_sync_timer.run(); f->wait_in_sync_timer.run();
} }
@ -95,7 +113,8 @@ 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 //! 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<cell_srch_res>& on_complete) bool phy_controller::start_cell_search(const srslte::event_callback<cell_srch_res>& on_complete)
{ {
if (not trigger(on_complete)) { trigger(on_complete);
if (not is_in_state<searching_cell>()) {
log_h->warning("Failed to launch cell search\n"); log_h->warning("Failed to launch cell search\n");
return false; return false;
} }
@ -104,18 +123,22 @@ bool phy_controller::start_cell_search(const srslte::event_callback<cell_srch_re
bool phy_controller::cell_search_completed(cell_search_ret_t cs_ret, phy_cell_t found_cell) bool phy_controller::cell_search_completed(cell_search_ret_t cs_ret, phy_cell_t found_cell)
{ {
return trigger(cell_srch_res{cs_ret, found_cell}); cell_srch_res res{cs_ret, found_cell};
} if (trigger(res)) {
// Signal callers the result of cell search
bool phy_controller::cell_selection_completed(bool outcome) for (auto& f : csearch_callbacks) {
{ f(res);
return trigger(outcome); }
csearch_callbacks.clear();
return true;
}
return false;
} }
void phy_controller::searching_cell::enter(phy_controller* f, const cell_search_cmd& cmd) void phy_controller::searching_cell::enter(phy_controller* f, const cell_search_cmd& cmd)
{ {
f->log_h->info("Initiated Cell search\n"); f->log_h->info("Initiated Cell search\n");
csearch_callbacks.emplace_back(cmd); f->csearch_callbacks.emplace_back(cmd);
f->stack->start_cell_search(); f->stack->start_cell_search();
} }
@ -133,17 +156,14 @@ 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) // TODO: check what errors can happen (currently not handled in our code)
} }
// Signal back completion // Forward cell search result to be handled in next state
for (auto& f : s.csearch_callbacks) { // trigger(result);
f(result);
}
s.csearch_callbacks.clear();
} }
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& callback)
{ {
log_h->info("Cell Search already running. Re-utilizing result.\n"); log_h->info("Cell Search already running. Re-utilizing result.\n");
s.csearch_callbacks.emplace_back(callback); csearch_callbacks.emplace_back(callback);
} }
} // namespace srsue } // namespace srsue

View File

@ -46,8 +46,9 @@ proc_outcome_t rrc::cell_search_proc::init()
{ {
Info("Starting...\n"); Info("Starting...\n");
state = state_t::phy_cell_search; state = state_t::phy_cell_search;
if (not rrc_ptr->phy_ctrl->start_cell_search( rrc_ptr->phy_ctrl->start_cell_search(
[this](const phy_controller::cell_srch_res& res) { rrc_ptr->cell_searcher.trigger(res); })) { [this](const phy_controller::cell_srch_res& res) { rrc_ptr->cell_searcher.trigger(res); });
if (not rrc_ptr->phy_ctrl->is_in_state<phy_controller::searching_cell>()) {
Warning("Failed to initiate Cell Search.\n"); Warning("Failed to initiate Cell Search.\n");
return proc_outcome_t::error; return proc_outcome_t::error;
} }
@ -546,7 +547,8 @@ proc_outcome_t rrc::cell_selection_proc::start_cell_selection()
state = search_state_t::cell_selection; state = search_state_t::cell_selection;
auto on_complete = [this](const bool& result) { rrc_ptr->cell_selector.trigger(cell_select_event_t{result}); }; 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)) { rrc_ptr->phy_ctrl->start_cell_select(rrc_ptr->meas_cells.serving_cell().phy_cell, on_complete);
if (not rrc_ptr->phy_ctrl->is_in_state<phy_controller::selecting_cell>()) {
Error("Failed to launch PHY Cell Selection\n"); Error("Failed to launch PHY Cell Selection\n");
return proc_outcome_t::error; return proc_outcome_t::error;
} }
@ -1487,7 +1489,8 @@ srslte::proc_outcome_t rrc::ho_proc::step()
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); 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}); }; 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)) { rrc_ptr->phy_ctrl->start_cell_select(rrc_ptr->meas_cells.serving_cell().phy_cell, on_complete);
if (not rrc_ptr->phy_ctrl->is_in_state<phy_controller::selecting_cell>()) {
Error("Failed to launch the selection of target cell %s\n", target_cell->to_string().c_str()); Error("Failed to launch the selection of target cell %s\n", target_cell->to_string().c_str());
return proc_outcome_t::error; return proc_outcome_t::error;
} }

View File

@ -46,10 +46,16 @@ int test_phy_ctrl_fsm()
// TEST: Correct initiation of Cell Search state // TEST: Correct initiation of Cell Search state
bool csearch_res_present = false; bool csearch_res_present = false;
phy_controller::cell_srch_res csearch_res = {}; phy_controller::cell_srch_res csearch_res = {};
auto cell_sel_callback = [&csearch_res_present, &csearch_res](const phy_controller::cell_srch_res& result) { auto cell_sel_callback =
csearch_res_present = true; [&csearch_res_present, &csearch_res, &phy_ctrl](const phy_controller::cell_srch_res& result) {
csearch_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(cell_sel_callback));
TESTASSERT(not phy_ctrl.is_in_sync()); TESTASSERT(not phy_ctrl.is_in_sync());
@ -76,7 +82,14 @@ int test_phy_ctrl_fsm()
// TEST: Correct initiation of Cell Select state // TEST: Correct initiation of Cell Select state
int cell_select_success = -1; int cell_select_success = -1;
auto csel_callback = [&cell_select_success](const bool& res) { cell_select_success = res ? 1 : 0; }; 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, csel_callback);
TESTASSERT(not phy_ctrl.is_in_sync()); TESTASSERT(not phy_ctrl.is_in_sync());
TESTASSERT(phy_ctrl.current_state_name() == "selecting_cell"); TESTASSERT(phy_ctrl.current_state_name() == "selecting_cell");