From 7e6826ec036cf1efa4a233f8479951048151b685 Mon Sep 17 00:00:00 2001 From: rmagueta Date: Fri, 11 Apr 2025 18:33:29 +0100 Subject: [PATCH] Refactor and minor improvements in get_MeasConfig function --- openair2/RRC/NR/MESSAGES/asn1_msg.c | 79 ++++++++++++++++++++--------- openair2/RRC/NR/MESSAGES/asn1_msg.h | 1 + openair2/RRC/NR/rrc_gNB.c | 27 ++++++---- 3 files changed, 72 insertions(+), 35 deletions(-) diff --git a/openair2/RRC/NR/MESSAGES/asn1_msg.c b/openair2/RRC/NR/MESSAGES/asn1_msg.c index e6816bfcbd..3ff6aecea9 100644 --- a/openair2/RRC/NR/MESSAGES/asn1_msg.c +++ b/openair2/RRC/NR/MESSAGES/asn1_msg.c @@ -995,22 +995,32 @@ static NR_MeasIdToAddMod_t *get_MeasId(NR_MeasId_t measId, NR_ReportConfigId_t r NR_MeasConfig_t *get_MeasConfig(const NR_MeasTiming_t *mt, int band, int scs, + int nr_pci, NR_ReportConfigToAddMod_t *rc_PER, NR_ReportConfigToAddMod_t *rc_A2, seq_arr_t *rc_A3_seq, seq_arr_t *neigh_seq) { + DevAssert(mt != NULL && mt->frequencyAndTiming != NULL); + const struct NR_MeasTiming__frequencyAndTiming *ft = mt->frequencyAndTiming; + NR_MeasConfig_t *mc = calloc_or_fail(1, sizeof(*mc)); mc->measObjectToAddModList = calloc_or_fail(1, sizeof(*mc->measObjectToAddModList)); mc->reportConfigToAddModList = calloc_or_fail(1, sizeof(*mc->reportConfigToAddModList)); mc->measIdToAddModList = calloc_or_fail(1, sizeof(*mc->measIdToAddModList)); + // Report Configuration: A reporting configuration defines the reporting criteria. The reporting criteria are classified as event + // triggered reporting, periodic reporting, CGI reporting or SFTD reporting. + + // Periodic report if (rc_PER) asn1cSeqAdd(&mc->reportConfigToAddModList->list, rc_PER); + // Event A2 if (rc_A2) asn1cSeqAdd(&mc->reportConfigToAddModList->list, rc_A2); + // Event A3 if (rc_A3_seq) { for (int i = 0; i < rc_A3_seq->size; i++) { NR_ReportConfigToAddMod_t *rc_A3 = (NR_ReportConfigToAddMod_t *)seq_arr_at(rc_A3_seq, i); @@ -1018,33 +1028,19 @@ NR_MeasConfig_t *get_MeasConfig(const NR_MeasTiming_t *mt, } } - DevAssert(mt != NULL && mt->frequencyAndTiming != NULL); - const struct NR_MeasTiming__frequencyAndTiming *ft = mt->frequencyAndTiming; - // Measurement Objects: Specifies what is to be measured. For NR and inter-RAT E-UTRA measurements, this may include // cell-specific offsets, blacklisted cells to be ignored and whitelisted cells to consider for measurements. + + // Serving cell NR_MeasObjectToAddMod_t *mo1 = get_MeasObject(ft, band, ft->carrierFreq, 1); - if (neigh_seq) { - NR_MeasObjectNR_t *monr1 = mo1->measObject.choice.measObjectNR; - if (monr1->cellsToAddModList == NULL) - monr1->cellsToAddModList = calloc_or_fail(1, sizeof(*monr1->cellsToAddModList)); - FOR_EACH_SEQ_ARR(nr_neighbour_cell_t *, n, neigh_seq) { - NR_CellsToAddMod_t *cell = calloc_or_fail(1, sizeof(*cell)); - cell->physCellId = n->physicalCellId; - ASN_SEQUENCE_ADD(&monr1->cellsToAddModList->list, cell); - } - } + NR_MeasObjectNR_t *monr1 = mo1->measObject.choice.measObjectNR; + monr1->cellsToAddModList = calloc_or_fail(1, sizeof(*monr1->cellsToAddModList)); + NR_CellsToAddMod_t *cell = calloc_or_fail(1, sizeof(*cell)); + cell->physCellId = nr_pci; + ASN_SEQUENCE_ADD(&monr1->cellsToAddModList->list, cell); asn1cSeqAdd(&mc->measObjectToAddModList->list, mo1); - // Preparation of measId - uint8_t reportIdx = 0; - for (; reportIdx < mc->reportConfigToAddModList->list.count; reportIdx++) { - const NR_ReportConfigId_t reportId = mc->reportConfigToAddModList->list.array[reportIdx]->reportConfigId; - NR_MeasIdToAddMod_t *measid = get_MeasId(reportIdx + 1, reportId, 1); - asn1cSeqAdd(&mc->measIdToAddModList->list, measid); - } - - // Preparation of measId for neighbour cells for periodic report + // Neighbour cells if (neigh_seq) { int mo_id = 2; FOR_EACH_SEQ_ARR(nr_neighbour_cell_t *, neigh_cell, neigh_seq) { @@ -1055,13 +1051,46 @@ NR_MeasConfig_t *get_MeasConfig(const NR_MeasTiming_t *mt, cell->physCellId = neigh_cell->physicalCellId; ASN_SEQUENCE_ADD(&monr->cellsToAddModList->list, cell); asn1cSeqAdd(&mc->measObjectToAddModList->list, mo_neighbour); - NR_MeasIdToAddMod_t *measid = get_MeasId(reportIdx + 1, rc_PER->reportConfigId, mo_id); - asn1cSeqAdd(&mc->measIdToAddModList->list, measid); - reportIdx++; mo_id++; } } + // Measurement identities: A list of measurement identities where each measurement identity links one measurement object with one + // reporting configuration. By configuring multiple measurement identities, it is possible to link more than one measurement + // object to the same reporting configuration, as well as to link more than one reporting configuration to the same measurement + // object. + + // MeasId for Periodic report + int meas_idx = 0; + if (rc_PER) { + for (; meas_idx < mc->measObjectToAddModList->list.count; meas_idx++) { + const NR_MeasObjectId_t measObjectId = mc->measObjectToAddModList->list.array[meas_idx]->measObjectId; + NR_MeasIdToAddMod_t *measid = get_MeasId(meas_idx + 1, rc_PER->reportConfigId, measObjectId); + asn1cSeqAdd(&mc->measIdToAddModList->list, measid); + } + } + + // MeasId for Event A2 + if (rc_A2) { + NR_MeasIdToAddMod_t *measid_A2 = get_MeasId(meas_idx + 1, rc_A2->reportConfigId, 1); + meas_idx++; + asn1cSeqAdd(&mc->measIdToAddModList->list, measid_A2); + } + + // MeasId for Event A3 + if (neigh_seq) { + int i = 0; + FOR_EACH_SEQ_ARR(nr_neighbour_cell_t *, neigh_cell, neigh_seq) { + NR_ReportConfigId_t reportConfigId = neigh_cell->physicalCellId == -1 ? 3 : i + 4; + NR_MeasIdToAddMod_t *measid_A3 = get_MeasId(meas_idx + 1, reportConfigId, i + 2); + meas_idx++; + asn1cSeqAdd(&mc->measIdToAddModList->list, measid_A3); + i++; + } + } + + // Quantity configurations: The quantity configuration defines the measurement filtering configuration used for measurement event + // evaluation and related reporting, and for periodical reporting of that measurement. mc->quantityConfig = calloc_or_fail(1, sizeof(*mc->quantityConfig)); mc->quantityConfig->quantityConfigNR_List = calloc_or_fail(1, sizeof(*mc->quantityConfig->quantityConfigNR_List)); NR_QuantityConfigNR_t *qcnr = calloc_or_fail(1, sizeof(*qcnr)); diff --git a/openair2/RRC/NR/MESSAGES/asn1_msg.h b/openair2/RRC/NR/MESSAGES/asn1_msg.h index 432db0e5cd..dde62d142f 100644 --- a/openair2/RRC/NR/MESSAGES/asn1_msg.h +++ b/openair2/RRC/NR/MESSAGES/asn1_msg.h @@ -153,6 +153,7 @@ int do_RRCReestablishmentComplete(uint8_t *buffer, size_t buffer_size, int64_t r NR_MeasConfig_t *get_MeasConfig(const NR_MeasTiming_t *mt, int band, int scs, + int nr_pci, NR_ReportConfigToAddMod_t *rc_PER, NR_ReportConfigToAddMod_t *rc_A2, seq_arr_t *rc_A3_seq, diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index 000c4f46cb..0e5912aafe 100644 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -544,12 +544,12 @@ static NR_ReportConfigToAddMod_t *prepare_a2_event_report(const nr_a2_event_t *a return rc_A2; } -static NR_ReportConfigToAddMod_t *prepare_a3_event_report(const nr_a3_event_t *a3_event) +static NR_ReportConfigToAddMod_t *prepare_a3_event_report(const nr_a3_event_t *a3_event, NR_ReportConfigId_t reportConfigId) { NR_ReportConfigToAddMod_t *rc_A3 = calloc(1, sizeof(*rc_A3)); // 3 is default A3 Report Config ID. So cellId(0) specific Report Config ID // starts from 4 - rc_A3->reportConfigId = a3_event->pci == -1 ? 3 : a3_event->pci + 4; + rc_A3->reportConfigId = reportConfigId; rc_A3->reportConfig.present = NR_ReportConfigToAddMod__reportConfig_PR_reportConfigNR; NR_EventTriggerConfig_t *etrc_A3 = calloc(1, sizeof(*etrc_A3)); etrc_A3->eventId.present = NR_EventTriggerConfig__eventId_PR_eventA3; @@ -593,6 +593,7 @@ NR_MeasConfig_t *nr_rrc_get_measconfig(const gNB_RRC_INST *rrc, uint64_t nr_cell NR_ReportConfigToAddMod_t *rc_PER = NULL; NR_ReportConfigToAddMod_t *rc_A2 = NULL; seq_arr_t *rc_A3_seq = NULL; + seq_arr_t *neigh_seq = NULL; if (du->mtc != NULL) { int scs = get_ssb_scs(cell_info); int band = get_dl_band(cell_info); @@ -609,24 +610,30 @@ NR_MeasConfig_t *nr_rrc_get_measconfig(const gNB_RRC_INST *rrc, uint64_t nr_cell If default one added once as a report, no need to add it again && duplication. */ rc_A3_seq = malloc(sizeof(seq_arr_t)); + neigh_seq = malloc(sizeof(seq_arr_t)); seq_arr_init(rc_A3_seq, sizeof(NR_ReportConfigToAddMod_t)); - LOG_D(NR_RRC, "HO LOG: Preparing A3 Event Measurement Configuration!\n"); - bool is_default_a3_added = false; + seq_arr_init(neigh_seq, sizeof(nr_neighbour_cell_t)); + LOG_D(NR_RRC, "Preparing A3 Event Measurement Configuration!\n"); + bool default_a3_added = false; // To ensure that the default configuration is only added once for (int i = 0; i < neighbour_cells->size; i++) { nr_neighbour_cell_t *neighbourCell = (nr_neighbour_cell_t *)seq_arr_at(neighbour_cells, i); - const nr_a3_event_t *a3Event = get_a3_configuration((gNB_RRC_INST *)rrc, neighbourCell->physicalCellId); - if (!a3Event || is_default_a3_added) + if (default_a3_added && neighbourCell->physicalCellId == -1) continue; - if (a3Event->pci == -1) - is_default_a3_added = true; - seq_arr_push_back(rc_A3_seq, prepare_a3_event_report(a3Event), sizeof(NR_ReportConfigToAddMod_t)); + seq_arr_push_back(neigh_seq, neighbourCell, sizeof(nr_neighbour_cell_t)); + const nr_a3_event_t *a3Event = get_a3_configuration((gNB_RRC_INST *)rrc, neighbourCell->physicalCellId); + if (a3Event) { + NR_ReportConfigId_t reportConfigId = neighbourCell->physicalCellId == -1 ? 3 : i + 4; + seq_arr_push_back(rc_A3_seq, prepare_a3_event_report(a3Event, reportConfigId), sizeof(NR_ReportConfigToAddMod_t)); + if (neighbourCell->physicalCellId == -1) + default_a3_added = true; + } } } if (rrc->measurementConfiguration.per_event) rc_PER = prepare_periodic_event_report(rrc->measurementConfiguration.per_event); if (rrc->measurementConfiguration.a2_event) rc_A2 = prepare_a2_event_report(rrc->measurementConfiguration.a2_event); - return get_MeasConfig(mt, band, scs, rc_PER, rc_A2, rc_A3_seq, neighbour_cells); + return get_MeasConfig(mt, band, scs, cell_info->nr_pci, rc_PER, rc_A2, rc_A3_seq, neigh_seq); } return NULL; }