diff --git a/srsue/hdr/stack/rrc/rrc_cell.h b/srsue/hdr/stack/rrc/rrc_cell.h index 783e3a830..d28a45f76 100644 --- a/srsue/hdr/stack/rrc/rrc_cell.h +++ b/srsue/hdr/stack/rrc/rrc_cell.h @@ -247,6 +247,10 @@ public: // serving cell handling int set_serving_cell(phy_cell_t phy_cell, bool discard_serving); + // Set serving cell and earfcn for each cc_idx + void set_scell_cc_idx(uint32_t cc_idx, uint32_t earfcn, uint32_t pci); + bool get_scell_cc_idx(uint32_t earfcn, uint32_t& pci); + T& serving_cell() { return *serv_cell; } const T& serving_cell() const { return *serv_cell; } @@ -263,6 +267,9 @@ private: unique_meas_cell serv_cell; std::vector neighbour_cells; + + // store serving pci and earfcn for each carrier + std::array, SRSRAN_MAX_CARRIERS> current_cell_pci_earfcn = {}; }; } // namespace srsue diff --git a/srsue/src/phy/sync.cc b/srsue/src/phy/sync.cc index 58cef2815..0ceb998e3 100644 --- a/srsue/src/phy/sync.cc +++ b/srsue/src/phy/sync.cc @@ -129,16 +129,18 @@ sync::~sync() void sync::stop() { running = false; - wait_thread_finish(); std::lock_guard lock(intra_freq_cfg_mutex); - worker_com->semaphore.wait_all(); for (auto& q : intra_freq_meas) { q->stop(); } // Reset (stop Rx stream) as soon as possible to avoid base-band Rx buffer overflow radio_h->reset(); + + // let the sync FSM finish before waiting for workers semaphores to avoid workers locking + wait_thread_finish(); + worker_com->semaphore.wait_all(); } void sync::reset() diff --git a/srsue/src/stack/rrc/rrc.cc b/srsue/src/stack/rrc/rrc.cc index 481c62501..64ababa23 100644 --- a/srsue/src/stack/rrc/rrc.cc +++ b/srsue/src/stack/rrc/rrc.cc @@ -457,7 +457,8 @@ void rrc::process_new_cell_meas(const std::vector& meas) bool neighbour_added = meas_cells.process_new_cell_meas(meas, filter); // Instruct measurements subclass to update phy with new cells to measure based on strongest neighbours - if (state == RRC_STATE_CONNECTED && neighbour_added) { + // Avoid updating PHY while HO procedure is busy + if (state == RRC_STATE_CONNECTED && neighbour_added && !ho_handler.is_busy()) { measurements->update_phy(); } } @@ -2482,6 +2483,8 @@ void rrc::apply_phy_scell_config(const scell_to_add_mod_r10_s& scell_config, boo logger.error("Adding SCell cc_idx=%d", scell_config.scell_idx_r10); } else if (!phy_ctrl->set_cell_config(scell_cfg, scell_config.scell_idx_r10)) { logger.error("Setting SCell configuration for cc_idx=%d", scell_config.scell_idx_r10); + } else { + meas_cells.set_scell_cc_idx(scell_config.scell_idx_r10, earfcn, scell.id); } } diff --git a/srsue/src/stack/rrc/rrc_cell.cc b/srsue/src/stack/rrc/rrc_cell.cc index cdd0b6693..94410f0d7 100644 --- a/srsue/src/stack/rrc/rrc_cell.cc +++ b/srsue/src/stack/rrc/rrc_cell.cc @@ -434,6 +434,25 @@ int meas_cell_list::set_serving_cell(phy_cell_t phy_cell, bool discard_servin return SRSRAN_SUCCESS; } +template +void meas_cell_list::set_scell_cc_idx(uint32_t cc_idx, uint32_t earfcn, uint32_t pci) +{ + current_cell_pci_earfcn[cc_idx].first = earfcn; + current_cell_pci_earfcn[cc_idx].second = pci; +} + +template +bool meas_cell_list::get_scell_cc_idx(uint32_t earfcn, uint32_t& pci) +{ + for (auto& cell : current_cell_pci_earfcn) { + if (cell.first == earfcn) { + pci = cell.second; + return true; + } + } + return false; +} + template bool meas_cell_list::process_new_cell_meas(const std::vector& meas, const std::function& filter_meas) diff --git a/srsue/src/stack/rrc/rrc_meas.cc b/srsue/src/stack/rrc/rrc_meas.cc index f9926e89d..985dbf904 100644 --- a/srsue/src/stack/rrc/rrc_meas.cc +++ b/srsue/src/stack/rrc/rrc_meas.cc @@ -118,7 +118,6 @@ bool rrc::rrc_meas::parse_meas_config(const rrc_conn_recfg_r8_ies_s* mob_reconf_ void rrc::rrc_meas::ho_reest_actions(const uint32_t src_earfcn, const uint32_t dst_earfcn) { meas_cfg.ho_reest_finish(src_earfcn, dst_earfcn); - update_phy(); } void rrc::rrc_meas::run_tti() @@ -224,12 +223,10 @@ void rrc::rrc_meas::var_meas_report_list::generate_report_eutra(meas_results_s* for (auto& cell : var_meas.cell_triggered_list) { // report neighbour cells only if (cell.pci == serv_cell->get_pci() && cell.earfcn == serv_cell->get_earfcn()) { - logger.info("MEAS: skipping serving cell in report neighbour=%d, pci=%d, earfcn=%d, rsrp=%+.1f, rsrq=%+.1f", + logger.info("MEAS: skipping serving cell in report neighbour=%d, pci=%d, earfcn=%d", neigh_list.size(), cell.pci, - var_meas.carrier_freq, - rrc_ptr->get_cell_rsrp(var_meas.carrier_freq, cell.pci), - rrc_ptr->get_cell_rsrq(var_meas.carrier_freq, cell.pci)); + var_meas.carrier_freq); continue; } if (neigh_list.size() <= var_meas.report_cfg_eutra.max_report_cells) { @@ -767,16 +764,31 @@ void rrc::rrc_meas::var_meas_cfg::eval_triggers_eutra(uint32_t meas_i } }; + eutra_event_s::event_id_c_ event_id = report_cfg.trigger_type.event().event_id; + + // For A1/A2 events, get serving cell from current carrier + if (event_id.type().value < eutra_event_s::event_id_c_::types::event_a3 && + meas_obj.carrier_freq != serv_cell->get_earfcn()) { + uint32_t scell_pci = 0; + if (!rrc_ptr->meas_cells.get_scell_cc_idx(meas_obj.carrier_freq, scell_pci)) { + logger.error("MEAS: Could not find serving cell for carrier earfcn=%d", meas_obj.carrier_freq); + return; + } + serv_cell = rrc_ptr->meas_cells.get_neighbour_cell_handle(meas_obj.carrier_freq, scell_pci); + if (!serv_cell) { + logger.error( + "MEAS: Could not find serving cell for carrier earfcn=%d and pci=%d", meas_obj.carrier_freq, scell_pci); + return; + } + } + double hyst = 0.5 * report_cfg.trigger_type.event().hysteresis; float Ms = is_rsrp(report_cfg.trigger_quant.value) ? serv_cell->get_rsrp() : serv_cell->get_rsrq(); - if (!std::isnormal(Ms)) { logger.debug("MEAS: Serving cell Ms=%f invalid when evaluating triggers", Ms); return; } - eutra_event_s::event_id_c_ event_id = report_cfg.trigger_type.event().event_id; - if (report_cfg.trigger_type.type() == report_cfg_eutra_s::trigger_type_c_::types::event) { // A1 & A2 are for serving cell only if (event_id.type().value < eutra_event_s::event_id_c_::types::event_a3) { diff --git a/srsue/src/stack/rrc/rrc_procedures.cc b/srsue/src/stack/rrc/rrc_procedures.cc index 23cf181ad..8b954370f 100644 --- a/srsue/src/stack/rrc/rrc_procedures.cc +++ b/srsue/src/stack/rrc/rrc_procedures.cc @@ -1555,6 +1555,8 @@ srsran::proc_outcome_t rrc::connection_reest_proc::react(const asn1::rrc::rrc_co // 1> perform the measurement related actions as specified in 5.5.6.1; rrc_ptr->measurements->ho_reest_actions(rrc_ptr->get_serving_cell()->get_earfcn(), rrc_ptr->get_serving_cell()->get_earfcn()); + // Update PHY measurements after HO Reestablishment actions. + rrc_ptr->measurements->update_phy(); // 1> submit the RRCConnectionReestablishmentComplete message to lower layers for transmission, upon which the // procedure ends; @@ -1738,6 +1740,8 @@ srsran::proc_outcome_t rrc::ho_proc::init(const asn1::rrc::rrc_conn_recfg_s& rrc // perform the measurement related actions as specified in 5.5.6.1; rrc_ptr->measurements->ho_reest_actions(ho_src_cell.earfcn, target_earfcn); + // Do not update PHY measurements here since it will be updated after the HO procedure finishes + // Note: We delay the enqueuing of RRC Reconf Complete message to avoid that the message goes in an UL grant // directed at the old RNTI. rrc_ptr->task_sched.defer_callback(4, [this]() { @@ -1796,6 +1800,8 @@ void rrc::ho_proc::then(const srsran::proc_state_t& result) srsran::console("HO %ssuccessful\n", result.is_success() ? "" : "un"); rrc_ptr->t304.stop(); + + rrc_ptr->measurements->update_phy(); } } // namespace srsue