Files
openairinterface5g/openair2/RRC/NR/MESSAGES/asn1_msg.c
T
Robert Schmidt c1a2b65697 Delete nr_DRB_preconfiguration() and replace with existing functions
nr_DRB_preconfiguration() does a "pre-configuration" for the default DRB
for "noS1" mode, i.e., when there is no connection to core network. In
this case, there is no PDU session to be set up, and hence we need to
preconfigure the DRBs.

We replace this function with partially existing functions and a new
function fill_nr_noS1_bearer_config() which returns a bearer
configuration for the noS1 case, also better reflected in the function
name. It has also been moved to asn1_msg.c, away from the actual PDCP
layer.
2023-04-11 10:33:27 +02:00

1384 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 "UTIL/OSA/osa_defs.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, uint8_t bearer_id_start, uint8_t nb_bearers_to_setup, 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
for (int i = bearer_id_start; i < bearer_id_start + nb_bearers_to_setup; 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;
NR_RLC_BearerConfig_t *rlc_BearerConfig = get_DRB_RLC_BearerConfig(3 + i, i, rlc_conf, priority[0]); // Fixme: priority hardcoded see caller function, all is wrong
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;
ue_context_pP->ue_context.reestablishment_xid = Transaction_id;
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);
}