diff --git a/openair2/GNB_APP/gnb_config.c b/openair2/GNB_APP/gnb_config.c index a73a77b0ee..10ab9a73d0 100644 --- a/openair2/GNB_APP/gnb_config.c +++ b/openair2/GNB_APP/gnb_config.c @@ -2012,94 +2012,81 @@ static nr_neighbour_cell_t *get_neighbour_by_pci(seq_arr_t *neighbour_cells, int return NULL; } -static void fill_neighbour_cell_configuration(uint8_t gnb_idx, gNB_RRC_INST *rrc) +static void parse_neighbour_cells_list(neighbour_cell_configuration_t *cell, const paramlist_def_t *list, const char *n_path) { - char gnbpath[MAX_OPTNAME_SIZE + 8]; - snprintf(gnbpath, sizeof(gnbpath), "%s.[%i]", GNB_CONFIG_STRING_GNB_LIST, gnb_idx); + cell->neighbour_cells = malloc_or_fail(sizeof(seq_arr_t)); + seq_arr_init(cell->neighbour_cells, sizeof(nr_neighbour_cell_t)); - GET_PARAMS_LIST(neighbour_list_param_list, - neighbour_list_params, - GNB_NEIGHBOUR_LIST_PARAM_LIST, - GNB_CONFIG_STRING_NEIGHBOUR_LIST, - gnbpath); + for (int l = 0; l < list->numelt; ++l) { + const paramdef_t *cell_params = list->paramarray[l]; + nr_neighbour_cell_t n = {.gNB_ID = *cell_params[GNB_CONFIG_N_CELL_GNB_ID_IDX].uptr, + .nrcell_id = (uint64_t)*cell_params[GNB_CONFIG_N_CELL_NR_CELLID_IDX].u64ptr, + .physicalCellId = *cell_params[GNB_CONFIG_N_CELL_PHYSICAL_ID_IDX].uptr, + .subcarrierSpacing = *cell_params[GNB_CONFIG_N_CELL_SCS_IDX].uptr, + .band = *cell_params[GNB_CONFIG_N_CELL_BAND_IDX].uptr, + .absoluteFrequencySSB = *cell_params[GNB_CONFIG_N_CELL_ABS_FREQ_SSB_IDX].i64ptr, + .tac = *cell_params[GNB_CONFIG_N_CELL_TAC_IDX].uptr}; - if (neighbour_list_param_list.numelt < 1) - return; + char p[CONFIG_MAXOPTLENGTH]; // plmn path + snprintf(p, sizeof(p), "%s.%s.[%i].%s", n_path, GNB_CONFIG_STRING_NEIGHBOUR_CELL_LIST, l, GNB_CONFIG_STRING_NEIGHBOUR_PLMN); + GET_PARAMS(NeighbourPlmn, GNBPLMNPARAMS_DESC, p); + n.plmn = extract_plmn_from_params(NeighbourPlmn, sizeofArray(NeighbourPlmn)); - rrc->neighbour_cell_configuration = malloc(sizeof(seq_arr_t)); - seq_arr_init(rrc->neighbour_cell_configuration, sizeof(neighbour_cell_configuration_t)); + LOG_I(GNB_APP, + "Neighbour[%d]: cellId %ld, PLMN %03u.%0*u, gNB %d, PCI %d, SCS %d, SSB ARFCN %u, TAC %u\n", + l, + n.nrcell_id, + n.plmn.mcc, + n.plmn.mnc_digit_length, + n.plmn.mnc, + n.gNB_ID, + n.physicalCellId, + n.subcarrierSpacing, + n.absoluteFrequencySSB, + n.tac); - for (int elm = 0; elm < neighbour_list_param_list.numelt; ++elm) { - neighbour_cell_configuration_t cell = {0}; - cell.nr_cell_id = (uint64_t)*neighbour_list_param_list.paramarray[elm][0].u64ptr; - - char neighbourpath[MAX_OPTNAME_SIZE + 8]; - snprintf(neighbourpath, sizeof(neighbourpath), "%s.[%i].%s.[%i]", GNB_CONFIG_STRING_GNB_LIST, gnb_idx, GNB_CONFIG_STRING_NEIGHBOUR_LIST, elm); - GET_PARAMS_LIST(NeighbourCellParamList, - NeighbourCellParams, - GNBNEIGHBOURCELLPARAMS_DESC, - GNB_CONFIG_STRING_NEIGHBOUR_CELL_LIST, - neighbourpath); - LOG_I(GNB_APP, "Cell %ld has %d neighbours\n", cell.nr_cell_id, NeighbourCellParamList.numelt); - if (NeighbourCellParamList.numelt < 1) - continue; - - cell.neighbour_cells = malloc_or_fail(sizeof(seq_arr_t)); - seq_arr_init(cell.neighbour_cells, sizeof(nr_neighbour_cell_t)); - for (int l = 0; l < NeighbourCellParamList.numelt; ++l) { - nr_neighbour_cell_t n = {0}; - n.gNB_ID = *(NeighbourCellParamList.paramarray[l][GNB_CONFIG_N_CELL_GNB_ID_IDX].uptr); - n.nrcell_id = (uint64_t) * (NeighbourCellParamList.paramarray[l][GNB_CONFIG_N_CELL_NR_CELLID_IDX].u64ptr); - n.physicalCellId = *NeighbourCellParamList.paramarray[l][GNB_CONFIG_N_CELL_PHYSICAL_ID_IDX].uptr; - n.subcarrierSpacing = *NeighbourCellParamList.paramarray[l][GNB_CONFIG_N_CELL_SCS_IDX].uptr; - n.band = *NeighbourCellParamList.paramarray[l][GNB_CONFIG_N_CELL_BAND_IDX].uptr; - n.absoluteFrequencySSB = *NeighbourCellParamList.paramarray[l][GNB_CONFIG_N_CELL_ABS_FREQ_SSB_IDX].i64ptr; - n.tac = *NeighbourCellParamList.paramarray[l][GNB_CONFIG_N_CELL_TAC_IDX].uptr; - - char neighbour_plmn_path[CONFIG_MAXOPTLENGTH]; - snprintf(neighbour_plmn_path, - sizeof(neighbour_plmn_path), - "%s.%s.[%i].%s", - neighbourpath, - GNB_CONFIG_STRING_NEIGHBOUR_CELL_LIST, - l, - GNB_CONFIG_STRING_NEIGHBOUR_PLMN); - GET_PARAMS(NeighbourPlmn, GNBPLMNPARAMS_DESC, neighbour_plmn_path); - - n.plmn.mcc = *NeighbourPlmn[GNB_MOBILE_COUNTRY_CODE_IDX].uptr; - n.plmn.mnc = *NeighbourPlmn[GNB_MOBILE_NETWORK_CODE_IDX].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)); - LOG_I(GNB_APP, - " [%d] neighbor ID %d cellId %ld PCI %d SCS %d SSB ARFCN %u TAC %u PLMN %03u.%0*u\n", - l, - n.gNB_ID, - n.nrcell_id, - n.physicalCellId, - n.subcarrierSpacing, - n.absoluteFrequencySSB, - n.tac, - n.plmn.mcc, - n.plmn.mnc_digit_length, - n.plmn.mnc); + if (get_neighbour_by_pci(cell->neighbour_cells, n.physicalCellId) != NULL) { + LOG_E(GNB_APP, "Cell %ld: duplicate PCI %d in neighbour list (NCI=%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(rrc->neighbour_cell_configuration, &cell, sizeof(cell)); + + seq_arr_push_back(cell->neighbour_cells, &n, sizeof(n)); } +} + +static void sort_neighbour_configuration(gNB_RRC_INST *rrc) +{ void *base = seq_arr_front(rrc->neighbour_cell_configuration); size_t nmemb = seq_arr_size(rrc->neighbour_cell_configuration); size_t element_size = sizeof(neighbour_cell_configuration_t); - qsort(base, nmemb, element_size, sort_neighbour_cell_config_by_cell_id); } +static void fill_neighbour_cell_configuration(const uint8_t gnb_idx, gNB_RRC_INST *rrc) +{ + char path[MAX_OPTNAME_SIZE + 8]; + snprintf(path, sizeof(path), "%s.[%i]", GNB_CONFIG_STRING_GNB_LIST, gnb_idx); + GET_PARAMS_LIST(nlist, nparams, GNB_NEIGHBOUR_LIST_PARAM_LIST, GNB_CONFIG_STRING_NEIGHBOUR_LIST, path); + + if (nlist.numelt < 1) + return; + + rrc->neighbour_cell_configuration = malloc_or_fail(sizeof(seq_arr_t)); + seq_arr_init(rrc->neighbour_cell_configuration, sizeof(neighbour_cell_configuration_t)); + + for (int elm = 0; elm < nlist.numelt; ++elm) { + neighbour_cell_configuration_t cell = {.nr_cell_id = *nlist.paramarray[elm][0].u64ptr}; + snprintf(path, sizeof(path), "%s.[%i].%s.[%i]", GNB_CONFIG_STRING_GNB_LIST, gnb_idx, GNB_CONFIG_STRING_NEIGHBOUR_LIST, elm); + GET_PARAMS_LIST(ncell_list, ncell_params, GNBNEIGHBOURCELLPARAMS_DESC, GNB_CONFIG_STRING_NEIGHBOUR_CELL_LIST, path); + if (ncell_list.numelt < 1) + continue; + parse_neighbour_cells_list(&cell, &ncell_list, path); + seq_arr_push_back(rrc->neighbour_cell_configuration, &cell, sizeof(cell)); + } + + sort_neighbour_configuration(rrc); +} + static void fill_measurement_configuration(uint8_t gnb_idx, gNB_RRC_INST *rrc) { char measurement_path[MAX_OPTNAME_SIZE + 8]; diff --git a/openair2/GNB_APP/gnb_config_common.c b/openair2/GNB_APP/gnb_config_common.c index 395af98750..5aed92f810 100644 --- a/openair2/GNB_APP/gnb_config_common.c +++ b/openair2/GNB_APP/gnb_config_common.c @@ -31,19 +31,25 @@ uint16_t set_snssai_config(nssai_t *nssai, const int max_num_ssi, uint8_t k, uin return num_ssi; } +plmn_id_t extract_plmn_from_params(const paramdef_t *params, int n_params) +{ + plmn_id_t plmn = {.mcc = *gpd(params, n_params, GNB_CONFIG_STRING_MOBILE_COUNTRY_CODE)->uptr, + .mnc = *gpd(params, n_params, GNB_CONFIG_STRING_MOBILE_NETWORK_CODE)->uptr, + .mnc_digit_length = *gpd(params, n_params, GNB_CONFIG_STRING_MNC_DIGIT_LENGTH)->uptr}; + AssertFatal((plmn.mnc_digit_length == 2) || (plmn.mnc_digit_length == 3), "BAD MNC DIGIT LENGTH %d", plmn.mnc_digit_length); + return plmn; +} + uint8_t set_plmn_config(plmn_id_t *p, uint8_t idx) { char gnbpath[MAX_OPTNAME_SIZE * 2 + 8]; snprintf(gnbpath, sizeof(gnbpath), "%s.[%i]", GNB_CONFIG_STRING_GNB_LIST, idx); GET_PARAMS_LIST(PLMNParamList, PLMNParams, GNBPLMNPARAMS_DESC, GNB_CONFIG_STRING_PLMN_LIST, gnbpath, PLMNPARAMS_CHECK); uint8_t num_plmn = PLMNParamList.numelt; + const int n_plmn_params = sizeofArray(PLMNParams); AssertFatal(num_plmn >= 1 && num_plmn <= 6, "The number of PLMN IDs must be in [1,6], but is %d\n", num_plmn); for (int l = 0; l < num_plmn; ++l) { - plmn_id_t *plmn = &p[l]; - plmn->mcc = *PLMNParamList.paramarray[l][GNB_MOBILE_COUNTRY_CODE_IDX].uptr; - plmn->mnc = *PLMNParamList.paramarray[l][GNB_MOBILE_NETWORK_CODE_IDX].uptr; - plmn->mnc_digit_length = *PLMNParamList.paramarray[l][GNB_MNC_DIGIT_LENGTH].u8ptr; - AssertFatal((plmn->mnc_digit_length == 2) || (plmn->mnc_digit_length == 3), "BAD MNC DIGIT LENGTH %d", plmn->mnc_digit_length); + p[l] = extract_plmn_from_params(PLMNParamList.paramarray[l], n_plmn_params); } return num_plmn; } diff --git a/openair2/GNB_APP/gnb_config_common.h b/openair2/GNB_APP/gnb_config_common.h index ae2ae4e799..bfa875c13d 100644 --- a/openair2/GNB_APP/gnb_config_common.h +++ b/openair2/GNB_APP/gnb_config_common.h @@ -4,6 +4,8 @@ #include #include "common/5g_platform_types.h" +#include "common/config/config_paramdesc.h" uint16_t set_snssai_config(nssai_t *nssai, const int max_num_ssi, uint8_t k, uint8_t l); uint8_t set_plmn_config(plmn_id_t *p, uint8_t idx); +plmn_id_t extract_plmn_from_params(const paramdef_t *params, int n_params);