From 88e6d9df099aecfd60c04c266ba6eed5c5b6b736 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Mon, 27 Mar 2023 10:05:49 +0200 Subject: [PATCH] Refactor SIB1 handling --- .../LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c | 2 +- openair2/RRC/NR/L2_nr_interface.c | 1 - openair2/RRC/NR/MESSAGES/asn1_msg.c | 292 ---------------- openair2/RRC/NR/MESSAGES/asn1_msg.h | 7 - openair2/RRC/NR/nr_rrc_config.c | 311 ++++++++++++++++++ openair2/RRC/NR/nr_rrc_config.h | 6 + openair2/RRC/NR/nr_rrc_extern.h | 2 - openair2/RRC/NR/rrc_gNB.c | 9 +- 8 files changed, 324 insertions(+), 306 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c index c2b7b0964e..6ffbe7c270 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c @@ -38,7 +38,7 @@ #include "common/utils/LOG/log.h" #include "common/utils/LOG/vcd_signal_dumper.h" #include "UTIL/OPT/opt.h" -#include "RRC/NR/nr_rrc_extern.h" +#include "RRC/NR/nr_rrc_config.h" #include "common/utils/nr/nr_common.h" diff --git a/openair2/RRC/NR/L2_nr_interface.c b/openair2/RRC/NR/L2_nr_interface.c index 20d5a6ec20..2e83c69af2 100644 --- a/openair2/RRC/NR/L2_nr_interface.c +++ b/openair2/RRC/NR/L2_nr_interface.c @@ -86,7 +86,6 @@ uint16_t mac_rrc_nr_data_req(const module_id_t Mod_idP, return encode_size; } - // TODO BCCH SIB1 SIBs if ((Srb_id & RAB_OFFSET) == BCCH) { memcpy(&buffer_pP[0], RC.nrrrc[Mod_idP]->carrier.SIB1, RC.nrrrc[Mod_idP]->carrier.sizeof_SIB1); return RC.nrrrc[Mod_idP]->carrier.sizeof_SIB1; diff --git a/openair2/RRC/NR/MESSAGES/asn1_msg.c b/openair2/RRC/NR/MESSAGES/asn1_msg.c index 92ecf37546..c9ffd4f098 100644 --- a/openair2/RRC/NR/MESSAGES/asn1_msg.c +++ b/openair2/RRC/NR/MESSAGES/asn1_msg.c @@ -194,298 +194,6 @@ int xer_nr_sprint (char *string, size_t string_size, asn_TYPE_descriptor_t *td, //------------------------------------------------------------------------------ -uint16_t do_SIB1_NR(rrc_gNB_carrier_data_t *carrier, - gNB_RrcConfigurationReq *configuration) { - - asn_enc_rval_t enc_rval; - NR_BCCH_DL_SCH_Message_t *sib1_message = CALLOC(1,sizeof(NR_BCCH_DL_SCH_Message_t)); - carrier->siblock1 = sib1_message; - sib1_message->message.present = NR_BCCH_DL_SCH_MessageType_PR_c1; - sib1_message->message.choice.c1 = CALLOC(1,sizeof(struct NR_BCCH_DL_SCH_MessageType__c1)); - sib1_message->message.choice.c1->present = NR_BCCH_DL_SCH_MessageType__c1_PR_systemInformationBlockType1; - sib1_message->message.choice.c1->choice.systemInformationBlockType1 = CALLOC(1,sizeof(struct NR_SIB1)); - - struct NR_SIB1 *sib1 = sib1_message->message.choice.c1->choice.systemInformationBlockType1; - - // cellSelectionInfo - sib1->cellSelectionInfo = CALLOC(1,sizeof(struct NR_SIB1__cellSelectionInfo)); - // Fixme: should be in config file - //The IE Q-RxLevMin is used to indicate for cell selection/ re-selection the required minimum received RSRP level in the (NR) cell. - //Corresponds to parameter Qrxlevmin in TS38.304. - //Actual value Qrxlevmin = field value * 2 [dBm]. - sib1->cellSelectionInfo->q_RxLevMin = -65; - - // cellAccessRelatedInfo - // TODO : Add support for more than one PLMN - int num_plmn = 1; // int num_plmn = configuration->num_plmn; - asn1cSequenceAdd(sib1->cellAccessRelatedInfo.plmn_IdentityInfoList.list, struct NR_PLMN_IdentityInfo, nr_plmn_info); - for (int i = 0; i < num_plmn; ++i) { - asn1cSequenceAdd(nr_plmn_info->plmn_IdentityList.list, struct NR_PLMN_Identity, nr_plmn); - asn1cCalloc(nr_plmn->mcc, mcc); - int confMcc=configuration->mcc[i]; - asn1cSequenceAdd(mcc->list, NR_MCC_MNC_Digit_t, mcc0); - *mcc0=(confMcc/100)%10; - asn1cSequenceAdd(mcc->list, NR_MCC_MNC_Digit_t, mcc1); - *mcc1=(confMcc/10)%10; - asn1cSequenceAdd(mcc->list, NR_MCC_MNC_Digit_t, mcc2); - *mcc2=confMcc%10; - int mnc=configuration->mnc[i]; - if(configuration->mnc_digit_length[i] == 3) { - asn1cSequenceAdd(nr_plmn->mnc.list, NR_MCC_MNC_Digit_t, mnc0); - *mnc0=(configuration->mnc[i]/100)%10; - } - asn1cSequenceAdd(nr_plmn->mnc.list, NR_MCC_MNC_Digit_t, mnc1); - *mnc1=(mnc/10)%10; - asn1cSequenceAdd(nr_plmn->mnc.list, NR_MCC_MNC_Digit_t, mnc2); - *mnc2=(mnc)%10; - }//end plmn loop - - nr_plmn_info->cellIdentity.buf = CALLOC(1,5); - nr_plmn_info->cellIdentity.size= 5; - nr_plmn_info->cellIdentity.bits_unused= 4; - uint64_t tmp=htobe64(configuration->cell_identity)<<4; - memcpy(nr_plmn_info->cellIdentity.buf, ((char*)&tmp)+3, 5); - nr_plmn_info->cellReservedForOperatorUse = NR_PLMN_IdentityInfo__cellReservedForOperatorUse_notReserved; - - nr_plmn_info->trackingAreaCode = CALLOC(1,sizeof(NR_TrackingAreaCode_t)); - uint32_t tmp2=htobe32(configuration->tac); - nr_plmn_info->trackingAreaCode->buf = CALLOC(1,3); - memcpy(nr_plmn_info->trackingAreaCode->buf, ((char*) &tmp2)+1, 3); - nr_plmn_info->trackingAreaCode->size = 3; - nr_plmn_info->trackingAreaCode->bits_unused = 0; - - // connEstFailureControl - // TODO: add connEstFailureControl - - //si-SchedulingInfo - /*sib1->si_SchedulingInfo = CALLOC(1,sizeof(struct NR_SI_SchedulingInfo)); - asn_set_empty(&sib1->si_SchedulingInfo->schedulingInfoList.list); - sib1->si_SchedulingInfo->si_WindowLength = NR_SI_SchedulingInfo__si_WindowLength_s40; - struct NR_SchedulingInfo *schedulingInfo = CALLOC(1,sizeof(struct NR_SchedulingInfo)); - schedulingInfo->si_BroadcastStatus = NR_SchedulingInfo__si_BroadcastStatus_broadcasting; - schedulingInfo->si_Periodicity = NR_SchedulingInfo__si_Periodicity_rf8; - asn_set_empty(&schedulingInfo->sib_MappingInfo.list); - - NR_SIB_TypeInfo_t *sib_type3 = CALLOC(1,sizeof(e_NR_SIB_TypeInfo__type)); - sib_type3->type = NR_SIB_TypeInfo__type_sibType3; - sib_type3->valueTag = CALLOC(1,sizeof(sib_type3->valueTag)); - asn1cSeqAdd(&schedulingInfo->sib_MappingInfo.list,sib_type3); - - NR_SIB_TypeInfo_t *sib_type5 = CALLOC(1,sizeof(e_NR_SIB_TypeInfo__type)); - sib_type5->type = NR_SIB_TypeInfo__type_sibType5; - sib_type5->valueTag = CALLOC(1,sizeof(sib_type5->valueTag)); - asn1cSeqAdd(&schedulingInfo->sib_MappingInfo.list,sib_type5); - - NR_SIB_TypeInfo_t *sib_type4 = CALLOC(1,sizeof(e_NR_SIB_TypeInfo__type)); - sib_type4->type = NR_SIB_TypeInfo__type_sibType4; - sib_type4->valueTag = CALLOC(1,sizeof(sib_type4->valueTag)); - asn1cSeqAdd(&schedulingInfo->sib_MappingInfo.list,sib_type4); - - NR_SIB_TypeInfo_t *sib_type2 = CALLOC(1,sizeof(e_NR_SIB_TypeInfo__type)); - sib_type2->type = NR_SIB_TypeInfo__type_sibType2; - sib_type2->valueTag = CALLOC(1,sizeof(sib_type2->valueTag)); - asn1cSeqAdd(&schedulingInfo->sib_MappingInfo.list,sib_type2); - - asn1cSeqAdd(&sib1->si_SchedulingInfo->schedulingInfoList.list,schedulingInfo);*/ - - // servingCellConfigCommon - asn1cCalloc(sib1->servingCellConfigCommon, ServCellCom); - NR_BWP_DownlinkCommon_t *initialDownlinkBWP=&ServCellCom->downlinkConfigCommon.initialDownlinkBWP; - initialDownlinkBWP->genericParameters= - configuration->scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters; - - for(int i = 0; i< configuration->scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.count; i++) { - asn1cSequenceAdd(ServCellCom->downlinkConfigCommon.frequencyInfoDL.frequencyBandList.list, - struct NR_NR_MultiBandInfo, nrMultiBandInfo); - nrMultiBandInfo->freqBandIndicatorNR = configuration->scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[i]; - } - - int scs_scaling0 = 1<<(configuration->scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.subcarrierSpacing); - int scs_scaling = scs_scaling0; - int scs_scaling2 = scs_scaling0; - if (configuration->scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA < 600000) { - scs_scaling = scs_scaling0*3; - } - if (configuration->scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA > 2016666) { - scs_scaling = scs_scaling0>>2; - scs_scaling2 = scs_scaling0>>2; - } - uint32_t absolute_diff = (*configuration->scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencySSB - - configuration->scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA); - - sib1->servingCellConfigCommon->downlinkConfigCommon.frequencyInfoDL.offsetToPointA = scs_scaling2 * (absolute_diff/(12*scs_scaling) - 10); - - LOG_I(NR_RRC,"SIB1 freq: absoluteFrequencySSB %ld, absoluteFrequencyPointA %ld\n", - *configuration->scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencySSB, - configuration->scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA); - LOG_I(NR_RRC,"SIB1 freq: absolute_diff %d, %d*(absolute_diff/(12*%d) - 10) %d\n", - absolute_diff,scs_scaling2,scs_scaling,(int)sib1->servingCellConfigCommon->downlinkConfigCommon.frequencyInfoDL.offsetToPointA); - - for(int i = 0; i< configuration->scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.count; i++) { - asn1cSeqAdd(&ServCellCom->downlinkConfigCommon.frequencyInfoDL.scs_SpecificCarrierList.list, - configuration->scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[i]); - } - - initialDownlinkBWP->pdcch_ConfigCommon = - configuration->scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon; - initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->commonSearchSpaceList = - CALLOC(1,sizeof(struct NR_PDCCH_ConfigCommon__commonSearchSpaceList)); - - NR_SearchSpace_t *ss1 = rrc_searchspace_config(true, 1, 0); - asn1cSeqAdd(&initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->commonSearchSpaceList->list, ss1); - - NR_SearchSpace_t *ss2 = rrc_searchspace_config(true, 2, 0); - asn1cSeqAdd(&initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->commonSearchSpaceList->list, ss2); - - NR_SearchSpace_t *ss3 = rrc_searchspace_config(true, 3, 0); - asn1cSeqAdd(&initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->commonSearchSpaceList->list, ss3); - - asn1cCallocOne(initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->searchSpaceSIB1, 0); - asn1cCallocOne(initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->searchSpaceOtherSystemInformation, 3); - asn1cCallocOne(initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->pagingSearchSpace, 2); - asn1cCallocOne(initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->ra_SearchSpace, 1); - - initialDownlinkBWP->pdsch_ConfigCommon = configuration->scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon; - ServCellCom->downlinkConfigCommon.bcch_Config.modificationPeriodCoeff = NR_BCCH_Config__modificationPeriodCoeff_n2; - ServCellCom->downlinkConfigCommon.pcch_Config.defaultPagingCycle = NR_PagingCycle_rf256; - ServCellCom->downlinkConfigCommon.pcch_Config.nAndPagingFrameOffset.present = NR_PCCH_Config__nAndPagingFrameOffset_PR_quarterT; - ServCellCom->downlinkConfigCommon.pcch_Config.nAndPagingFrameOffset.choice.quarterT = 1; - ServCellCom->downlinkConfigCommon.pcch_Config.ns = NR_PCCH_Config__ns_one; - - asn1cCalloc(ServCellCom->downlinkConfigCommon.pcch_Config.firstPDCCH_MonitoringOccasionOfPO, - P0); - P0->present = NR_PCCH_Config__firstPDCCH_MonitoringOccasionOfPO_PR_sCS120KHZoneT_SCS60KHZhalfT_SCS30KHZquarterT_SCS15KHZoneEighthT; - - asn1cCalloc(P0->choice.sCS120KHZoneT_SCS60KHZhalfT_SCS30KHZquarterT_SCS15KHZoneEighthT, - Z8); - asn1cSequenceAdd(Z8->list, - long, - ZoneEight); - asn1cCallocOne(ZoneEight, 0); - - asn1cCalloc(ServCellCom->uplinkConfigCommon, UL); - asn_set_empty(&UL->frequencyInfoUL.scs_SpecificCarrierList.list); - for(int i = 0; i< configuration->scc->uplinkConfigCommon->frequencyInfoUL->scs_SpecificCarrierList.list.count; i++) { - asn1cSeqAdd(&UL->frequencyInfoUL.scs_SpecificCarrierList.list, - configuration->scc->uplinkConfigCommon->frequencyInfoUL->scs_SpecificCarrierList.list.array[i]); - } - - asn1cCallocOne(UL->frequencyInfoUL.p_Max, *configuration->scc->uplinkConfigCommon->frequencyInfoUL->p_Max); - - UL->initialUplinkBWP.genericParameters = configuration->scc->uplinkConfigCommon->initialUplinkBWP->genericParameters; - UL->initialUplinkBWP.rach_ConfigCommon = configuration->scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon; - UL->initialUplinkBWP.pusch_ConfigCommon = configuration->scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon; - UL->initialUplinkBWP.pusch_ConfigCommon->choice.setup->groupHoppingEnabledTransformPrecoding = NULL; - - UL->initialUplinkBWP.pucch_ConfigCommon = configuration->scc->uplinkConfigCommon->initialUplinkBWP->pucch_ConfigCommon; - - UL->timeAlignmentTimerCommon = NR_TimeAlignmentTimer_infinity; - - ServCellCom->n_TimingAdvanceOffset = configuration->scc->n_TimingAdvanceOffset; - - ServCellCom->ssb_PositionsInBurst.inOneGroup.buf = calloc(1, sizeof(uint8_t)); - uint8_t bitmap8,temp_bitmap=0; - switch (configuration->scc->ssb_PositionsInBurst->present) { - case NR_ServingCellConfigCommon__ssb_PositionsInBurst_PR_shortBitmap: - ServCellCom->ssb_PositionsInBurst.inOneGroup = configuration->scc->ssb_PositionsInBurst->choice.shortBitmap; - break; - case NR_ServingCellConfigCommon__ssb_PositionsInBurst_PR_mediumBitmap: - ServCellCom->ssb_PositionsInBurst.inOneGroup = configuration->scc->ssb_PositionsInBurst->choice.mediumBitmap; - break; - /* - groupPresence: This field is present when maximum number of SS/PBCH blocks per half frame equals to 64 as defined in TS 38.213 [13], clause 4.1. - The first/leftmost bit corresponds to the SS/PBCH index 0-7, the second bit corresponds to SS/PBCH block 8-15, and so on. - Value 0 in the bitmap indicates that the SSBs according to inOneGroup are absent. Value 1 indicates that the SS/PBCH blocks are transmitted in accordance with inOneGroup. - inOneGroup: When maximum number of SS/PBCH blocks per half frame equals to 64 as defined in TS 38.213 [13], clause 4.1, all 8 bit are valid; - The first/ leftmost bit corresponds to the first SS/PBCH block index in the group (i.e., to SSB index 0, 8, and so on); the second bit corresponds to the second SS/PBCH block index in the group - (i.e., to SSB index 1, 9, and so on), and so on. Value 0 in the bitmap indicates that the corresponding SS/PBCH block is not transmitted while value 1 indicates that the corresponding SS/PBCH block is transmitted. - */ - case NR_ServingCellConfigCommon__ssb_PositionsInBurst_PR_longBitmap: - ServCellCom->ssb_PositionsInBurst.inOneGroup.size = 1; - ServCellCom->ssb_PositionsInBurst.inOneGroup.bits_unused = 0; - ServCellCom->ssb_PositionsInBurst.groupPresence = calloc(1, sizeof(BIT_STRING_t)); - ServCellCom->ssb_PositionsInBurst.groupPresence->size = 1; - ServCellCom->ssb_PositionsInBurst.groupPresence->bits_unused = 0; - ServCellCom->ssb_PositionsInBurst.groupPresence->buf = calloc(1, sizeof(uint8_t)); - ServCellCom->ssb_PositionsInBurst.groupPresence->buf[0] = 0; - for (int i=0; i<8; i++){ - bitmap8 = configuration->scc->ssb_PositionsInBurst->choice.longBitmap.buf[i]; - if (bitmap8!=0){ - if(temp_bitmap==0) - temp_bitmap = bitmap8; - else - AssertFatal(temp_bitmap==bitmap8,"For longBitmap the groups of 8 SSBs containing at least 1 transmitted SSB should be all the same\n"); - - ServCellCom->ssb_PositionsInBurst.inOneGroup.buf[0] = bitmap8; - ServCellCom->ssb_PositionsInBurst.groupPresence->buf[0] |= 1<<(7-i); - } - } - break; - default: - AssertFatal(false,"ssb_PositionsInBurst not present\n"); - break; - } - - ServCellCom->ssb_PeriodicityServingCell = *configuration->scc->ssb_periodicityServingCell; - if (configuration->scc->tdd_UL_DL_ConfigurationCommon) { - ServCellCom->tdd_UL_DL_ConfigurationCommon = CALLOC(1,sizeof(struct NR_TDD_UL_DL_ConfigCommon)); - ServCellCom->tdd_UL_DL_ConfigurationCommon->referenceSubcarrierSpacing = configuration->scc->tdd_UL_DL_ConfigurationCommon->referenceSubcarrierSpacing; - ServCellCom->tdd_UL_DL_ConfigurationCommon->pattern1 = configuration->scc->tdd_UL_DL_ConfigurationCommon->pattern1; - ServCellCom->tdd_UL_DL_ConfigurationCommon->pattern2 = configuration->scc->tdd_UL_DL_ConfigurationCommon->pattern2; - } - ServCellCom->ss_PBCH_BlockPower = configuration->scc->ss_PBCH_BlockPower; - - // ims-EmergencySupport - // TODO: add ims-EmergencySupport - - // eCallOverIMS-Support - // TODO: add eCallOverIMS-Support - - // ue-TimersAndConstants - sib1->ue_TimersAndConstants = CALLOC(1,sizeof(struct NR_UE_TimersAndConstants)); - sib1->ue_TimersAndConstants->t300 = NR_UE_TimersAndConstants__t300_ms400; - sib1->ue_TimersAndConstants->t301 = NR_UE_TimersAndConstants__t301_ms400; - sib1->ue_TimersAndConstants->t310 = NR_UE_TimersAndConstants__t310_ms2000; - sib1->ue_TimersAndConstants->n310 = NR_UE_TimersAndConstants__n310_n10; - sib1->ue_TimersAndConstants->t311 = NR_UE_TimersAndConstants__t311_ms3000; - sib1->ue_TimersAndConstants->n311 = NR_UE_TimersAndConstants__n311_n1; - sib1->ue_TimersAndConstants->t319 = NR_UE_TimersAndConstants__t319_ms400; - - // uac-BarringInfo - /*sib1->uac_BarringInfo = CALLOC(1, sizeof(struct NR_SIB1__uac_BarringInfo)); - NR_UAC_BarringInfoSet_t *nr_uac_BarringInfoSet = CALLOC(1, sizeof(NR_UAC_BarringInfoSet_t)); - asn_set_empty(&sib1->uac_BarringInfo->uac_BarringInfoSetList); - nr_uac_BarringInfoSet->uac_BarringFactor = NR_UAC_BarringInfoSet__uac_BarringFactor_p95; - nr_uac_BarringInfoSet->uac_BarringTime = NR_UAC_BarringInfoSet__uac_BarringTime_s4; - nr_uac_BarringInfoSet->uac_BarringForAccessIdentity.buf = CALLOC(1, 1); - nr_uac_BarringInfoSet->uac_BarringForAccessIdentity.size = 1; - nr_uac_BarringInfoSet->uac_BarringForAccessIdentity.bits_unused = 1; - asn1cSeqAdd(&sib1->uac_BarringInfo->uac_BarringInfoSetList, nr_uac_BarringInfoSet);*/ - - // useFullResumeID - // TODO: add useFullResumeID - - // lateNonCriticalExtension - // TODO: add lateNonCriticalExtension - - // nonCriticalExtension - // TODO: add nonCriticalExtension - - xer_fprint(stdout, &asn_DEF_NR_SIB1, (const void*)sib1_message->message.choice.c1->choice.systemInformationBlockType1); - - if(carrier->SIB1 == NULL) carrier->SIB1=(uint8_t *) malloc16(NR_MAX_SIB_LENGTH/8); - enc_rval = uper_encode_to_buffer(&asn_DEF_NR_BCCH_DL_SCH_Message, - NULL, - (void *)sib1_message, - carrier->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); - AssertFatal(enc_rval.encoded <= NR_MAX_SIB_LENGTH, "ASN1 encoded length %zd bits. 3GPP TS 38.331 section 5.2.1 - The physical layer imposes a limit to the maximum size a SIB can take. The maximum SIB1 or SI message size is 2976 bits.\n", enc_rval.encoded); - - return((enc_rval.encoded+7)/8); -} - uint8_t do_SIB23_NR(rrc_gNB_carrier_data_t *carrier, gNB_RrcConfigurationReq *configuration) { asn_enc_rval_t enc_rval; diff --git a/openair2/RRC/NR/MESSAGES/asn1_msg.h b/openair2/RRC/NR/MESSAGES/asn1_msg.h index c51932a6fa..3c0dcc5a12 100644 --- a/openair2/RRC/NR/MESSAGES/asn1_msg.h +++ b/openair2/RRC/NR/MESSAGES/asn1_msg.h @@ -55,13 +55,6 @@ */ int xer_sprint_NR(char *string, size_t string_size, struct asn_TYPE_descriptor_s *td, void *sptr); -/** -\brief Generate configuration for SIB1 (gNB). -@param carrier pointer to Carrier information -@param configuration Pointer Configuration Request structure -@return size of encoded bit stream in bytes*/ -uint16_t do_SIB1_NR(rrc_gNB_carrier_data_t *carrier, gNB_RrcConfigurationReq *configuration); - uint8_t do_SIB23_NR(rrc_gNB_carrier_data_t *carrier, gNB_RrcConfigurationReq *configuration); diff --git a/openair2/RRC/NR/nr_rrc_config.c b/openair2/RRC/NR/nr_rrc_config.c index 430399f561..e6616c7e68 100644 --- a/openair2/RRC/NR/nr_rrc_config.c +++ b/openair2/RRC/NR/nr_rrc_config.c @@ -1689,3 +1689,314 @@ int encode_MIB_NR(NR_BCCH_BCH_Message_t *mib, int frame, uint8_t *buf, int buf_s LOG_D(NR_RRC, "Encoded MIB for frame %d sfn_msb %d, bits %lu\n", frame, sfn_msb, enc_rval.encoded); return (enc_rval.encoded + 7) / 8; } + +NR_BCCH_DL_SCH_Message_t *get_SIB1_NR(const gNB_RrcConfigurationReq *configuration) +{ + NR_BCCH_DL_SCH_Message_t *sib1_message = CALLOC(1,sizeof(NR_BCCH_DL_SCH_Message_t)); + AssertFatal(sib1_message != NULL, "out of memory\n"); + sib1_message->message.present = NR_BCCH_DL_SCH_MessageType_PR_c1; + sib1_message->message.choice.c1 = CALLOC(1,sizeof(struct NR_BCCH_DL_SCH_MessageType__c1)); + AssertFatal(sib1_message->message.choice.c1 != NULL, "out of memory\n"); + sib1_message->message.choice.c1->present = NR_BCCH_DL_SCH_MessageType__c1_PR_systemInformationBlockType1; + sib1_message->message.choice.c1->choice.systemInformationBlockType1 = CALLOC(1,sizeof(struct NR_SIB1)); + AssertFatal(sib1_message->message.choice.c1->choice.systemInformationBlockType1 != NULL, "out of memory\n"); + struct NR_SIB1 *sib1 = sib1_message->message.choice.c1->choice.systemInformationBlockType1; + + // cellSelectionInfo + sib1->cellSelectionInfo = CALLOC(1,sizeof(*sib1->cellSelectionInfo)); + AssertFatal(sib1->cellSelectionInfo != NULL, "out of memory\n"); + // Fixme: should be in config file + //The IE Q-RxLevMin is used to indicate for cell selection/ re-selection the required minimum received RSRP level in the (NR) cell. + //Corresponds to parameter Qrxlevmin in TS38.304. + //Actual value Qrxlevmin = field value * 2 [dBm]. + sib1->cellSelectionInfo->q_RxLevMin = -65; + + // cellAccessRelatedInfo + // TODO : Add support for more than one PLMN + int num_plmn = 1; // int num_plmn = configuration->num_plmn; + asn1cSequenceAdd(sib1->cellAccessRelatedInfo.plmn_IdentityInfoList.list, struct NR_PLMN_IdentityInfo, nr_plmn_info); + for (int i = 0; i < num_plmn; ++i) { + asn1cSequenceAdd(nr_plmn_info->plmn_IdentityList.list, struct NR_PLMN_Identity, nr_plmn); + asn1cCalloc(nr_plmn->mcc, mcc); + int confMcc = configuration->mcc[i]; + asn1cSequenceAdd(mcc->list, NR_MCC_MNC_Digit_t, mcc0); + *mcc0 = (confMcc / 100) % 10; + asn1cSequenceAdd(mcc->list, NR_MCC_MNC_Digit_t, mcc1); + *mcc1 = (confMcc / 10) % 10; + asn1cSequenceAdd(mcc->list, NR_MCC_MNC_Digit_t, mcc2); + *mcc2 = confMcc % 10; + int mnc = configuration->mnc[i]; + if (configuration->mnc_digit_length[i] == 3) { + asn1cSequenceAdd(nr_plmn->mnc.list, NR_MCC_MNC_Digit_t, mnc0); + *mnc0 = (configuration->mnc[i] / 100) % 10; + } + asn1cSequenceAdd(nr_plmn->mnc.list, NR_MCC_MNC_Digit_t, mnc1); + *mnc1 = (mnc / 10) % 10; + asn1cSequenceAdd(nr_plmn->mnc.list, NR_MCC_MNC_Digit_t, mnc2); + *mnc2 = (mnc) % 10; + } + + nr_plmn_info->cellIdentity.buf = CALLOC(1, 5); + AssertFatal(nr_plmn_info->cellIdentity.buf != NULL, "out of memory\n"); + nr_plmn_info->cellIdentity.size = 5; + nr_plmn_info->cellIdentity.bits_unused = 4; + uint64_t tmp = htobe64(configuration->cell_identity) << 4; + memcpy(nr_plmn_info->cellIdentity.buf, ((char *)&tmp) + 3, 5); + nr_plmn_info->cellReservedForOperatorUse = NR_PLMN_IdentityInfo__cellReservedForOperatorUse_notReserved; + + nr_plmn_info->trackingAreaCode = CALLOC(1, sizeof(NR_TrackingAreaCode_t)); + AssertFatal(nr_plmn_info->trackingAreaCode != NULL, "out of memory\n"); + uint32_t tmp2 = htobe32(configuration->tac); + nr_plmn_info->trackingAreaCode->buf = CALLOC(1, 3); + AssertFatal(nr_plmn_info->trackingAreaCode->buf != NULL, "out of memory\n"); + memcpy(nr_plmn_info->trackingAreaCode->buf, ((char *)&tmp2) + 1, 3); + nr_plmn_info->trackingAreaCode->size = 3; + nr_plmn_info->trackingAreaCode->bits_unused = 0; + + // connEstFailureControl + // TODO: add connEstFailureControl + + //si-SchedulingInfo + /*sib1->si_SchedulingInfo = CALLOC(1,sizeof(struct NR_SI_SchedulingInfo)); + asn_set_empty(&sib1->si_SchedulingInfo->schedulingInfoList.list); + sib1->si_SchedulingInfo->si_WindowLength = NR_SI_SchedulingInfo__si_WindowLength_s40; + struct NR_SchedulingInfo *schedulingInfo = CALLOC(1,sizeof(struct NR_SchedulingInfo)); + schedulingInfo->si_BroadcastStatus = NR_SchedulingInfo__si_BroadcastStatus_broadcasting; + schedulingInfo->si_Periodicity = NR_SchedulingInfo__si_Periodicity_rf8; + asn_set_empty(&schedulingInfo->sib_MappingInfo.list); + + NR_SIB_TypeInfo_t *sib_type3 = CALLOC(1,sizeof(e_NR_SIB_TypeInfo__type)); + sib_type3->type = NR_SIB_TypeInfo__type_sibType3; + sib_type3->valueTag = CALLOC(1,sizeof(sib_type3->valueTag)); + asn1cSeqAdd(&schedulingInfo->sib_MappingInfo.list,sib_type3); + + NR_SIB_TypeInfo_t *sib_type5 = CALLOC(1,sizeof(e_NR_SIB_TypeInfo__type)); + sib_type5->type = NR_SIB_TypeInfo__type_sibType5; + sib_type5->valueTag = CALLOC(1,sizeof(sib_type5->valueTag)); + asn1cSeqAdd(&schedulingInfo->sib_MappingInfo.list,sib_type5); + + NR_SIB_TypeInfo_t *sib_type4 = CALLOC(1,sizeof(e_NR_SIB_TypeInfo__type)); + sib_type4->type = NR_SIB_TypeInfo__type_sibType4; + sib_type4->valueTag = CALLOC(1,sizeof(sib_type4->valueTag)); + asn1cSeqAdd(&schedulingInfo->sib_MappingInfo.list,sib_type4); + + NR_SIB_TypeInfo_t *sib_type2 = CALLOC(1,sizeof(e_NR_SIB_TypeInfo__type)); + sib_type2->type = NR_SIB_TypeInfo__type_sibType2; + sib_type2->valueTag = CALLOC(1,sizeof(sib_type2->valueTag)); + asn1cSeqAdd(&schedulingInfo->sib_MappingInfo.list,sib_type2); + + asn1cSeqAdd(&sib1->si_SchedulingInfo->schedulingInfoList.list,schedulingInfo);*/ + + // servingCellConfigCommon + asn1cCalloc(sib1->servingCellConfigCommon, ServCellCom); + NR_BWP_DownlinkCommon_t *initialDownlinkBWP = &ServCellCom->downlinkConfigCommon.initialDownlinkBWP; + initialDownlinkBWP->genericParameters = configuration->scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters; + + const NR_FrequencyInfoDL_t *frequencyInfoDL = configuration->scc->downlinkConfigCommon->frequencyInfoDL; + for (int i = 0; i < frequencyInfoDL->frequencyBandList.list.count; i++) { + asn1cSequenceAdd(ServCellCom->downlinkConfigCommon.frequencyInfoDL.frequencyBandList.list, + struct NR_NR_MultiBandInfo, + nrMultiBandInfo); + nrMultiBandInfo->freqBandIndicatorNR = + frequencyInfoDL->frequencyBandList.list.array[i]; + } + + int scs_scaling0 = 1 << (configuration->scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.subcarrierSpacing); + int scs_scaling = scs_scaling0; + int scs_scaling2 = scs_scaling0; + if (frequencyInfoDL->absoluteFrequencyPointA < 600000) { + scs_scaling = scs_scaling0 * 3; + } + if (frequencyInfoDL->absoluteFrequencyPointA > 2016666) { + scs_scaling = scs_scaling0 >> 2; + scs_scaling2 = scs_scaling0 >> 2; + } + uint32_t absolute_diff = (*frequencyInfoDL->absoluteFrequencySSB - frequencyInfoDL->absoluteFrequencyPointA); + + sib1->servingCellConfigCommon->downlinkConfigCommon.frequencyInfoDL.offsetToPointA = + scs_scaling2 * (absolute_diff / (12 * scs_scaling) - 10); + + LOG_I(NR_RRC, + "SIB1 freq: absoluteFrequencySSB %ld, absoluteFrequencyPointA %ld\n", + *frequencyInfoDL->absoluteFrequencySSB, + frequencyInfoDL->absoluteFrequencyPointA); + LOG_I(NR_RRC, + "SIB1 freq: absolute_diff %d, %d*(absolute_diff/(12*%d) - 10) %d\n", + absolute_diff, + scs_scaling2, + scs_scaling, + (int)sib1->servingCellConfigCommon->downlinkConfigCommon.frequencyInfoDL.offsetToPointA); + + for (int i = 0; i < frequencyInfoDL->scs_SpecificCarrierList.list.count; i++) { + asn1cSeqAdd(&ServCellCom->downlinkConfigCommon.frequencyInfoDL.scs_SpecificCarrierList.list, + frequencyInfoDL->scs_SpecificCarrierList.list.array[i]); + } + + initialDownlinkBWP->pdcch_ConfigCommon = configuration->scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon; + initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->commonSearchSpaceList = + CALLOC(1, sizeof(struct NR_PDCCH_ConfigCommon__commonSearchSpaceList)); + AssertFatal(initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->commonSearchSpaceList != NULL, "out of memory\n"); + + NR_SearchSpace_t *ss1 = rrc_searchspace_config(true, 1, 0); + asn1cSeqAdd(&initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->commonSearchSpaceList->list, ss1); + + NR_SearchSpace_t *ss2 = rrc_searchspace_config(true, 2, 0); + asn1cSeqAdd(&initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->commonSearchSpaceList->list, ss2); + + NR_SearchSpace_t *ss3 = rrc_searchspace_config(true, 3, 0); + asn1cSeqAdd(&initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->commonSearchSpaceList->list, ss3); + + asn1cCallocOne(initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->searchSpaceSIB1, 0); + asn1cCallocOne(initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->searchSpaceOtherSystemInformation, 3); + asn1cCallocOne(initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->pagingSearchSpace, 2); + asn1cCallocOne(initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->ra_SearchSpace, 1); + + initialDownlinkBWP->pdsch_ConfigCommon = configuration->scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon; + ServCellCom->downlinkConfigCommon.bcch_Config.modificationPeriodCoeff = NR_BCCH_Config__modificationPeriodCoeff_n2; + ServCellCom->downlinkConfigCommon.pcch_Config.defaultPagingCycle = NR_PagingCycle_rf256; + ServCellCom->downlinkConfigCommon.pcch_Config.nAndPagingFrameOffset.present = NR_PCCH_Config__nAndPagingFrameOffset_PR_quarterT; + ServCellCom->downlinkConfigCommon.pcch_Config.nAndPagingFrameOffset.choice.quarterT = 1; + ServCellCom->downlinkConfigCommon.pcch_Config.ns = NR_PCCH_Config__ns_one; + + asn1cCalloc(ServCellCom->downlinkConfigCommon.pcch_Config.firstPDCCH_MonitoringOccasionOfPO, P0); + P0->present = NR_PCCH_Config__firstPDCCH_MonitoringOccasionOfPO_PR_sCS120KHZoneT_SCS60KHZhalfT_SCS30KHZquarterT_SCS15KHZoneEighthT; + + asn1cCalloc(P0->choice.sCS120KHZoneT_SCS60KHZhalfT_SCS30KHZquarterT_SCS15KHZoneEighthT, Z8); + asn1cSequenceAdd(Z8->list, long, ZoneEight); + asn1cCallocOne(ZoneEight, 0); + + asn1cCalloc(ServCellCom->uplinkConfigCommon, UL); + asn_set_empty(&UL->frequencyInfoUL.scs_SpecificCarrierList.list); + const NR_FrequencyInfoUL_t *frequencyInfoUL = configuration->scc->uplinkConfigCommon->frequencyInfoUL; + for (int i = 0; i < frequencyInfoUL->scs_SpecificCarrierList.list.count; i++) { + asn1cSeqAdd(&UL->frequencyInfoUL.scs_SpecificCarrierList.list, frequencyInfoUL->scs_SpecificCarrierList.list.array[i]); + } + + asn1cCallocOne(UL->frequencyInfoUL.p_Max, *frequencyInfoUL->p_Max); + + UL->initialUplinkBWP.genericParameters = configuration->scc->uplinkConfigCommon->initialUplinkBWP->genericParameters; + UL->initialUplinkBWP.rach_ConfigCommon = configuration->scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon; + UL->initialUplinkBWP.pusch_ConfigCommon = configuration->scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon; + UL->initialUplinkBWP.pusch_ConfigCommon->choice.setup->groupHoppingEnabledTransformPrecoding = NULL; + + UL->initialUplinkBWP.pucch_ConfigCommon = configuration->scc->uplinkConfigCommon->initialUplinkBWP->pucch_ConfigCommon; + + UL->timeAlignmentTimerCommon = NR_TimeAlignmentTimer_infinity; + + ServCellCom->n_TimingAdvanceOffset = configuration->scc->n_TimingAdvanceOffset; + + ServCellCom->ssb_PositionsInBurst.inOneGroup.buf = calloc(1, sizeof(uint8_t)); + uint8_t bitmap8,temp_bitmap=0; + switch (configuration->scc->ssb_PositionsInBurst->present) { + case NR_ServingCellConfigCommon__ssb_PositionsInBurst_PR_shortBitmap: + ServCellCom->ssb_PositionsInBurst.inOneGroup = configuration->scc->ssb_PositionsInBurst->choice.shortBitmap; + break; + case NR_ServingCellConfigCommon__ssb_PositionsInBurst_PR_mediumBitmap: + ServCellCom->ssb_PositionsInBurst.inOneGroup = configuration->scc->ssb_PositionsInBurst->choice.mediumBitmap; + break; + /* + * groupPresence: This field is present when maximum number of SS/PBCH blocks per half frame equals to 64 as defined in + * TS 38.213 [13], clause 4.1. The first/leftmost bit corresponds to the SS/PBCH index 0-7, the second bit corresponds to + * SS/PBCH block 8-15, and so on. Value 0 in the bitmap indicates that the SSBs according to inOneGroup are absent. Value 1 + * indicates that the SS/PBCH blocks are transmitted in accordance with inOneGroup. inOneGroup: When maximum number of SS/PBCH + * blocks per half frame equals to 64 as defined in TS 38.213 [13], clause 4.1, all 8 bit are valid; The first/ leftmost bit + * corresponds to the first SS/PBCH block index in the group (i.e., to SSB index 0, 8, and so on); the second bit corresponds to + * the second SS/PBCH block index in the group (i.e., to SSB index 1, 9, and so on), and so on. Value 0 in the bitmap indicates + * that the corresponding SS/PBCH block is not transmitted while value 1 indicates that the corresponding SS/PBCH block is + * transmitted. + */ + case NR_ServingCellConfigCommon__ssb_PositionsInBurst_PR_longBitmap: + ServCellCom->ssb_PositionsInBurst.inOneGroup.size = 1; + ServCellCom->ssb_PositionsInBurst.inOneGroup.bits_unused = 0; + ServCellCom->ssb_PositionsInBurst.groupPresence = calloc(1, sizeof(BIT_STRING_t)); + AssertFatal(ServCellCom->ssb_PositionsInBurst.groupPresence != NULL, "out of memory\n"); + ServCellCom->ssb_PositionsInBurst.groupPresence->size = 1; + ServCellCom->ssb_PositionsInBurst.groupPresence->bits_unused = 0; + ServCellCom->ssb_PositionsInBurst.groupPresence->buf = calloc(1, sizeof(uint8_t)); + AssertFatal(ServCellCom->ssb_PositionsInBurst.groupPresence->buf != NULL, "out of memory\n"); + ServCellCom->ssb_PositionsInBurst.groupPresence->buf[0] = 0; + for (int i = 0; i < 8; i++) { + bitmap8 = configuration->scc->ssb_PositionsInBurst->choice.longBitmap.buf[i]; + if (bitmap8 != 0) { + if (temp_bitmap == 0) + temp_bitmap = bitmap8; + else + AssertFatal(temp_bitmap == bitmap8, + "For longBitmap the groups of 8 SSBs containing at least 1 transmitted SSB should be all the same\n"); + + ServCellCom->ssb_PositionsInBurst.inOneGroup.buf[0] = bitmap8; + ServCellCom->ssb_PositionsInBurst.groupPresence->buf[0] |= 1<<(7-i); + } + } + break; + default: + AssertFatal(false, "ssb_PositionsInBurst not present\n"); + break; + } + + ServCellCom->ssb_PeriodicityServingCell = *configuration->scc->ssb_periodicityServingCell; + if (configuration->scc->tdd_UL_DL_ConfigurationCommon) { + ServCellCom->tdd_UL_DL_ConfigurationCommon = CALLOC(1,sizeof(struct NR_TDD_UL_DL_ConfigCommon)); + AssertFatal(ServCellCom->tdd_UL_DL_ConfigurationCommon != NULL, "out of memory\n"); + ServCellCom->tdd_UL_DL_ConfigurationCommon->referenceSubcarrierSpacing = configuration->scc->tdd_UL_DL_ConfigurationCommon->referenceSubcarrierSpacing; + ServCellCom->tdd_UL_DL_ConfigurationCommon->pattern1 = configuration->scc->tdd_UL_DL_ConfigurationCommon->pattern1; + ServCellCom->tdd_UL_DL_ConfigurationCommon->pattern2 = configuration->scc->tdd_UL_DL_ConfigurationCommon->pattern2; + } + ServCellCom->ss_PBCH_BlockPower = configuration->scc->ss_PBCH_BlockPower; + + // ims-EmergencySupport + // TODO: add ims-EmergencySupport + + // eCallOverIMS-Support + // TODO: add eCallOverIMS-Support + + // ue-TimersAndConstants + sib1->ue_TimersAndConstants = CALLOC(1,sizeof(struct NR_UE_TimersAndConstants)); + AssertFatal(sib1->ue_TimersAndConstants != NULL, "out of memory\n"); + sib1->ue_TimersAndConstants->t300 = NR_UE_TimersAndConstants__t300_ms400; + sib1->ue_TimersAndConstants->t301 = NR_UE_TimersAndConstants__t301_ms400; + sib1->ue_TimersAndConstants->t310 = NR_UE_TimersAndConstants__t310_ms2000; + sib1->ue_TimersAndConstants->n310 = NR_UE_TimersAndConstants__n310_n10; + sib1->ue_TimersAndConstants->t311 = NR_UE_TimersAndConstants__t311_ms3000; + sib1->ue_TimersAndConstants->n311 = NR_UE_TimersAndConstants__n311_n1; + sib1->ue_TimersAndConstants->t319 = NR_UE_TimersAndConstants__t319_ms400; + + // uac-BarringInfo + /*sib1->uac_BarringInfo = CALLOC(1, sizeof(struct NR_SIB1__uac_BarringInfo)); + NR_UAC_BarringInfoSet_t *nr_uac_BarringInfoSet = CALLOC(1, sizeof(NR_UAC_BarringInfoSet_t)); + asn_set_empty(&sib1->uac_BarringInfo->uac_BarringInfoSetList); + nr_uac_BarringInfoSet->uac_BarringFactor = NR_UAC_BarringInfoSet__uac_BarringFactor_p95; + nr_uac_BarringInfoSet->uac_BarringTime = NR_UAC_BarringInfoSet__uac_BarringTime_s4; + nr_uac_BarringInfoSet->uac_BarringForAccessIdentity.buf = CALLOC(1, 1); + nr_uac_BarringInfoSet->uac_BarringForAccessIdentity.size = 1; + nr_uac_BarringInfoSet->uac_BarringForAccessIdentity.bits_unused = 1; + asn1cSeqAdd(&sib1->uac_BarringInfo->uac_BarringInfoSetList, nr_uac_BarringInfoSet);*/ + + // useFullResumeID + // TODO: add useFullResumeID + + // lateNonCriticalExtension + // TODO: add lateNonCriticalExtension + + // nonCriticalExtension + // TODO: add nonCriticalExtension + + //xer_fprint(stdout, &asn_DEF_NR_SIB1, (const void*)sib1_message->message.choice.c1->choice.systemInformationBlockType1); + return sib1_message; +} + +void free_SIB1_NR(NR_BCCH_DL_SCH_Message_t *sib1) +{ + ASN_STRUCT_FREE(asn_DEF_NR_BCCH_DL_SCH_Message, sib1); +} + +int encode_SIB1_NR(NR_BCCH_DL_SCH_Message_t *sib1, uint8_t *buffer, int max_buffer_size) +{ + AssertFatal(max_buffer_size <= NR_MAX_SIB_LENGTH / 8, + "%s(): maximum buffer size too large: 3GPP TS 38.331 section 5.2.1 - The physical layer imposes a limit to the " + "maximum size a SIB can take. The maximum SIB1 or SI message size is 2976 bits.\n", + __func__); + asn_enc_rval_t enc_rval = uper_encode_to_buffer(&asn_DEF_NR_BCCH_DL_SCH_Message, NULL, sib1, buffer, max_buffer_size); + AssertFatal(enc_rval.encoded > 0 && enc_rval.encoded <= max_buffer_size * 8, "ASN1 message encoding failed (%s, %lu)!\n", enc_rval.failed_type->name, enc_rval.encoded); + return (enc_rval.encoded + 7) / 8; +} diff --git a/openair2/RRC/NR/nr_rrc_config.h b/openair2/RRC/NR/nr_rrc_config.h index 095ba716be..df6047d61e 100644 --- a/openair2/RRC/NR/nr_rrc_config.h +++ b/openair2/RRC/NR/nr_rrc_config.h @@ -109,4 +109,10 @@ NR_BCCH_BCH_Message_t *get_new_MIB_NR(const NR_ServingCellConfigCommon_t *scc); void free_MIB_NR(NR_BCCH_BCH_Message_t *mib); int encode_MIB_NR(NR_BCCH_BCH_Message_t *mib, int frame, uint8_t *buf, int buf_size); + +#define NR_MAX_SIB_LENGTH 2976 // 3GPP TS 38.331 section 5.2.1 +NR_BCCH_DL_SCH_Message_t *get_SIB1_NR(const gNB_RrcConfigurationReq *configuration); +void free_SIB1_NR(NR_BCCH_DL_SCH_Message_t *sib1); +int encode_SIB1_NR(NR_BCCH_DL_SCH_Message_t *sib1, uint8_t *buffer, int max_buffer_size); + #endif diff --git a/openair2/RRC/NR/nr_rrc_extern.h b/openair2/RRC/NR/nr_rrc_extern.h index 34041b8a88..3cbda2e802 100644 --- a/openair2/RRC/NR/nr_rrc_extern.h +++ b/openair2/RRC/NR/nr_rrc_extern.h @@ -35,8 +35,6 @@ #include "LAYER2/RLC/rlc.h" #include "openair2/RRC/common.h" -#define NR_MAX_SIB_LENGTH 2976 // 3GPP TS 38.331 section 5.2.1 - The physical layer imposes a limit to the maximum size a SIB can take. The maximum SIB1 or SI message size is 2976 bits. - extern UE_RRC_INST *UE_rrc_inst; extern uint8_t DRB2LCHAN[8]; diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index 524befd70c..a3dd0891f5 100644 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -181,7 +181,12 @@ static void init_NR_SI(gNB_RRC_INST *rrc, gNB_RrcConfigurationReq *configuration rrc->carrier.mib = get_new_MIB_NR(rrc->carrier.servingcellconfigcommon); if((get_softmodem_params()->sa) && ( (NODE_IS_DU(rrc->node_type) || NODE_IS_MONOLITHIC(rrc->node_type)))) { - rrc->carrier.sizeof_SIB1 = do_SIB1_NR(&rrc->carrier,configuration); + NR_BCCH_DL_SCH_Message_t *sib1 = get_SIB1_NR(configuration); + rrc->carrier.SIB1 = calloc(NR_MAX_SIB_LENGTH / 8, sizeof(*rrc->carrier.SIB1)); + AssertFatal(rrc->carrier.SIB1 != NULL, "out of memory\n"); + rrc->carrier.sizeof_SIB1 = encode_SIB1_NR(sib1, rrc->carrier.SIB1, NR_MAX_SIB_LENGTH / 8); + rrc->carrier.siblock1 = sib1; + nr_mac_config_sib1(RC.nrmac[rrc->module_id], sib1); } if (!NODE_IS_DU(rrc->node_type)) { @@ -203,8 +208,6 @@ static void init_NR_SI(gNB_RRC_INST *rrc, gNB_RrcConfigurationReq *configuration rrc->configuration.minRXTXTIME, rrc->carrier.servingcellconfigcommon); nr_mac_config_mib(RC.nrmac[rrc->module_id], rrc->carrier.mib); - if (get_softmodem_params()->sa) - nr_mac_config_sib1(RC.nrmac[rrc->module_id], rrc->carrier.siblock1); } /* set flag to indicate that cell information is configured. This is required