Commit 88e6d9df authored by Robert Schmidt's avatar Robert Schmidt

Refactor SIB1 handling

parent 7cb50288
......@@ -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"
......
......@@ -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;
......
......@@ -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;
......
......@@ -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);
......
......@@ -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;
}
......@@ -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
......@@ -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];
......
......@@ -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
......
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