|
|
|
@ -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,
|
|
|
|
|
const srslte::event_callback<cell_sel_res>& on_complete)
|
|
|
|
|
{
|
|
|
|
|
if (not trigger(cell_sel_cmd{phy_cell, on_complete})) {
|
|
|
|
|
log_h->warning("Failed to launch cell selection\n");
|
|
|
|
|
trigger(cell_sel_cmd{phy_cell, on_complete});
|
|
|
|
|
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 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_)
|
|
|
|
|
{
|
|
|
|
|
wait_in_sync_timer = parent_fsm()->stack->get_unique_timer();
|
|
|
|
@ -58,7 +74,7 @@ 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;
|
|
|
|
|
csel_callback = ev.callback;
|
|
|
|
|
f->csel_callback = ev.callback;
|
|
|
|
|
result = false;
|
|
|
|
|
|
|
|
|
|
f->log_h->info("Starting \"%s\" for pci=%d, earfcn=%d\n",
|
|
|
|
@ -77,14 +93,16 @@ void phy_controller::selecting_cell::exit(phy_controller* f)
|
|
|
|
|
} 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
|
|
|
|
|
csel_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->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();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -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
|
|
|
|
|
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");
|
|
|
|
|
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)
|
|
|
|
|
{
|
|
|
|
|
return trigger(cell_srch_res{cs_ret, found_cell});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool phy_controller::cell_selection_completed(bool outcome)
|
|
|
|
|
{
|
|
|
|
|
return trigger(outcome);
|
|
|
|
|
cell_srch_res res{cs_ret, found_cell};
|
|
|
|
|
if (trigger(res)) {
|
|
|
|
|
// Signal callers the result of cell search
|
|
|
|
|
for (auto& f : csearch_callbacks) {
|
|
|
|
|
f(res);
|
|
|
|
|
}
|
|
|
|
|
csearch_callbacks.clear();
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void phy_controller::searching_cell::enter(phy_controller* f, const cell_search_cmd& cmd)
|
|
|
|
|
{
|
|
|
|
|
f->log_h->info("Initiated Cell search\n");
|
|
|
|
|
csearch_callbacks.emplace_back(cmd);
|
|
|
|
|
f->csearch_callbacks.emplace_back(cmd);
|
|
|
|
|
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)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Signal back completion
|
|
|
|
|
for (auto& f : s.csearch_callbacks) {
|
|
|
|
|
f(result);
|
|
|
|
|
}
|
|
|
|
|
s.csearch_callbacks.clear();
|
|
|
|
|
// Forward cell search result to be handled in next state
|
|
|
|
|
// trigger(result);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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");
|
|
|
|
|
s.csearch_callbacks.emplace_back(callback);
|
|
|
|
|
csearch_callbacks.emplace_back(callback);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} // namespace srsue
|
|
|
|
|