RRC multi-cell: enforce unique PCI in per-cell neighbour lists
Neighbour lists are built per serving cell in fill_neighbour_cell_configuration. Each neighbour in a list is identified by PCI; having two entries with the same PCI in one cell's list would be ambiguous and indicate a configuration error. This commit adds validation so that duplicate PCIs within a cell's neighbour list are detected at configuration load time and cause a fatal assertion with a clear error message. Changes: - Add eq_neighbour_pci() and get_neighbour_by_pci() using common/utils/alg/find.h to look up a neighbour by PCI in a seq_arr. - In fill_neighbour_cell_configuration(), before appending each cell's neighbour list, iterate over neighbours and assert that no PCI appears more than once
This commit is contained in:
@@ -75,6 +75,7 @@
|
|||||||
#include "s1ap_messages_types.h"
|
#include "s1ap_messages_types.h"
|
||||||
#include "sctp_default_values.h"
|
#include "sctp_default_values.h"
|
||||||
#include "seq_arr.h"
|
#include "seq_arr.h"
|
||||||
|
#include "common/utils/alg/find.h"
|
||||||
#include "uper_encoder.h"
|
#include "uper_encoder.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include "x2ap_messages_types.h"
|
#include "x2ap_messages_types.h"
|
||||||
@@ -1851,6 +1852,22 @@ static seq_arr_t *fill_cu_sibs(paramdef_t *GNBparamarray)
|
|||||||
return SIBs;
|
return SIBs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool eq_neighbour_pci(const void *vval, const void *vit)
|
||||||
|
{
|
||||||
|
const int *pci = (const int *)vval;
|
||||||
|
const nr_neighbour_cell_t *neighbour = (const nr_neighbour_cell_t *)vit;
|
||||||
|
return neighbour->physicalCellId == *pci;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @brief Find neighbour by PCI within a cell's neighbour list (first match) */
|
||||||
|
static nr_neighbour_cell_t *get_neighbour_by_pci(seq_arr_t *neighbour_cells, int pci)
|
||||||
|
{
|
||||||
|
elm_arr_t elm = find_if(neighbour_cells, &pci, eq_neighbour_pci);
|
||||||
|
if (elm.found)
|
||||||
|
return (nr_neighbour_cell_t *)elm.it;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
static void fill_neighbour_cell_configuration(uint8_t gnb_idx, gNB_RRC_INST *rrc)
|
static void fill_neighbour_cell_configuration(uint8_t gnb_idx, gNB_RRC_INST *rrc)
|
||||||
{
|
{
|
||||||
char gnbpath[MAX_OPTNAME_SIZE + 8];
|
char gnbpath[MAX_OPTNAME_SIZE + 8];
|
||||||
@@ -1908,6 +1925,14 @@ static void fill_neighbour_cell_configuration(uint8_t gnb_idx, gNB_RRC_INST *rrc
|
|||||||
n.plmn.mcc = *NeighbourPlmn[GNB_MOBILE_COUNTRY_CODE_IDX].uptr;
|
n.plmn.mcc = *NeighbourPlmn[GNB_MOBILE_COUNTRY_CODE_IDX].uptr;
|
||||||
n.plmn.mnc = *NeighbourPlmn[GNB_MOBILE_NETWORK_CODE_IDX].uptr;
|
n.plmn.mnc = *NeighbourPlmn[GNB_MOBILE_NETWORK_CODE_IDX].uptr;
|
||||||
n.plmn.mnc_digit_length = *NeighbourPlmn[GNB_MNC_DIGIT_LENGTH].uptr;
|
n.plmn.mnc_digit_length = *NeighbourPlmn[GNB_MNC_DIGIT_LENGTH].uptr;
|
||||||
|
if (get_neighbour_by_pci(cell.neighbour_cells, n.physicalCellId) != NULL) {
|
||||||
|
LOG_E(GNB_APP,
|
||||||
|
"Cell %ld: duplicate PCI %d in neighbour list (nrcell_id %ld)\n",
|
||||||
|
cell.nr_cell_id,
|
||||||
|
n.physicalCellId,
|
||||||
|
n.nrcell_id);
|
||||||
|
AssertFatal(false, "PCI must be unique within a cell's neighbour list\n");
|
||||||
|
}
|
||||||
seq_arr_push_back(cell.neighbour_cells, &n, sizeof(n));
|
seq_arr_push_back(cell.neighbour_cells, &n, sizeof(n));
|
||||||
LOG_I(GNB_APP,
|
LOG_I(GNB_APP,
|
||||||
" [%d] neighbor ID %d cellId %ld PCI %d SCS %d SSB ARFCN %u TAC %u PLMN %03u.%0*u\n",
|
" [%d] neighbor ID %d cellId %ld PCI %d SCS %d SSB ARFCN %u TAC %u PLMN %03u.%0*u\n",
|
||||||
|
|||||||
Reference in New Issue
Block a user