more ergonomic event callback

master
Francisco Paisana 5 years ago
parent 58a9610efa
commit 9c5471b094

@ -682,7 +682,19 @@ private:
};
template <typename Event>
using event_callback = std::function<void(const Event&)>;
struct event_callback {
event_callback() = default;
template <typename FSM>
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<void(const Event&)> callback;
};
} // namespace srslte

@ -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<cs_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();

@ -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<phy_controller::cell_srch_res>{&rrc_ptr->cell_searcher});
if (not rrc_ptr->phy_ctrl->is_in_state<phy_controller::searching_cell>()) {
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<bool>{&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<bool>{&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<bool>{&rrc_ptr->cell_selector});
if (not rrc_ptr->phy_ctrl->is_in_state<phy_controller::selecting_cell>()) {
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<bool>{&rrc_ptr->ho_handler});
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());
return proc_outcome_t::error;

@ -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<phy_controller::cell_srch_res>{&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<bool>{&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<bool>{&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;

Loading…
Cancel
Save