From 325ac4f8e2ac1624a7a61e77f07d0d9ed76c9156 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Wed, 23 Aug 2023 16:06:54 +0200 Subject: [PATCH] Restructure config read: first PLMN info, then SIB1, then F1 Setup request In NSA case: do not send SIB1 --- openair2/GNB_APP/gnb_config.c | 241 +++++++++++++++++++--------------- 1 file changed, 132 insertions(+), 109 deletions(-) diff --git a/openair2/GNB_APP/gnb_config.c b/openair2/GNB_APP/gnb_config.c index 4134d03ca2..28bdb9fce4 100644 --- a/openair2/GNB_APP/gnb_config.c +++ b/openair2/GNB_APP/gnb_config.c @@ -947,7 +947,127 @@ static NR_ServingCellConfig_t *get_scd_config(void) return scd; } -static f1ap_setup_req_t *RC_read_F1Setup(const NR_ServingCellConfigCommon_t *scc, NR_BCCH_BCH_Message_t *mib, const NR_BCCH_DL_SCH_Message_t *sib1); +static int read_du_cell_info(uint64_t *id, char **name, f1ap_served_cell_info_t *info, int max_cell_info) +{ + AssertFatal(max_cell_info == 1, "only one cell supported\n"); + memset(info, 0, sizeof(*info)); + + paramdef_t GNBSParams[] = GNBSPARAMS_DESC; + paramdef_t GNBParams[] = GNBPARAMS_DESC; + paramlist_def_t GNBParamList = {GNB_CONFIG_STRING_GNB_LIST,NULL,0}; + config_get( GNBSParams,sizeof(GNBSParams)/sizeof(paramdef_t),NULL); + int num_gnbs = GNBSParams[GNB_ACTIVE_GNBS_IDX].numelt; + AssertFatal(num_gnbs == 1, "cannot configure DU: required config section \"gNBs\" missing\n"); + + // Output a list of all eNBs. + config_getlist(&GNBParamList, GNBParams, sizeof(GNBParams) / sizeof(paramdef_t), NULL); + AssertFatal(GNBParamList.paramarray[0][GNB_GNB_ID_IDX].uptr != NULL, "gNB id %u is not defined in configuration file\n", 0); + + AssertFatal(strcmp(GNBSParams[GNB_ACTIVE_GNBS_IDX].strlistptr[0], *GNBParamList.paramarray[0][GNB_GNB_NAME_IDX].strptr) == 0, + "no active gNB found/mismatch of gNBs: %s vs %s\n", + GNBSParams[GNB_ACTIVE_GNBS_IDX].strlistptr[0], + *GNBParamList.paramarray[0][GNB_GNB_NAME_IDX].strptr); + + char aprefix[MAX_OPTNAME_SIZE * 2 + 8]; + sprintf(aprefix, "%s.[0]", GNB_CONFIG_STRING_GNB_LIST); + paramdef_t PLMNParams[] = GNBPLMNPARAMS_DESC; + /* map parameter checking array instances to parameter definition array instances */ + checkedparam_t config_check_PLMNParams[] = PLMNPARAMS_CHECK; + for (int I = 0; I < sizeof(PLMNParams) / sizeof(paramdef_t); ++I) + PLMNParams[I].chkPptr = &(config_check_PLMNParams[I]); + paramlist_def_t PLMNParamList = {GNB_CONFIG_STRING_PLMN_LIST, NULL, 0}; + config_getlist(&PLMNParamList, PLMNParams, sizeof(PLMNParams) / sizeof(paramdef_t), aprefix); + + *id = *(GNBParamList.paramarray[0][GNB_GNB_ID_IDX].uptr); + *name = strdup(*(GNBParamList.paramarray[0][GNB_GNB_NAME_IDX].strptr)); + info->tac = malloc(sizeof(*info->tac)); + AssertFatal(info->tac != NULL, "out of memory\n"); + *info->tac = *GNBParamList.paramarray[0][GNB_TRACKING_AREA_CODE_IDX].uptr; + info->plmn.mcc = *PLMNParamList.paramarray[0][GNB_MOBILE_COUNTRY_CODE_IDX].uptr; + info->plmn.mnc = *PLMNParamList.paramarray[0][GNB_MOBILE_NETWORK_CODE_IDX].uptr; + info->plmn.mnc_digit_length = *PLMNParamList.paramarray[0][GNB_MNC_DIGIT_LENGTH].u8ptr; + AssertFatal((info->plmn.mnc_digit_length == 2) || (info->plmn.mnc_digit_length == 3), + "BAD MNC DIGIT LENGTH %d", + info->plmn.mnc_digit_length); + info->nr_cellid = (uint64_t) * (GNBParamList.paramarray[0][GNB_NRCELLID_IDX].u64ptr); + + LOG_W(GNB_APP, "no slices transported via F1 Setup Request!\n"); + info->num_ssi = 0; + + return 1; +} + +static f1ap_setup_req_t *RC_read_F1Setup(uint64_t id, + const char *name, + const f1ap_served_cell_info_t *info, + const NR_ServingCellConfigCommon_t *scc, + NR_BCCH_BCH_Message_t *mib, + const NR_BCCH_DL_SCH_Message_t *sib1) +{ + f1ap_setup_req_t *req = calloc(1, sizeof(*req)); + AssertFatal(req != NULL, "out of memory\n"); + req->gNB_DU_id = id; + req->gNB_DU_name = strdup(name); + req->num_cells_available = 1; + req->cell[0].info = *info; + LOG_I(GNB_APP, + "F1AP: gNB idx %d gNB_DU_id %ld, gNB_DU_name %s, TAC %d MCC/MNC/length %d/%d/%d cellID %ld\n", + 0, + req->gNB_DU_id, + req->gNB_DU_name, + *req->cell[0].info.tac, + req->cell[0].info.plmn.mcc, + req->cell[0].info.plmn.mnc, + req->cell[0].info.plmn.mnc_digit_length, + req->cell[0].info.nr_cellid); + + req->cell[0].info.nr_pci = *scc->physCellId; + if (scc->tdd_UL_DL_ConfigurationCommon) { + LOG_I(GNB_APP, "ngran_DU: Configuring Cell %d for TDD\n", 0); + req->cell[0].info.mode = F1AP_MODE_TDD; + f1ap_tdd_info_t *tdd = &req->cell[0].info.tdd; + tdd->freqinfo.arfcn = scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA; + tdd->tbw.scs = scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing; + tdd->tbw.nrb = scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth; + tdd->freqinfo.band = *scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0]; + } else { + LOG_I(GNB_APP, "ngran_DU: Configuring Cell %d for FDD\n", 0); + req->cell[0].info.mode = F1AP_MODE_FDD; + f1ap_fdd_info_t *fdd = &req->cell[0].info.fdd; + fdd->dl_freqinfo.arfcn = scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA; + fdd->ul_freqinfo.arfcn = *scc->uplinkConfigCommon->frequencyInfoUL->absoluteFrequencyPointA; + fdd->dl_tbw.scs = scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing; + fdd->ul_tbw.scs = scc->uplinkConfigCommon->frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing; + fdd->dl_tbw.nrb = scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth; + fdd->ul_tbw.nrb = scc->uplinkConfigCommon->frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth; + fdd->dl_freqinfo.band = *scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0]; + fdd->ul_freqinfo.band = *scc->uplinkConfigCommon->frequencyInfoUL->frequencyBandList->list.array[0]; + } + + req->cell[0].info.measurement_timing_information = "0"; + + int buf_len = 3; // this is what we assume in monolithic + req->cell[0].sys_info = calloc(1, sizeof(*req->cell[0].sys_info)); + AssertFatal(req->cell[0].sys_info != NULL, "out of memory\n"); + f1ap_gnb_du_system_info_t *sys_info = req->cell[0].sys_info; + sys_info->mib = calloc(buf_len, sizeof(*sys_info->mib)); + DevAssert(sys_info->mib != NULL); + DevAssert(mib != NULL); + sys_info->mib_length = encode_MIB_NR(mib, 0, sys_info->mib, buf_len); + DevAssert(sys_info->mib_length == buf_len); + + if (get_softmodem_params()->sa) { + // in NSA we don't transmit SIB1 + DevAssert(sib1 != NULL); + NR_SIB1_t *bcch_SIB1 = sib1->message.choice.c1->choice.systemInformationBlockType1; + sys_info->sib1 = calloc(NR_MAX_SIB_LENGTH / 8, sizeof(*sys_info->sib1)); + asn_enc_rval_t enc_rval = uper_encode_to_buffer(&asn_DEF_NR_SIB1, NULL, (void *)bcch_SIB1, sys_info->sib1, NR_MAX_SIB_LENGTH / 8); + AssertFatal(enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n", enc_rval.failed_type->name, enc_rval.encoded); + sys_info->sib1_length = (enc_rval.encoded + 7) / 8; + } + + return req; +} void RCconfig_nr_macrlc() { int j = 0; @@ -1013,8 +1133,6 @@ void RCconfig_nr_macrlc() { config.do_SRS, config.force_256qam_off ? "force off" : "may be on"); - // note: no need for PLMN info, it is read in RC_read_F1Setup() - NR_ServingCellConfigCommon_t *scc = get_scc_config(config.minRXTXTIME); //xer_fprint(stdout, &asn_DEF_NR_ServingCellConfigCommon, scc); NR_ServingCellConfig_t *scd = get_scd_config(); @@ -1104,14 +1222,24 @@ void RCconfig_nr_macrlc() { memcpy(RC.nrmac[j]->ulprbbl, prbbl, 275 * sizeof(prbbl[0])); } // for (j=0;jsa) + nr_mac_configure_sib1(RC.nrmac[0], &info.plmn, info.nr_cellid, *info.tac); + // read F1 Setup information from config and generated MIB/SIB1 // and store it at MAC for sending later NR_BCCH_BCH_Message_t *mib = RC.nrmac[0]->common_channels[0].mib; const NR_BCCH_DL_SCH_Message_t *sib1 = RC.nrmac[0]->common_channels[0].sib1; - f1ap_setup_req_t *req = RC_read_F1Setup(scc, mib, sib1); + f1ap_setup_req_t *req = RC_read_F1Setup(id, name, &info, scc, mib, sib1); AssertFatal(req != NULL, "could not read F1 Setup information\n"); RC.nrmac[0]->f1_config.setup_req = req; + free(name); /* read_du_cell_info() allocated memory */ + } else { // MacRLC_ParamList.numelt > 0 LOG_E(PHY, "No %s configuration found\n", CONFIG_STRING_MACRLC_LIST); // AssertFatal (0,"No " CONFIG_STRING_MACRLC_LIST " configuration found"); @@ -1924,111 +2052,6 @@ int RCconfig_NR_X2(MessageDef *msg_p, uint32_t i) { return 0; } - -static f1ap_setup_req_t *RC_read_F1Setup(const NR_ServingCellConfigCommon_t *scc, NR_BCCH_BCH_Message_t *mib, const NR_BCCH_DL_SCH_Message_t *sib1) -{ - paramdef_t GNBSParams[] = GNBSPARAMS_DESC; - paramdef_t GNBParams[] = GNBPARAMS_DESC; - paramlist_def_t GNBParamList = {GNB_CONFIG_STRING_GNB_LIST,NULL,0}; - config_get( GNBSParams,sizeof(GNBSParams)/sizeof(paramdef_t),NULL); - int num_gnbs = GNBSParams[GNB_ACTIVE_GNBS_IDX].numelt; - AssertFatal(num_gnbs == 1, "cannot configure DU: required config section \"gNBs\" missing\n"); - - // Output a list of all eNBs. - config_getlist(&GNBParamList, GNBParams, sizeof(GNBParams) / sizeof(paramdef_t), NULL); - AssertFatal(GNBParamList.paramarray[0][GNB_GNB_ID_IDX].uptr != NULL, "gNB id %u is not defined in configuration file\n", 0); - - AssertFatal(strcmp(GNBSParams[GNB_ACTIVE_GNBS_IDX].strlistptr[0], *GNBParamList.paramarray[0][GNB_GNB_NAME_IDX].strptr) == 0, - "no active gNB found/mismatch of gNBs: %s vs %s\n", - GNBSParams[GNB_ACTIVE_GNBS_IDX].strlistptr[0], - *GNBParamList.paramarray[0][GNB_GNB_NAME_IDX].strptr); - - char aprefix[MAX_OPTNAME_SIZE * 2 + 8]; - sprintf(aprefix, "%s.[0]", GNB_CONFIG_STRING_GNB_LIST); - paramdef_t PLMNParams[] = GNBPLMNPARAMS_DESC; - paramlist_def_t PLMNParamList = {GNB_CONFIG_STRING_PLMN_LIST, NULL, 0}; - /* map parameter checking array instances to parameter definition array instances */ - checkedparam_t config_check_PLMNParams[] = PLMNPARAMS_CHECK; - - for (int I = 0; I < sizeof(PLMNParams) / sizeof(paramdef_t); ++I) - PLMNParams[I].chkPptr = &(config_check_PLMNParams[I]); - - config_getlist(&PLMNParamList, PLMNParams, sizeof(PLMNParams) / sizeof(paramdef_t), aprefix); - - f1ap_setup_req_t *req = calloc(1, sizeof(*req)); - req->num_cells_available = 1; - req->gNB_DU_id = *(GNBParamList.paramarray[0][GNB_GNB_ID_IDX].uptr); - req->gNB_DU_name = strdup(*(GNBParamList.paramarray[0][GNB_GNB_NAME_IDX].strptr)); - req->cell[0].info.tac = malloc(sizeof(*req->cell[0].info.tac)); - AssertFatal(req->cell[0].info.tac != NULL, "out of memory\n"); - *req->cell[0].info.tac = *GNBParamList.paramarray[0][GNB_TRACKING_AREA_CODE_IDX].uptr; - req->cell[0].info.plmn.mcc = *PLMNParamList.paramarray[0][GNB_MOBILE_COUNTRY_CODE_IDX].uptr; - req->cell[0].info.plmn.mnc = *PLMNParamList.paramarray[0][GNB_MOBILE_NETWORK_CODE_IDX].uptr; - req->cell[0].info.plmn.mnc_digit_length = *PLMNParamList.paramarray[0][GNB_MNC_DIGIT_LENGTH].u8ptr; - AssertFatal((req->cell[0].info.plmn.mnc_digit_length == 2) || (req->cell[0].info.plmn.mnc_digit_length == 3), - "BAD MNC DIGIT LENGTH %d", - req->cell[0].info.plmn.mnc_digit_length); - req->cell[0].info.nr_cellid = (uint64_t) * (GNBParamList.paramarray[0][GNB_NRCELLID_IDX].u64ptr); - LOG_I(GNB_APP, - "F1AP: gNB idx %d gNB_DU_id %ld, gNB_DU_name %s, TAC %d MCC/MNC/length %d/%d/%d cellID %ld\n", - 0, - req->gNB_DU_id, - req->gNB_DU_name, - *req->cell[0].info.tac, - req->cell[0].info.plmn.mcc, - req->cell[0].info.plmn.mnc, - req->cell[0].info.plmn.mnc_digit_length, - req->cell[0].info.nr_cellid); - - - req->cell[0].info.nr_pci = *scc->physCellId; - LOG_W(GNB_APP, "no slices transported via F1 Setup Request!\n"); - req->cell[0].info.num_ssi = 0; - - if (scc->tdd_UL_DL_ConfigurationCommon) { - LOG_I(GNB_APP, "ngran_DU: Configuring Cell %d for TDD\n", 0); - req->cell[0].info.mode = F1AP_MODE_TDD; - f1ap_tdd_info_t *tdd = &req->cell[0].info.tdd; - tdd->freqinfo.arfcn = scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA; - tdd->tbw.scs = scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing; - tdd->tbw.nrb = scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth; - tdd->freqinfo.band = *scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0]; - } else { - LOG_I(GNB_APP, "ngran_DU: Configuring Cell %d for FDD\n", 0); - req->cell[0].info.mode = F1AP_MODE_FDD; - f1ap_fdd_info_t *fdd = &req->cell[0].info.fdd; - fdd->dl_freqinfo.arfcn = scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA; - fdd->ul_freqinfo.arfcn = *scc->uplinkConfigCommon->frequencyInfoUL->absoluteFrequencyPointA; - fdd->dl_tbw.scs = scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing; - fdd->ul_tbw.scs = scc->uplinkConfigCommon->frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing; - fdd->dl_tbw.nrb = scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth; - fdd->ul_tbw.nrb = scc->uplinkConfigCommon->frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth; - fdd->dl_freqinfo.band = *scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0]; - fdd->ul_freqinfo.band = *scc->uplinkConfigCommon->frequencyInfoUL->frequencyBandList->list.array[0]; - } - - req->cell[0].info.measurement_timing_information = "0"; - - int buf_len = 3; // this is what we assume in monolithic - req->cell[0].sys_info = calloc(1, sizeof(*req->cell[0].sys_info)); - AssertFatal(req->cell[0].sys_info != NULL, "out of memory\n"); - f1ap_gnb_du_system_info_t *sys_info = req->cell[0].sys_info; - sys_info->mib = calloc(buf_len, sizeof(*sys_info->mib)); - DevAssert(sys_info->mib != NULL); - DevAssert(mib != NULL); - sys_info->mib_length = encode_MIB_NR(mib, 0, sys_info->mib, buf_len); - DevAssert(sys_info->mib_length == buf_len); - - DevAssert(sib1 != NULL); - NR_SIB1_t *bcch_SIB1 = sib1->message.choice.c1->choice.systemInformationBlockType1; - sys_info->sib1 = calloc(NR_MAX_SIB_LENGTH / 8, sizeof(*sys_info->sib1)); - asn_enc_rval_t enc_rval = uper_encode_to_buffer(&asn_DEF_NR_SIB1, NULL, (void *)bcch_SIB1, sys_info->sib1, NR_MAX_SIB_LENGTH / 8); - AssertFatal(enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n", enc_rval.failed_type->name, enc_rval.encoded); - sys_info->sib1_length = (enc_rval.encoded + 7) / 8; - - return req; -} - void wait_f1_setup_response(void) { gNB_MAC_INST *mac = RC.nrmac[0];