Refactor SIB1 handling
This commit is contained in:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user