From 7f8af023b8113c0dc81191e042aabab0a7a52e29 Mon Sep 17 00:00:00 2001 From: Francisco Paisana Date: Tue, 22 Sep 2020 10:24:51 +0200 Subject: [PATCH] added a callback that always gets triggered when the phy cell selection completes. This callback checks if cell selection failed, and if so, sets the rsrp of the selected cell to -infinity --- srsue/hdr/stack/rrc/phy_controller.h | 13 ++++++++----- srsue/hdr/stack/rrc/rrc_cell.h | 1 + srsue/src/stack/rrc/phy_controller.cc | 12 ++++++++---- srsue/src/stack/rrc/rrc.cc | 10 +++++++++- srsue/src/stack/rrc/rrc_cell.cc | 8 ++++++++ srsue/src/stack/rrc/rrc_procedures.cc | 10 +++------- 6 files changed, 37 insertions(+), 17 deletions(-) diff --git a/srsue/hdr/stack/rrc/phy_controller.h b/srsue/hdr/stack/rrc/phy_controller.h index 2110798a5..2bfe45a6f 100644 --- a/srsue/hdr/stack/rrc/phy_controller.h +++ b/srsue/hdr/stack/rrc/phy_controller.h @@ -52,7 +52,9 @@ public: struct in_sync_ev {}; struct out_sync_ev {}; - explicit phy_controller(phy_interface_rrc_lte* phy_, srslte::task_sched_handle task_sched_); + explicit phy_controller(phy_interface_rrc_lte* phy_, + srslte::task_sched_handle task_sched_, + std::function on_cell_selection = {}); // PHY procedures interfaces bool start_cell_select(const phy_cell_t& phy_cell, srslte::event_observer observer); @@ -114,10 +116,11 @@ public: }; private: - phy_interface_rrc_lte* phy = nullptr; - srslte::task_sched_handle task_sched; - srslte::event_observer cell_selection_observer; - srslte::event_dispatcher cell_search_observers; + phy_interface_rrc_lte* phy = nullptr; + srslte::task_sched_handle task_sched; + srslte::event_observer cell_selection_once_observer; + std::function cell_selection_always_observer; + srslte::event_dispatcher cell_search_observers; protected: state_list states{this, diff --git a/srsue/hdr/stack/rrc/rrc_cell.h b/srsue/hdr/stack/rrc/rrc_cell.h index aeb4d9595..9f5fcaf7a 100644 --- a/srsue/hdr/stack/rrc/rrc_cell.h +++ b/srsue/hdr/stack/rrc/rrc_cell.h @@ -189,6 +189,7 @@ public: cell_t& operator[](size_t idx) { return *neighbour_cells[idx]; } const cell_t& operator[](size_t idx) const { return *neighbour_cells[idx]; } cell_t& at(size_t idx) { return *neighbour_cells.at(idx); } + cell_t* find_cell(uint32_t earfcn, uint32_t pci); // serving cell handling int set_serving_cell(phy_interface_rrc_lte::phy_cell_t phy_cell, bool discard_serving); diff --git a/srsue/src/stack/rrc/phy_controller.cc b/srsue/src/stack/rrc/phy_controller.cc index dd683e0f1..6850c181f 100644 --- a/srsue/src/stack/rrc/phy_controller.cc +++ b/srsue/src/stack/rrc/phy_controller.cc @@ -30,10 +30,13 @@ std::string to_string(const phy_interface_rrc_lte::phy_cell_t& cell) return buffer; } -phy_controller::phy_controller(srsue::phy_interface_rrc_lte* phy_, srslte::task_sched_handle task_sched_) : +phy_controller::phy_controller(srsue::phy_interface_rrc_lte* phy_, + srslte::task_sched_handle task_sched_, + std::function on_cell_selection) : base_t(srslte::log_ref{"RRC"}), phy(phy_), - task_sched(task_sched_) + task_sched(task_sched_), + cell_selection_always_observer(std::move(on_cell_selection)) {} void phy_controller::in_sync() @@ -56,7 +59,7 @@ bool phy_controller::start_cell_select(const phy_cell_t& phy_cell, srslte::event log_h->warning("Failed to launch cell selection. Current state: %s\n", current_state_name().c_str()); return false; } - cell_selection_observer = std::move(observer); + cell_selection_once_observer = std::move(observer); return true; } @@ -96,7 +99,8 @@ void phy_controller::selecting_cell::exit(phy_controller* f) // Signal result back to FSM that called cell selection bool result = csel_res.result; - f->task_sched.defer_task([f, result]() { f->cell_selection_observer(result); }); + f->cell_selection_always_observer(target_cell.earfcn, target_cell.pci, result); + f->task_sched.defer_task([f, result]() { f->cell_selection_once_observer(result); }); } void phy_controller::selecting_cell::wait_in_sync::enter(selecting_cell* f) diff --git a/srsue/src/stack/rrc/rrc.cc b/srsue/src/stack/rrc/rrc.cc index 05f3adc46..3b41d8837 100644 --- a/srsue/src/stack/rrc/rrc.cc +++ b/srsue/src/stack/rrc/rrc.cc @@ -116,7 +116,15 @@ void rrc::init(phy_interface_rrc_lte* phy_, args = args_; - phy_ctrl.reset(new phy_controller{phy, task_sched}); + auto on_every_cell_selection = [this](uint32_t earfcn, uint32_t pci, bool csel_result) { + if (not csel_result) { + cell_t* c = meas_cells.find_cell(earfcn, pci); + if (c != nullptr) { + c->set_rsrp(-INFINITY); + } + } + }; + phy_ctrl.reset(new phy_controller{phy, task_sched, on_every_cell_selection}); state = RRC_STATE_IDLE; plmn_is_selected = false; diff --git a/srsue/src/stack/rrc/rrc_cell.cc b/srsue/src/stack/rrc/rrc_cell.cc index f100ff631..f347bc244 100644 --- a/srsue/src/stack/rrc/rrc_cell.cc +++ b/srsue/src/stack/rrc/rrc_cell.cc @@ -329,6 +329,14 @@ bool meas_cell_list::has_neighbour_cell(uint32_t earfcn, uint32_t pci) const return get_neighbour_cell_handle(earfcn, pci) != nullptr; } +cell_t* meas_cell_list::find_cell(uint32_t earfcn, uint32_t pci) +{ + if (serving_cell().phy_cell.pci == pci and serving_cell().phy_cell.earfcn == earfcn) { + return &serving_cell(); + } + return get_neighbour_cell_handle(earfcn, pci); +} + int meas_cell_list::set_serving_cell(phy_interface_rrc_lte::phy_cell_t phy_cell, bool discard_serving) { // don't update neighbor cell list unless serving cell changes diff --git a/srsue/src/stack/rrc/rrc_procedures.cc b/srsue/src/stack/rrc/rrc_procedures.cc index 2528288da..dca7a15f3 100644 --- a/srsue/src/stack/rrc/rrc_procedures.cc +++ b/srsue/src/stack/rrc/rrc_procedures.cc @@ -1358,13 +1358,9 @@ srslte::proc_outcome_t rrc::ho_proc::init(const asn1::rrc::rrc_conn_recfg_s& rrc : rrc_ptr->meas_cells.serving_cell().get_earfcn(); // Target cell shall be either serving cell (intra-cell HO) or neighbour cell - if (rrc_ptr->has_neighbour_cell(target_earfcn, mob_ctrl_info->target_pci)) { - // target cell is neighbour cell - target_cell = - rrc_ptr->meas_cells.get_neighbour_cell_handle(target_earfcn, recfg_r8.mob_ctrl_info.target_pci)->phy_cell; - } else if (recfg_r8.mob_ctrl_info.target_pci == rrc_ptr->meas_cells.serving_cell().get_pci()) { - // intra-cell HO, target cell is current serving cell - target_cell = rrc_ptr->get_serving_cell()->phy_cell; + cell_t* cell_to_ho = rrc_ptr->meas_cells.find_cell(target_earfcn, mob_ctrl_info->target_pci); + if (cell_to_ho != nullptr) { + target_cell = cell_to_ho->phy_cell; } else { rrc_ptr->rrc_log->console("Received HO command to unknown PCI=%d\n", mob_ctrl_info->target_pci); Error("Could not find target cell earfcn=%d, pci=%d\n",