Refactor SIB1 handling
This commit is contained in:
@@ -38,7 +38,7 @@
|
|||||||
#include "common/utils/LOG/log.h"
|
#include "common/utils/LOG/log.h"
|
||||||
#include "common/utils/LOG/vcd_signal_dumper.h"
|
#include "common/utils/LOG/vcd_signal_dumper.h"
|
||||||
#include "UTIL/OPT/opt.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"
|
#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;
|
return encode_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO BCCH SIB1 SIBs
|
|
||||||
if ((Srb_id & RAB_OFFSET) == BCCH) {
|
if ((Srb_id & RAB_OFFSET) == BCCH) {
|
||||||
memcpy(&buffer_pP[0], RC.nrrrc[Mod_idP]->carrier.SIB1, RC.nrrrc[Mod_idP]->carrier.sizeof_SIB1);
|
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;
|
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,
|
uint8_t do_SIB23_NR(rrc_gNB_carrier_data_t *carrier,
|
||||||
gNB_RrcConfigurationReq *configuration) {
|
gNB_RrcConfigurationReq *configuration) {
|
||||||
asn_enc_rval_t enc_rval;
|
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);
|
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,
|
uint8_t do_SIB23_NR(rrc_gNB_carrier_data_t *carrier,
|
||||||
gNB_RrcConfigurationReq *configuration);
|
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);
|
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;
|
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);
|
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);
|
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
|
#endif
|
||||||
|
|||||||
@@ -35,8 +35,6 @@
|
|||||||
#include "LAYER2/RLC/rlc.h"
|
#include "LAYER2/RLC/rlc.h"
|
||||||
#include "openair2/RRC/common.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 UE_RRC_INST *UE_rrc_inst;
|
||||||
|
|
||||||
extern uint8_t DRB2LCHAN[8];
|
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);
|
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)))) {
|
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)) {
|
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->configuration.minRXTXTIME,
|
||||||
rrc->carrier.servingcellconfigcommon);
|
rrc->carrier.servingcellconfigcommon);
|
||||||
nr_mac_config_mib(RC.nrmac[rrc->module_id], rrc->carrier.mib);
|
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
|
/* set flag to indicate that cell information is configured. This is required
|
||||||
|
|||||||
Reference in New Issue
Block a user