Files
openairinterface5g/openair2/RRC/NR/MESSAGES/asn1_msg.c
T
2023-05-26 12:35:33 +02:00

1393 lines
70 KiB
C

/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file asn1_msg.c
* \brief primitives to build the asn1 messages
* \author Raymond Knopp and Navid Nikaein, WEI-TAI CHEN
* \date 2011, 2018
* \version 1.0
* \company Eurecom, NTUST
* \email: {raymond.knopp, navid.nikaein}@eurecom.fr and kroempa@gmail.com
*/
#include <stdio.h>
#include <sys/types.h>
#include <stdlib.h> /* for atoi(3) */
#include <unistd.h> /* for getopt(3) */
#include <string.h> /* for strerror(3) */
#include <sysexits.h> /* for EX_* exit codes */
#include <errno.h> /* for errno */
#include "common/utils/LOG/log.h"
#include "oai_asn1.h"
#include <asn_application.h>
#include <per_encoder.h>
#include <nr/nr_common.h>
#include <softmodem-common.h>
#include "executables/softmodem-common.h"
#include "LAYER2/nr_rlc/nr_rlc_oai_api.h"
#include "asn1_msg.h"
#include "../nr_rrc_proto.h"
#include "openair3/SECU/key_nas_deriver.h"
#include "RRC/NR/nr_rrc_extern.h"
#include "NR_DL-CCCH-Message.h"
#include "NR_UL-CCCH-Message.h"
#include "NR_DL-DCCH-Message.h"
#include "NR_RRCReject.h"
#include "NR_RejectWaitTime.h"
#include "NR_RRCSetup.h"
#include "NR_RRCSetup-IEs.h"
#include "NR_SRB-ToAddModList.h"
#include "NR_CellGroupConfig.h"
#include "NR_RLC-BearerConfig.h"
#include "NR_RLC-Config.h"
#include "NR_LogicalChannelConfig.h"
#include "NR_PDCP-Config.h"
#include "NR_MAC-CellGroupConfig.h"
#include "NR_SecurityModeCommand.h"
#include "NR_CipheringAlgorithm.h"
#include "NR_RRCReconfiguration-IEs.h"
#include "NR_DRB-ToAddMod.h"
#include "NR_DRB-ToAddModList.h"
#include "NR_SecurityConfig.h"
#include "NR_RRCReconfiguration-v1530-IEs.h"
#include "NR_UL-DCCH-Message.h"
#include "NR_SDAP-Config.h"
#include "NR_RRCReconfigurationComplete.h"
#include "NR_RRCReconfigurationComplete-IEs.h"
#include "NR_DLInformationTransfer.h"
#include "NR_RRCReestablishmentRequest.h"
#include "NR_PCCH-Message.h"
#include "NR_PagingRecord.h"
#include "NR_UE-CapabilityRequestFilterNR.h"
#include "common/utils/nr/nr_common.h"
#if defined(NR_Rel16)
#include "NR_SCS-SpecificCarrier.h"
#include "NR_TDD-UL-DL-ConfigCommon.h"
#include "NR_FrequencyInfoUL.h"
#include "NR_FrequencyInfoDL.h"
#include "NR_RACH-ConfigGeneric.h"
#include "NR_RACH-ConfigCommon.h"
#include "NR_PUSCH-TimeDomainResourceAllocation.h"
#include "NR_PUSCH-ConfigCommon.h"
#include "NR_PUCCH-ConfigCommon.h"
#include "NR_PDSCH-TimeDomainResourceAllocation.h"
#include "NR_PDSCH-ConfigCommon.h"
#include "NR_RateMatchPattern.h"
#include "NR_RateMatchPatternLTE-CRS.h"
#include "NR_SearchSpace.h"
#include "NR_ControlResourceSet.h"
#include "NR_EUTRA-MBSFN-SubframeConfig.h"
#include "NR_BWP-DownlinkCommon.h"
#include "NR_BWP-DownlinkDedicated.h"
#include "NR_UplinkConfigCommon.h"
#include "NR_SetupRelease.h"
#include "NR_PDCCH-ConfigCommon.h"
#include "NR_BWP-UplinkCommon.h"
#include "assertions.h"
//#include "RRCConnectionRequest.h"
//#include "UL-CCCH-Message.h"
#include "NR_UL-DCCH-Message.h"
//#include "DL-CCCH-Message.h"
#include "NR_DL-DCCH-Message.h"
//#include "EstablishmentCause.h"
//#include "RRCConnectionSetup.h"
#include "NR_SRB-ToAddModList.h"
#include "NR_DRB-ToAddModList.h"
//#include "MCCH-Message.h"
//#define MRB1 1
//#include "RRCConnectionSetupComplete.h"
//#include "RRCConnectionReconfigurationComplete.h"
//#include "RRCConnectionReconfiguration.h"
#include "NR_MIB.h"
//#include "SystemInformation.h"
#include "NR_SIB1.h"
#include "NR_ServingCellConfigCommon.h"
//#include "SIB-Type.h"
//#include "BCCH-DL-SCH-Message.h"
//#include "PHY/defs.h"
#include "NR_MeasObjectToAddModList.h"
#include "NR_ReportConfigToAddModList.h"
#include "NR_MeasIdToAddModList.h"
#include "gnb_config.h"
#endif
#include "intertask_interface.h"
#include "common/ran_context.h"
#include "conversions.h"
//#define XER_PRINT
typedef struct xer_sprint_string_s {
char *string;
size_t string_size;
size_t string_index;
} xer_sprint_string_t;
extern RAN_CONTEXT_t RC;
/*
* This is a helper function for xer_sprint, which directs all incoming data
* into the provided string.
*/
static int xer__nr_print2s (const void *buffer, size_t size, void *app_key) {
xer_sprint_string_t *string_buffer = (xer_sprint_string_t *) app_key;
size_t string_remaining = string_buffer->string_size - string_buffer->string_index;
if (string_remaining > 0) {
if (size > string_remaining) {
size = string_remaining;
}
memcpy(&string_buffer->string[string_buffer->string_index], buffer, size);
string_buffer->string_index += size;
}
return 0;
}
int xer_nr_sprint (char *string, size_t string_size, asn_TYPE_descriptor_t *td, void *sptr) {
asn_enc_rval_t er;
xer_sprint_string_t string_buffer;
string_buffer.string = string;
string_buffer.string_size = string_size;
string_buffer.string_index = 0;
er = xer_encode(td, sptr, XER_F_BASIC, xer__nr_print2s, &string_buffer);
if (er.encoded < 0) {
LOG_E(RRC, "xer_sprint encoding error (%zd)!", er.encoded);
er.encoded = string_buffer.string_size;
} else {
if (er.encoded > string_buffer.string_size) {
LOG_E(RRC, "xer_sprint string buffer too small, got %zd need %zd!", string_buffer.string_size, er.encoded);
er.encoded = string_buffer.string_size;
}
}
return er.encoded;
}
//------------------------------------------------------------------------------
uint8_t do_SIB23_NR(rrc_gNB_carrier_data_t *carrier,
gNB_RrcConfigurationReq *configuration) {
asn_enc_rval_t enc_rval;
SystemInformation_IEs__sib_TypeAndInfo__Member *sib2 = NULL;
SystemInformation_IEs__sib_TypeAndInfo__Member *sib3 = NULL;
NR_BCCH_DL_SCH_Message_t *sib_message = CALLOC(1,sizeof(NR_BCCH_DL_SCH_Message_t));
sib_message->message.present = NR_BCCH_DL_SCH_MessageType_PR_c1;
sib_message->message.choice.c1 = CALLOC(1,sizeof(struct NR_BCCH_DL_SCH_MessageType__c1));
sib_message->message.choice.c1->present = NR_BCCH_DL_SCH_MessageType__c1_PR_systemInformation;
sib_message->message.choice.c1->choice.systemInformation = CALLOC(1,sizeof(struct NR_SystemInformation));
struct NR_SystemInformation *sib = sib_message->message.choice.c1->choice.systemInformation;
sib->criticalExtensions.present = NR_SystemInformation__criticalExtensions_PR_systemInformation;
sib->criticalExtensions.choice.systemInformation = CALLOC(1, sizeof(struct NR_SystemInformation_IEs));
struct NR_SystemInformation_IEs *ies = sib->criticalExtensions.choice.systemInformation;
sib2 = CALLOC(1, sizeof(SystemInformation_IEs__sib_TypeAndInfo__Member));
sib2->present = NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib2;
sib2->choice.sib2 = CALLOC(1, sizeof(struct NR_SIB2));
sib2->choice.sib2->cellReselectionInfoCommon.q_Hyst = NR_SIB2__cellReselectionInfoCommon__q_Hyst_dB1;
sib2->choice.sib2->cellReselectionServingFreqInfo.threshServingLowP = 2; // INTEGER (0..31)
sib2->choice.sib2->cellReselectionServingFreqInfo.cellReselectionPriority = 2; // INTEGER (0..7)
sib2->choice.sib2->intraFreqCellReselectionInfo.q_RxLevMin = -50; // INTEGER (-70..-22)
sib2->choice.sib2->intraFreqCellReselectionInfo.s_IntraSearchP = 2; // INTEGER (0..31)
sib2->choice.sib2->intraFreqCellReselectionInfo.t_ReselectionNR = 2; // INTEGER (0..7)
sib2->choice.sib2->intraFreqCellReselectionInfo.deriveSSB_IndexFromCell = true;
asn1cSeqAdd(&ies->sib_TypeAndInfo.list, sib2);
sib3 = CALLOC(1, sizeof(SystemInformation_IEs__sib_TypeAndInfo__Member));
sib3->present = NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib3;
sib3->choice.sib3 = CALLOC(1, sizeof(struct NR_SIB3));
asn1cSeqAdd(&ies->sib_TypeAndInfo.list, sib3);
//encode SIB to data
// carrier->SIB23 = (uint8_t *) malloc16(128);
enc_rval = uper_encode_to_buffer(&asn_DEF_NR_BCCH_DL_SCH_Message,
NULL,
(void *)sib_message,
carrier->SIB23,
100);
AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n",
enc_rval.failed_type->name, enc_rval.encoded);
return((enc_rval.encoded+7)/8);
}
void do_SpCellConfig(gNB_RRC_INST *rrc,
struct NR_SpCellConfig *spconfig){
//gNB_RrcConfigurationReq *common_configuration;
//common_configuration = CALLOC(1,sizeof(gNB_RrcConfigurationReq));
//Fill servingcellconfigcommon config value
//Fill common config to structure
// rrc->configuration = common_configuration;
spconfig->reconfigurationWithSync = CALLOC(1,sizeof(struct NR_ReconfigurationWithSync));
}
//------------------------------------------------------------------------------
int do_RRCReject(uint8_t Mod_id,
uint8_t *const buffer)
//------------------------------------------------------------------------------
{
asn_enc_rval_t enc_rval;
NR_DL_CCCH_Message_t dl_ccch_msg;
NR_RRCReject_t *rrcReject;
NR_RejectWaitTime_t waitTime = 1;
memset((void *)&dl_ccch_msg, 0, sizeof(NR_DL_CCCH_Message_t));
dl_ccch_msg.message.present = NR_DL_CCCH_MessageType_PR_c1;
dl_ccch_msg.message.choice.c1 = CALLOC(1, sizeof(struct NR_DL_CCCH_MessageType__c1));
dl_ccch_msg.message.choice.c1->present = NR_DL_CCCH_MessageType__c1_PR_rrcReject;
dl_ccch_msg.message.choice.c1->choice.rrcReject = CALLOC(1,sizeof(NR_RRCReject_t));
rrcReject = dl_ccch_msg.message.choice.c1->choice.rrcReject;
rrcReject->criticalExtensions.choice.rrcReject = CALLOC(1, sizeof(struct NR_RRCReject_IEs));
rrcReject->criticalExtensions.choice.rrcReject->waitTime = CALLOC(1, sizeof(NR_RejectWaitTime_t));
rrcReject->criticalExtensions.present = NR_RRCReject__criticalExtensions_PR_rrcReject;
rrcReject->criticalExtensions.choice.rrcReject->waitTime = &waitTime;
if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) {
xer_fprint(stdout, &asn_DEF_NR_DL_CCCH_Message, (void *)&dl_ccch_msg);
}
enc_rval = uper_encode_to_buffer(&asn_DEF_NR_DL_CCCH_Message,
NULL,
(void *)&dl_ccch_msg,
buffer,
100);
AssertFatal(enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n",
enc_rval.failed_type->name, enc_rval.encoded);
LOG_D(NR_RRC,"RRCReject Encoded %zd bits (%zd bytes)\n",
enc_rval.encoded,(enc_rval.encoded+7)/8);
return (enc_rval.encoded + 7) / 8;
}
NR_RLC_BearerConfig_t *get_SRB_RLC_BearerConfig(long channelId,
long priority,
e_NR_LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration bucketSizeDuration)
{
NR_RLC_BearerConfig_t *rlc_BearerConfig = NULL;
rlc_BearerConfig = calloc(1, sizeof(NR_RLC_BearerConfig_t));
rlc_BearerConfig->logicalChannelIdentity = channelId;
rlc_BearerConfig->servedRadioBearer = calloc(1, sizeof(*rlc_BearerConfig->servedRadioBearer));
rlc_BearerConfig->servedRadioBearer->present = NR_RLC_BearerConfig__servedRadioBearer_PR_srb_Identity;
rlc_BearerConfig->servedRadioBearer->choice.srb_Identity = channelId;
rlc_BearerConfig->reestablishRLC = NULL;
NR_RLC_Config_t *rlc_Config = calloc(1, sizeof(NR_RLC_Config_t));
rlc_Config->present = NR_RLC_Config_PR_am;
rlc_Config->choice.am = calloc(1, sizeof(*rlc_Config->choice.am));
rlc_Config->choice.am->dl_AM_RLC.sn_FieldLength = calloc(1, sizeof(NR_SN_FieldLengthAM_t));
*(rlc_Config->choice.am->dl_AM_RLC.sn_FieldLength) = NR_SN_FieldLengthAM_size12;
rlc_Config->choice.am->dl_AM_RLC.t_Reassembly = NR_T_Reassembly_ms35;
rlc_Config->choice.am->dl_AM_RLC.t_StatusProhibit = NR_T_StatusProhibit_ms0;
rlc_Config->choice.am->ul_AM_RLC.sn_FieldLength = calloc(1, sizeof(NR_SN_FieldLengthAM_t));
*(rlc_Config->choice.am->ul_AM_RLC.sn_FieldLength) = NR_SN_FieldLengthAM_size12;
rlc_Config->choice.am->ul_AM_RLC.t_PollRetransmit = NR_T_PollRetransmit_ms45;
rlc_Config->choice.am->ul_AM_RLC.pollPDU = NR_PollPDU_infinity;
rlc_Config->choice.am->ul_AM_RLC.pollByte = NR_PollByte_infinity;
rlc_Config->choice.am->ul_AM_RLC.maxRetxThreshold = NR_UL_AM_RLC__maxRetxThreshold_t8;
rlc_BearerConfig->rlc_Config = rlc_Config;
NR_LogicalChannelConfig_t *logicalChannelConfig = calloc(1, sizeof(NR_LogicalChannelConfig_t));
logicalChannelConfig->ul_SpecificParameters = calloc(1, sizeof(*logicalChannelConfig->ul_SpecificParameters));
logicalChannelConfig->ul_SpecificParameters->priority = priority;
logicalChannelConfig->ul_SpecificParameters->prioritisedBitRate = NR_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity;
logicalChannelConfig->ul_SpecificParameters->bucketSizeDuration = bucketSizeDuration;
long *logicalChannelGroup = CALLOC(1, sizeof(long));
*logicalChannelGroup = 0;
logicalChannelConfig->ul_SpecificParameters->logicalChannelGroup = logicalChannelGroup;
logicalChannelConfig->ul_SpecificParameters->schedulingRequestID = CALLOC(1, sizeof(*logicalChannelConfig->ul_SpecificParameters->schedulingRequestID));
*logicalChannelConfig->ul_SpecificParameters->schedulingRequestID = 0;
logicalChannelConfig->ul_SpecificParameters->logicalChannelSR_Mask = 0;
logicalChannelConfig->ul_SpecificParameters->logicalChannelSR_DelayTimerApplied = 0;
rlc_BearerConfig->mac_LogicalChannelConfig = logicalChannelConfig;
return rlc_BearerConfig;
}
static void nr_drb_config(struct NR_RLC_Config *rlc_Config, NR_RLC_Config_PR rlc_config_pr)
{
switch (rlc_config_pr) {
case NR_RLC_Config_PR_um_Bi_Directional:
// RLC UM Bi-directional Bearer configuration
LOG_I(RLC, "RLC UM Bi-directional Bearer configuration selected \n");
rlc_Config->choice.um_Bi_Directional = calloc(1, sizeof(*rlc_Config->choice.um_Bi_Directional));
rlc_Config->choice.um_Bi_Directional->ul_UM_RLC.sn_FieldLength =
calloc(1, sizeof(*rlc_Config->choice.um_Bi_Directional->ul_UM_RLC.sn_FieldLength));
*rlc_Config->choice.um_Bi_Directional->ul_UM_RLC.sn_FieldLength = NR_SN_FieldLengthUM_size12;
rlc_Config->choice.um_Bi_Directional->dl_UM_RLC.sn_FieldLength =
calloc(1, sizeof(*rlc_Config->choice.um_Bi_Directional->dl_UM_RLC.sn_FieldLength));
*rlc_Config->choice.um_Bi_Directional->dl_UM_RLC.sn_FieldLength = NR_SN_FieldLengthUM_size12;
rlc_Config->choice.um_Bi_Directional->dl_UM_RLC.t_Reassembly = NR_T_Reassembly_ms15;
break;
case NR_RLC_Config_PR_am:
// RLC AM Bearer configuration
rlc_Config->choice.am = calloc(1, sizeof(*rlc_Config->choice.am));
rlc_Config->choice.am->ul_AM_RLC.sn_FieldLength = calloc(1, sizeof(*rlc_Config->choice.am->ul_AM_RLC.sn_FieldLength));
*rlc_Config->choice.am->ul_AM_RLC.sn_FieldLength = NR_SN_FieldLengthAM_size18;
rlc_Config->choice.am->ul_AM_RLC.t_PollRetransmit = NR_T_PollRetransmit_ms45;
rlc_Config->choice.am->ul_AM_RLC.pollPDU = NR_PollPDU_p64;
rlc_Config->choice.am->ul_AM_RLC.pollByte = NR_PollByte_kB500;
rlc_Config->choice.am->ul_AM_RLC.maxRetxThreshold = NR_UL_AM_RLC__maxRetxThreshold_t32;
rlc_Config->choice.am->dl_AM_RLC.sn_FieldLength = calloc(1, sizeof(*rlc_Config->choice.am->dl_AM_RLC.sn_FieldLength));
*rlc_Config->choice.am->dl_AM_RLC.sn_FieldLength = NR_SN_FieldLengthAM_size18;
rlc_Config->choice.am->dl_AM_RLC.t_Reassembly = NR_T_Reassembly_ms15;
rlc_Config->choice.am->dl_AM_RLC.t_StatusProhibit = NR_T_StatusProhibit_ms15;
break;
default:
AssertFatal(false, "RLC config type %d not handled\n", rlc_config_pr);
break;
}
rlc_Config->present = rlc_config_pr;
}
NR_RLC_BearerConfig_t *get_DRB_RLC_BearerConfig(long lcChannelId, long drbId, NR_RLC_Config_PR rlc_conf, long priority)
{
NR_RLC_BearerConfig_t *rlc_BearerConfig = calloc(1, sizeof(NR_RLC_BearerConfig_t));
rlc_BearerConfig->logicalChannelIdentity = lcChannelId;
rlc_BearerConfig->servedRadioBearer = calloc(1, sizeof(*rlc_BearerConfig->servedRadioBearer));
rlc_BearerConfig->servedRadioBearer->present = NR_RLC_BearerConfig__servedRadioBearer_PR_drb_Identity;
rlc_BearerConfig->servedRadioBearer->choice.drb_Identity = drbId;
rlc_BearerConfig->reestablishRLC = NULL;
NR_RLC_Config_t *rlc_Config = calloc(1, sizeof(NR_RLC_Config_t));
nr_drb_config(rlc_Config, rlc_conf);
rlc_BearerConfig->rlc_Config = rlc_Config;
NR_LogicalChannelConfig_t *logicalChannelConfig = calloc(1, sizeof(NR_LogicalChannelConfig_t));
logicalChannelConfig->ul_SpecificParameters = calloc(1, sizeof(*logicalChannelConfig->ul_SpecificParameters));
logicalChannelConfig->ul_SpecificParameters->priority = priority;
logicalChannelConfig->ul_SpecificParameters->prioritisedBitRate = NR_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_kBps8;
logicalChannelConfig->ul_SpecificParameters->bucketSizeDuration = NR_LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms100;
long *logicalChannelGroup = CALLOC(1, sizeof(long));
*logicalChannelGroup = 1;
logicalChannelConfig->ul_SpecificParameters->logicalChannelGroup = logicalChannelGroup;
logicalChannelConfig->ul_SpecificParameters->schedulingRequestID = CALLOC(1, sizeof(*logicalChannelConfig->ul_SpecificParameters->schedulingRequestID));
*logicalChannelConfig->ul_SpecificParameters->schedulingRequestID = 0;
logicalChannelConfig->ul_SpecificParameters->logicalChannelSR_Mask = 0;
logicalChannelConfig->ul_SpecificParameters->logicalChannelSR_DelayTimerApplied = 0;
rlc_BearerConfig->mac_LogicalChannelConfig = logicalChannelConfig;
return rlc_BearerConfig;
}
/* returns a default radio bearer config suitable for NSA etc */
NR_RadioBearerConfig_t *get_default_rbconfig(int eps_bearer_id,
int rb_id,
e_NR_CipheringAlgorithm ciphering_algorithm,
e_NR_SecurityConfig__keyToUse key_to_use)
{
NR_RadioBearerConfig_t *rbconfig = calloc(1, sizeof(*rbconfig));
rbconfig->srb_ToAddModList = NULL;
rbconfig->srb3_ToRelease = NULL;
rbconfig->drb_ToAddModList = calloc(1,sizeof(*rbconfig->drb_ToAddModList));
NR_DRB_ToAddMod_t *drb_ToAddMod = calloc(1,sizeof(*drb_ToAddMod));
drb_ToAddMod->cnAssociation = calloc(1,sizeof(*drb_ToAddMod->cnAssociation));
drb_ToAddMod->cnAssociation->present = NR_DRB_ToAddMod__cnAssociation_PR_eps_BearerIdentity;
drb_ToAddMod->cnAssociation->choice.eps_BearerIdentity= eps_bearer_id;
drb_ToAddMod->drb_Identity = rb_id;
drb_ToAddMod->reestablishPDCP = NULL;
drb_ToAddMod->recoverPDCP = NULL;
drb_ToAddMod->pdcp_Config = calloc(1,sizeof(*drb_ToAddMod->pdcp_Config));
asn1cCalloc(drb_ToAddMod->pdcp_Config->drb, drb);
asn1cCallocOne(drb->discardTimer, NR_PDCP_Config__drb__discardTimer_infinity);
asn1cCallocOne(drb->pdcp_SN_SizeUL, NR_PDCP_Config__drb__pdcp_SN_SizeUL_len18bits);
asn1cCallocOne(drb->pdcp_SN_SizeDL, NR_PDCP_Config__drb__pdcp_SN_SizeDL_len18bits);
drb->headerCompression.present = NR_PDCP_Config__drb__headerCompression_PR_notUsed;
drb->headerCompression.choice.notUsed = 0;
drb->integrityProtection = NULL;
drb->statusReportRequired = NULL;
drb->outOfOrderDelivery = NULL;
drb_ToAddMod->pdcp_Config->moreThanOneRLC = NULL;
asn1cCallocOne(drb_ToAddMod->pdcp_Config->t_Reordering, NR_PDCP_Config__t_Reordering_ms100);
drb_ToAddMod->pdcp_Config->ext1 = NULL;
asn1cSeqAdd(&rbconfig->drb_ToAddModList->list,drb_ToAddMod);
rbconfig->drb_ToReleaseList = NULL;
asn1cCalloc(rbconfig->securityConfig, secConf);
asn1cCalloc(secConf->securityAlgorithmConfig, secConfAlgo);
secConfAlgo->cipheringAlgorithm = ciphering_algorithm;
secConfAlgo->integrityProtAlgorithm = NULL;
asn1cCallocOne(secConf->keyToUse, key_to_use);
return rbconfig;
}
void fill_nr_noS1_bearer_config(NR_RadioBearerConfig_t **rbconfig,
NR_RLC_BearerConfig_t **rlc_rbconfig)
{
/* the EPS bearer ID is arbitrary; the rb_id is 1/the first DRB, it needs to
* match the one in get_DRB_RLC_BearerConfig(). No ciphering is to be
* configured */
*rbconfig = get_default_rbconfig(10, 1, NR_CipheringAlgorithm_nea0, NR_SecurityConfig__keyToUse_master);
AssertFatal(*rbconfig != NULL, "get_default_rbconfig() failed\n");
/* LCID is 4 because the RLC layer requires it to be 3+rb_id; the rb_id 1 is
* common with get_default_rbconfig() (first RB). We pre-configure RLC UM
* Bi-directional, priority is 1 */
*rlc_rbconfig = get_DRB_RLC_BearerConfig(4, 1, NR_RLC_Config_PR_um_Bi_Directional, 1);
AssertFatal(*rlc_rbconfig != NULL, "get_DRB_RLC_BearerConfig() failed\n");
}
void free_nr_noS1_bearer_config(NR_RadioBearerConfig_t **rbconfig,
NR_RLC_BearerConfig_t **rlc_rbconfig)
{
ASN_STRUCT_FREE(asn_DEF_NR_RadioBearerConfig, *rbconfig);
*rbconfig = NULL;
ASN_STRUCT_FREE(asn_DEF_NR_RLC_BearerConfig, *rlc_rbconfig);
*rlc_rbconfig = NULL;
}
void fill_mastercellGroupConfig(NR_CellGroupConfig_t *cellGroupConfig,
NR_CellGroupConfig_t *ue_context_mastercellGroup,
int use_rlc_um_for_drb,
uint8_t configure_srb,
NR_DRB_ToAddModList_t *drb_configList,
long *priority)
{
cellGroupConfig->cellGroupId = 0;
cellGroupConfig->rlc_BearerToReleaseList = NULL;
cellGroupConfig->rlc_BearerToAddModList = calloc(1, sizeof(*cellGroupConfig->rlc_BearerToAddModList));
// RLC Bearer Config
// TS38.331 9.2.1 Default SRB configurations
if (configure_srb){
NR_RLC_BearerConfig_t *rlc_BearerConfig = get_SRB_RLC_BearerConfig(2, 3, NR_LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms5);
asn1cSeqAdd(&cellGroupConfig->rlc_BearerToAddModList->list, rlc_BearerConfig);
asn1cSeqAdd(&ue_context_mastercellGroup->rlc_BearerToAddModList->list, rlc_BearerConfig);
}
// DRB Configuration
if (drb_configList != NULL) {
for (int i = 0; i < drb_configList->list.count; ++i) {
const NR_RLC_Config_PR rlc_conf = use_rlc_um_for_drb ? NR_RLC_Config_PR_um_Bi_Directional : NR_RLC_Config_PR_am;
int rb_id = drb_configList->list.array[i]->drb_Identity;
NR_RLC_BearerConfig_t *rlc_BearerConfig = get_DRB_RLC_BearerConfig(3 + rb_id, rb_id, rlc_conf, priority[rb_id - 1]);
asn1cSeqAdd(&cellGroupConfig->rlc_BearerToAddModList->list, rlc_BearerConfig);
asn1cSeqAdd(&ue_context_mastercellGroup->rlc_BearerToAddModList->list, rlc_BearerConfig);
}
}
}
//------------------------------------------------------------------------------
int do_RRCSetup(rrc_gNB_ue_context_t *const ue_context_pP,
uint8_t *const buffer,
const uint8_t transaction_id,
const uint8_t *masterCellGroup,
int masterCellGroup_len,
const gNB_RrcConfigurationReq *configuration)
//------------------------------------------------------------------------------
{
asn_enc_rval_t enc_rval;
NR_DL_CCCH_Message_t dl_ccch_msg;
NR_RRCSetup_t *rrcSetup;
NR_RRCSetup_IEs_t *ie;
NR_SRB_ToAddMod_t *SRB1_config = NULL;
NR_PDCP_Config_t *pdcp_Config = NULL;
AssertFatal(ue_context_pP != NULL,"ue_context_p is null\n");
gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context;
NR_SRB_ToAddModList_t **SRB_configList = &ue_p->SRB_configList;
memset((void *)&dl_ccch_msg, 0, sizeof(NR_DL_CCCH_Message_t));
dl_ccch_msg.message.present = NR_DL_CCCH_MessageType_PR_c1;
dl_ccch_msg.message.choice.c1 = CALLOC(1, sizeof(struct NR_DL_CCCH_MessageType__c1));
dl_ccch_msg.message.choice.c1->present = NR_DL_CCCH_MessageType__c1_PR_rrcSetup;
dl_ccch_msg.message.choice.c1->choice.rrcSetup = calloc(1, sizeof(NR_RRCSetup_t));
rrcSetup = dl_ccch_msg.message.choice.c1->choice.rrcSetup;
rrcSetup->criticalExtensions.present = NR_RRCSetup__criticalExtensions_PR_rrcSetup;
rrcSetup->rrc_TransactionIdentifier = transaction_id;
rrcSetup->criticalExtensions.choice.rrcSetup = calloc(1, sizeof(NR_RRCSetup_IEs_t));
ie = rrcSetup->criticalExtensions.choice.rrcSetup;
/****************************** radioBearerConfig ******************************/
/* Configure SRB1 */
if (*SRB_configList) {
free(*SRB_configList);
}
*SRB_configList = calloc(1, sizeof(NR_SRB_ToAddModList_t));
// SRB1
/* TODO */
SRB1_config = calloc(1, sizeof(NR_SRB_ToAddMod_t));
SRB1_config->srb_Identity = 1;
// pdcp_Config->t_Reordering
SRB1_config->pdcp_Config = pdcp_Config;
ie->radioBearerConfig.srb_ToAddModList = *SRB_configList;
asn1cSeqAdd(&(*SRB_configList)->list, SRB1_config);
ie->radioBearerConfig.srb3_ToRelease = NULL;
ie->radioBearerConfig.drb_ToAddModList = NULL;
ie->radioBearerConfig.drb_ToReleaseList = NULL;
ie->radioBearerConfig.securityConfig = NULL;
/****************************** masterCellGroup ******************************/
DevAssert(masterCellGroup && masterCellGroup_len > 0);
ie->masterCellGroup.buf = malloc(masterCellGroup_len);
AssertFatal(ie->masterCellGroup.buf != NULL, "could not allocate memory for masterCellGroup\n");
memcpy(ie->masterCellGroup.buf, masterCellGroup, masterCellGroup_len);
ie->masterCellGroup.size = masterCellGroup_len;
// decode masterCellGroup OCTET_STRING received from DU and place in ue context
ue_p->masterCellGroup = decode_cellGroupConfig(masterCellGroup, masterCellGroup_len);
if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) {
xer_fprint(stdout, &asn_DEF_NR_CellGroupConfig, ue_p->masterCellGroup);
xer_fprint(stdout, &asn_DEF_NR_DL_CCCH_Message, (void *)&dl_ccch_msg);
}
enc_rval = uper_encode_to_buffer(&asn_DEF_NR_DL_CCCH_Message,
NULL,
(void *)&dl_ccch_msg,
buffer,
1000);
AssertFatal(enc_rval.encoded >0, "ASN1 message encoding failed (%s, %lu)!\n",
enc_rval.failed_type->name, enc_rval.encoded);
LOG_D(NR_RRC,"RRCSetup Encoded %zd bits (%zd bytes)\n",
enc_rval.encoded,(enc_rval.encoded+7)/8);
return((enc_rval.encoded+7)/8);
}
uint8_t do_NR_SecurityModeCommand(
const protocol_ctxt_t *const ctxt_pP,
uint8_t *const buffer,
const uint8_t Transaction_id,
const uint8_t cipheringAlgorithm,
NR_IntegrityProtAlgorithm_t integrityProtAlgorithm
)
//------------------------------------------------------------------------------
{
NR_DL_DCCH_Message_t dl_dcch_msg={0};
asn_enc_rval_t enc_rval;
dl_dcch_msg.message.present = NR_DL_DCCH_MessageType_PR_c1;
asn1cCalloc(dl_dcch_msg.message.choice.c1, c1);
c1->present = NR_DL_DCCH_MessageType__c1_PR_securityModeCommand;
asn1cCalloc(c1->choice.securityModeCommand,scm);
scm->rrc_TransactionIdentifier = Transaction_id;
scm->criticalExtensions.present = NR_SecurityModeCommand__criticalExtensions_PR_securityModeCommand;
asn1cCalloc(scm->criticalExtensions.choice.securityModeCommand,scmIE);
// the two following information could be based on the mod_id
scmIE->securityConfigSMC.securityAlgorithmConfig.cipheringAlgorithm
= (NR_CipheringAlgorithm_t)cipheringAlgorithm;
asn1cCallocOne(scmIE->securityConfigSMC.securityAlgorithmConfig.integrityProtAlgorithm, integrityProtAlgorithm);
if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) {
xer_fprint(stdout, &asn_DEF_NR_DL_DCCH_Message, (void *)&dl_dcch_msg);
}
enc_rval = uper_encode_to_buffer(&asn_DEF_NR_DL_DCCH_Message,
NULL,
(void *)&dl_dcch_msg,
buffer,
100);
AssertFatal(enc_rval.encoded >0 , "ASN1 message encoding failed (%s, %lu)!\n",
enc_rval.failed_type->name, enc_rval.encoded);
ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NR_DL_DCCH_Message,&dl_dcch_msg);
LOG_D(NR_RRC, "[gNB %d] securityModeCommand for UE %lx Encoded %zd bits (%zd bytes)\n", ctxt_pP->module_id, ctxt_pP->rntiMaybeUEid, enc_rval.encoded, (enc_rval.encoded + 7) / 8);
// rrc_ue_process_ueCapabilityEnquiry(0,1000,&dl_dcch_msg.message.choice.c1.choice.ueCapabilityEnquiry,0);
// exit(-1);
return((enc_rval.encoded+7)/8);
}
/*TODO*/
//------------------------------------------------------------------------------
uint8_t do_NR_SA_UECapabilityEnquiry( const protocol_ctxt_t *const ctxt_pP,
uint8_t *const buffer,
const uint8_t Transaction_id)
//------------------------------------------------------------------------------
{
NR_UE_CapabilityRequestFilterNR_t *sa_band_filter;
NR_FreqBandList_t *sa_band_list;
NR_FreqBandInformation_t *sa_band_info;
NR_FreqBandInformationNR_t *sa_band_infoNR;
NR_DL_DCCH_Message_t dl_dcch_msg;
NR_UE_CapabilityRAT_Request_t *ue_capabilityrat_request;
asn_enc_rval_t enc_rval;
memset(&dl_dcch_msg,0,sizeof(NR_DL_DCCH_Message_t));
dl_dcch_msg.message.present = NR_DL_DCCH_MessageType_PR_c1;
dl_dcch_msg.message.choice.c1 = CALLOC(1,sizeof(struct NR_DL_DCCH_MessageType__c1));
dl_dcch_msg.message.choice.c1->present = NR_DL_DCCH_MessageType__c1_PR_ueCapabilityEnquiry;
dl_dcch_msg.message.choice.c1->choice.ueCapabilityEnquiry = CALLOC(1,sizeof(struct NR_UECapabilityEnquiry));
dl_dcch_msg.message.choice.c1->choice.ueCapabilityEnquiry->rrc_TransactionIdentifier = Transaction_id;
dl_dcch_msg.message.choice.c1->choice.ueCapabilityEnquiry->criticalExtensions.present = NR_UECapabilityEnquiry__criticalExtensions_PR_ueCapabilityEnquiry;
dl_dcch_msg.message.choice.c1->choice.ueCapabilityEnquiry->criticalExtensions.choice.ueCapabilityEnquiry = CALLOC(1,sizeof(struct NR_UECapabilityEnquiry_IEs));
ue_capabilityrat_request = CALLOC(1,sizeof(NR_UE_CapabilityRAT_Request_t));
memset(ue_capabilityrat_request,0,sizeof(NR_UE_CapabilityRAT_Request_t));
ue_capabilityrat_request->rat_Type = NR_RAT_Type_nr;
sa_band_infoNR = (NR_FreqBandInformationNR_t*)calloc(1,sizeof(NR_FreqBandInformationNR_t));
sa_band_infoNR->bandNR = 78;
sa_band_info = (NR_FreqBandInformation_t*)calloc(1,sizeof(NR_FreqBandInformation_t));
sa_band_info->present = NR_FreqBandInformation_PR_bandInformationNR;
sa_band_info->choice.bandInformationNR = sa_band_infoNR;
sa_band_list = (NR_FreqBandList_t *)calloc(1, sizeof(NR_FreqBandList_t));
asn1cSeqAdd(&sa_band_list->list, sa_band_info);
sa_band_filter = (NR_UE_CapabilityRequestFilterNR_t*)calloc(1,sizeof(NR_UE_CapabilityRequestFilterNR_t));
sa_band_filter->frequencyBandListFilter = sa_band_list;
OCTET_STRING_t req_freq;
unsigned char req_freq_buf[1024];
enc_rval = uper_encode_to_buffer(&asn_DEF_NR_UE_CapabilityRequestFilterNR,
NULL,
(void *)sa_band_filter,
req_freq_buf,
1024);
AssertFatal(enc_rval.encoded >0, "ASN1 message encoding failed (%s, %lu)!\n",
enc_rval.failed_type->name, enc_rval.encoded);
if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) {
xer_fprint(stdout, &asn_DEF_NR_UE_CapabilityRequestFilterNR, (void *)sa_band_filter);
}
req_freq.buf = req_freq_buf;
req_freq.size = (enc_rval.encoded+7)/8;
ue_capabilityrat_request->capabilityRequestFilter = &req_freq;
asn1cSeqAdd(&dl_dcch_msg.message.choice.c1->choice.ueCapabilityEnquiry->criticalExtensions.choice.ueCapabilityEnquiry->ue_CapabilityRAT_RequestList.list,
ue_capabilityrat_request);
if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) {
xer_fprint(stdout, &asn_DEF_NR_DL_DCCH_Message, (void *)&dl_dcch_msg);
}
enc_rval = uper_encode_to_buffer(&asn_DEF_NR_DL_DCCH_Message,
NULL,
(void *)&dl_dcch_msg,
buffer,
100);
AssertFatal(enc_rval.encoded >0, "ASN1 message encoding failed (%s, %lu)!\n",
enc_rval.failed_type->name, enc_rval.encoded);
LOG_D(NR_RRC, "[gNB %d] NR UECapabilityRequest for UE %lx Encoded %zd bits (%zd bytes)\n", ctxt_pP->module_id, ctxt_pP->rntiMaybeUEid, enc_rval.encoded, (enc_rval.encoded + 7) / 8);
return((enc_rval.encoded+7)/8);
}
int do_NR_RRCRelease(uint8_t *buffer, size_t buffer_size, uint8_t Transaction_id)
{
asn_enc_rval_t enc_rval;
NR_DL_DCCH_Message_t dl_dcch_msg;
NR_RRCRelease_t *rrcConnectionRelease;
memset(&dl_dcch_msg,0,sizeof(NR_DL_DCCH_Message_t));
dl_dcch_msg.message.present = NR_DL_DCCH_MessageType_PR_c1;
dl_dcch_msg.message.choice.c1=CALLOC(1,sizeof(struct NR_DL_DCCH_MessageType__c1));
dl_dcch_msg.message.choice.c1->present = NR_DL_DCCH_MessageType__c1_PR_rrcRelease;
dl_dcch_msg.message.choice.c1->choice.rrcRelease = CALLOC(1, sizeof(NR_RRCRelease_t));
rrcConnectionRelease = dl_dcch_msg.message.choice.c1->choice.rrcRelease;
// RRCConnectionRelease
rrcConnectionRelease->rrc_TransactionIdentifier = Transaction_id;
rrcConnectionRelease->criticalExtensions.present = NR_RRCRelease__criticalExtensions_PR_rrcRelease;
rrcConnectionRelease->criticalExtensions.choice.rrcRelease = CALLOC(1, sizeof(NR_RRCRelease_IEs_t));
rrcConnectionRelease->criticalExtensions.choice.rrcRelease->deprioritisationReq =
CALLOC(1, sizeof(struct NR_RRCRelease_IEs__deprioritisationReq));
rrcConnectionRelease->criticalExtensions.choice.rrcRelease->deprioritisationReq->deprioritisationType =
NR_RRCRelease_IEs__deprioritisationReq__deprioritisationType_nr;
rrcConnectionRelease->criticalExtensions.choice.rrcRelease->deprioritisationReq->deprioritisationTimer =
NR_RRCRelease_IEs__deprioritisationReq__deprioritisationTimer_min10;
enc_rval = uper_encode_to_buffer(&asn_DEF_NR_DL_DCCH_Message,
NULL,
(void *)&dl_dcch_msg,
buffer,
buffer_size);
AssertFatal(enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n",
enc_rval.failed_type->name, enc_rval.encoded);
return((enc_rval.encoded+7)/8);
}
//------------------------------------------------------------------------------
int16_t do_RRCReconfiguration(
const protocol_ctxt_t *const ctxt_pP,
uint8_t *buffer,
size_t buffer_size,
uint8_t Transaction_id,
NR_SRB_ToAddModList_t *SRB_configList,
NR_DRB_ToAddModList_t *DRB_configList,
NR_DRB_ToReleaseList_t *DRB_releaseList,
NR_SecurityConfig_t *security_config,
NR_SDAP_Config_t *sdap_config,
NR_MeasConfig_t *meas_config,
struct NR_RRCReconfiguration_v1530_IEs__dedicatedNAS_MessageList *dedicatedNAS_MessageList,
rrc_gNB_ue_context_t *const ue_context_pP,
rrc_gNB_carrier_data_t *carrier,
const gNB_RrcConfigurationReq *configuration,
NR_MAC_CellGroupConfig_t *mac_CellGroupConfig,
NR_CellGroupConfig_t *cellGroupConfig)
//------------------------------------------------------------------------------
{
NR_DL_DCCH_Message_t dl_dcch_msg={0};
asn_enc_rval_t enc_rval;
NR_RRCReconfiguration_IEs_t *ie;
unsigned char masterCellGroup_buf[1000];
dl_dcch_msg.message.present = NR_DL_DCCH_MessageType_PR_c1;
asn1cCalloc(dl_dcch_msg.message.choice.c1, c1);// = CALLOC(1, sizeof(struct NR_DL_DCCH_MessageType__c1));
c1->present = NR_DL_DCCH_MessageType__c1_PR_rrcReconfiguration;
asn1cCalloc(c1->choice.rrcReconfiguration, rrcReconf); // = calloc(1, sizeof(NR_RRCReconfiguration_t));
rrcReconf->rrc_TransactionIdentifier = Transaction_id;
rrcReconf->criticalExtensions.present = NR_RRCReconfiguration__criticalExtensions_PR_rrcReconfiguration;
/******************** Radio Bearer Config ********************/
/* Configure Security */
// security_config = CALLOC(1, sizeof(NR_SecurityConfig_t));
// security_config->securityAlgorithmConfig = CALLOC(1, sizeof(*ie->radioBearerConfig->securityConfig->securityAlgorithmConfig));
// security_config->securityAlgorithmConfig->cipheringAlgorithm = NR_CipheringAlgorithm_nea0;
// security_config->securityAlgorithmConfig->integrityProtAlgorithm = NULL;
// security_config->keyToUse = CALLOC(1, sizeof(*ie->radioBearerConfig->securityConfig->keyToUse));
// *security_config->keyToUse = NR_SecurityConfig__keyToUse_master;
ie = calloc(1, sizeof(NR_RRCReconfiguration_IEs_t));
if ((SRB_configList && SRB_configList->list.size) ||
(DRB_configList && DRB_configList->list.size)) {
ie->radioBearerConfig = calloc(1, sizeof(NR_RadioBearerConfig_t));
ie->radioBearerConfig->srb_ToAddModList = SRB_configList;
ie->radioBearerConfig->drb_ToAddModList = DRB_configList;
ie->radioBearerConfig->securityConfig = security_config;
ie->radioBearerConfig->srb3_ToRelease = NULL;
ie->radioBearerConfig->drb_ToReleaseList = DRB_releaseList;
}
/******************** Meas Config ********************/
// measConfig
ie->measConfig = meas_config;
// lateNonCriticalExtension
ie->lateNonCriticalExtension = NULL;
// nonCriticalExtension
if (cellGroupConfig || dedicatedNAS_MessageList) {
ie->nonCriticalExtension = calloc(1, sizeof(NR_RRCReconfiguration_v1530_IEs_t));
if (dedicatedNAS_MessageList)
ie->nonCriticalExtension->dedicatedNAS_MessageList = dedicatedNAS_MessageList;
}
if(cellGroupConfig!=NULL){
update_cellGroupConfig(cellGroupConfig, ue_context_pP->ue_context.gNB_ue_ngap_id, ue_context_pP ? ue_context_pP->ue_context.UE_Capability_nr : NULL, configuration);
enc_rval = uper_encode_to_buffer(&asn_DEF_NR_CellGroupConfig,
NULL,
(void *)cellGroupConfig,
masterCellGroup_buf,
1000);
AssertFatal(enc_rval.encoded >0, "ASN1 message encoding failed (%s, %lu)!\n",
enc_rval.failed_type->name, enc_rval.encoded);
if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) {
xer_fprint(stdout, &asn_DEF_NR_CellGroupConfig, (const void *) cellGroupConfig);
}
ie->nonCriticalExtension->masterCellGroup = calloc(1,sizeof(OCTET_STRING_t));
ie->nonCriticalExtension->masterCellGroup->buf = masterCellGroup_buf;
ie->nonCriticalExtension->masterCellGroup->size = (enc_rval.encoded+7)/8;
}
dl_dcch_msg.message.choice.c1->choice.rrcReconfiguration->criticalExtensions.choice.rrcReconfiguration = ie;
if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) {
xer_fprint(stdout, &asn_DEF_NR_DL_DCCH_Message, (void *)&dl_dcch_msg);
}
enc_rval = uper_encode_to_buffer(&asn_DEF_NR_DL_DCCH_Message,
NULL,
(void *)&dl_dcch_msg,
buffer,
buffer_size);
AssertFatal(enc_rval.encoded >0, "ASN1 message encoding failed (%s, %lu)!\n",
enc_rval.failed_type->name, enc_rval.encoded);
LOG_D(NR_RRC,"[gNB %d] RRCReconfiguration for UE %lx Encoded %zd bits (%zd bytes)\n",
ctxt_pP->module_id,
ctxt_pP->rntiMaybeUEid,
enc_rval.encoded,
(enc_rval.encoded+7)/8);
return((enc_rval.encoded+7)/8);
}
uint8_t do_RRCSetupRequest(uint8_t Mod_id, uint8_t *buffer, size_t buffer_size, uint8_t *rv) {
asn_enc_rval_t enc_rval;
uint8_t buf[5],buf2=0;
NR_UL_CCCH_Message_t ul_ccch_msg;
NR_RRCSetupRequest_t *rrcSetupRequest;
memset((void *)&ul_ccch_msg,0,sizeof(NR_UL_CCCH_Message_t));
ul_ccch_msg.message.present = NR_UL_CCCH_MessageType_PR_c1;
ul_ccch_msg.message.choice.c1 = CALLOC(1, sizeof(struct NR_UL_CCCH_MessageType__c1));
ul_ccch_msg.message.choice.c1->present = NR_UL_CCCH_MessageType__c1_PR_rrcSetupRequest;
ul_ccch_msg.message.choice.c1->choice.rrcSetupRequest = CALLOC(1, sizeof(NR_RRCSetupRequest_t));
rrcSetupRequest = ul_ccch_msg.message.choice.c1->choice.rrcSetupRequest;
if (1) {
rrcSetupRequest->rrcSetupRequest.ue_Identity.present = NR_InitialUE_Identity_PR_randomValue;
rrcSetupRequest->rrcSetupRequest.ue_Identity.choice.randomValue.size = 5;
rrcSetupRequest->rrcSetupRequest.ue_Identity.choice.randomValue.bits_unused = 1;
rrcSetupRequest->rrcSetupRequest.ue_Identity.choice.randomValue.buf = buf;
rrcSetupRequest->rrcSetupRequest.ue_Identity.choice.randomValue.buf[0] = rv[0];
rrcSetupRequest->rrcSetupRequest.ue_Identity.choice.randomValue.buf[1] = rv[1];
rrcSetupRequest->rrcSetupRequest.ue_Identity.choice.randomValue.buf[2] = rv[2];
rrcSetupRequest->rrcSetupRequest.ue_Identity.choice.randomValue.buf[3] = rv[3];
rrcSetupRequest->rrcSetupRequest.ue_Identity.choice.randomValue.buf[4] = rv[4]&0xfe;
} else {
rrcSetupRequest->rrcSetupRequest.ue_Identity.present = NR_InitialUE_Identity_PR_ng_5G_S_TMSI_Part1;
rrcSetupRequest->rrcSetupRequest.ue_Identity.choice.ng_5G_S_TMSI_Part1.size = 1;
rrcSetupRequest->rrcSetupRequest.ue_Identity.choice.ng_5G_S_TMSI_Part1.bits_unused = 0;
rrcSetupRequest->rrcSetupRequest.ue_Identity.choice.ng_5G_S_TMSI_Part1.buf = buf;
rrcSetupRequest->rrcSetupRequest.ue_Identity.choice.ng_5G_S_TMSI_Part1.buf[0] = 0x12;
}
rrcSetupRequest->rrcSetupRequest.establishmentCause = NR_EstablishmentCause_mo_Signalling; //EstablishmentCause_mo_Data;
rrcSetupRequest->rrcSetupRequest.spare.buf = &buf2;
rrcSetupRequest->rrcSetupRequest.spare.size=1;
rrcSetupRequest->rrcSetupRequest.spare.bits_unused = 7;
if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) {
xer_fprint(stdout, &asn_DEF_NR_UL_CCCH_Message, (void *)&ul_ccch_msg);
}
enc_rval = uper_encode_to_buffer(&asn_DEF_NR_UL_CCCH_Message,
NULL,
(void *)&ul_ccch_msg,
buffer,
buffer_size);
AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n", enc_rval.failed_type->name, enc_rval.encoded);
LOG_D(NR_RRC,"[UE] RRCSetupRequest Encoded %zd bits (%zd bytes)\n", enc_rval.encoded, (enc_rval.encoded+7)/8);
return((enc_rval.encoded+7)/8);
}
//------------------------------------------------------------------------------
uint8_t
do_NR_RRCReconfigurationComplete_for_nsa(
uint8_t *buffer,
size_t buffer_size,
NR_RRC_TransactionIdentifier_t Transaction_id
)
//------------------------------------------------------------------------------
{
NR_RRCReconfigurationComplete_t rrc_complete_msg;
memset(&rrc_complete_msg, 0, sizeof(rrc_complete_msg));
rrc_complete_msg.rrc_TransactionIdentifier = Transaction_id;
rrc_complete_msg.criticalExtensions.choice.rrcReconfigurationComplete =
CALLOC(1, sizeof(*rrc_complete_msg.criticalExtensions.choice.rrcReconfigurationComplete));
rrc_complete_msg.criticalExtensions.present =
NR_RRCReconfigurationComplete__criticalExtensions_PR_rrcReconfigurationComplete;
rrc_complete_msg.criticalExtensions.choice.rrcReconfigurationComplete->nonCriticalExtension = NULL;
rrc_complete_msg.criticalExtensions.choice.rrcReconfigurationComplete->lateNonCriticalExtension = NULL;
if (0) {
xer_fprint(stdout, &asn_DEF_NR_RRCReconfigurationComplete, (void *)&rrc_complete_msg);
}
asn_enc_rval_t enc_rval = uper_encode_to_buffer(&asn_DEF_NR_RRCReconfigurationComplete,
NULL,
(void *)&rrc_complete_msg,
buffer,
buffer_size);
AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n",
enc_rval.failed_type->name, enc_rval.encoded);
LOG_A(NR_RRC, "rrcReconfigurationComplete Encoded %zd bits (%zd bytes)\n", enc_rval.encoded, (enc_rval.encoded+7)/8);
return((enc_rval.encoded+7)/8);
}
//------------------------------------------------------------------------------
uint8_t
do_NR_RRCReconfigurationComplete(
const protocol_ctxt_t *const ctxt_pP,
uint8_t *buffer,
size_t buffer_size,
const uint8_t Transaction_id
)
//------------------------------------------------------------------------------
{
asn_enc_rval_t enc_rval;
NR_UL_DCCH_Message_t ul_dcch_msg;
NR_RRCReconfigurationComplete_t *rrcReconfigurationComplete;
memset((void *)&ul_dcch_msg,0,sizeof(NR_UL_DCCH_Message_t));
ul_dcch_msg.message.present = NR_UL_DCCH_MessageType_PR_c1;
ul_dcch_msg.message.choice.c1 = CALLOC(1, sizeof(struct NR_UL_DCCH_MessageType__c1));
ul_dcch_msg.message.choice.c1->present = NR_UL_DCCH_MessageType__c1_PR_rrcReconfigurationComplete;
ul_dcch_msg.message.choice.c1->choice.rrcReconfigurationComplete = CALLOC(1, sizeof(NR_RRCReconfigurationComplete_t));
rrcReconfigurationComplete = ul_dcch_msg.message.choice.c1->choice.rrcReconfigurationComplete;
rrcReconfigurationComplete->rrc_TransactionIdentifier = Transaction_id;
rrcReconfigurationComplete->criticalExtensions.choice.rrcReconfigurationComplete = CALLOC(1, sizeof(NR_RRCReconfigurationComplete_IEs_t));
rrcReconfigurationComplete->criticalExtensions.present =
NR_RRCReconfigurationComplete__criticalExtensions_PR_rrcReconfigurationComplete;
rrcReconfigurationComplete->criticalExtensions.choice.rrcReconfigurationComplete->nonCriticalExtension = NULL;
rrcReconfigurationComplete->criticalExtensions.choice.rrcReconfigurationComplete->lateNonCriticalExtension = NULL;
if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) {
xer_fprint(stdout, &asn_DEF_NR_UL_DCCH_Message, (void *)&ul_dcch_msg);
}
enc_rval = uper_encode_to_buffer(&asn_DEF_NR_UL_DCCH_Message,
NULL,
(void *)&ul_dcch_msg,
buffer,
buffer_size);
AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n",
enc_rval.failed_type->name, enc_rval.encoded);
LOG_I(NR_RRC,"rrcReconfigurationComplete Encoded %zd bits (%zd bytes)\n",enc_rval.encoded,(enc_rval.encoded+7)/8);
return((enc_rval.encoded+7)/8);
}
uint8_t do_RRCSetupComplete(uint8_t Mod_id, uint8_t *buffer, size_t buffer_size,
const uint8_t Transaction_id, uint8_t sel_plmn_id, const int dedicatedInfoNASLength, const char *dedicatedInfoNAS){
asn_enc_rval_t enc_rval;
NR_UL_DCCH_Message_t ul_dcch_msg;
NR_RRCSetupComplete_t *RrcSetupComplete;
memset((void *)&ul_dcch_msg,0,sizeof(NR_UL_DCCH_Message_t));
uint8_t buf[6];
ul_dcch_msg.message.present = NR_UL_DCCH_MessageType_PR_c1;
ul_dcch_msg.message.choice.c1 = CALLOC(1,sizeof(struct NR_UL_DCCH_MessageType__c1));
ul_dcch_msg.message.choice.c1->present = NR_UL_DCCH_MessageType__c1_PR_rrcSetupComplete;
ul_dcch_msg.message.choice.c1->choice.rrcSetupComplete = CALLOC(1, sizeof(NR_RRCSetupComplete_t));
RrcSetupComplete = ul_dcch_msg.message.choice.c1->choice.rrcSetupComplete;
RrcSetupComplete->rrc_TransactionIdentifier = Transaction_id;
RrcSetupComplete->criticalExtensions.present = NR_RRCSetupComplete__criticalExtensions_PR_rrcSetupComplete;
RrcSetupComplete->criticalExtensions.choice.rrcSetupComplete = CALLOC(1, sizeof(NR_RRCSetupComplete_IEs_t));
// RrcSetupComplete->criticalExtensions.choice.rrcSetupComplete->nonCriticalExtension = CALLOC(1,
// sizeof(*RrcSetupComplete->criticalExtensions.choice.rrcSetupComplete->nonCriticalExtension));
RrcSetupComplete->criticalExtensions.choice.rrcSetupComplete->selectedPLMN_Identity = sel_plmn_id;
RrcSetupComplete->criticalExtensions.choice.rrcSetupComplete->registeredAMF = NULL;
RrcSetupComplete->criticalExtensions.choice.rrcSetupComplete->ng_5G_S_TMSI_Value = CALLOC(1, sizeof(struct NR_RRCSetupComplete_IEs__ng_5G_S_TMSI_Value));
RrcSetupComplete->criticalExtensions.choice.rrcSetupComplete->ng_5G_S_TMSI_Value->present = NR_RRCSetupComplete_IEs__ng_5G_S_TMSI_Value_PR_ng_5G_S_TMSI;
RrcSetupComplete->criticalExtensions.choice.rrcSetupComplete->ng_5G_S_TMSI_Value->choice.ng_5G_S_TMSI.size = 6;
RrcSetupComplete->criticalExtensions.choice.rrcSetupComplete->ng_5G_S_TMSI_Value->choice.ng_5G_S_TMSI.buf = buf;
RrcSetupComplete->criticalExtensions.choice.rrcSetupComplete->ng_5G_S_TMSI_Value->choice.ng_5G_S_TMSI.buf[0] = 0x12;
RrcSetupComplete->criticalExtensions.choice.rrcSetupComplete->ng_5G_S_TMSI_Value->choice.ng_5G_S_TMSI.buf[1] = 0x34;
RrcSetupComplete->criticalExtensions.choice.rrcSetupComplete->ng_5G_S_TMSI_Value->choice.ng_5G_S_TMSI.buf[2] = 0x56;
RrcSetupComplete->criticalExtensions.choice.rrcSetupComplete->ng_5G_S_TMSI_Value->choice.ng_5G_S_TMSI.buf[3] = 0x78;
RrcSetupComplete->criticalExtensions.choice.rrcSetupComplete->ng_5G_S_TMSI_Value->choice.ng_5G_S_TMSI.buf[4] = 0x9A;
RrcSetupComplete->criticalExtensions.choice.rrcSetupComplete->ng_5G_S_TMSI_Value->choice.ng_5G_S_TMSI.buf[5] = 0xBC;
memset(&RrcSetupComplete->criticalExtensions.choice.rrcSetupComplete->dedicatedNAS_Message,0,sizeof(OCTET_STRING_t));
OCTET_STRING_fromBuf(&RrcSetupComplete->criticalExtensions.choice.rrcSetupComplete->dedicatedNAS_Message,dedicatedInfoNAS,dedicatedInfoNASLength);
if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) {
xer_fprint(stdout, &asn_DEF_NR_UL_DCCH_Message, (void *)&ul_dcch_msg);
}
enc_rval = uper_encode_to_buffer(&asn_DEF_NR_UL_DCCH_Message,
NULL,
(void *)&ul_dcch_msg,
buffer,
buffer_size);
AssertFatal(enc_rval.encoded > 0,"ASN1 message encoding failed (%s, %lu)!\n",
enc_rval.failed_type->name,enc_rval.encoded);
LOG_D(NR_RRC,"RRCSetupComplete Encoded %zd bits (%zd bytes)\n",enc_rval.encoded,(enc_rval.encoded+7)/8);
return((enc_rval.encoded+7)/8);
}
//------------------------------------------------------------------------------
uint8_t
do_NR_DLInformationTransfer(
uint8_t Mod_id,
uint8_t **buffer,
uint8_t transaction_id,
uint32_t pdu_length,
uint8_t *pdu_buffer
)
//------------------------------------------------------------------------------
{
ssize_t encoded;
NR_DL_DCCH_Message_t dl_dcch_msg={0};
dl_dcch_msg.message.present = NR_DL_DCCH_MessageType_PR_c1;
asn1cCalloc(dl_dcch_msg.message.choice.c1, c1);
c1->present = NR_DL_DCCH_MessageType__c1_PR_dlInformationTransfer;
asn1cCalloc(c1->choice.dlInformationTransfer, infoTransfer);
infoTransfer->rrc_TransactionIdentifier = transaction_id;
infoTransfer->criticalExtensions.present =
NR_DLInformationTransfer__criticalExtensions_PR_dlInformationTransfer;
asn1cCalloc(infoTransfer->criticalExtensions.choice.dlInformationTransfer, dlInfoTransfer);
asn1cCalloc(dlInfoTransfer->dedicatedNAS_Message,msg);
// we will free the caller buffer, that is ok in the present code logic (else it will leak memory) but not natural,
// comprehensive code design
msg->buf = pdu_buffer;
msg->size = pdu_length;
encoded = uper_encode_to_new_buffer (&asn_DEF_NR_DL_DCCH_Message, NULL, (void *) &dl_dcch_msg, (void **)buffer);
AssertFatal(encoded > 0,"ASN1 message encoding failed (%s, %ld)!\n",
"DLInformationTransfer", encoded);
ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NR_DL_DCCH_Message,&dl_dcch_msg );
LOG_D(NR_RRC,"DLInformationTransfer Encoded %zd bytes\n", encoded);
//for (int i=0;i<encoded;i++) printf("%02x ",(*buffer)[i]);
return encoded;
}
uint8_t do_NR_ULInformationTransfer(uint8_t **buffer, uint32_t pdu_length, uint8_t *pdu_buffer) {
ssize_t encoded;
NR_UL_DCCH_Message_t ul_dcch_msg;
memset(&ul_dcch_msg, 0, sizeof(NR_UL_DCCH_Message_t));
ul_dcch_msg.message.present = NR_UL_DCCH_MessageType_PR_c1;
ul_dcch_msg.message.choice.c1 = CALLOC(1,sizeof(struct NR_UL_DCCH_MessageType__c1));
ul_dcch_msg.message.choice.c1->present = NR_UL_DCCH_MessageType__c1_PR_ulInformationTransfer;
ul_dcch_msg.message.choice.c1->choice.ulInformationTransfer = CALLOC(1,sizeof(struct NR_ULInformationTransfer));
ul_dcch_msg.message.choice.c1->choice.ulInformationTransfer->criticalExtensions.present = NR_ULInformationTransfer__criticalExtensions_PR_ulInformationTransfer;
ul_dcch_msg.message.choice.c1->choice.ulInformationTransfer->criticalExtensions.choice.ulInformationTransfer = CALLOC(1,sizeof(struct NR_ULInformationTransfer_IEs));
struct NR_ULInformationTransfer_IEs *ulInformationTransfer = ul_dcch_msg.message.choice.c1->choice.ulInformationTransfer->criticalExtensions.choice.ulInformationTransfer;
ulInformationTransfer->dedicatedNAS_Message = CALLOC(1,sizeof(NR_DedicatedNAS_Message_t));
ulInformationTransfer->dedicatedNAS_Message->buf = pdu_buffer;
ulInformationTransfer->dedicatedNAS_Message->size = pdu_length;
ulInformationTransfer->lateNonCriticalExtension = NULL;
encoded = uper_encode_to_new_buffer (&asn_DEF_NR_UL_DCCH_Message, NULL, (void *) &ul_dcch_msg, (void **) buffer);
AssertFatal(encoded > 0,"ASN1 message encoding failed (%s, %ld)!\n",
"ULInformationTransfer",encoded);
LOG_D(NR_RRC,"ULInformationTransfer Encoded %zd bytes\n",encoded);
return encoded;
}
uint8_t do_RRCReestablishmentRequest(uint8_t Mod_id, uint8_t *buffer, uint16_t c_rnti) {
asn_enc_rval_t enc_rval;
NR_UL_CCCH_Message_t ul_ccch_msg;
NR_RRCReestablishmentRequest_t *rrcReestablishmentRequest;
uint8_t buf[2];
memset((void *)&ul_ccch_msg,0,sizeof(NR_UL_CCCH_Message_t));
ul_ccch_msg.message.present = NR_UL_CCCH_MessageType_PR_c1;
ul_ccch_msg.message.choice.c1 = CALLOC(1, sizeof(struct NR_UL_CCCH_MessageType__c1));
ul_ccch_msg.message.choice.c1->present = NR_UL_CCCH_MessageType__c1_PR_rrcReestablishmentRequest;
ul_ccch_msg.message.choice.c1->choice.rrcReestablishmentRequest = CALLOC(1, sizeof(NR_RRCReestablishmentRequest_t));
rrcReestablishmentRequest = ul_ccch_msg.message.choice.c1->choice.rrcReestablishmentRequest;
// test
rrcReestablishmentRequest->rrcReestablishmentRequest.reestablishmentCause = NR_ReestablishmentCause_reconfigurationFailure;
rrcReestablishmentRequest->rrcReestablishmentRequest.ue_Identity.c_RNTI = c_rnti;
rrcReestablishmentRequest->rrcReestablishmentRequest.ue_Identity.physCellId = 0;
rrcReestablishmentRequest->rrcReestablishmentRequest.ue_Identity.shortMAC_I.buf = buf;
rrcReestablishmentRequest->rrcReestablishmentRequest.ue_Identity.shortMAC_I.buf[0] = 0x08;
rrcReestablishmentRequest->rrcReestablishmentRequest.ue_Identity.shortMAC_I.buf[1] = 0x32;
rrcReestablishmentRequest->rrcReestablishmentRequest.ue_Identity.shortMAC_I.size = 2;
if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) {
xer_fprint(stdout, &asn_DEF_NR_UL_CCCH_Message, (void *)&ul_ccch_msg);
}
enc_rval = uper_encode_to_buffer(&asn_DEF_NR_UL_CCCH_Message,
NULL,
(void *)&ul_ccch_msg,
buffer,
100);
AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n", enc_rval.failed_type->name, enc_rval.encoded);
LOG_D(NR_RRC,"[UE] RRCReestablishmentRequest Encoded %zd bits (%zd bytes)\n", enc_rval.encoded, (enc_rval.encoded+7)/8);
return((enc_rval.encoded+7)/8);
}
//------------------------------------------------------------------------------
int do_RRCReestablishment(const protocol_ctxt_t *const ctxt_pP,
rrc_gNB_ue_context_t *const ue_context_pP,
int CC_id,
uint8_t *const buffer,
size_t buffer_size,
const uint8_t Transaction_id,
NR_SRB_ToAddModList_t **SRB_configList,
const uint8_t *masterCellGroup_from_DU,
NR_ServingCellConfigCommon_t *scc,
rrc_gNB_carrier_data_t *carrier)
{
asn_enc_rval_t enc_rval;
struct NR_SRB_ToAddMod *SRB1_config = NULL;
struct NR_SRB_ToAddMod *SRB2_config = NULL;
NR_DL_DCCH_Message_t dl_dcch_msg = {0};
NR_RRCReestablishment_t *rrcReestablishment = NULL;
NR_SRB_ToAddModList_t **SRB_configList2 = NULL;
SRB_configList2 = &ue_context_pP->ue_context.SRB_configList2[Transaction_id];
if (*SRB_configList2) {
free(*SRB_configList2);
}
*SRB_configList2 = CALLOC(1, sizeof(NR_SRB_ToAddModList_t));
dl_dcch_msg.message.present = NR_DL_DCCH_MessageType_PR_c1;
dl_dcch_msg.message.choice.c1 = calloc(1, sizeof(struct NR_DL_DCCH_MessageType__c1));
dl_dcch_msg.message.choice.c1->present = NR_DL_DCCH_MessageType__c1_PR_rrcReestablishment;
dl_dcch_msg.message.choice.c1->choice.rrcReestablishment = CALLOC(1, sizeof(NR_RRCReestablishment_t));
rrcReestablishment = dl_dcch_msg.message.choice.c1->choice.rrcReestablishment;
// get old configuration of SRB2
if (*SRB_configList != NULL) {
for (int i = 0; (i < (*SRB_configList)->list.count) && (i < 3); i++) {
LOG_D(NR_RRC, "(*SRB_configList)->list.array[%d]->srb_Identity=%ld\n", i, (*SRB_configList)->list.array[i]->srb_Identity);
if ((*SRB_configList)->list.array[i]->srb_Identity == 2) {
SRB2_config = (*SRB_configList)->list.array[i];
} else if ((*SRB_configList)->list.array[i]->srb_Identity == 1) {
SRB1_config = (*SRB_configList)->list.array[i];
}
}
}
if (SRB1_config == NULL) {
// default SRB1 configuration
LOG_W(NR_RRC, "SRB1 configuration does not exist in SRB configuration list, use default\n");
/// SRB1
SRB1_config = CALLOC(1, sizeof(*SRB1_config));
SRB1_config->srb_Identity = 1;
}
if (SRB2_config == NULL) {
LOG_W(NR_RRC, "SRB2 configuration does not exist in SRB configuration list\n");
} else {
asn1cSeqAdd(&(*SRB_configList2)->list, SRB2_config);
}
if (*SRB_configList) {
free(*SRB_configList);
}
*SRB_configList = CALLOC(1, sizeof(NR_SRB_ToAddModList_t));
asn1cSeqAdd(&(*SRB_configList)->list, SRB1_config);
/****************************** masterCellGroup ******************************/
rrcReestablishment->rrc_TransactionIdentifier = Transaction_id;
rrcReestablishment->criticalExtensions.present = NR_RRCReestablishment__criticalExtensions_PR_rrcReestablishment;
rrcReestablishment->criticalExtensions.choice.rrcReestablishment = CALLOC(1, sizeof(NR_RRCReestablishment_IEs_t));
uint16_t pci = RC.nrrrc[ctxt_pP->module_id]->carrier.physCellId;
uint32_t nr_arfcn_dl = (uint64_t)*scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencySSB;
LOG_I(NR_RRC, "Reestablishment update key pci=%d, earfcn_dl=%u\n", pci, nr_arfcn_dl);
// 3GPP TS 33.501 Section 6.11 Security handling for RRC connection re-establishment procedure
if (ue_context_pP->ue_context.nh_ncc >= 0) {
nr_derive_key_ng_ran_star(pci, nr_arfcn_dl, ue_context_pP->ue_context.nh, ue_context_pP->ue_context.kgnb);
rrcReestablishment->criticalExtensions.choice.rrcReestablishment->nextHopChainingCount = ue_context_pP->ue_context.nh_ncc;
} else { // first HO
nr_derive_key_ng_ran_star(pci, nr_arfcn_dl, ue_context_pP->ue_context.kgnb, ue_context_pP->ue_context.kgnb);
// LG: really 1
rrcReestablishment->criticalExtensions.choice.rrcReestablishment->nextHopChainingCount = 0;
}
ue_context_pP->ue_context.kgnb_ncc = 0;
rrcReestablishment->criticalExtensions.choice.rrcReestablishment->lateNonCriticalExtension = NULL;
rrcReestablishment->criticalExtensions.choice.rrcReestablishment->nonCriticalExtension = NULL;
if (LOG_DEBUGFLAG(DEBUG_ASN1)) {
xer_fprint(stdout, &asn_DEF_NR_DL_DCCH_Message, (void *)&dl_dcch_msg);
}
enc_rval = uper_encode_to_buffer(&asn_DEF_NR_DL_DCCH_Message, NULL, (void *)&dl_dcch_msg, buffer, 100);
AssertFatal(enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n",
enc_rval.failed_type->name, enc_rval.encoded);
LOG_D(NR_RRC, "RRCReestablishment Encoded %u bits (%u bytes)\n", (uint32_t)enc_rval.encoded, (uint32_t)(enc_rval.encoded + 7) / 8);
return ((enc_rval.encoded + 7) / 8);
}
int do_RRCReestablishmentComplete(uint8_t *buffer, size_t buffer_size, int64_t rrc_TransactionIdentifier)
{
asn_enc_rval_t enc_rval;
NR_UL_DCCH_Message_t ul_dcch_msg;
NR_RRCReestablishmentComplete_t *rrcReestablishmentComplete;
memset((void *)&ul_dcch_msg,0,sizeof(NR_UL_DCCH_Message_t));
ul_dcch_msg.message.present = NR_UL_DCCH_MessageType_PR_c1;
ul_dcch_msg.message.choice.c1 = CALLOC(1, sizeof(struct NR_UL_DCCH_MessageType__c1));
ul_dcch_msg.message.choice.c1->present = NR_UL_DCCH_MessageType__c1_PR_rrcReestablishmentComplete;
ul_dcch_msg.message.choice.c1->choice.rrcReestablishmentComplete = CALLOC(1, sizeof(NR_RRCReestablishmentComplete_t));
rrcReestablishmentComplete = ul_dcch_msg.message.choice.c1->choice.rrcReestablishmentComplete;
rrcReestablishmentComplete->rrc_TransactionIdentifier = rrc_TransactionIdentifier;
rrcReestablishmentComplete->criticalExtensions.present = NR_RRCReestablishmentComplete__criticalExtensions_PR_rrcReestablishmentComplete;
rrcReestablishmentComplete->criticalExtensions.choice.rrcReestablishmentComplete = CALLOC(1, sizeof(NR_RRCReestablishmentComplete_IEs_t));
rrcReestablishmentComplete->criticalExtensions.choice.rrcReestablishmentComplete->lateNonCriticalExtension = NULL;
rrcReestablishmentComplete->criticalExtensions.choice.rrcReestablishmentComplete->nonCriticalExtension = NULL;
if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) {
xer_fprint(stdout, &asn_DEF_NR_UL_CCCH_Message, (void *)&ul_dcch_msg);
}
enc_rval = uper_encode_to_buffer(&asn_DEF_NR_UL_DCCH_Message,
NULL,
(void *)&ul_dcch_msg,
buffer,
buffer_size);
AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n", enc_rval.failed_type->name, enc_rval.encoded);
LOG_D(NR_RRC,"[UE] RRCReestablishmentComplete Encoded %zd bits (%zd bytes)\n", enc_rval.encoded, (enc_rval.encoded+7)/8);
return((enc_rval.encoded+7)/8);
}
NR_MeasConfig_t *get_defaultMeasConfig(const gNB_RrcConfigurationReq *conf)
{
const NR_FrequencyInfoDL_t *freqInfoDL = conf->scc->downlinkConfigCommon->frequencyInfoDL;
const NR_ARFCN_ValueNR_t absFreqSSB = *freqInfoDL->absoluteFrequencySSB;
DevAssert(freqInfoDL->scs_SpecificCarrierList.list.count == 1);
const NR_SubcarrierSpacing_t scs = freqInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing;
DevAssert(freqInfoDL->frequencyBandList.list.count == 1);
const NR_FreqBandIndicatorNR_t band = *freqInfoDL->frequencyBandList.list.array[0];
NR_MeasConfig_t *mc = calloc(1, sizeof(*mc));
mc->measObjectToAddModList = calloc(1, sizeof(*mc->measObjectToAddModList));
mc->reportConfigToAddModList = calloc(1, sizeof(*mc->reportConfigToAddModList));
// Measurement Objects: Specifies what is to be measured. For NR and inter-RAT E-UTRA measurements, this may include
// cell-specific offsets, blacklisted cells to be ignored and whitelisted cells to consider for measurements.
NR_MeasObjectToAddMod_t *mo1 = calloc(1, sizeof(*mo1));
mo1->measObjectId = 1;
mo1->measObject.present = NR_MeasObjectToAddMod__measObject_PR_measObjectNR;
NR_MeasObjectNR_t *monr1 = calloc(1, sizeof(*monr1));
asn1cCallocOne(monr1->ssbFrequency, absFreqSSB);
asn1cCallocOne(monr1->ssbSubcarrierSpacing, scs);
monr1->referenceSignalConfig.ssb_ConfigMobility = calloc(1, sizeof(*monr1->referenceSignalConfig.ssb_ConfigMobility));
monr1->referenceSignalConfig.ssb_ConfigMobility->deriveSSB_IndexFromCell = true;
monr1->absThreshSS_BlocksConsolidation = calloc(1, sizeof(*monr1->absThreshSS_BlocksConsolidation));
asn1cCallocOne(monr1->absThreshSS_BlocksConsolidation->thresholdRSRP, 36);
asn1cCallocOne(monr1->nrofSS_BlocksToAverage, 8);
monr1->smtc1 = calloc(1, sizeof(*monr1->smtc1));
monr1->smtc1->periodicityAndOffset.present = NR_SSB_MTC__periodicityAndOffset_PR_sf20;
monr1->smtc1->periodicityAndOffset.choice.sf20 = 2;
monr1->smtc1->duration = NR_SSB_MTC__duration_sf2;
monr1->quantityConfigIndex = 1;
monr1->ext1 = calloc(1, sizeof(*monr1->ext1));
asn1cCallocOne(monr1->ext1->freqBandIndicatorNR, band);
mo1->measObject.choice.measObjectNR = monr1;
asn1cSeqAdd(&mc->measObjectToAddModList->list, mo1);
// Reporting Configuration: Specifies how reporting should be done. This could be periodic or event-triggered.
NR_ReportConfigToAddMod_t *rc = calloc(1, sizeof(*rc));
rc->reportConfigId = 1;
rc->reportConfig.present = NR_ReportConfigToAddMod__reportConfig_PR_reportConfigNR;
NR_PeriodicalReportConfig_t *prc = calloc(1, sizeof(*prc));
prc->rsType = NR_NR_RS_Type_ssb;
prc->reportInterval = NR_ReportInterval_ms1024;
prc->reportAmount = NR_PeriodicalReportConfig__reportAmount_infinity;
prc->reportQuantityCell.rsrp = true;
prc->reportQuantityCell.rsrq = true;
prc->reportQuantityCell.sinr = true;
prc->reportQuantityRS_Indexes = calloc(1, sizeof(*prc->reportQuantityRS_Indexes));
prc->reportQuantityRS_Indexes->rsrp = true;
prc->reportQuantityRS_Indexes->rsrq = true;
prc->reportQuantityRS_Indexes->sinr = true;
asn1cCallocOne(prc->maxNrofRS_IndexesToReport, 4);
prc->maxReportCells = 4;
prc->includeBeamMeasurements = true;
NR_ReportConfigNR_t *rcnr = calloc(1, sizeof(*rcnr));
rcnr->reportType.present = NR_ReportConfigNR__reportType_PR_periodical;
rcnr->reportType.choice.periodical = prc;
rc->reportConfig.choice.reportConfigNR = rcnr;
asn1cSeqAdd(&mc->reportConfigToAddModList->list, rc);
// Measurement ID: Identifies how to report measurements of a specific object. This is a many-to-many mapping: a
// measurement object could have multiple reporting configurations, a reporting configuration could apply to multiple
// objects. A unique ID is used for each object-to-report-config association. When UE sends a MeasurementReport
// message, a single ID and related measurements are included in the message.
mc->measIdToAddModList = calloc(1, sizeof(*mc->measIdToAddModList));
NR_MeasIdToAddMod_t *measid = calloc(1, sizeof(*measid));
measid->measId = 1;
measid->measObjectId = 1;
measid->reportConfigId = 1;
asn1cSeqAdd(&mc->measIdToAddModList->list, measid);
// Quantity Configuration: Specifies parameters for layer 3 filtering of measurements. Only after filtering, reporting
// criteria are evaluated. The formula used is F_n = (1-a)F_(n-1) + a*M_n, where M is the latest measurement, F is the
// filtered measurement, and ais based on configured filter coefficient.
mc->quantityConfig = calloc(1, sizeof(*mc->quantityConfig));
mc->quantityConfig->quantityConfigNR_List = calloc(1, sizeof(*mc->quantityConfig->quantityConfigNR_List));
NR_QuantityConfigNR_t *qcnr3 = calloc(1, sizeof(*qcnr3));
asn1cCallocOne(qcnr3->quantityConfigCell.ssb_FilterConfig.filterCoefficientRSRP, NR_FilterCoefficient_fc6);
asn1cCallocOne(qcnr3->quantityConfigCell.csi_RS_FilterConfig.filterCoefficientRSRP, NR_FilterCoefficient_fc6);
asn1cSeqAdd(&mc->quantityConfig->quantityConfigNR_List->list, qcnr3);
return mc;
}
uint8_t do_NR_Paging(uint8_t Mod_id, uint8_t *buffer, uint32_t tmsi) {
LOG_D(NR_RRC, "[gNB %d] do_NR_Paging start\n", Mod_id);
NR_PCCH_Message_t pcch_msg;
pcch_msg.message.present = NR_PCCH_MessageType_PR_c1;
asn1cCalloc(pcch_msg.message.choice.c1, c1);
c1->present = NR_PCCH_MessageType__c1_PR_paging;
c1->choice.paging = CALLOC(1, sizeof(NR_Paging_t));
c1->choice.paging->pagingRecordList = CALLOC(
1, sizeof(*pcch_msg.message.choice.c1->choice.paging->pagingRecordList));
c1->choice.paging->nonCriticalExtension = NULL;
asn_set_empty(&c1->choice.paging->pagingRecordList->list);
c1->choice.paging->pagingRecordList->list.count = 0;
asn1cSequenceAdd(c1->choice.paging->pagingRecordList->list, NR_PagingRecord_t,
paging_record_p);
/* convert ue_paging_identity_t to PagingUE_Identity_t */
paging_record_p->ue_Identity.present = NR_PagingUE_Identity_PR_ng_5G_S_TMSI;
// set ng_5G_S_TMSI
INT32_TO_BIT_STRING(tmsi, &paging_record_p->ue_Identity.choice.ng_5G_S_TMSI);
/* add to list */
LOG_D(NR_RRC, "[gNB %d] do_Paging paging_record: PagingRecordList.count %d\n",
Mod_id, c1->choice.paging->pagingRecordList->list.count);
asn_enc_rval_t enc_rval = uper_encode_to_buffer(
&asn_DEF_NR_PCCH_Message, NULL, (void *)&pcch_msg, buffer, RRC_BUF_SIZE);
ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NR_PCCH_Message, &pcch_msg);
if(enc_rval.encoded == -1) {
LOG_I(NR_RRC, "[gNB AssertFatal]ASN1 message encoding failed (%s, %lu)!\n",
enc_rval.failed_type->name, enc_rval.encoded);
return -1;
}
if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) {
xer_fprint(stdout, &asn_DEF_NR_PCCH_Message, (void *)&pcch_msg);
}
return((enc_rval.encoded+7)/8);
}