Commit 5d05078f authored by Robert Schmidt's avatar Robert Schmidt

Validate neighbour config when DUs connect

parent 3cfc10dd
......@@ -1697,6 +1697,11 @@ static void fill_measurement_configuration(uint8_t gnb_idx, gNB_RRC_INST *rrc)
nr_a3_event_t *a3_event = (nr_a3_event_t *)calloc(1, sizeof(nr_a3_event_t));
AssertFatal(a3_event != NULL, "out of memory\n");
a3_event->pci = *A3_EventList.paramarray[i][MEASUREMENT_EVENTS_PCI_ID_IDX].i64ptr;
AssertFatal(a3_event->pci >= -1 && a3_event->pci < 1024,
"entry %s.%s must be -1<=PCI<1024, but is %d\n",
measurement_path,
MEASUREMENT_EVENTS_PCI_ID,
a3_event->pci);
a3_event->timeToTrigger = *A3_EventList.paramarray[i][MEASUREMENT_EVENTS_TIMETOTRIGGER_IDX].i64ptr;
a3_event->a3_offset = *A3_EventList.paramarray[i][MEASUREMENT_EVENTS_OFFSET_IDX].i64ptr;
a3_event->hysteresis = *A3_EventList.paramarray[i][MEASUREMENT_EVENTS_HYSTERESIS_IDX].i64ptr;
......
......@@ -40,14 +40,19 @@ int get_ssb_scs(const struct f1ap_served_cell_info_t *cell_info)
return cell_info->mode == F1AP_MODE_TDD ? cell_info->tdd.tbw.scs : cell_info->fdd.dl_tbw.scs;
}
int get_ssb_arfcn(const struct nr_rrc_du_container_t *du)
static int ssb_arfcn_mtc(const NR_MeasurementTimingConfiguration_t *mtc)
{
DevAssert(du != NULL && du->mtc != NULL);
/* format has been verified when accepting MeasurementTimingConfiguration */
NR_MeasTimingList_t *mtlist = du->mtc->criticalExtensions.choice.c1->choice.measTimingConf->measTiming;
NR_MeasTimingList_t *mtlist = mtc->criticalExtensions.choice.c1->choice.measTimingConf->measTiming;
return mtlist->list.array[0]->frequencyAndTiming->carrierFreq;
}
int get_ssb_arfcn(const struct nr_rrc_du_container_t *du)
{
DevAssert(du != NULL && du->mtc != NULL);
return ssb_arfcn_mtc(du->mtc);
}
static int du_compare(const nr_rrc_du_container_t *a, const nr_rrc_du_container_t *b)
{
if (a->assoc_id > b->assoc_id)
......@@ -197,6 +202,58 @@ static void label_intra_frequency_neighbours(gNB_RRC_INST *rrc,
for_each(cell_neighbour_list, (void *)&ssb_arfcn, is_intra_frequency_neighbour);
}
static bool valid_du_in_neighbour_configs(const seq_arr_t *neighbour_cell_configuration, const f1ap_served_cell_info_t *cell, int ssb_arfcn)
{
for (int c = 0; c < neighbour_cell_configuration->size; c++) {
const neighbour_cell_configuration_t *neighbour_config = seq_arr_at(neighbour_cell_configuration, c);
for (int ni = 0; ni < neighbour_config->neighbour_cells->size; ni++) {
const nr_neighbour_gnb_configuration_t *nc = seq_arr_at(neighbour_config->neighbour_cells, ni);
if (nc->nrcell_id != cell->nr_cellid)
continue;
// current cell is in the nc config, check that config matches
if (nc->physicalCellId != cell->nr_pci) {
LOG_W(NR_RRC, "Cell %ld in neighbour config: PCI mismatch (%d vs %d)\n", cell->nr_cellid, cell->nr_pci, nc->physicalCellId);
return false;
}
if (cell->tac && nc->tac != *cell->tac) {
LOG_W(NR_RRC, "Cell %ld in neighbour config: TAC mismatch (%d vs %d)\n", cell->nr_cellid, *cell->tac, nc->tac);
return false;
}
if (ssb_arfcn != nc->absoluteFrequencySSB) {
LOG_W(NR_RRC,
"Cell %ld in neighbour config: SSB ARFCN mismatch (%d vs %d)\n",
cell->nr_cellid,
ssb_arfcn,
nc->absoluteFrequencySSB);
return false;
}
if (get_ssb_scs(cell) != nc->subcarrierSpacing) {
LOG_W(NR_RRC,
"Cell %ld in neighbour config: SCS mismatch (%d vs %d)\n",
cell->nr_cellid,
get_ssb_scs(cell),
nc->subcarrierSpacing);
return false;
}
if (cell->plmn.mcc != nc->plmn.mcc || cell->plmn.mnc != nc->plmn.mnc
|| cell->plmn.mnc_digit_length != nc->plmn.mnc_digit_length) {
LOG_W(NR_RRC,
"Cell %ld in neighbour config: PLMN mismatch (%03d.%0*d vs %03d.%0*d)\n",
cell->nr_cellid,
cell->plmn.mcc,
cell->plmn.mnc_digit_length,
cell->plmn.mnc,
nc->plmn.mcc,
nc->plmn.mnc_digit_length,
nc->plmn.mnc);
return false;
}
LOG_D(NR_RRC, "Cell %ld is neighbor of cell %ld\n", cell->nr_cellid, neighbour_config->nr_cell_id);
}
}
return true;
}
void rrc_gNB_process_f1_setup_req(f1ap_setup_req_t *req, sctp_assoc_t assoc_id)
{
AssertFatal(assoc_id != 0, "illegal assoc_id == 0: should be -1 (monolithic) or >0 (split)\n");
......@@ -264,6 +321,15 @@ void rrc_gNB_process_f1_setup_req(f1ap_setup_req_t *req, sctp_assoc_t assoc_id)
NR_MeasurementTimingConfiguration_t *mtc =
extract_mtc(cell_info->measurement_timing_config, cell_info->measurement_timing_config_len);
if (rrc->neighbour_cell_configuration
&& !valid_du_in_neighbour_configs(rrc->neighbour_cell_configuration, cell_info, ssb_arfcn_mtc(mtc))) {
LOG_E(NR_RRC, "problem with DU %ld in neighbor configuration, rejecting DU\n", req->gNB_DU_id);
f1ap_setup_failure_t fail = {.cause = F1AP_CauseMisc_unspecified};
rrc->mac_rrc.f1_setup_failure(assoc_id, &fail);
ASN_STRUCT_FREE(asn_DEF_NR_MeasurementTimingConfiguration, mtc);
return;
}
const f1ap_gnb_du_system_info_t *sys_info = req->cell[0].sys_info;
NR_MIB_t *mib = NULL;
NR_SIB1_t *sib1 = NULL;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment