diff --git a/srsenb/hdr/stack/rrc/rrc_mobility.h b/srsenb/hdr/stack/rrc/rrc_mobility.h index 415173c0b..06383d2dd 100644 --- a/srsenb/hdr/stack/rrc/rrc_mobility.h +++ b/srsenb/hdr/stack/rrc/rrc_mobility.h @@ -30,51 +30,6 @@ namespace srsenb { -/** - * This class is responsible for storing the UE Measurement Configuration at the eNB side. - * Has the same fields as asn1::rrc::var_meas_cfg but stored in data structs that are easier to handle - */ -class var_meas_cfg_t -{ -public: - using meas_cell_t = asn1::rrc::cells_to_add_mod_s; - using meas_id_t = asn1::rrc::meas_id_to_add_mod_s; - using meas_obj_t = asn1::rrc::meas_obj_to_add_mod_s; - using report_cfg_t = asn1::rrc::report_cfg_to_add_mod_s; - - var_meas_cfg_t(); - std::tuple add_cell_cfg(const meas_cell_cfg_t& cellcfg); - std::pair add_meas_obj(uint32_t dl_earfcn); - report_cfg_t* add_report_cfg(const asn1::rrc::report_cfg_eutra_s& reportcfg); - meas_id_t* add_measid_cfg(uint8_t measobjid, uint8_t repid); - asn1::rrc::quant_cfg_s* add_quant_cfg(const asn1::rrc::quant_cfg_eutra_s& quantcfg); - - bool compute_diff_meas_cfg(const var_meas_cfg_t& target_cfg, asn1::rrc::meas_cfg_s* meas_cfg) const; - void compute_diff_meas_objs(const var_meas_cfg_t& target_cfg, asn1::rrc::meas_cfg_s* meas_cfg) const; - void compute_diff_cells(const asn1::rrc::meas_obj_eutra_s& target_it, - const asn1::rrc::meas_obj_eutra_s& src_it, - asn1::rrc::meas_obj_to_add_mod_s* added_obj) const; - void compute_diff_report_cfgs(const var_meas_cfg_t& target_cfg, asn1::rrc::meas_cfg_s* meas_cfg) const; - void compute_diff_meas_ids(const var_meas_cfg_t& target_cfg, asn1::rrc::meas_cfg_s* meas_cfg) const; - void compute_diff_quant_cfg(const var_meas_cfg_t& target_cfg, asn1::rrc::meas_cfg_s* meas_cfg_msg) const; - - // getters - const asn1::rrc::meas_obj_to_add_mod_list_l& meas_objs() const { return var_meas.meas_obj_list; } - const asn1::rrc::report_cfg_to_add_mod_list_l& rep_cfgs() const { return var_meas.report_cfg_list; } - const asn1::rrc::meas_id_to_add_mod_list_l& meas_ids() const { return var_meas.meas_id_list; } - asn1::rrc::meas_obj_to_add_mod_list_l& meas_objs() { return var_meas.meas_obj_list; } - asn1::rrc::report_cfg_to_add_mod_list_l& rep_cfgs() { return var_meas.report_cfg_list; } - asn1::rrc::meas_id_to_add_mod_list_l& meas_ids() { return var_meas.meas_id_list; } - std::string to_string() const; - - static var_meas_cfg_t make(const asn1::rrc::meas_cfg_s& meas_cfg); - static var_meas_cfg_t make(const rrc_cfg_t& cfg, const cell_info_common& pcell); - -private: - asn1::rrc::var_meas_cfg_s var_meas; - srslte::log_ref rrc_log; -}; - enum class ho_interface_t { S1, X2, intra_enb }; class rrc::ue::rrc_mobility : public srslte::fsm_t diff --git a/srsenb/src/stack/rrc/rrc_mobility.cc b/srsenb/src/stack/rrc/rrc_mobility.cc index ed7757260..83f9658d4 100644 --- a/srsenb/src/stack/rrc/rrc_mobility.cc +++ b/srsenb/src/stack/rrc/rrc_mobility.cc @@ -32,7 +32,6 @@ #include #include #include -#include namespace srsenb { @@ -124,380 +123,8 @@ std::string to_string(const cells_to_add_mod_s& obj) return {buf}; } -//! Find MeasObj with same earfcn -meas_obj_to_add_mod_s* find_meas_obj(meas_obj_to_add_mod_list_l& l, uint32_t earfcn) -{ - auto same_earfcn = [earfcn](const meas_obj_to_add_mod_s& obj) { - return obj.meas_obj.type().value == meas_obj_to_add_mod_s::meas_obj_c_::types_opts::meas_obj_eutra and - obj.meas_obj.meas_obj_eutra().carrier_freq == earfcn; - }; - auto it = std::find_if(l.begin(), l.end(), same_earfcn); - if (it == l.end()) { - return nullptr; - } - return it; -} - -/** Finds a cell in this->objects based on pci and earfcn - * return pair of (meas_obj,cell_obj). If no cell has frequency==earfcn, meas_obj=nullptr - */ -std::pair -find_cell(meas_obj_to_add_mod_list_l& l, uint32_t earfcn, uint32_t pci) -{ - // find meas_obj with same earfcn - meas_obj_to_add_mod_s* obj = rrc_details::find_meas_obj(l, earfcn); - if (obj == nullptr) { - return std::make_pair(obj, (cells_to_add_mod_s*)nullptr); - } - // find cell with same id - auto& cells = obj->meas_obj.meas_obj_eutra().cells_to_add_mod_list; - auto cell_it = std::find_if(cells.begin(), cells.end(), [pci](const cells_to_add_mod_s& c) { return c.pci == pci; }); - if (cell_it == cells.end()) { - cell_it = nullptr; - } - return std::make_pair(obj, cell_it); -} - -/** - * Section 5.5.2.5 - * Description: Adds MeasObjtoAddMod to MeasCfg object - */ -meas_obj_to_add_mod_s* meascfg_add_meas_obj(meas_cfg_s* meas_cfg, const meas_obj_to_add_mod_s& meas_obj) -{ - meas_cfg->meas_obj_to_add_mod_list_present = true; - - // search for meas_obj by obj_id to ensure uniqueness (assume sorted) - auto meas_obj_it = srslte::add_rrc_obj_id(meas_cfg->meas_obj_to_add_mod_list, meas_obj.meas_obj_id); - // TODO: Assert dl_earfcn is the same - - auto& target_eutra = meas_obj_it->meas_obj.set_meas_obj_eutra(); - auto& src_eutra = meas_obj.meas_obj.meas_obj_eutra(); - target_eutra.carrier_freq = src_eutra.carrier_freq; - target_eutra.offset_freq_present = src_eutra.offset_freq_present; - target_eutra.offset_freq = src_eutra.offset_freq; - target_eutra.allowed_meas_bw = src_eutra.allowed_meas_bw; - target_eutra.presence_ant_port1 = src_eutra.presence_ant_port1; - target_eutra.neigh_cell_cfg = src_eutra.neigh_cell_cfg; - // do not add cellsToAddModList, blacCells, whiteCells, etc. according to (5.5.2.5 1|1|1) - - return meas_obj_it; -} - } // namespace rrc_details -/************************************************************************************************* - * var_meas_cfg_t class - ************************************************************************************************/ - -var_meas_cfg_t::var_meas_cfg_t() : rrc_log(srslte::logmap::get("RRC")) {} - -//! Add EARFCN to the varMeasCfg -std::pair var_meas_cfg_t::add_meas_obj(uint32_t dl_earfcn) -{ - auto* obj = rrc_details::find_meas_obj(var_meas.meas_obj_list, dl_earfcn); - if (obj != nullptr) { - return {false, obj}; - } - - meas_obj_t new_obj; - new_obj.meas_obj_id = srslte::find_rrc_obj_id_gap(var_meas.meas_obj_list); - asn1::rrc::meas_obj_eutra_s& eutra = new_obj.meas_obj.set_meas_obj_eutra(); - eutra.carrier_freq = dl_earfcn; - eutra.allowed_meas_bw.value = asn1::rrc::allowed_meas_bw_e::mbw6; // TODO: What value to add here? - eutra.neigh_cell_cfg.from_number(1); // No MBSFN subframes present in neighbors - eutra.offset_freq_present = false; // no offset - obj = srslte::add_rrc_obj(var_meas.meas_obj_list, new_obj); - var_meas.meas_obj_list_present = true; - return {true, obj}; -} - -//! Add cell parsed in configuration file to the varMeasCfg -std::tuple -var_meas_cfg_t::add_cell_cfg(const meas_cell_cfg_t& cellcfg) -{ - using namespace rrc_details; - bool inserted_flag = true; - - q_offset_range_e offset; - asn1::number_to_enum(offset, (int8_t)cellcfg.q_offset); - - std::pair ret = - rrc_details::find_cell(var_meas.meas_obj_list, cellcfg.earfcn, cellcfg.pci); - cells_to_add_mod_s new_cell; - new_cell.cell_individual_offset = offset; - new_cell.pci = cellcfg.pci; - - if (ret.first != nullptr) { - // there are cells with the same earfcn at least. - if (ret.second != nullptr) { - // the cell already existed. - if (ret.second->cell_individual_offset != offset) { - // members of cell were updated - new_cell.cell_idx = ret.second->cell_idx; - *ret.second = new_cell; - } else { - inserted_flag = false; - } - } else { - auto& eutra_obj = ret.first->meas_obj.meas_obj_eutra(); - // pci not found. create new cell - new_cell.cell_idx = srslte::find_rrc_obj_id_gap(eutra_obj.cells_to_add_mod_list); - ret.second = srslte::add_rrc_obj(eutra_obj.cells_to_add_mod_list, new_cell); - eutra_obj.cells_to_add_mod_list_present = true; - } - } else { - // no measobj has been found with same earfcn, create a new one - auto ret2 = add_meas_obj(cellcfg.earfcn); - ret.first = ret2.second; - - new_cell.cell_idx = 1; - auto& eutra = ret2.second->meas_obj.meas_obj_eutra(); - eutra.cells_to_add_mod_list_present = true; - eutra.cells_to_add_mod_list.push_back(new_cell); - ret.second = &ret.first->meas_obj.meas_obj_eutra().cells_to_add_mod_list.back(); - } - - if (inserted_flag) { - var_meas.meas_obj_list_present = true; - } - - return std::make_tuple(inserted_flag, ret.first, ret.second); -} - -report_cfg_to_add_mod_s* var_meas_cfg_t::add_report_cfg(const report_cfg_eutra_s& reportcfg) -{ - report_cfg_to_add_mod_s new_rep; - new_rep.report_cfg_id = srslte::find_rrc_obj_id_gap(var_meas.report_cfg_list); - new_rep.report_cfg.set_report_cfg_eutra() = reportcfg; - - var_meas.report_cfg_list_present = true; - return srslte::add_rrc_obj(var_meas.report_cfg_list, new_rep); -} - -meas_id_to_add_mod_s* var_meas_cfg_t::add_measid_cfg(uint8_t measobjid, uint8_t measrepid) -{ - // ensure MeasObjId and ReportCfgId already exist - auto objit = srslte::find_rrc_obj_id(var_meas.meas_obj_list, measobjid); - if (objit == var_meas.meas_obj_list.end()) { - ERROR("Failed to add MeasId because MeasObjId=%d is not found.\n", measobjid); - return nullptr; - } - auto repit = srslte::find_rrc_obj_id(var_meas.report_cfg_list, measrepid); - if (repit == var_meas.report_cfg_list.end()) { - ERROR("Failed to add MeasId because ReportCfgId=%d is not found.\n", measrepid); - return nullptr; - } - meas_id_to_add_mod_s new_measid; - new_measid.report_cfg_id = measrepid; - new_measid.meas_obj_id = measobjid; - new_measid.meas_id = srslte::find_rrc_obj_id_gap(var_meas.meas_id_list); - - var_meas.meas_id_list_present = true; - return srslte::add_rrc_obj(var_meas.meas_id_list, new_measid); -} - -asn1::rrc::quant_cfg_s* var_meas_cfg_t::add_quant_cfg(const asn1::rrc::quant_cfg_eutra_s& quantcfg) -{ - var_meas.quant_cfg_present = true; - var_meas.quant_cfg.quant_cfg_eutra_present = true; - var_meas.quant_cfg.quant_cfg_eutra = quantcfg; - return &var_meas.quant_cfg; -} - -bool var_meas_cfg_t::compute_diff_meas_cfg(const var_meas_cfg_t& target_cfg, asn1::rrc::meas_cfg_s* meas_cfg) const -{ - *meas_cfg = {}; - - // Shortcut in case this is the same as target - if (this == &target_cfg) { - return false; - } - - // Set a MeasConfig in the RRC Connection Reconfiguration for HO. - compute_diff_meas_objs(target_cfg, meas_cfg); - compute_diff_report_cfgs(target_cfg, meas_cfg); - compute_diff_meas_ids(target_cfg, meas_cfg); - compute_diff_quant_cfg(target_cfg, meas_cfg); - meas_cfg->meas_gap_cfg_present = false; // NOTE: we do not support inter-freq. HO - meas_cfg->s_measure_present = false; // NOTE: We do not support SCells - meas_cfg->pre_regist_info_hrpd_present = false; // NOTE: not supported - meas_cfg->speed_state_pars_present = false; // NOTE: not supported - - bool diff = meas_cfg->meas_obj_to_add_mod_list_present; - diff |= meas_cfg->meas_obj_to_rem_list_present; - diff |= meas_cfg->report_cfg_to_add_mod_list_present; - diff |= meas_cfg->report_cfg_to_rem_list_present; - diff |= meas_cfg->meas_id_to_add_mod_list_present; - diff |= meas_cfg->meas_id_to_rem_list_present; - diff |= meas_cfg->quant_cfg_present; - diff |= meas_cfg->meas_gap_cfg_present; - diff |= meas_cfg->s_measure_present; - diff |= meas_cfg->pre_regist_info_hrpd_present; - diff |= meas_cfg->speed_state_pars_present; - return diff; -} - -//! adds all the cells that got updated to MeasCfg. -void var_meas_cfg_t::compute_diff_cells(const meas_obj_eutra_s& target_it, - const meas_obj_eutra_s& src_it, - meas_obj_to_add_mod_s* added_obj) const -{ - meas_obj_eutra_s* eutra_obj = &added_obj->meas_obj.meas_obj_eutra(); - srslte::compute_cfg_diff(src_it.cells_to_add_mod_list, - target_it.cells_to_add_mod_list, - eutra_obj->cells_to_add_mod_list, - eutra_obj->cells_to_rem_list); - eutra_obj->cells_to_add_mod_list_present = eutra_obj->cells_to_add_mod_list.size() > 0; - eutra_obj->cells_to_rem_list_present = eutra_obj->cells_to_rem_list.size() > 0; -} - -/** - * Section 5.5.2.4/5, Measurement Object removal and addition/modification - * Description: compute diff between target_cfg and var_meas -> depending on diff, add/remove/update meas_obj in - * meas_cfg - */ -void var_meas_cfg_t::compute_diff_meas_objs(const var_meas_cfg_t& target_cfg, meas_cfg_s* meas_cfg) const -{ - auto rem_func = [meas_cfg](const meas_obj_to_add_mod_s* it) { - meas_cfg->meas_obj_to_rem_list.push_back(it->meas_obj_id); - }; - auto add_func = [meas_cfg](const meas_obj_to_add_mod_s* it) { meas_cfg->meas_obj_to_add_mod_list.push_back(*it); }; - auto mod_func = [this, meas_cfg](const meas_obj_to_add_mod_s* src_it, const meas_obj_to_add_mod_s* target_it) { - if (not(*src_it == *target_it)) { - meas_obj_to_add_mod_s* added_obj = rrc_details::meascfg_add_meas_obj(meas_cfg, *target_it); - // Add cells if there were changes. - compute_diff_cells(target_it->meas_obj.meas_obj_eutra(), src_it->meas_obj.meas_obj_eutra(), added_obj); - } - }; - srslte::compute_cfg_diff(var_meas.meas_obj_list, target_cfg.var_meas.meas_obj_list, rem_func, add_func, mod_func); - meas_cfg->meas_obj_to_add_mod_list_present = meas_cfg->meas_obj_to_add_mod_list.size() > 0; - meas_cfg->meas_obj_to_rem_list_present = meas_cfg->meas_obj_to_rem_list.size() > 0; - // TODO: black cells and white cells -} - -/** - * Section 5.5.2.6/7 - Reporting configuration removal and addition/modification - */ -void var_meas_cfg_t::compute_diff_report_cfgs(const var_meas_cfg_t& target_cfg, asn1::rrc::meas_cfg_s* meas_cfg) const -{ - srslte::compute_cfg_diff(var_meas.report_cfg_list, - target_cfg.var_meas.report_cfg_list, - meas_cfg->report_cfg_to_add_mod_list, - meas_cfg->report_cfg_to_rem_list); - meas_cfg->report_cfg_to_add_mod_list_present = meas_cfg->report_cfg_to_add_mod_list.size() > 0; - meas_cfg->report_cfg_to_rem_list_present = meas_cfg->report_cfg_to_rem_list.size() > 0; -} - -void var_meas_cfg_t::compute_diff_meas_ids(const var_meas_cfg_t& target_cfg, asn1::rrc::meas_cfg_s* meas_cfg) const -{ - srslte::compute_cfg_diff(var_meas.meas_id_list, - target_cfg.var_meas.meas_id_list, - meas_cfg->meas_id_to_add_mod_list, - meas_cfg->meas_id_to_rem_list); - meas_cfg->meas_id_to_add_mod_list_present = meas_cfg->meas_id_to_add_mod_list.size() > 0; - meas_cfg->meas_id_to_rem_list_present = meas_cfg->meas_id_to_rem_list.size() > 0; -} - -void var_meas_cfg_t::compute_diff_quant_cfg(const var_meas_cfg_t& target_cfg, asn1::rrc::meas_cfg_s* meas_cfg_msg) const -{ - if (target_cfg.var_meas.quant_cfg_present and - (not var_meas.quant_cfg_present or not(target_cfg.var_meas.quant_cfg == var_meas.quant_cfg))) { - meas_cfg_msg->quant_cfg_present = true; - meas_cfg_msg->quant_cfg = target_cfg.var_meas.quant_cfg; - } -} - -std::string var_meas_cfg_t::to_string() const -{ - asn1::json_writer js; - var_meas.to_json(js); - return js.to_string(); -} - -/** - * Convert MeasCfg asn1 struct to var_meas_cfg_t - * @param meas_cfg - * @return - */ -var_meas_cfg_t var_meas_cfg_t::make(const asn1::rrc::meas_cfg_s& meas_cfg) -{ - var_meas_cfg_t var{}; - if (meas_cfg.meas_id_to_add_mod_list_present) { - var.var_meas.meas_id_list_present = true; - var.var_meas.meas_id_list = meas_cfg.meas_id_to_add_mod_list; - } - if (meas_cfg.meas_obj_to_add_mod_list_present) { - var.var_meas.meas_obj_list_present = true; - var.var_meas.meas_obj_list = meas_cfg.meas_obj_to_add_mod_list; - } - if (meas_cfg.report_cfg_to_add_mod_list_present) { - var.var_meas.report_cfg_list_present = true; - var.var_meas.report_cfg_list = meas_cfg.report_cfg_to_add_mod_list; - } - if (meas_cfg.quant_cfg_present) { - var.var_meas.quant_cfg_present = true; - var.var_meas.quant_cfg = meas_cfg.quant_cfg; - } - if (meas_cfg.s_measure_present) { - var.var_meas.s_measure_present = true; - var.var_meas.s_measure = meas_cfg.s_measure; - } - if (meas_cfg.speed_state_pars_present) { - var.var_meas.speed_state_pars_present = true; - var.var_meas.speed_state_pars.set(meas_cfg.speed_state_pars.type().value); - if (var.var_meas.speed_state_pars.type().value == setup_opts::setup) { - var.var_meas.speed_state_pars.setup().mob_state_params = meas_cfg.speed_state_pars.setup().mob_state_params; - var.var_meas.speed_state_pars.setup().time_to_trigger_sf = meas_cfg.speed_state_pars.setup().time_to_trigger_sf; - } - } - if (meas_cfg.report_cfg_to_rem_list_present or meas_cfg.meas_obj_to_rem_list_present or - meas_cfg.meas_id_to_rem_list_present) { - srslte::logmap::get("RRC")->warning("Remove lists not handled by the var_meas_cfg_t method\n"); - } - return var; -} - -var_meas_cfg_t var_meas_cfg_t::make(const rrc_cfg_t& cfg, const cell_info_common& pcell) -{ - // The measConfig contains measObjs for the PCell DL-EARFCN and activated UE carriers - auto active_earfcns = get_measobj_earfcns(pcell); - - var_meas_cfg_t var_meas; - if (not cfg.meas_cfg_present) { - return var_meas; - } - - // Add PCell+Scells as MeasObjs - for (uint32_t earfcn : active_earfcns) { - var_meas.add_meas_obj(earfcn); - } - - for (const auto& cell_cfg : cfg.cell_list) { - // inserts all neighbor cells and pcell, if q_offset > 0 - for (const meas_cell_cfg_t& meascell : cell_cfg.meas_cfg.meas_cells) { - if (meascell.pci != pcell.cell_cfg.pci or meascell.earfcn != pcell.cell_cfg.dl_earfcn or meascell.q_offset > 0) { - var_meas.add_cell_cfg(meascell); - } - } - // insert same report cfg for all cells - for (const report_cfg_eutra_s& reportcfg : cell_cfg.meas_cfg.meas_reports) { - var_meas.add_report_cfg(reportcfg); - } - // insert quantity config - var_meas.add_quant_cfg(cell_cfg.meas_cfg.quant_cfg); - } - - // insert all meas ids - // TODO: add this to the parser - if (var_meas.rep_cfgs().size() > 0) { - for (const auto& measobj : var_meas.meas_objs()) { - var_meas.add_measid_cfg(measobj.meas_obj_id, var_meas.rep_cfgs().begin()->report_cfg_id); - } - } - - return var_meas; -} - /************************************************************************************************* * mobility_cfg class ************************************************************************************************/ @@ -582,8 +209,8 @@ bool rrc::ue::rrc_mobility::fill_conn_recfg_no_ho_cmd(asn1::rrc::rrc_conn_recfg_ } // Check if there has been any update in ue_var_meas based on UE current cell list - conn_recfg->meas_cfg_present = apply_meascfg_updates( - conn_recfg->meas_cfg, rrc_ue->current_ue_cfg.meas_cfg, rrc_ue->cell_ded_list); + conn_recfg->meas_cfg_present = + apply_meascfg_updates(conn_recfg->meas_cfg, rrc_ue->current_ue_cfg.meas_cfg, rrc_ue->cell_ded_list); return conn_recfg->meas_cfg_present; } diff --git a/srsenb/src/stack/rrc/ue_meas_cfg.cc b/srsenb/src/stack/rrc/ue_meas_cfg.cc index 0fdb0cbce..92a0b1b5e 100644 --- a/srsenb/src/stack/rrc/ue_meas_cfg.cc +++ b/srsenb/src/stack/rrc/ue_meas_cfg.cc @@ -268,6 +268,47 @@ meas_gap_cfg_c make_measgap(const meas_obj_list& measobjs, const cell_ctxt_dedic return meas_gap; } +bool apply_meas_gap_updates(const meas_gap_cfg_c& src_gaps, + const meas_gap_cfg_c& target_gaps, + meas_gap_cfg_c& diff_gaps) +{ + if (src_gaps.type() != target_gaps.type()) { + if (target_gaps.type().value == setup_opts::setup) { + diff_gaps = target_gaps; + return true; + } else if (src_gaps.type().value == setup_opts::setup) { + diff_gaps.set(setup_opts::release); + return true; + } + } else if (target_gaps.type().value == setup_opts::setup) { + const auto& target_offset = target_gaps.setup().gap_offset; + const auto& src_offset = src_gaps.setup().gap_offset; + if (target_offset.type().value != src_offset.type().value) { + diff_gaps = target_gaps; + return true; + } else { + switch (target_offset.type().value) { + case meas_gap_cfg_c::setup_s_::gap_offset_c_::types_opts::gp0: + if (target_offset.gp0() != src_offset.gp0()) { + diff_gaps = target_gaps; + return true; + } + break; + case meas_gap_cfg_c::setup_s_::gap_offset_c_::types_opts::gp1: + if (target_offset.gp1() != src_offset.gp1()) { + diff_gaps = target_gaps; + return true; + } + break; + default: + srslte::logmap::get("RRC")->warning("MeasGap of type %s not supported\n", + target_offset.type().to_string().c_str()); + } + } + } + return false; +} + /*********************************** * measConfig **********************************/ @@ -291,10 +332,10 @@ bool set_meascfg_presence_flags(meas_cfg_s& meascfg) bool fill_meascfg_enb_cfg(meas_cfg_s& meascfg, const cell_ctxt_dedicated_list& ue_cell_list) { - const cell_ctxt_dedicated* pcell = ue_cell_list.get_ue_cc_idx(UE_PCELL_CC_IDX); + const cell_ctxt_dedicated* pcell = ue_cell_list.get_ue_cc_idx(UE_PCELL_CC_IDX); assert(pcell != nullptr); - const cell_info_common* pcell_cfg = pcell->cell_common; - const auto& pcell_meascfg = pcell_cfg->cell_cfg.meas_cfg; + const cell_info_common* pcell_cfg = pcell->cell_common; + const auto& pcell_meascfg = pcell_cfg->cell_cfg.meas_cfg; // Add PCell+Scells to measObjToAddModList for (uint32_t ue_cc_idx = 0; ue_cc_idx < ue_cell_list.nof_cells(); ++ue_cc_idx) { @@ -414,17 +455,10 @@ bool apply_meascfg_updates(meas_cfg_s& meascfg, (target_meascfg.quant_cfg_present and target_meascfg.quant_cfg != current_meascfg.quant_cfg)) { meascfg.quant_cfg = target_meascfg.quant_cfg; } - // Only update measGap if it was not set before or periodicity changed - if (current_meascfg.meas_gap_cfg.type().value == setup_opts::setup) { - if (target_meascfg.meas_gap_cfg.type().value != setup_opts::setup) { - meascfg.meas_gap_cfg.set(setup_opts::release); - } else if (target_meascfg.meas_gap_cfg.setup().gap_offset.type() != - current_meascfg.meas_gap_cfg.setup().gap_offset.type()) { - meascfg.meas_gap_cfg = target_meascfg.meas_gap_cfg; - } - } else { - meascfg.meas_gap_cfg = target_meascfg.meas_gap_cfg; - } + + // Set measGaps if changed + meascfg.meas_gap_cfg_present = + apply_meas_gap_updates(current_meascfg.meas_gap_cfg, target_meascfg.meas_gap_cfg, meascfg.meas_gap_cfg); // Update current measconfig bool ret = set_meascfg_presence_flags(meascfg);