diff --git a/srsue/hdr/stack/rrc/rrc_meas.h b/srsue/hdr/stack/rrc/rrc_meas.h index a98356ba2..69c543889 100644 --- a/srsue/hdr/stack/rrc/rrc_meas.h +++ b/srsue/hdr/stack/rrc/rrc_meas.h @@ -111,7 +111,13 @@ private: void log_debug_trigger_value(const eutra_event_s::event_id_c_& e); static bool is_rsrp(report_cfg_eutra_s::trigger_quant_opts::options q); + + // Helpers + void measObject_addmod_eutra(uint8_t meas_obj_id, const meas_obj_eutra_s& cfg_obj); + void measObject_addmod_nr_r15(uint8_t meas_obj_id, const meas_obj_nr_r15_s& cfg_obj); + void reportConfig_addmod_eutra(uint8_t report_cfg_id, const report_cfg_eutra_s& report_cfg); + class cell_trigger_state { public: @@ -125,9 +131,10 @@ private: }; // varMeasConfig data - std::map measIdList; // Uses MeasId as key - std::map measObjectsList; // Uses MeasObjectId as key - std::map reportConfigList; // Uses ReportConfigId as key + std::map measIdList; // Uses MeasId as key + std::map measObjectsList; // Uses MeasObjectId as key + std::map measObjectsListNrR15; // Uses MeasObjectId as key + std::map reportConfigList; // Uses ReportConfigId as key phy_quant_t filter_a = {1.0, 1.0}; // disable filtering until quantityConfig is received (see Sec. 5.5.3.2 Note 2) float s_measure_value = 0.0; diff --git a/srsue/src/stack/rrc/rrc_meas.cc b/srsue/src/stack/rrc/rrc_meas.cc index 42268c2de..029dc1cc6 100644 --- a/srsue/src/stack/rrc/rrc_meas.cc +++ b/srsue/src/stack/rrc/rrc_meas.cc @@ -789,126 +789,197 @@ void rrc::rrc_meas::var_meas_cfg::measObject_removal(const meas_obj_to_rem_list_ } } +void rrc::rrc_meas::var_meas_cfg::measObject_addmod_eutra(uint8_t meas_obj_id, const meas_obj_eutra_s& cfg_obj) +{ + bool entry_exists = measObjectsList.count(meas_obj_id) > 0; + if (!entry_exists) { + // add a new entry for the received measObject to the measObjectList within VarMeasConfig + measObjectsList.emplace(meas_obj_id, cfg_obj); + } + + meas_obj_eutra_s& local_obj = measObjectsList.at(meas_obj_id); + + // if an entry with the matching measObjectId exists in the measObjectList within the VarMeasConfig + if (entry_exists) { + // Update carrier frequency0 + local_obj.carrier_freq = cfg_obj.carrier_freq; + local_obj.allowed_meas_bw = cfg_obj.allowed_meas_bw; + + // Combine the new cells with the existing ones and remove the cells indicated in config + { + // Remove cells + if (cfg_obj.cells_to_rem_list_present) { + log_h->debug("MEAS: Removing %d cells\n", cfg_obj.cells_to_rem_list.size()); + cells_to_add_mod_list_l new_list; + for (auto& local_cell : local_obj.cells_to_add_mod_list) { + // If not in the list to remove, copy to new list + if (std::find(cfg_obj.cells_to_rem_list.begin(), cfg_obj.cells_to_rem_list.end(), local_cell.cell_idx) == + cfg_obj.cells_to_rem_list.end()) { + new_list.push_back(local_cell); + } + } + local_obj.cells_to_add_mod_list = new_list; + if (log_h->get_level() == LOG_LEVEL_DEBUG) { + for (auto& c : local_obj.cells_to_add_mod_list) { + log_h->debug("MEAS: cell idx=%d, pci=%d, q_offset=%d\n", + c.cell_idx, + c.pci, + c.cell_individual_offset.to_number()); + } + } + } + if (cfg_obj.cells_to_add_mod_list_present) { + for (auto& new_cell : cfg_obj.cells_to_add_mod_list) { + // If an entry with the matching cellIndex exists in the local object cellsToAddModList: + auto it = std::find_if(local_obj.cells_to_add_mod_list.begin(), + local_obj.cells_to_add_mod_list.end(), + [&new_cell](const cells_to_add_mod_s& c) { return c.cell_idx == new_cell.cell_idx; }); + if (it != local_obj.cells_to_add_mod_list.end()) { + // If the new cell exists, copy it + *it = new_cell; + } else { + // otherwise add it + local_obj.cells_to_add_mod_list.push_back(new_cell); + } + } + } + } + + // Do the same with black list + { + if (cfg_obj.black_cells_to_add_mod_list_present) { + black_cells_to_add_mod_list_l new_list; + for (auto& local_cell : local_obj.black_cells_to_add_mod_list) { + // If doesn't exists in cells to rem + if (std::find(cfg_obj.black_cells_to_rem_list.begin(), + cfg_obj.black_cells_to_rem_list.end(), + local_cell.cell_idx) == cfg_obj.black_cells_to_rem_list.end()) { + new_list.push_back(local_cell); + } + } + local_obj.black_cells_to_add_mod_list = new_list; + } + if (cfg_obj.black_cells_to_add_mod_list_present) { + for (auto& new_cell : cfg_obj.black_cells_to_add_mod_list) { + // If an entry with the matching cellIndex exists in the local object blackCellsToAddModList: + auto it = + std::find_if(local_obj.black_cells_to_add_mod_list.begin(), + local_obj.black_cells_to_add_mod_list.end(), + [&new_cell](const black_cells_to_add_mod_s& c) { return c.cell_idx == new_cell.cell_idx; }); + if (it != local_obj.black_cells_to_add_mod_list.end()) { + // copy the new entry + *it = new_cell; + } else { + local_obj.black_cells_to_add_mod_list.push_back(new_cell); + } + } + } + } + + // for each measId associated with this measObjectId in the measIdList within the VarMeasConfig + for (auto& m : measIdList) { + if (m.second.meas_obj_id == meas_obj_id) { + remove_varmeas_report(m.first); + } + } + } + + log_h->info("MEAS: %s objectId=%d, carrier_freq=%d, %u cells, %u black-listed cells\n", + !entry_exists ? "Added" : "Modified", + meas_obj_id, + local_obj.carrier_freq, + local_obj.cells_to_add_mod_list.size(), + local_obj.black_cells_to_add_mod_list.size()); + if (log_h->get_level() == LOG_LEVEL_DEBUG) { + for (auto& c : local_obj.cells_to_add_mod_list) { + log_h->debug( + "MEAS: cell idx=%d, pci=%d, q_offset=%d\n", c.cell_idx, c.pci, c.cell_individual_offset.to_number()); + } + for (auto& b : local_obj.black_cells_to_add_mod_list) { + log_h->debug("MEAS: black-listed cell idx=%d\n", b.cell_idx); + } + } +} + +void rrc::rrc_meas::var_meas_cfg::measObject_addmod_nr_r15(uint8_t meas_obj_id, const meas_obj_nr_r15_s& cfg_obj) +{ + bool entry_exists = measObjectsListNrR15.count(meas_obj_id) > 0; + if (!entry_exists) { + // add a new entry for the received measObject to the measObjectList within VarMeasConfig + measObjectsListNrR15.emplace(meas_obj_id, cfg_obj); + } + meas_obj_nr_r15_s& local_obj = measObjectsListNrR15.at(meas_obj_id); + + // if an entry with the matching measObjectId exists in the measObjectList within the VarMeasConfig + if (entry_exists) { + // Update carrier frequency0 + local_obj.carrier_freq_r15 = cfg_obj.carrier_freq_r15; + + // Combine the new cells with the existing ones and remove the cells indicated in config + // Do the same with black list + { + if (cfg_obj.black_cells_to_add_mod_list_r15_present) { + cells_to_add_mod_list_nr_r15_l new_list; + for (auto& local_cell : local_obj.black_cells_to_add_mod_list_r15) { + // If doesn't exists in cells to rem + if (std::find(cfg_obj.black_cells_to_rem_list_r15.begin(), + cfg_obj.black_cells_to_rem_list_r15.end(), + local_cell.cell_idx_r15) == cfg_obj.black_cells_to_rem_list_r15.end()) { + new_list.push_back(local_cell); + } + } + local_obj.black_cells_to_add_mod_list_r15 = new_list; + } + if (cfg_obj.black_cells_to_add_mod_list_r15_present) { + for (auto& new_cell : cfg_obj.black_cells_to_add_mod_list_r15) { + // If an entry with the matching cellIndex exists in the local object blackCellsToAddModList: + auto it = std::find_if( + local_obj.black_cells_to_add_mod_list_r15.begin(), + local_obj.black_cells_to_add_mod_list_r15.end(), + [&new_cell](const cells_to_add_mod_nr_r15_s& c) { return c.cell_idx_r15 == new_cell.cell_idx_r15; }); + if (it != local_obj.black_cells_to_add_mod_list_r15.end()) { + // copy the new entry + *it = new_cell; + } else { + local_obj.black_cells_to_add_mod_list_r15.push_back(new_cell); + } + } + } + } + // for each measId associated with this measObjectId in the measIdList within the VarMeasConfig + for (auto& m : measIdList) { + if (m.second.meas_obj_id == meas_obj_id) { + remove_varmeas_report(m.first); + } + } + } + + log_h->info("MEAS (NR R15): %s objectId=%d, carrier_freq=%d, %u black-listed cells\n", + !entry_exists ? "Added" : "Modified", + meas_obj_id, + local_obj.carrier_freq_r15, + local_obj.black_cells_to_add_mod_list_r15.size()); + if (log_h->get_level() == LOG_LEVEL_DEBUG) { + for (auto& b : local_obj.black_cells_to_add_mod_list_r15) { + log_h->debug("MEAS: black-listed cell idx=%d\n", b.cell_idx_r15); + } + } +} + // Measurement object addition/modification Section 5.5.2.5 void rrc::rrc_meas::var_meas_cfg::measObject_addmod(const meas_obj_to_add_mod_list_l& list) { for (auto& l : list) { - if (l.meas_obj.type().value == meas_obj_to_add_mod_s::meas_obj_c_::types_opts::meas_obj_eutra) { - bool entry_exists = measObjectsList.count(l.meas_obj_id) > 0; - const meas_obj_eutra_s& cfg_obj = l.meas_obj.meas_obj_eutra(); - if (!entry_exists) { - // add a new entry for the received measObject to the measObjectList within VarMeasConfig - measObjectsList.emplace(l.meas_obj_id, cfg_obj); - } - - meas_obj_eutra_s& local_obj = measObjectsList.at(l.meas_obj_id); - - // if an entry with the matching measObjectId exists in the measObjectList within the VarMeasConfig - if (entry_exists) { - // Update carrier frequency0 - local_obj.carrier_freq = cfg_obj.carrier_freq; - local_obj.allowed_meas_bw = cfg_obj.allowed_meas_bw; - - // Combine the new cells with the existing ones and remove the cells indicated in config - { - // Remove cells - if (cfg_obj.cells_to_rem_list_present) { - log_h->debug("MEAS: Removing %d cells\n", cfg_obj.cells_to_rem_list.size()); - cells_to_add_mod_list_l new_list; - for (auto& local_cell : local_obj.cells_to_add_mod_list) { - // If not in the list to remove, copy to new list - if (std::find(cfg_obj.cells_to_rem_list.begin(), cfg_obj.cells_to_rem_list.end(), local_cell.cell_idx) == - cfg_obj.cells_to_rem_list.end()) { - new_list.push_back(local_cell); - } - } - local_obj.cells_to_add_mod_list = new_list; - if (log_h->get_level() == LOG_LEVEL_DEBUG) { - for (auto& c : local_obj.cells_to_add_mod_list) { - log_h->debug("MEAS: cell idx=%d, pci=%d, q_offset=%d\n", - c.cell_idx, - c.pci, - c.cell_individual_offset.to_number()); - } - } - } - if (cfg_obj.cells_to_add_mod_list_present) { - for (auto& new_cell : cfg_obj.cells_to_add_mod_list) { - // If an entry with the matching cellIndex exists in the local object cellsToAddModList: - auto it = - std::find_if(local_obj.cells_to_add_mod_list.begin(), - local_obj.cells_to_add_mod_list.end(), - [&new_cell](const cells_to_add_mod_s& c) { return c.cell_idx == new_cell.cell_idx; }); - if (it != local_obj.cells_to_add_mod_list.end()) { - // If the new cell exists, copy it - *it = new_cell; - } else { - // otherwise add it - local_obj.cells_to_add_mod_list.push_back(new_cell); - } - } - } - } - - // Do the same with black list - { - if (cfg_obj.black_cells_to_add_mod_list_present) { - black_cells_to_add_mod_list_l new_list; - for (auto& local_cell : local_obj.black_cells_to_add_mod_list) { - // If doesn't exists in cells to rem - if (std::find(cfg_obj.black_cells_to_rem_list.begin(), - cfg_obj.black_cells_to_rem_list.end(), - local_cell.cell_idx) == cfg_obj.black_cells_to_rem_list.end()) { - new_list.push_back(local_cell); - } - } - local_obj.black_cells_to_add_mod_list = new_list; - } - if (cfg_obj.black_cells_to_add_mod_list_present) { - for (auto& new_cell : cfg_obj.black_cells_to_add_mod_list) { - // If an entry with the matching cellIndex exists in the local object blackCellsToAddModList: - auto it = std::find_if( - local_obj.black_cells_to_add_mod_list.begin(), - local_obj.black_cells_to_add_mod_list.end(), - [&new_cell](const black_cells_to_add_mod_s& c) { return c.cell_idx == new_cell.cell_idx; }); - if (it != local_obj.black_cells_to_add_mod_list.end()) { - // copy the new entry - *it = new_cell; - } else { - local_obj.black_cells_to_add_mod_list.push_back(new_cell); - } - } - } - } - - // for each measId associated with this measObjectId in the measIdList within the VarMeasConfig - for (auto& m : measIdList) { - if (m.second.meas_obj_id == l.meas_obj_id) { - remove_varmeas_report(m.first); - } - } - } - - log_h->info("MEAS: %s objectId=%d, carrier_freq=%d, %u cells, %u black-listed cells\n", - !entry_exists ? "Added" : "Modified", - l.meas_obj_id, - local_obj.carrier_freq, - local_obj.cells_to_add_mod_list.size(), - local_obj.black_cells_to_add_mod_list.size()); - if (log_h->get_level() == LOG_LEVEL_DEBUG) { - for (auto& c : local_obj.cells_to_add_mod_list) { - log_h->debug("MEAS: cell idx=%d, pci=%d, q_offset=%d\n", - c.cell_idx, - c.pci, - c.cell_individual_offset.to_number()); - } - for (auto& b : local_obj.black_cells_to_add_mod_list) { - log_h->debug("MEAS: black-listed cell idx=%d\n", b.cell_idx); - } - } - - } else { - log_h->error("Unsupported measObject type: %s\n", l.meas_obj.type().to_string().c_str()); + switch (l.meas_obj.type().value) { + case meas_obj_to_add_mod_s::meas_obj_c_::types_opts::meas_obj_eutra: + measObject_addmod_eutra(l.meas_obj_id, l.meas_obj.meas_obj_eutra()); + break; + case meas_obj_to_add_mod_s::meas_obj_c_::types_opts::meas_obj_nr_r15: + measObject_addmod_nr_r15(l.meas_obj_id, l.meas_obj.meas_obj_nr_r15()); + break; + default: + log_h->error("Unsupported measObject type: %s\n", l.meas_obj.type().to_string().c_str()); + break; } } } @@ -936,39 +1007,46 @@ void rrc::rrc_meas::var_meas_cfg::reportConfig_removal(const report_cfg_to_rem_l } } +void rrc::rrc_meas::var_meas_cfg::reportConfig_addmod_eutra(uint8_t report_cfg_id, const report_cfg_eutra_s& report_cfg) +{ + if (!(report_cfg.trigger_type.type().value == report_cfg_eutra_s::trigger_type_c_::types_opts::event)) { + log_h->error("MEAS: Periodical reports not supported. Received in reportConfigId=%d\n", report_cfg_id); + return; + } + bool entry_exists = reportConfigList.count(report_cfg_id) > 0; + if (entry_exists) { + reportConfigList.at(report_cfg_id) = report_cfg; + // for each measId associated with this reportConfigId in the measIdList within the VarMeasConfig + for (auto& m : measIdList) { + if (m.second.report_cfg_id == report_cfg_id) { + remove_varmeas_report(m.first); + } + } + } else { + reportConfigList.emplace(report_cfg_id, report_cfg); + } + log_h->info("MEAS: %s reportConfig id=%d, event-type=%s, time-to-trigger=%d ms, reportInterval=%d\n", + !entry_exists ? "Added" : "Modified", + report_cfg_id, + report_cfg.trigger_type.event().event_id.type().to_string().c_str(), + report_cfg.trigger_type.event().time_to_trigger.to_number(), + report_cfg.report_interv.to_number()); + if (entry_exists) { + log_debug_trigger_value(report_cfg.trigger_type.event().event_id); + } +} // perform the reporting configuration addition/ modification procedure as specified in 5.5.2.7 void rrc::rrc_meas::var_meas_cfg::reportConfig_addmod(const report_cfg_to_add_mod_list_l& list) { for (auto& l : list) { - if (l.report_cfg.type() == report_cfg_to_add_mod_s::report_cfg_c_::types_opts::report_cfg_eutra) { - if (l.report_cfg.report_cfg_eutra().trigger_type.type().value == - report_cfg_eutra_s::trigger_type_c_::types_opts::event) { - bool entry_exists = reportConfigList.count(l.report_cfg_id) > 0; - if (entry_exists) { - reportConfigList.at(l.report_cfg_id) = l.report_cfg.report_cfg_eutra(); - // for each measId associated with this reportConfigId in the measIdList within the VarMeasConfig - for (auto& m : measIdList) { - if (m.second.report_cfg_id == l.report_cfg_id) { - remove_varmeas_report(m.first); - } - } - } else { - reportConfigList.emplace(l.report_cfg_id, l.report_cfg.report_cfg_eutra()); - } - log_h->info("MEAS: %s reportConfig id=%d, event-type=%s, time-to-trigger=%d ms, reportInterval=%d\n", - !entry_exists ? "Added" : "Modified", - l.report_cfg_id, - l.report_cfg.report_cfg_eutra().trigger_type.event().event_id.type().to_string().c_str(), - l.report_cfg.report_cfg_eutra().trigger_type.event().time_to_trigger.to_number(), - l.report_cfg.report_cfg_eutra().report_interv.to_number()); - if (entry_exists) { - log_debug_trigger_value(l.report_cfg.report_cfg_eutra().trigger_type.event().event_id); - } - } else { - log_h->error("MEAS: Periodical reports not supported. Received in reportConfigId=%d\n", l.report_cfg_id); - } - } else { + switch (l.report_cfg.type()) + { + case report_cfg_to_add_mod_s::report_cfg_c_::types_opts::report_cfg_eutra: + reportConfig_addmod_eutra(l.report_cfg_id,l.report_cfg.report_cfg_eutra()); + break; + default: log_h->error("MEAS: Unsupported reportConfig type: %s\n", l.report_cfg.type().to_string().c_str()); + break; } } } diff --git a/srsue/test/upper/rrc_meas_test.cc b/srsue/test/upper/rrc_meas_test.cc index 2ce2f0ea1..c854fa035 100644 --- a/srsue/test/upper/rrc_meas_test.cc +++ b/srsue/test/upper/rrc_meas_test.cc @@ -1116,10 +1116,93 @@ int a3event_report_test(uint32_t a3_offset, uint32_t hyst, bool report_on_leave) return SRSLTE_SUCCESS; } +// Minimal testcase for testing inter rat reporting with nr +int meas_obj_inter_rat_nr_test() +{ + srslte::log_ref log1("RRC_MEAS"), rrc_log("RRC"); + log1->set_level(srslte::LOG_LEVEL_DEBUG); + log1->set_hex_limit(-1); + rrc_log->set_level(srslte::LOG_LEVEL_DEBUG); + rrc_log->set_hex_limit(-1); + + printf("==========================================================\n"); + printf("====== NR Inter Rat Configuration Testing ==========\n"); + printf("==========================================================\n"); + + stack_test_dummy stack; + rrc_test rrctest(log1, &stack); + rrctest.init(); + rrctest.connect(); + + rrc_conn_recfg_r8_ies_s rrc_conn_recfg = {}; + rrc_conn_recfg.meas_cfg_present = true; + meas_cfg_s& meas_cfg = rrc_conn_recfg.meas_cfg; + + meas_obj_to_add_mod_s obj = {}; + + obj.meas_obj_id = 2; + obj.meas_obj.set_meas_obj_nr_r15(); + obj.meas_obj.meas_obj_nr_r15().ext = true; + obj.meas_obj.meas_obj_nr_r15().carrier_freq_r15 = 631680; + obj.meas_obj.meas_obj_nr_r15().rs_cfg_ssb_r15.meas_timing_cfg_r15.periodicity_and_offset_r15.set_sf20_r15(); + obj.meas_obj.meas_obj_nr_r15().rs_cfg_ssb_r15.meas_timing_cfg_r15.ssb_dur_r15 = asn1::rrc::mtc_ssb_nr_r15_s::ssb_dur_r15_opts::options::sf1; + obj.meas_obj.meas_obj_nr_r15().rs_cfg_ssb_r15.subcarrier_spacing_ssb_r15 = asn1::rrc::rs_cfg_ssb_nr_r15_s::subcarrier_spacing_ssb_r15_opts::options::khz30; + obj.meas_obj.meas_obj_nr_r15().quant_cfg_set_r15 = 1; + obj.meas_obj.meas_obj_nr_r15().band_nr_r15.reset(new asn1::rrc::meas_obj_nr_r15_s::band_nr_r15_c_{}); + obj.meas_obj.meas_obj_nr_r15().band_nr_r15->set_setup() = 78; + + meas_cfg.meas_obj_to_add_mod_list.push_back(obj); + + obj = {}; + obj.meas_obj_id = 1; + obj.meas_obj.set_meas_obj_eutra(); + obj.meas_obj.meas_obj_eutra().carrier_freq = 300; + obj.meas_obj.meas_obj_eutra().allowed_meas_bw = asn1::rrc::allowed_meas_bw_opts::options::mbw100; + obj.meas_obj.meas_obj_eutra().presence_ant_port1 = true; + obj.meas_obj.meas_obj_eutra().neigh_cell_cfg.from_number(01); + + meas_cfg.meas_obj_to_add_mod_list.push_back(obj); + meas_cfg.meas_obj_to_add_mod_list_present = true; + + report_cfg_to_add_mod_s rep = {}; + rep.report_cfg_id = 1; + rep.report_cfg.set_report_cfg_inter_rat(); + rep.report_cfg.report_cfg_inter_rat().ext = true; + rep.report_cfg.report_cfg_inter_rat().trigger_type.set_event(); + rep.report_cfg.report_cfg_inter_rat().trigger_type.event().event_id.set_event_b1_nr_r15(); + rep.report_cfg.report_cfg_inter_rat().trigger_type.event().event_id.event_b1_nr_r15().b1_thres_nr_r15.set_nr_rsrp_r15(); + rep.report_cfg.report_cfg_inter_rat().trigger_type.event().event_id.event_b1_nr_r15().report_on_leave_r15 = true; + rep.report_cfg.report_cfg_inter_rat().trigger_type.event().hysteresis = 0; + rep.report_cfg.report_cfg_inter_rat().trigger_type.event().time_to_trigger = asn1::rrc::time_to_trigger_opts::options::ms100; + rep.report_cfg.report_cfg_inter_rat().max_report_cells = 8; + rep.report_cfg.report_cfg_inter_rat().report_interv = asn1::rrc::report_interv_opts::options::ms120; + rep.report_cfg.report_cfg_inter_rat().report_amount = asn1::rrc::report_cfg_inter_rat_s::report_amount_opts::r1; + rep.report_cfg.report_cfg_inter_rat().report_quant_cell_nr_r15.reset(new asn1::rrc::report_quant_nr_r15_s{}); + rep.report_cfg.report_cfg_inter_rat().report_quant_cell_nr_r15->ss_rsrp = true; + rep.report_cfg.report_cfg_inter_rat().report_quant_cell_nr_r15->ss_rsrq = true; + rep.report_cfg.report_cfg_inter_rat().report_quant_cell_nr_r15->ss_sinr = true; + + meas_cfg.report_cfg_to_add_mod_list.push_back(rep); + meas_cfg.report_cfg_to_add_mod_list_present = true; + + meas_cfg.meas_id_to_add_mod_list_present = true; + meas_id_to_add_mod_s meas = {}; + meas.meas_id = 1; + meas.meas_obj_id = 2; + meas.report_cfg_id = 1; + meas_cfg.meas_id_to_add_mod_list.push_back(meas); + + // Just test it doesn't crash + TESTASSERT(rrctest.send_meas_cfg(rrc_conn_recfg)); + TESTASSERT(rrctest.phytest.meas_nof_freqs() == 0); + return SRSLTE_SUCCESS; +} + int main(int argc, char** argv) { TESTASSERT(cell_select_test() == SRSLTE_SUCCESS); TESTASSERT(meas_obj_test() == SRSLTE_SUCCESS); + TESTASSERT(meas_obj_inter_rat_nr_test() == SRSLTE_SUCCESS); TESTASSERT( a1event_report_test( 30, time_to_trigger_opts::ms40, 3, report_cfg_eutra_s::report_amount_opts::r1, report_interv_opts::ms120) ==