removal of phy cell selection procedure as it now it is replaced by phy controller

master
Francisco Paisana 5 years ago
parent 489969722e
commit 48138b5281

@ -66,6 +66,9 @@ using srslte::byte_buffer_t;
namespace srsue {
class phy_controller;
class rrc : public rrc_interface_nas,
public rrc_interface_phy_lte,
public rrc_interface_mac,
@ -191,8 +194,8 @@ private:
bool drb_up = false;
typedef enum { phy_unknown_sync = 0, phy_in_sync, phy_out_of_sync } phy_sync_state_t;
phy_sync_state_t phy_sync_state = phy_unknown_sync;
// PHY controller state machine
std::unique_ptr<phy_controller> phy_ctrl;
rrc_args_t args = {};
@ -290,7 +293,6 @@ private:
enum class cs_result_t { changed_cell, same_cell, no_cell };
// RRC procedures (fwd declared)
class phy_cell_select_proc;
class cell_search_proc;
class si_acquire_proc;
class serving_cell_config_proc;
@ -302,7 +304,6 @@ private:
class cell_reselection_proc;
class connection_reest_proc;
class ho_proc;
srslte::proc_t<phy_cell_select_proc> phy_cell_selector;
srslte::proc_t<cell_search_proc, phy_interface_rrc_lte::cell_search_ret_t> cell_searcher;
srslte::proc_t<si_acquire_proc> si_acquirer;
srslte::proc_t<serving_cell_config_proc> serv_cell_cfg;

@ -19,6 +19,7 @@
*
*/
#include "phy_controller.h"
#include "srslte/common/log.h"
#include "srsue/hdr/stack/rrc/rrc.h"
#include <map>
@ -43,36 +44,16 @@ struct cell_select_event_t {
* Procedures
*******************************/
class rrc::phy_cell_select_proc
{
public:
explicit phy_cell_select_proc(rrc* parent_);
srslte::proc_outcome_t init(const cell_t& target_cell);
srslte::proc_outcome_t react(cell_select_event_t ev);
void then(const srslte::proc_state_t& result);
srslte::proc_outcome_t step() { return srslte::proc_outcome_t::yield; }
static const char* name() { return "PHY Cell Select"; }
private:
// args
rrc* rrc_ptr;
const cell_t* target_cell;
};
class rrc::cell_search_proc
{
public:
struct cell_search_event_t {
phy_interface_rrc_lte::cell_search_ret_t cs_ret;
phy_interface_rrc_lte::phy_cell_t found_cell;
};
enum class state_t { phy_cell_search, si_acquire, wait_measurement, phy_cell_select };
explicit cell_search_proc(rrc* parent_);
srslte::proc_outcome_t init();
srslte::proc_outcome_t step();
srslte::proc_outcome_t step_si_acquire();
srslte::proc_outcome_t react(const cell_search_event_t& event);
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 step_wait_measurement();
@ -86,7 +67,7 @@ private:
rrc* rrc_ptr;
// state vars
cell_search_event_t search_result;
phy_controller::cell_srch_res search_result;
srslte::proc_future_t<void> si_acquire_fut;
state_t state;
};
@ -164,7 +145,6 @@ private:
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_wait_in_sync();
srslte::proc_outcome_t step_cell_search();
srslte::proc_outcome_t step_cell_config();
@ -172,7 +152,7 @@ private:
rrc* rrc_ptr;
// state variables
enum class search_state_t { cell_selection, serv_cell_camp, wait_in_sync, cell_config, cell_search };
enum class search_state_t { cell_selection, serv_cell_camp, cell_config, cell_search };
cs_result_t cs_result;
search_state_t state;
uint32_t neigh_index;

@ -126,7 +126,7 @@ void phy_controller::handle_cell_search_res(searching_cell& s, const cell_srch_r
log_h->info("PHY cell search completed. Found cell %s\n", to_string(result.found_cell).c_str());
break;
case cell_search_ret_t::CELL_NOT_FOUND:
log_h->warning("PHY cell search completed. No cells found\n");
log_h->warning("PHY cell search completed. No cells found.\n");
break;
default:
log_h->error("Invalid cell search result\n");

@ -23,6 +23,7 @@
#include "srslte/asn1/rrc_asn1.h"
#include "srslte/common/bcd_helpers.h"
#include "srslte/common/security.h"
#include "srsue/hdr/stack/rrc/phy_controller.h"
#include "srsue/hdr/stack/rrc/rrc_meas.h"
#include "srsue/hdr/stack/rrc/rrc_procedures.h"
#include <cstdlib>
@ -57,7 +58,6 @@ rrc::rrc(stack_interface_rrc* stack_, srslte::task_sched_handle task_sched_) :
drb_up(false),
rrc_log("RRC"),
measurements(new rrc_meas()),
phy_cell_selector(this),
cell_searcher(this),
si_acquirer(this),
serv_cell_cfg(this),
@ -116,6 +116,8 @@ void rrc::init(phy_interface_rrc_lte* phy_,
args = args_;
phy_ctrl.reset(new phy_controller{phy, stack});
state = RRC_STATE_IDLE;
plmn_is_selected = false;
@ -382,7 +384,7 @@ void rrc::out_of_sync()
{
// CAUTION: We do not lock in this function since they are called from real-time threads
if (meas_cells.serving_cell().is_valid() && rrc_log) {
phy_sync_state = phy_out_of_sync;
phy_ctrl->out_sync();
// upon receiving N310 consecutive "out-of-sync" indications for the PCell from lower layers while neither T300,
// T301, T304 nor T311 is running:
@ -412,7 +414,7 @@ void rrc::out_of_sync()
void rrc::in_sync()
{
// CAUTION: We do not lock in this function since they are called from real-time threads
phy_sync_state = phy_in_sync;
phy_ctrl->in_sync();
if (t310.is_running()) {
n311_cnt++;
if (n311_cnt == N311) {
@ -1008,12 +1010,12 @@ void rrc::start_con_restablishment(reest_cause_e cause)
void rrc::cell_search_completed(const phy_interface_rrc_lte::cell_search_ret_t& cs_ret,
const phy_interface_rrc_lte::phy_cell_t& found_cell)
{
cell_searcher.trigger(cell_search_proc::cell_search_event_t{cs_ret, found_cell});
phy_ctrl->cell_search_completed(cs_ret, found_cell);
}
void rrc::cell_select_completed(bool cs_ret)
{
phy_cell_selector.trigger(cell_select_event_t{cs_ret});
phy_ctrl->cell_selection_completed(cs_ret);
}
/**

@ -35,42 +35,6 @@ namespace srsue {
using srslte::proc_outcome_t;
using srslte::tti_point;
/**************************************
* PHY Cell Select Procedure
*************************************/
rrc::phy_cell_select_proc::phy_cell_select_proc(rrc* parent_) : rrc_ptr(parent_) {}
srslte::proc_outcome_t rrc::phy_cell_select_proc::init(const cell_t& target_cell_)
{
target_cell = &target_cell_;
Info("Starting for %s\n", target_cell->to_string().c_str());
rrc_ptr->start_phy_cell_select(&target_cell->phy_cell);
return proc_outcome_t::yield;
}
srslte::proc_outcome_t rrc::phy_cell_select_proc::react(cell_select_event_t ev)
{
if (not ev.cs_ret) {
Error("Couldn't select new serving cell\n");
return proc_outcome_t::error;
}
return proc_outcome_t::success;
}
void rrc::phy_cell_select_proc::then(const srslte::proc_state_t& result)
{
Info("Finished %s\n", result.is_success() ? "successfully" : "with error");
// Warn other procedures that depend on this procedure
if (rrc_ptr->cell_searcher.is_busy()) {
rrc_ptr->cell_searcher.trigger(cell_select_event_t{result.is_success()});
} else if (rrc_ptr->cell_selector.is_busy()) {
rrc_ptr->cell_selector.trigger(cell_select_event_t{result.is_success()});
} else {
rrc_ptr->ho_handler.trigger(cell_select_event_t{result.is_success()});
}
}
/**************************************
* Cell Search Procedure
*************************************/
@ -82,7 +46,11 @@ proc_outcome_t rrc::cell_search_proc::init()
{
Info("Starting...\n");
state = state_t::phy_cell_search;
rrc_ptr->start_phy_cell_search();
if (not rrc_ptr->phy_ctrl->start_cell_search(
[this](const phy_controller::cell_srch_res& res) { rrc_ptr->cell_searcher.trigger(res); })) {
Warning("Failed to initiate Cell Search.\n");
return proc_outcome_t::error;
}
return proc_outcome_t::yield;
}
@ -130,7 +98,8 @@ proc_outcome_t rrc::cell_search_proc::handle_cell_found(const phy_interface_rrc_
// set new serving cell in PHY
state = state_t::phy_cell_select;
if (not rrc_ptr->phy_cell_selector.launch(rrc_ptr->meas_cells.serving_cell())) {
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)) {
Error("Couldn't start phy cell selection\n");
return proc_outcome_t::error;
}
@ -183,7 +152,7 @@ proc_outcome_t rrc::cell_search_proc::react(const cell_select_event_t& event)
return proc_outcome_t::yield;
}
proc_outcome_t rrc::cell_search_proc::react(const cell_search_event_t& event)
proc_outcome_t rrc::cell_search_proc::react(const phy_controller::cell_srch_res& event)
{
if (state != state_t::phy_cell_search) {
Error("Received unexpected cell search result\n");
@ -191,22 +160,14 @@ proc_outcome_t rrc::cell_search_proc::react(const cell_search_event_t& event)
}
search_result = event;
Info("PHY cell search completed.\n");
// Transition to SI Acquire or finish
switch (search_result.cs_ret.found) {
case phy_interface_rrc_lte::cell_search_ret_t::CELL_FOUND:
if (search_result.cs_ret.found == phy_interface_rrc_lte::cell_search_ret_t::CELL_FOUND) {
return handle_cell_found(search_result.found_cell);
case phy_interface_rrc_lte::cell_search_ret_t::CELL_NOT_FOUND:
rrc_ptr->phy_sync_state = phy_unknown_sync;
Info("No cells found.\n");
// do nothing
} else if (search_result.cs_ret.found == phy_interface_rrc_lte::cell_search_ret_t::CELL_NOT_FOUND) {
// No cells found. Do nothing
return proc_outcome_t::success;
case phy_interface_rrc_lte::cell_search_ret_t::ERROR:
Error("Error while performing cell search\n");
// TODO: check what errors can happen (currently not handled in our code)
return proc_outcome_t::error;
}
return proc_outcome_t::yield;
return proc_outcome_t::error;
}
/****************************************************************
@ -495,7 +456,7 @@ rrc::cell_selection_proc::cell_selection_proc(rrc* parent_) : rrc_ptr(parent_) {
*/
proc_outcome_t rrc::cell_selection_proc::init()
{
if (rrc_ptr->meas_cells.nof_neighbours() == 0 and rrc_ptr->phy_sync_state == phy_in_sync and
if (rrc_ptr->meas_cells.nof_neighbours() == 0 and rrc_ptr->phy_ctrl->is_in_sync() and
rrc_ptr->phy->cell_is_camping()) {
// don't bother with cell selection if there are no neighbours and we are already camping
Debug("Skipping Cell Selection Procedure as there are no neighbour and cell is camping.\n");
@ -505,7 +466,7 @@ proc_outcome_t rrc::cell_selection_proc::init()
Info("Starting...\n");
Info("Current neighbor cells: [%s]\n", rrc_ptr->meas_cells.print_neighbour_cells().c_str());
Info("Current PHY state: %s\n", rrc_ptr->phy_sync_state == phy_in_sync ? "in-sync" : "out-of-sync");
Info("Current PHY state: %s\n", rrc_ptr->phy_ctrl->is_in_sync() ? "in-sync" : "out-of-sync");
if (rrc_ptr->meas_cells.serving_cell().has_sib3()) {
Info("Cell selection criteria: Qrxlevmin=%f, Qrxlevminoffset=%f\n",
rrc_ptr->cell_resel_cfg.Qrxlevmin,
@ -542,7 +503,7 @@ proc_outcome_t rrc::cell_selection_proc::react(const cell_select_event_t& event)
proc_outcome_t rrc::cell_selection_proc::start_serv_cell_selection()
{
if (rrc_ptr->phy_sync_state == phy_in_sync and rrc_ptr->phy->cell_is_camping()) {
if (rrc_ptr->phy_ctrl->is_in_sync() and rrc_ptr->phy->cell_is_camping()) {
cs_result = cs_result_t::same_cell;
return proc_outcome_t::success;
}
@ -550,7 +511,8 @@ 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;
if (not rrc_ptr->phy_cell_selector.launch(rrc_ptr->meas_cells.serving_cell())) {
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)) {
Error("Failed to launch PHY Cell Selection\n");
return proc_outcome_t::error;
}
@ -574,7 +536,7 @@ proc_outcome_t rrc::cell_selection_proc::start_cell_selection()
// Matches S criteria
float rsrp = rrc_ptr->meas_cells.at(neigh_index).get_rsrp();
if (rrc_ptr->phy_sync_state != phy_in_sync or
if (not rrc_ptr->phy_ctrl->is_in_sync() or
(rrc_ptr->cell_selection_criteria(rsrp) and rsrp > rrc_ptr->meas_cells.serving_cell().get_rsrp() + 5)) {
// currently connected and verifies cell selection criteria
// Try to select Cell
@ -583,7 +545,8 @@ proc_outcome_t rrc::cell_selection_proc::start_cell_selection()
Info("Selected cell: %s\n", rrc_ptr->meas_cells.serving_cell().to_string().c_str());
state = search_state_t::cell_selection;
if (not rrc_ptr->phy_cell_selector.launch(rrc_ptr->meas_cells.serving_cell())) {
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)) {
Error("Failed to launch PHY Cell Selection\n");
return proc_outcome_t::error;
}
@ -610,17 +573,23 @@ proc_outcome_t rrc::cell_selection_proc::start_cell_selection()
proc_outcome_t rrc::cell_selection_proc::step_cell_selection(const cell_select_event_t& event)
{
rrc_ptr->phy_sync_state = phy_unknown_sync;
if (event.cs_ret) {
// successful selection
Info("Wait PHY to be in-synch\n");
state = search_state_t::wait_in_sync;
return step();
if (rrc_ptr->cell_selection_criteria(rrc_ptr->meas_cells.serving_cell().get_rsrp())) {
Info("PHY is in SYNC and cell selection passed\n");
if (not rrc_ptr->serv_cell_cfg.launch(&serv_cell_cfg_fut, rrc_ptr->ue_required_sibs)) {
return proc_outcome_t::error;
}
state = search_state_t::cell_config;
return proc_outcome_t::yield;
}
Info("PHY is in SYNC but cell selection did not pass. Go back to select step.\n");
cs_result = cs_result_t::no_cell;
} else {
Error("Could not camp on serving cell.\n");
discard_serving = true;
}
discard_serving = true; // Discard this cell
// Continue to next neighbour cell
++neigh_index;
return start_cell_selection();
@ -635,32 +604,11 @@ srslte::proc_outcome_t rrc::cell_selection_proc::step_serv_cell_camp(const cell_
return proc_outcome_t::success;
}
rrc_ptr->phy_sync_state = phy_unknown_sync;
rrc_ptr->meas_cells.serving_cell().set_rsrp(-INFINITY);
Warning("Could not camp on serving cell.\n");
return neigh_index >= rrc_ptr->meas_cells.nof_neighbours() ? proc_outcome_t::error : proc_outcome_t::yield;
}
proc_outcome_t rrc::cell_selection_proc::step_wait_in_sync()
{
if (rrc_ptr->phy_sync_state == phy_in_sync) {
if (rrc_ptr->cell_selection_criteria(rrc_ptr->meas_cells.serving_cell().get_rsrp())) {
Info("PHY is in SYNC and cell selection passed\n");
if (not rrc_ptr->serv_cell_cfg.launch(&serv_cell_cfg_fut, rrc_ptr->ue_required_sibs)) {
return proc_outcome_t::error;
}
state = search_state_t::cell_config;
} else {
Info("PHY is in SYNC but cell selection did not pass. Go back to select step.\n");
cs_result = cs_result_t::no_cell;
neigh_index++;
discard_serving = true; // Discard this cell
return start_cell_selection();
}
}
return proc_outcome_t::yield;
}
proc_outcome_t rrc::cell_selection_proc::step_cell_search()
{
if (rrc_ptr->cell_searcher.run()) {
@ -703,8 +651,6 @@ proc_outcome_t rrc::cell_selection_proc::step()
case search_state_t::serv_cell_camp:
// this state waits for phy event
return proc_outcome_t::yield;
case search_state_t::wait_in_sync:
return step_wait_in_sync();
case search_state_t::cell_config:
return step_cell_config();
case search_state_t::cell_search:
@ -955,11 +901,9 @@ srslte::proc_outcome_t rrc::connection_request_proc::react(const cell_selection_
switch (cs_ret) {
case cs_result_t::same_cell:
log_h->warning("Did not reselect cell but serving cell is out-of-sync.\n");
rrc_ptr->phy_sync_state = phy_unknown_sync;
break;
case cs_result_t::changed_cell:
log_h->warning("Selected a new cell but could not camp on. Setting out-of-sync.\n");
rrc_ptr->phy_sync_state = phy_unknown_sync;
break;
default:
log_h->warning("Could not find any suitable cell to connect\n");
@ -1132,7 +1076,7 @@ rrc::cell_reselection_proc::cell_reselection_proc(srsue::rrc* rrc_) : rrc_ptr(rr
proc_outcome_t rrc::cell_reselection_proc::init()
{
if (rrc_ptr->meas_cells.nof_neighbours() == 0 and rrc_ptr->phy_sync_state == phy_in_sync and
if (rrc_ptr->meas_cells.nof_neighbours() == 0 and rrc_ptr->phy_ctrl->is_in_sync() and
rrc_ptr->phy->cell_is_camping()) {
// don't bother with cell selection if there are no neighbours and we are already camping
return proc_outcome_t::success;
@ -1171,7 +1115,6 @@ proc_outcome_t rrc::cell_reselection_proc::step()
case cs_result_t::same_cell:
if (!rrc_ptr->phy->cell_is_camping()) {
Warning("Did not reselect cell but serving cell is out-of-sync.\n");
rrc_ptr->phy_sync_state = phy_unknown_sync;
}
break;
}
@ -1274,7 +1217,7 @@ srslte::proc_outcome_t rrc::connection_reest_proc::step_cell_reselection()
}
// Cell reselection finished or not started
if (rrc_ptr->phy_sync_state == phy_in_sync) {
if (rrc_ptr->phy_ctrl->is_in_sync()) {
// In-sync, check SIBs
if (rrc_ptr->meas_cells.serving_cell().has_sib1() && rrc_ptr->meas_cells.serving_cell().has_sib2() &&
rrc_ptr->meas_cells.serving_cell().has_sib3()) {
@ -1318,7 +1261,7 @@ proc_outcome_t rrc::connection_reest_proc::step_cell_configuration()
}
// SIBs adquisition not started or finished
if (rrc_ptr->phy_sync_state == phy_in_sync) {
if (rrc_ptr->phy_ctrl->is_in_sync()) {
// In-sync
if (rrc_ptr->meas_cells.serving_cell().has_sib1() && rrc_ptr->meas_cells.serving_cell().has_sib2() &&
rrc_ptr->meas_cells.serving_cell().has_sib3()) {
@ -1543,7 +1486,8 @@ srslte::proc_outcome_t rrc::ho_proc::step()
cell_t* target_cell =
rrc_ptr->meas_cells.get_neighbour_cell_handle(target_earfcn, recfg_r8.mob_ctrl_info.target_pci);
if (not rrc_ptr->phy_cell_selector.launch(*target_cell)) {
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)) {
Error("Failed to launch the selection of target cell %s\n", target_cell->to_string().c_str());
return proc_outcome_t::error;
}

@ -84,7 +84,7 @@ int test_phy_ctrl_fsm()
// TEST: Cell Selection state ignores events other than the cell selection result, and callback is called
phy_ctrl.in_sync();
TESTASSERT(not phy_ctrl.is_in_sync());
phy_ctrl.cell_selection_completed(true);
TESTASSERT(phy_ctrl.cell_selection_completed(true));
// 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());
@ -96,7 +96,7 @@ int test_phy_ctrl_fsm()
// TEST: Cell Selection with timeout being reached
cell_select_success = -1;
phy_ctrl.start_cell_select(found_cell, csel_callback);
TESTASSERT(phy_ctrl.start_cell_select(found_cell, csel_callback));
TESTASSERT(not phy_ctrl.is_in_sync());
phy_ctrl.cell_selection_completed(true);
TESTASSERT(phy_ctrl.current_state_name() == "selecting_cell");

Loading…
Cancel
Save