From ada05ea0c827bd258cca190464b23a9b621850ab Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Wed, 22 Sep 2021 17:13:35 +0200 Subject: [PATCH] Add A1, A2 and A4 measurement Reports event triggers --- srsenb/rr.conf.example | 27 ++++--- srsenb/src/enb_cfg_parser.cc | 107 ++++++++++++++++++++++------ srsenb/src/stack/rrc/ue_meas_cfg.cc | 20 +++++- srsenb/test/rrc/rrc_meascfg_test.cc | 2 +- 4 files changed, 122 insertions(+), 34 deletions(-) diff --git a/srsenb/rr.conf.example b/srsenb/rr.conf.example index cfb984a7f..6e6417080 100644 --- a/srsenb/rr.conf.example +++ b/srsenb/rr.conf.example @@ -87,14 +87,25 @@ cell_list = } ); - // ReportCfg (only A3 supported) - meas_report_desc = { - a3_report_type = "RSRP"; - a3_offset = 6; - a3_hysteresis = 0; - a3_time_to_trigger = 480; - rsrq_config = 4; - }; + // Select measurement triggers (A3 and A4 events are all mapped to all cells in meas_cell_list) + meas_report_desc = + ( + { + eventA = 3 + a3_offset = 6; + hysteresis = 0; + time_to_trigger = 480; + trigger_quant = "RSRP"; + max_report_cells = 1; + report_interv = 120; + report_amount = 1; + } + ); + meas_quant_desc = { + // averaging filter coefficient + rsrq_config = 4; + rsrp_config = 4; + }; } // Add here more cells ); diff --git a/srsenb/src/enb_cfg_parser.cc b/srsenb/src/enb_cfg_parser.cc index 66eee24c4..01a2dfbb7 100644 --- a/srsenb/src/enb_cfg_parser.cc +++ b/srsenb/src/enb_cfg_parser.cc @@ -16,6 +16,7 @@ #include "srsran/common/band_helper.h" #include "srsran/common/multiqueue.h" #include "srsran/phy/common/phy_common.h" +#include "srsran/rrc/rrc_common.h" #include #define HANDLEPARSERCODE(cond) \ @@ -778,30 +779,92 @@ static int parse_meas_cell_list(rrc_meas_cfg_t* meas_cfg, Setting& root) return 0; } -static int parse_meas_report_desc(rrc_meas_cfg_t* meas_cfg, Setting& root) +static int parse_meas_report_desc(rrc_meas_cfg_t* meas_cfg, Setting& cellroot) { - // NOTE: For now, only support one meas_report for all cells. - // TODO: for a1 - // TODO: for a2 - // meas report parsing - meas_cfg->meas_reports.resize(1); - asn1::rrc::report_cfg_eutra_s& meas_item = meas_cfg->meas_reports[0]; - HANDLEPARSERCODE(asn1_parsers::str_to_enum(meas_item.trigger_quant, root["a3_report_type"])); - auto& event = meas_item.trigger_type.set_event(); - event.event_id.set_event_a3().report_on_leave = false; - event.event_id.event_a3().a3_offset = (int)root["a3_offset"]; - event.hysteresis = (int)root["a3_hysteresis"]; - meas_item.max_report_cells = 1; // TODO: parse - meas_item.report_amount.value = report_cfg_eutra_s::report_amount_e_::r1; // TODO: parse - meas_item.report_interv.value = report_interv_e::ms120; // TODO: parse - meas_item.report_quant.value = report_cfg_eutra_s::report_quant_opts::both; // TODO: parse + // NOTE: Events A1, A2, A3 and A4 are supported. A3 and A4 will be configured for all neighbour cells + + Setting& root = cellroot["meas_report_desc"]; + + meas_cfg->meas_reports.resize(root.getLength()); + for (int i = 0; i < root.getLength(); i++) { + asn1::rrc::report_cfg_eutra_s& meas_item = meas_cfg->meas_reports[i]; + + // Parse trigger quantity before event + HANDLEPARSERCODE(asn1_parsers::str_to_enum(meas_item.trigger_quant, root[i]["trigger_quant"])); + + auto& event = meas_item.trigger_type.set_event(); + + // Configure event + switch ((int)root[i]["eventA"]) { + case 1: + if (!root[i].exists("a1_thresh")) { + ERROR("Missing a1_thresh field for A1 event\n"); + return SRSRAN_ERROR; + } + if (meas_item.trigger_quant == report_cfg_eutra_s::trigger_quant_opts::rsrp) { + event.event_id.set_event_a1().a1_thres.set_thres_rsrp() = + rrc_value_to_range(srsran::quant_rsrp, (int)root[i]["a1_thresh"]); + } else { + event.event_id.set_event_a1().a1_thres.set_thres_rsrq() = + rrc_value_to_range(srsran::quant_rsrq, (int)root[i]["a1_thresh"]); + } + break; + case 2: + if (!root[i].exists("a2_thresh")) { + ERROR("Missing a2_thresh field for A2 event\n"); + return SRSRAN_ERROR; + } + if (meas_item.trigger_quant == report_cfg_eutra_s::trigger_quant_opts::rsrp) { + event.event_id.set_event_a2().a2_thres.set_thres_rsrp() = + rrc_value_to_range(srsran::quant_rsrp, (int)root[i]["a2_thresh"]); + } else { + event.event_id.set_event_a2().a2_thres.set_thres_rsrq() = + rrc_value_to_range(srsran::quant_rsrq, (int)root[i]["a2_thresh"]); + } + break; + case 3: + if (!root[i].exists("a3_offset")) { + ERROR("Missing a3_offset field for A3 event\n"); + return SRSRAN_ERROR; + } + event.event_id.set_event_a3().report_on_leave = false; + event.event_id.event_a3().a3_offset = (int)root[i]["a3_offset"]; + break; + case 4: + if (!root[i].exists("a4_thresh")) { + ERROR("Missing a4_thresh field for A4 event\n"); + return SRSRAN_ERROR; + } + if (meas_item.trigger_quant == report_cfg_eutra_s::trigger_quant_opts::rsrp) { + event.event_id.set_event_a4().a4_thres.set_thres_rsrp() = + rrc_value_to_range(srsran::quant_rsrp, (int)root[i]["a4_thresh"]); + } else { + event.event_id.set_event_a4().a4_thres.set_thres_rsrq() = + rrc_value_to_range(srsran::quant_rsrq, (int)root[i]["a4_thresh"]); + } + break; + default: + ERROR("Invalid or unsupported event A%d in meas_report_desc (only A1-A4 are supported)\n", + (int)root[i]["eventA"]); + return SRSRAN_ERROR; + } + + // Configure common variables + event.hysteresis = (int)root[i]["hysteresis"]; + HANDLEPARSERCODE(asn1_parsers::number_to_enum(event.time_to_trigger, root[i]["time_to_trigger"])); + meas_item.report_quant.value = report_cfg_eutra_s::report_quant_opts::both; // TODO: parse + meas_item.max_report_cells = (int)root[i]["max_report_cells"]; + HANDLEPARSERCODE(asn1_parsers::number_to_enum(meas_item.report_interv, root[i]["report_interv"])); + HANDLEPARSERCODE(asn1_parsers::number_to_enum(meas_item.report_amount, root[i]["report_amount"])); + } + // quant coeff parsing auto& quant = meas_cfg->quant_cfg; - HANDLEPARSERCODE(asn1_parsers::number_to_enum(event.time_to_trigger, root["a3_time_to_trigger"])); - HANDLEPARSERCODE( - asn1_parsers::opt_number_to_enum(quant.filt_coef_rsrp, quant.filt_coef_rsrp_present, root, "rsrp_config")); - HANDLEPARSERCODE( - asn1_parsers::opt_number_to_enum(quant.filt_coef_rsrq, quant.filt_coef_rsrq_present, root, "rsrq_config")); + + HANDLEPARSERCODE(asn1_parsers::opt_number_to_enum( + quant.filt_coef_rsrp, quant.filt_coef_rsrp_present, cellroot["meas_quant_desc"], "rsrp_config")); + HANDLEPARSERCODE(asn1_parsers::opt_number_to_enum( + quant.filt_coef_rsrq, quant.filt_coef_rsrq_present, cellroot["meas_quant_desc"], "rsrq_config")); return SRSRAN_SUCCESS; } @@ -864,7 +927,7 @@ static int parse_cell_list(all_args_t* args, rrc_cfg_t* rrc_cfg, Setting& root) ERROR("PARSER ERROR: \"ho_active\" is set to true, but field \"meas_report_desc\" doesn't exist.\n"); return SRSRAN_ERROR; } - HANDLEPARSERCODE(parse_meas_report_desc(&cell_cfg.meas_cfg, cellroot["meas_report_desc"])); + HANDLEPARSERCODE(parse_meas_report_desc(&cell_cfg.meas_cfg, cellroot)); } if (cellroot.exists("scell_list")) { diff --git a/srsenb/src/stack/rrc/ue_meas_cfg.cc b/srsenb/src/stack/rrc/ue_meas_cfg.cc index 106795cf6..ea7c166eb 100644 --- a/srsenb/src/stack/rrc/ue_meas_cfg.cc +++ b/srsenb/src/stack/rrc/ue_meas_cfg.cc @@ -351,11 +351,25 @@ bool fill_meascfg_enb_cfg(meas_cfg_s& meascfg, const ue_cell_ded_list& ue_cell_l meascfg.quant_cfg.quant_cfg_eutra = pcell_meascfg.quant_cfg; // Insert all measIds - // TODO: add this to the parser + // TODO: add this to the parser. Now we map all neighbours to all A3/A4 events and Pcell to A1/A2 if (meascfg.report_cfg_to_add_mod_list.size() > 0) { for (const auto& measobj : meascfg.meas_obj_to_add_mod_list) { - add_measid_cfg( - meascfg.meas_id_to_add_mod_list, measobj.meas_obj_id, meascfg.report_cfg_to_add_mod_list[0].report_cfg_id); + std::array events; + if (measobj.meas_obj.meas_obj_eutra().carrier_freq == pcell->get_dl_earfcn()) { + events[0] = asn1::rrc::eutra_event_s::event_id_c_::types_opts::event_a1; + events[1] = asn1::rrc::eutra_event_s::event_id_c_::types_opts::event_a2; + } else { + events[0] = asn1::rrc::eutra_event_s::event_id_c_::types_opts::event_a3; + events[1] = asn1::rrc::eutra_event_s::event_id_c_::types_opts::event_a4; + } + for (const auto& measrep : meascfg.report_cfg_to_add_mod_list) { + for (const auto& event : events) { + if (measrep.report_cfg.report_cfg_eutra().trigger_type.event().event_id.type().value == event) { + add_measid_cfg(meascfg.meas_id_to_add_mod_list, measobj.meas_obj_id, measrep.report_cfg_id); + break; + } + } + } } } diff --git a/srsenb/test/rrc/rrc_meascfg_test.cc b/srsenb/test/rrc/rrc_meascfg_test.cc index 69f9b0cb5..728e385a0 100644 --- a/srsenb/test/rrc/rrc_meascfg_test.cc +++ b/srsenb/test/rrc/rrc_meascfg_test.cc @@ -258,7 +258,7 @@ int test_correct_meascfg_calculation() cfg.cell_list[0].meas_cfg.meas_reports[0]); TESTASSERT(cell_meas_cfg.meas_id_to_add_mod_list_present); const auto& measid = cell_meas_cfg.meas_id_to_add_mod_list[0]; - TESTASSERT(measid.meas_id == 1 and measid.meas_obj_id == 1 and measid.report_cfg_id == 1); + TESTASSERT(measid.meas_id == 1 and measid.meas_obj_id == 2 and measid.report_cfg_id == 1); meas_cfg_s cell_meas_cfg2; ue_cell_list.set_cells({1});