Merge remote-tracking branch 'origin/fix-a3-event' into integration_2026_w04 (!3789)
fix A3 event configuration See commit message for more information. As a reference, for comparison purpose, PCAPs and TXT files for various tests done in develop and in this MR are available in the MR description.
This commit is contained in:
@@ -1121,7 +1121,8 @@ NR_MeasConfig_t *get_MeasConfig(const NR_MeasTiming_t *mt,
|
|||||||
NR_ReportConfigToAddMod_t *rc_PER,
|
NR_ReportConfigToAddMod_t *rc_PER,
|
||||||
NR_ReportConfigToAddMod_t *rc_A2,
|
NR_ReportConfigToAddMod_t *rc_A2,
|
||||||
seq_arr_t *rc_A3_seq,
|
seq_arr_t *rc_A3_seq,
|
||||||
seq_arr_t *neigh_seq)
|
seq_arr_t *neigh_seq,
|
||||||
|
int *neigh_a3_id)
|
||||||
{
|
{
|
||||||
DevAssert(mt != NULL && mt->frequencyAndTiming != NULL);
|
DevAssert(mt != NULL && mt->frequencyAndTiming != NULL);
|
||||||
const struct NR_MeasTiming__frequencyAndTiming *ft = mt->frequencyAndTiming;
|
const struct NR_MeasTiming__frequencyAndTiming *ft = mt->frequencyAndTiming;
|
||||||
@@ -1207,7 +1208,10 @@ NR_MeasConfig_t *get_MeasConfig(const NR_MeasTiming_t *mt,
|
|||||||
if (neigh_seq) {
|
if (neigh_seq) {
|
||||||
int i = 0;
|
int i = 0;
|
||||||
FOR_EACH_SEQ_ARR(nr_neighbour_cell_t *, neigh_cell, neigh_seq) {
|
FOR_EACH_SEQ_ARR(nr_neighbour_cell_t *, neigh_cell, neigh_seq) {
|
||||||
NR_ReportConfigId_t reportConfigId = neigh_cell->physicalCellId == -1 ? 3 : i + 4;
|
NR_ReportConfigId_t reportConfigId = neigh_a3_id[i];
|
||||||
|
/* check that there is a A3 configured for this neighbour */
|
||||||
|
if (reportConfigId == -1)
|
||||||
|
continue;
|
||||||
NR_MeasIdToAddMod_t *measid_A3 = get_MeasId(meas_idx + 1, reportConfigId, i + 2);
|
NR_MeasIdToAddMod_t *measid_A3 = get_MeasId(meas_idx + 1, reportConfigId, i + 2);
|
||||||
meas_idx++;
|
meas_idx++;
|
||||||
asn1cSeqAdd(&mc->measIdToAddModList->list, measid_A3);
|
asn1cSeqAdd(&mc->measIdToAddModList->list, measid_A3);
|
||||||
|
|||||||
@@ -164,7 +164,8 @@ NR_MeasConfig_t *get_MeasConfig(const NR_MeasTiming_t *mt,
|
|||||||
NR_ReportConfigToAddMod_t *rc_PER,
|
NR_ReportConfigToAddMod_t *rc_PER,
|
||||||
NR_ReportConfigToAddMod_t *rc_A2,
|
NR_ReportConfigToAddMod_t *rc_A2,
|
||||||
seq_arr_t *rc_A3_seq,
|
seq_arr_t *rc_A3_seq,
|
||||||
seq_arr_t *neigh_seq);
|
seq_arr_t *neigh_seq,
|
||||||
|
int *neigh_a3_id);
|
||||||
void free_MeasConfig(NR_MeasConfig_t *mc);
|
void free_MeasConfig(NR_MeasConfig_t *mc);
|
||||||
int do_NR_Paging(uint8_t Mod_id, uint8_t *buffer, uint32_t tmsi);
|
int do_NR_Paging(uint8_t Mod_id, uint8_t *buffer, uint32_t tmsi);
|
||||||
|
|
||||||
|
|||||||
+32
-11
@@ -622,9 +622,6 @@ static nr_a3_event_t *get_a3_configuration(gNB_RRC_INST *rrc, int pci)
|
|||||||
return a3_event;
|
return a3_event;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (measurementConfiguration->is_default_a3_configuration_exists)
|
|
||||||
return get_a3_configuration(rrc, -1);
|
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -750,6 +747,10 @@ NR_MeasConfig_t *nr_rrc_get_measconfig(const gNB_RRC_INST *rrc, uint64_t nr_cell
|
|||||||
if (neighbour_config)
|
if (neighbour_config)
|
||||||
neighbour_cells = neighbour_config->neighbour_cells;
|
neighbour_cells = neighbour_config->neighbour_cells;
|
||||||
|
|
||||||
|
int *neigh_a3_id = NULL;
|
||||||
|
if (neighbour_cells && neighbour_cells->size)
|
||||||
|
neigh_a3_id = calloc_or_fail(neighbour_cells->size, sizeof(int));
|
||||||
|
|
||||||
if (neighbour_cells && rrc->measurementConfiguration.a3_event_list && rrc->measurementConfiguration.a3_event_list->size > 0) {
|
if (neighbour_cells && rrc->measurementConfiguration.a3_event_list && rrc->measurementConfiguration.a3_event_list->size > 0) {
|
||||||
/* Loop through neighbours and find related A3 configuration
|
/* Loop through neighbours and find related A3 configuration
|
||||||
If no related A3 but there is default add the default one.
|
If no related A3 but there is default add the default one.
|
||||||
@@ -759,16 +760,31 @@ NR_MeasConfig_t *nr_rrc_get_measconfig(const gNB_RRC_INST *rrc, uint64_t nr_cell
|
|||||||
bool default_a3_added = false; // To ensure that the default configuration is only added once
|
bool default_a3_added = false; // To ensure that the default configuration is only added once
|
||||||
for (int i = 0; i < neighbour_cells->size; i++) {
|
for (int i = 0; i < neighbour_cells->size; i++) {
|
||||||
nr_neighbour_cell_t *neighbourCell = (nr_neighbour_cell_t *)seq_arr_at(neighbour_cells, i);
|
nr_neighbour_cell_t *neighbourCell = (nr_neighbour_cell_t *)seq_arr_at(neighbour_cells, i);
|
||||||
if (default_a3_added && neighbourCell->physicalCellId == -1)
|
|
||||||
continue;
|
|
||||||
seq_arr_push_back(&neigh_seq, neighbourCell, sizeof(nr_neighbour_cell_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);
|
const nr_a3_event_t *a3Event = get_a3_configuration((gNB_RRC_INST *)rrc, neighbourCell->physicalCellId);
|
||||||
if (a3Event) {
|
if (!a3Event) {
|
||||||
NR_ReportConfigId_t reportConfigId = neighbourCell->physicalCellId == -1 ? 3 : i + 4;
|
/* no A3 event configured for this neighbour, let's try the default one, if it exists */
|
||||||
seq_arr_push_back(&rc_A3_seq, prepare_a3_event_report(a3Event, reportConfigId), sizeof(NR_ReportConfigToAddMod_t));
|
if (default_a3_added) {
|
||||||
if (neighbourCell->physicalCellId == -1)
|
/* default A3 exists and is already added, use it for this neighbour */
|
||||||
default_a3_added = true;
|
neigh_a3_id[i] = 3;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
/* try to get the default A3 config */
|
||||||
|
a3Event = get_a3_configuration((gNB_RRC_INST *)rrc, -1);
|
||||||
|
if (!a3Event) {
|
||||||
|
/* no default A3 config found, so no A3 config for this neighbour */
|
||||||
|
neigh_a3_id[i] = -1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
default_a3_added = true;
|
||||||
|
/* default A3 report config ID is 3 */
|
||||||
|
neigh_a3_id[i] = 3;
|
||||||
|
} else {
|
||||||
|
/* specific A3 report config ID are 4, 5, ... */
|
||||||
|
neigh_a3_id[i] = i + 4;
|
||||||
}
|
}
|
||||||
|
NR_ReportConfigId_t reportConfigId = neigh_a3_id[i];
|
||||||
|
seq_arr_push_back(&rc_A3_seq, prepare_a3_event_report(a3Event, reportConfigId), sizeof(NR_ReportConfigToAddMod_t));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (rrc->measurementConfiguration.per_event)
|
if (rrc->measurementConfiguration.per_event)
|
||||||
@@ -776,12 +792,14 @@ NR_MeasConfig_t *nr_rrc_get_measconfig(const gNB_RRC_INST *rrc, uint64_t nr_cell
|
|||||||
if (rrc->measurementConfiguration.a2_event)
|
if (rrc->measurementConfiguration.a2_event)
|
||||||
rc_A2 = prepare_a2_event_report(rrc->measurementConfiguration.a2_event);
|
rc_A2 = prepare_a2_event_report(rrc->measurementConfiguration.a2_event);
|
||||||
|
|
||||||
NR_MeasConfig_t *result = get_MeasConfig(mt, band, scs, cell_info->nr_pci, rc_PER, rc_A2, &rc_A3_seq, &neigh_seq);
|
NR_MeasConfig_t *result = get_MeasConfig(mt, band, scs, cell_info->nr_pci, rc_PER, rc_A2, &rc_A3_seq, &neigh_seq, neigh_a3_id);
|
||||||
|
|
||||||
// Clean up sequence arrays
|
// Clean up sequence arrays
|
||||||
seq_arr_free(&rc_A3_seq, NULL);
|
seq_arr_free(&rc_A3_seq, NULL);
|
||||||
seq_arr_free(&neigh_seq, NULL);
|
seq_arr_free(&neigh_seq, NULL);
|
||||||
|
|
||||||
|
free(neigh_a3_id);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -1620,6 +1638,9 @@ static void process_Event_Based_Measurement_Report(gNB_RRC_INST *rrc,
|
|||||||
if (!neigh_cell && neighbour) {
|
if (!neigh_cell && neighbour) {
|
||||||
// No F1 connection but static neighbour configuration is available
|
// No F1 connection but static neighbour configuration is available
|
||||||
const nr_a3_event_t *a3_event_configuration = get_a3_configuration(rrc, neighbour->physicalCellId);
|
const nr_a3_event_t *a3_event_configuration = get_a3_configuration(rrc, neighbour->physicalCellId);
|
||||||
|
/* if no A3 event configured for this physical cell ID, try to get the default one */
|
||||||
|
if (!a3_event_configuration)
|
||||||
|
a3_event_configuration = get_a3_configuration(rrc, -1);
|
||||||
// Additional check - This part can be modified according to additional cell specific Handover Margin
|
// Additional check - This part can be modified according to additional cell specific Handover Margin
|
||||||
// a3-Offset: The actual value is field value * 0.5 dB.
|
// a3-Offset: The actual value is field value * 0.5 dB.
|
||||||
if (a3_event_configuration
|
if (a3_event_configuration
|
||||||
|
|||||||
Reference in New Issue
Block a user