Rework RRCReconfiguration handling in RRC/ASN1
according to TS 38.331, RRCReconfiguration messages can be carried
in a container by different RRC messages, e.g. HandoverPreparationInformation,
HandoverCommand, RRCResume etc.. therefore before the introduction of new
RRCReconfiguration messages, e.g. for handover, a new design seems to be necessary
in order to improve modularity and maintainability of the code.
The goal of this commit is to make the generation of RRCReconfiguration
messages more modular by (1) preparing the RRCReconfiguration parameters
data in RRC (2) pass it to ASN1 for IEs allocation (3) encode to buffer
The following changes are introduced:
(1) introduce struct nr_rrc_reconfig_param_t to store the RRC parameters relevant
to encode the RRCReconfiguration IEs
(2) add RRC function get_RRCReconfiguration_params to fetch nr_rrc_reconfig_param_t
data from the UE context and
(3) pass it to the ASN1 encoder, e.g. do_RRCReconfiguration
(4) add a function build_RRCReconfiguration_IEs to allocate memory and build the
ASN1 NR_RRCReconfiguration_IEs_t and
(5) adopt it in do_RRCReconfiguration
(4) add free_RRCReconfiguration_params for memory management of nr_rrc_reconfig_param_t data
(6) add test for rrc_reconfiguration
get_RRCReconfiguration_params:
This function prepares RRCReconfigurationParams for RRC encoding.
Motivation of this change: depending on the RRCReconfiguration
message to be encoded, the ownership of ASN1 memory allocation
should belong to the ASN1 layer, therefore this function is
preparing the nr_rrc_reconfig_param_t data to pass to the
ASN1 encoder to build the ASN1 message and encode to buffer
The function is preparing the params for the IEs that are
either mandatory or shared among different RRC messages.
Specific fields that depend on the message to be encoded are then
added afterwards in the caller. The input param to indicate
re-establishment has been split between SRBs and DRBs, since
depending on the scenario the PDCP re-establishment can vary.
This will be addressed in a later commit.
This function is also handling xid.
build_RRCReconfiguration_IE:
The long term goal is to transfer ownership of memory allocation in ASN1 encoding to
build_RRCReconfiguration_IE, then by calling ASN_STRUCT_FREE_CONTENTS_ONLY
on dl_dcch_msg, all IEs allocated in the context are freed after encoding to buffer.
In the long term, createDRBlist, createSRBlist can also be brought into the context
of build_RRCReconfiguration_IEs and free the ASN1 structure after encoding.
This improves maintability and helps preventing memory leaks.
Currently, what is not allocated in the context, is nulled and freed outside.
free_RRCReconfiguration_params:
this function frees memory allocated to build the nr_rrc_reconfig_param_t data,
including the NR_DRB_ToAddModList_t and NR_SRB_ToAddModList_t. The function
freeDRBlist has been removed since no longer necessary.
dedicated_NAS_msg_list:
dedicated_NAS_msg_list handling has also been refactored, by:
(1) fetch the NAS PDUs from the UE context in get_RRCReconfiguration_params,
which translates to (2) passing an array of dedicatedNAS-MessageList + size
to the ASN1 encoding function where (3) the ASN1 encoding logic for the
dedicated_NAS_msg_list IE has been moved
Note, 3GPP TS 38.331:
dedicatedNAS-MessageList: SEQUENCE (SIZE(1..maxDRB)) OF DedicatedNAS-Message
This commit is contained in:
@@ -143,6 +143,7 @@
|
||||
|
||||
#include "common/ran_context.h"
|
||||
#include "conversions.h"
|
||||
#include "ds/byte_array.h"
|
||||
|
||||
//#define XER_PRINT
|
||||
|
||||
@@ -499,112 +500,108 @@ int do_NR_RRCRelease(uint8_t *buffer, size_t buffer_size, uint8_t Transaction_id
|
||||
return((enc_rval.encoded+7)/8);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
int do_RRCReconfiguration(int rrc_ue_id,
|
||||
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_MeasConfig_t *meas_config,
|
||||
struct NR_RRCReconfiguration_v1530_IEs__dedicatedNAS_MessageList *dedicatedNAS_MessageList,
|
||||
NR_CellGroupConfig_t *cellGroupConfig)
|
||||
//------------------------------------------------------------------------------
|
||||
/** @brief Build RRCReconfiguration message (3GPP TS 38.331) */
|
||||
static NR_RRCReconfiguration_IEs_t *build_RRCReconfiguration_IEs(const nr_rrc_reconfig_param_t *params)
|
||||
{
|
||||
NR_DL_DCCH_Message_t dl_dcch_msg={0};
|
||||
asn_enc_rval_t enc_rval;
|
||||
NR_RRCReconfiguration_IEs_t *ie;
|
||||
NR_RRCReconfiguration_IEs_t *ie = calloc_or_fail(1, sizeof(*ie));
|
||||
|
||||
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;
|
||||
// radioBearerConfig
|
||||
if ((params->srb_config_list && params->srb_config_list->list.size)
|
||||
|| (params->drb_config_list && params->drb_config_list->list.size)) {
|
||||
ie->radioBearerConfig = calloc_or_fail(1, sizeof(*ie->radioBearerConfig));
|
||||
struct NR_RadioBearerConfig *cfg = ie->radioBearerConfig;
|
||||
cfg->srb_ToAddModList = params->srb_config_list;
|
||||
cfg->drb_ToAddModList = params->drb_config_list;
|
||||
cfg->securityConfig = params->security_config;
|
||||
cfg->srb3_ToRelease = NULL;
|
||||
cfg->drb_ToReleaseList = params->drb_release_list;
|
||||
}
|
||||
|
||||
asn1cCalloc(c1->choice.rrcReconfiguration, rrcReconf); // = calloc(1, sizeof(NR_RRCReconfiguration_t));
|
||||
rrcReconf->rrc_TransactionIdentifier = Transaction_id;
|
||||
rrcReconf->criticalExtensions.present = NR_RRCReconfiguration__criticalExtensions_PR_rrcReconfiguration;
|
||||
/* measConfig */
|
||||
ie->measConfig = params->meas_config;
|
||||
|
||||
/******************** 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;
|
||||
/* nonCriticalExtension, RRCReconfiguration-v1530-IEs */
|
||||
if (params->cell_group_config || params->num_nas_msg) {
|
||||
// Allocate memory for extension IE
|
||||
ie->nonCriticalExtension = calloc_or_fail(1, sizeof(*ie->nonCriticalExtension));
|
||||
}
|
||||
|
||||
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) {
|
||||
uint8_t *buf = NULL;
|
||||
ssize_t len = uper_encode_to_new_buffer(&asn_DEF_NR_CellGroupConfig, NULL, cellGroupConfig, (void **)&buf);
|
||||
AssertFatal(len > 0, "ASN1 message encoding failed (%lu)!\n", len);
|
||||
if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) {
|
||||
xer_fprint(stdout, &asn_DEF_NR_CellGroupConfig, (const void *) cellGroupConfig);
|
||||
// Configure Cell Group Config
|
||||
if (ie->nonCriticalExtension) {
|
||||
if (params->num_nas_msg) {
|
||||
asn1cCalloc(ie->nonCriticalExtension->dedicatedNAS_MessageList, list);
|
||||
/* dedicatedNAS-MessageList: The field is absent in case of reconfiguration with sync
|
||||
otherwise it is optionally present */
|
||||
for (int i = 0; i < params->num_nas_msg; i++) {
|
||||
asn1cSequenceAdd(list->list, NR_DedicatedNAS_Message_t, msg);
|
||||
OCTET_STRING_fromBuf(msg, (char *)params->dedicated_NAS_msg_list[i].buf, params->dedicated_NAS_msg_list[i].len);
|
||||
}
|
||||
ie->nonCriticalExtension->masterCellGroup = calloc(1,sizeof(OCTET_STRING_t));
|
||||
ie->nonCriticalExtension->masterCellGroup->buf = buf;
|
||||
ie->nonCriticalExtension->masterCellGroup->size = len;
|
||||
}
|
||||
|
||||
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);
|
||||
/* masterCellGroup */
|
||||
if (params->cell_group_config) {
|
||||
// Encode in extension IE (Master cell group)
|
||||
uint8_t *buf = NULL;
|
||||
ssize_t len = uper_encode_to_new_buffer(&asn_DEF_NR_CellGroupConfig, NULL, params->cell_group_config, (void **)&buf);
|
||||
AssertFatal(len > 0, "ASN1 message encoding failed (%lu)!\n", len);
|
||||
if (LOG_DEBUGFLAG(DEBUG_ASN1)) {
|
||||
xer_fprint(stdout, &asn_DEF_NR_CellGroupConfig, (const void *)params->cell_group_config);
|
||||
}
|
||||
ie->nonCriticalExtension->masterCellGroup = calloc_or_fail(1, sizeof(*ie->nonCriticalExtension->masterCellGroup));
|
||||
*ie->nonCriticalExtension->masterCellGroup = (OCTET_STRING_t){.buf = buf, .size = len};
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
// don't free what we did not allocate, so set fields with pointers to NULL
|
||||
// if memory comes from outside
|
||||
ie->measConfig = NULL;
|
||||
if (ie->radioBearerConfig) {
|
||||
ie->radioBearerConfig->srb_ToAddModList = NULL;
|
||||
ie->radioBearerConfig->drb_ToAddModList = NULL;
|
||||
ie->radioBearerConfig->securityConfig = NULL;
|
||||
ie->radioBearerConfig->srb3_ToRelease = NULL;
|
||||
ie->radioBearerConfig->drb_ToReleaseList = NULL;
|
||||
/* masterKeyUpdate */
|
||||
if (params->masterKeyUpdate) {
|
||||
ie->nonCriticalExtension->masterKeyUpdate = calloc_or_fail(1, sizeof(*ie->nonCriticalExtension->masterKeyUpdate));
|
||||
ie->nonCriticalExtension->masterKeyUpdate->keySetChangeIndicator = false;
|
||||
ie->nonCriticalExtension->masterKeyUpdate->nextHopChainingCount = params->nextHopChainingCount;
|
||||
}
|
||||
if (ie->nonCriticalExtension)
|
||||
ie->nonCriticalExtension->dedicatedNAS_MessageList = NULL;
|
||||
}
|
||||
|
||||
return ie;
|
||||
}
|
||||
|
||||
byte_array_t do_RRCReconfiguration(const nr_rrc_reconfig_param_t *params)
|
||||
{
|
||||
byte_array_t msg = {.buf = NULL, .len = 0};
|
||||
NR_RRCReconfiguration_IEs_t *ie = build_RRCReconfiguration_IEs(params);
|
||||
|
||||
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_rrcReconfiguration;
|
||||
asn1cCalloc(c1->choice.rrcReconfiguration, rrcReconf);
|
||||
rrcReconf->rrc_TransactionIdentifier = params->transaction_id;
|
||||
rrcReconf->criticalExtensions.present = NR_RRCReconfiguration__criticalExtensions_PR_rrcReconfiguration;
|
||||
rrcReconf->criticalExtensions.choice.rrcReconfiguration = ie;
|
||||
|
||||
if (LOG_DEBUGFLAG(DEBUG_ASN1)) {
|
||||
xer_fprint(stdout, &asn_DEF_NR_DL_DCCH_Message, (void *)&dl_dcch_msg);
|
||||
}
|
||||
|
||||
int val = uper_encode_to_new_buffer(&asn_DEF_NR_DL_DCCH_Message, NULL, &dl_dcch_msg, (void **)&msg.buf);
|
||||
if (val <= 0) {
|
||||
LOG_E(NR_RRC, "Failed to encode DL-DCCH message\n");
|
||||
ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NR_DL_DCCH_Message, &dl_dcch_msg);
|
||||
LOG_D(NR_RRC,
|
||||
"RRCReconfiguration for UE %d: Encoded %zd bits (%zd bytes)\n",
|
||||
rrc_ue_id,
|
||||
enc_rval.encoded,
|
||||
(enc_rval.encoded + 7) / 8);
|
||||
return msg;
|
||||
}
|
||||
msg.len = val;
|
||||
LOG_D(NR_RRC, "RRCReconfiguration: Encoded (%ld bytes)\n", msg.len);
|
||||
|
||||
return((enc_rval.encoded+7)/8);
|
||||
// Do not free what is not allocated in this context
|
||||
ie->measConfig = NULL;
|
||||
if (ie->radioBearerConfig) {
|
||||
ie->radioBearerConfig->securityConfig = NULL;
|
||||
ie->radioBearerConfig->drb_ToReleaseList = NULL;
|
||||
ie->radioBearerConfig->srb_ToAddModList = NULL;
|
||||
ie->radioBearerConfig->drb_ToAddModList = NULL;
|
||||
}
|
||||
|
||||
ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NR_DL_DCCH_Message, &dl_dcch_msg);
|
||||
|
||||
return msg;
|
||||
}
|
||||
|
||||
int do_RRCSetupRequest(uint8_t *buffer, size_t buffer_size, uint8_t *rv, uint64_t fiveG_S_TMSI)
|
||||
|
||||
@@ -51,10 +51,24 @@
|
||||
#include "NR_SRB-ToAddModList.h"
|
||||
#include "NR_SecurityConfig.h"
|
||||
#include "ds/seq_arr.h"
|
||||
#include "ds/byte_array.h"
|
||||
#include "rrc_messages_types.h"
|
||||
struct NR_RRCReconfiguration_v1530_IEs__dedicatedNAS_MessageList;
|
||||
struct asn_TYPE_descriptor_s;
|
||||
|
||||
typedef struct {
|
||||
uint8_t transaction_id;
|
||||
NR_SRB_ToAddModList_t *srb_config_list;
|
||||
NR_DRB_ToAddModList_t *drb_config_list;
|
||||
NR_DRB_ToReleaseList_t *drb_release_list;
|
||||
NR_SecurityConfig_t *security_config;
|
||||
NR_MeasConfig_t *meas_config;
|
||||
byte_array_t dedicated_NAS_msg_list[MAX_DRBS_PER_UE];
|
||||
int num_nas_msg;
|
||||
NR_CellGroupConfig_t *cell_group_config;
|
||||
bool masterKeyUpdate;
|
||||
int nextHopChainingCount;
|
||||
} nr_rrc_reconfig_param_t;
|
||||
|
||||
/*
|
||||
* The variant of the above function which dumps the BASIC-XER (XER_F_BASIC)
|
||||
* output into the chosen string buffer.
|
||||
@@ -91,17 +105,7 @@ int do_NR_SA_UECapabilityEnquiry(uint8_t *const buffer, const uint8_t Transactio
|
||||
|
||||
int do_NR_RRCRelease(uint8_t *buffer, size_t buffer_size, uint8_t Transaction_id);
|
||||
|
||||
int do_RRCReconfiguration(int rrc_ue_id,
|
||||
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_MeasConfig_t *meas_config,
|
||||
struct NR_RRCReconfiguration_v1530_IEs__dedicatedNAS_MessageList *dedicatedNAS_MessageList,
|
||||
NR_CellGroupConfig_t *cellGroupConfig);
|
||||
byte_array_t do_RRCReconfiguration(const nr_rrc_reconfig_param_t *params);
|
||||
|
||||
int do_RRCSetupComplete(uint8_t *buffer,
|
||||
size_t buffer_size,
|
||||
|
||||
@@ -20,14 +20,22 @@
|
||||
*/
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#include "openair2/RRC/NR/MESSAGES/asn1_msg.h"
|
||||
#include "common/ran_context.h"
|
||||
#include <stdbool.h>
|
||||
#include "common/utils/assertions.h"
|
||||
#include "common/utils/LOG/log.h"
|
||||
#include "NR_DRB-ToAddMod.h"
|
||||
#include "NR_DRB-ToAddModList.h"
|
||||
#include "NR_SRB-ToAddModList.h"
|
||||
#include "ds/byte_array.h"
|
||||
RAN_CONTEXT_t RC;
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
TEST(nr_asn1, rrc_reject)
|
||||
{
|
||||
@@ -77,6 +85,77 @@ TEST(nr_asn1, paging)
|
||||
EXPECT_GT(do_NR_Paging(0, buf, 0), 0);
|
||||
}
|
||||
|
||||
void free_RRCReconfiguration_params(nr_rrc_reconfig_param_t params)
|
||||
{
|
||||
ASN_STRUCT_FREE(asn_DEF_NR_MeasConfig, params.meas_config);
|
||||
ASN_STRUCT_FREE(asn_DEF_NR_DRB_ToReleaseList, params.drb_release_list);
|
||||
ASN_STRUCT_FREE(asn_DEF_NR_DRB_ToAddModList, params.drb_config_list);
|
||||
ASN_STRUCT_FREE(asn_DEF_NR_SRB_ToAddModList, params.srb_config_list);
|
||||
ASN_STRUCT_FREE(asn_DEF_NR_SecurityConfig, params.security_config);
|
||||
for (int i = 0; i < params.num_nas_msg; i++)
|
||||
FREE_AND_ZERO_BYTE_ARRAY(params.dedicated_NAS_msg_list[i]);
|
||||
}
|
||||
|
||||
TEST(nr_asn1, rrc_reconfiguration)
|
||||
{
|
||||
// SRB Configuration
|
||||
NR_SRB_ToAddModList_t *srb_config_list = (NR_SRB_ToAddModList_t *)calloc_or_fail(1, sizeof(*srb_config_list));
|
||||
for (int i = 0; i < 4; i++) {
|
||||
if (i == 1 || i == 2) {
|
||||
NR_SRB_ToAddMod_t *srb = (NR_SRB_ToAddMod_t *)calloc_or_fail(1, sizeof(*srb));
|
||||
ASN_SEQUENCE_ADD(&srb_config_list->list, srb);
|
||||
srb->srb_Identity = i;
|
||||
if (i == 1 || i == 2) {
|
||||
srb->reestablishPDCP = (long *)calloc_or_fail(1, sizeof(*srb->reestablishPDCP));
|
||||
*srb->reestablishPDCP = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DRB Configuration
|
||||
NR_DRB_ToAddModList_t *drb_config_list = (NR_DRB_ToAddModList_t *)calloc_or_fail(1, sizeof(*drb_config_list));
|
||||
for (int i = 0; i < 32; i++) {
|
||||
if (i == 1 || i == 2) {
|
||||
NR_DRB_ToAddMod_t *drb = (NR_DRB_ToAddMod_t *)calloc_or_fail(1, sizeof(*drb));
|
||||
ASN_SEQUENCE_ADD(&drb_config_list->list, drb);
|
||||
drb->drb_Identity = i;
|
||||
drb->reestablishPDCP = (long *)calloc_or_fail(1, sizeof(*drb->reestablishPDCP));
|
||||
*drb->reestablishPDCP = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// nr_rrc_reconfig_param_t setup
|
||||
nr_rrc_reconfig_param_t params = {};
|
||||
params.srb_config_list = srb_config_list;
|
||||
params.drb_config_list = drb_config_list;
|
||||
params.num_nas_msg = 2;
|
||||
params.masterKeyUpdate = false;
|
||||
params.nextHopChainingCount = 1;
|
||||
|
||||
byte_array_t nas_pdu_1;
|
||||
nas_pdu_1.buf = (uint8_t *)malloc_or_fail(4);
|
||||
memcpy(nas_pdu_1.buf, "NAS1", 4);
|
||||
nas_pdu_1.len = 4;
|
||||
|
||||
byte_array_t nas_pdu_2;
|
||||
nas_pdu_2.buf = (uint8_t *)malloc_or_fail(4);
|
||||
memcpy(nas_pdu_2.buf, "NAS2", 4);
|
||||
nas_pdu_2.len = 4;
|
||||
|
||||
params.dedicated_NAS_msg_list[0] = nas_pdu_1;
|
||||
params.dedicated_NAS_msg_list[1] = nas_pdu_2;
|
||||
|
||||
byte_array_t msg = do_RRCReconfiguration(¶ms);
|
||||
|
||||
EXPECT_GT(msg.len, 0);
|
||||
EXPECT_NE(msg.buf, nullptr);
|
||||
|
||||
LOG_D(NR_RRC, "RRCReconfiguration: Encoded (%ld bytes)\n", msg.len);
|
||||
|
||||
free_byte_array(msg);
|
||||
free_RRCReconfiguration_params(params);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
logInit();
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
#include "NR_CG-Config.h"
|
||||
#include "NR_CG-ConfigInfo.h"
|
||||
#include "NR_RRCReconfiguration.h"
|
||||
#include "RRC/NR/MESSAGES/asn1_msg.h"
|
||||
|
||||
void rrc_add_nsa_user(gNB_RRC_INST *rrc, x2ap_ENDC_sgnb_addition_req_t *m, sctp_assoc_t assoc_id);
|
||||
void rrc_add_nsa_user_resp(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE, const f1ap_ue_context_setup_t *resp);
|
||||
@@ -112,6 +113,8 @@ void rrc_gNB_generate_UeContextModificationRequest(const gNB_RRC_INST *rrc,
|
||||
int n_rel_drbs,
|
||||
const f1ap_drb_to_be_released_t *rel_drbs);
|
||||
|
||||
void free_RRCReconfiguration_params(nr_rrc_reconfig_param_t params);
|
||||
|
||||
pdusession_level_qos_parameter_t *get_qos_characteristics(const int qfi, rrc_pdu_session_param_t *pduSession);
|
||||
f1ap_qos_characteristics_t get_qos_char_from_qos_flow_param(const pdusession_level_qos_parameter_t *qos_param);
|
||||
void openair_rrc_gNB_configuration(gNB_RRC_INST *rrc, gNB_RrcConfigurationReq *configuration);
|
||||
|
||||
+127
-161
@@ -125,12 +125,6 @@ static void rrc_deliver_ue_ctxt_release_cmd(void *deliver_pdu_data, ue_id_t ue_i
|
||||
data->rrc->mac_rrc.ue_context_release_command(data->assoc_id, data->release_cmd);
|
||||
}
|
||||
|
||||
static void freeDRBlist(NR_DRB_ToAddModList_t *list)
|
||||
{
|
||||
ASN_STRUCT_FREE(asn_DEF_NR_DRB_ToAddModList, list);
|
||||
return;
|
||||
}
|
||||
|
||||
static bool eq_cell_id(const void *vval, const void *vit)
|
||||
{
|
||||
const int *cell_id = (const int *)vval;
|
||||
@@ -551,15 +545,23 @@ static NR_ReportConfigToAddMod_t *prepare_a3_event_report(const nr_a3_event_t *a
|
||||
return rc_A3;
|
||||
}
|
||||
|
||||
static int rrc_gNB_encode_RRCReconfiguration(gNB_RRC_INST *rrc,
|
||||
gNB_RRC_UE_t *UE,
|
||||
uint8_t xid,
|
||||
struct NR_RRCReconfiguration_v1530_IEs__dedicatedNAS_MessageList *nas_messages,
|
||||
uint8_t *buf,
|
||||
int max_len,
|
||||
bool reestablish)
|
||||
void free_RRCReconfiguration_params(nr_rrc_reconfig_param_t params)
|
||||
{
|
||||
NR_CellGroupConfig_t *cellGroupConfig = UE->masterCellGroup;
|
||||
ASN_STRUCT_FREE(asn_DEF_NR_DRB_ToReleaseList, params.drb_release_list);
|
||||
ASN_STRUCT_FREE(asn_DEF_NR_DRB_ToAddModList, params.drb_config_list);
|
||||
ASN_STRUCT_FREE(asn_DEF_NR_SRB_ToAddModList, params.srb_config_list);
|
||||
ASN_STRUCT_FREE(asn_DEF_NR_SecurityConfig, params.security_config);
|
||||
for (int i = 0; i < params.num_nas_msg; i++)
|
||||
FREE_AND_ZERO_BYTE_ARRAY(params.dedicated_NAS_msg_list[i]);
|
||||
}
|
||||
|
||||
/** @brief Prepare the instance of RRCReconfigurationParams to be pass to RRC encoding */
|
||||
static nr_rrc_reconfig_param_t get_RRCReconfiguration_params(gNB_RRC_INST *rrc,
|
||||
gNB_RRC_UE_t *UE,
|
||||
bool srb_reestablish,
|
||||
bool drb_reestablish)
|
||||
{
|
||||
uint8_t xid = rrc_gNB_get_next_transaction_identifier(rrc->module_id);
|
||||
nr_rrc_du_container_t *du = get_du_for_ue(rrc, UE->rrc_ue_id);
|
||||
DevAssert(du != NULL);
|
||||
f1ap_served_cell_info_t *cell_info = &du->setup_req->cell[0].info;
|
||||
@@ -617,71 +619,71 @@ static int rrc_gNB_encode_RRCReconfiguration(gNB_RRC_INST *rrc,
|
||||
|
||||
UE->measConfig = measconfig;
|
||||
|
||||
NR_SRB_ToAddModList_t *SRBs = createSRBlist(UE, reestablish);
|
||||
NR_DRB_ToAddModList_t *DRBs = createDRBlist(UE, reestablish);
|
||||
// Re-establish PDCP for SRB2 only
|
||||
NR_SRB_ToAddModList_t *SRBs = createSRBlist(UE, srb_reestablish);
|
||||
NR_DRB_ToAddModList_t *DRBs = createDRBlist(UE, drb_reestablish);
|
||||
nr_rrc_reconfig_param_t params = {.cell_group_config = UE->masterCellGroup,
|
||||
.transaction_id = xid,
|
||||
.drb_config_list = DRBs,
|
||||
.drb_release_list = UE->DRB_ReleaseList,
|
||||
.meas_config = UE->measConfig,
|
||||
.srb_config_list = SRBs};
|
||||
UE->DRB_ReleaseList = NULL; // pointer transferred to params
|
||||
|
||||
int size = do_RRCReconfiguration(UE->rrc_ue_id,
|
||||
buf,
|
||||
max_len,
|
||||
xid,
|
||||
SRBs,
|
||||
DRBs,
|
||||
UE->DRB_ReleaseList,
|
||||
NULL,
|
||||
measconfig,
|
||||
nas_messages,
|
||||
cellGroupConfig);
|
||||
LOG_DUMPMSG(NR_RRC, DEBUG_RRC, (char *)buf, size, "[MSG] RRC Reconfiguration\n");
|
||||
freeSRBlist(SRBs);
|
||||
freeDRBlist(DRBs);
|
||||
ASN_STRUCT_FREE(asn_DEF_NR_DRB_ToReleaseList, UE->DRB_ReleaseList);
|
||||
UE->DRB_ReleaseList = NULL;
|
||||
for (int i = 0; i < UE->nb_of_pdusessions; i++) {
|
||||
if (UE->pduSession[i].param.nas_pdu.len > 0) {
|
||||
params.dedicated_NAS_msg_list[params.num_nas_msg++] = UE->pduSession[i].param.nas_pdu;
|
||||
UE->pduSession[i].param.nas_pdu.buf = NULL;
|
||||
UE->pduSession[i].param.nas_pdu.len = 0;
|
||||
LOG_D(NR_RRC, "Transfer NAS info with size %ld (pdusession idx %d) to RRCReconfiguration params\n", UE->pduSession[i].param.nas_pdu.len, i);
|
||||
}
|
||||
}
|
||||
if (UE->nas_pdu.len > 0) {
|
||||
params.dedicated_NAS_msg_list[params.num_nas_msg++] = UE->nas_pdu;
|
||||
UE->nas_pdu.buf = NULL;
|
||||
UE->nas_pdu.len = 0;
|
||||
LOG_D(NR_RRC, "Transfer NAS info with size %ld to RRCReconfiguration params\n", UE->nas_pdu.len);
|
||||
}
|
||||
|
||||
return size;
|
||||
return params;
|
||||
}
|
||||
|
||||
static byte_array_t rrc_gNB_encode_RRCReconfiguration(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE, nr_rrc_reconfig_param_t params)
|
||||
{
|
||||
byte_array_t msg = do_RRCReconfiguration(¶ms);
|
||||
if (msg.len <= 0) {
|
||||
LOG_E(NR_RRC, "UE %d: Failed to generate RRCReconfiguration\n", UE->rrc_ue_id);
|
||||
return msg;
|
||||
}
|
||||
LOG_DUMPMSG(NR_RRC, DEBUG_RRC, msg.buf, msg.len, "[MSG] RRC Reconfiguration\n");
|
||||
return msg;
|
||||
}
|
||||
|
||||
static void rrc_gNB_generate_dedicatedRRCReconfiguration(gNB_RRC_INST *rrc, gNB_RRC_UE_t *ue_p)
|
||||
{
|
||||
uint8_t xid = rrc_gNB_get_next_transaction_identifier(rrc->module_id);
|
||||
ue_p->xids[xid] = RRC_PDUSESSION_ESTABLISH;
|
||||
struct NR_RRCReconfiguration_v1530_IEs__dedicatedNAS_MessageList *dedicatedNAS_MessageList = CALLOC(1, sizeof(*dedicatedNAS_MessageList));
|
||||
/* do not re-establish PDCP for any bearer */
|
||||
nr_rrc_reconfig_param_t params = get_RRCReconfiguration_params(rrc, ue_p, false, false);
|
||||
ue_p->xids[params.transaction_id] = RRC_PDUSESSION_ESTABLISH;
|
||||
byte_array_t msg = rrc_gNB_encode_RRCReconfiguration(rrc, ue_p, params);
|
||||
if (msg.len <= 0) {
|
||||
LOG_E(NR_RRC, "UE %d: Failed to generate RRCReconfiguration\n", ue_p->rrc_ue_id);
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < ue_p->nb_of_pdusessions; i++) {
|
||||
if (ue_p->pduSession[i].param.nas_pdu.buf != NULL) {
|
||||
asn1cSequenceAdd(dedicatedNAS_MessageList->list, NR_DedicatedNAS_Message_t, msg);
|
||||
OCTET_STRING_fromBuf(msg, (char *)ue_p->pduSession[i].param.nas_pdu.buf, ue_p->pduSession[i].param.nas_pdu.len);
|
||||
|
||||
LOG_D(NR_RRC, "add NAS info with size %ld (pdusession idx %d)\n", ue_p->pduSession[i].param.nas_pdu.len, i);
|
||||
ue_p->pduSession[i].xid = xid;
|
||||
ue_p->pduSession[i].xid = params.transaction_id;
|
||||
}
|
||||
if (ue_p->pduSession[i].status < PDU_SESSION_STATUS_ESTABLISHED) {
|
||||
ue_p->pduSession[i].status = PDU_SESSION_STATUS_DONE;
|
||||
}
|
||||
}
|
||||
|
||||
if (ue_p->nas_pdu.len) {
|
||||
asn1cSequenceAdd(dedicatedNAS_MessageList->list, NR_DedicatedNAS_Message_t, msg);
|
||||
OCTET_STRING_fromBuf(msg, (char *)ue_p->nas_pdu.buf, ue_p->nas_pdu.len);
|
||||
}
|
||||
|
||||
/* If list is empty free the list and reset the address */
|
||||
if (dedicatedNAS_MessageList->list.count == 0) {
|
||||
free(dedicatedNAS_MessageList);
|
||||
dedicatedNAS_MessageList = NULL;
|
||||
}
|
||||
|
||||
/* Free all NAS PDUs */
|
||||
for (int i = 0; i < ue_p->nb_of_pdusessions; i++)
|
||||
FREE_AND_ZERO_BYTE_ARRAY(ue_p->pduSession[i].param.nas_pdu);
|
||||
|
||||
uint8_t buffer[NR_RRC_BUF_SIZE] = {0};
|
||||
// TODO refactor dedicatedNAS_MessageList
|
||||
int size = rrc_gNB_encode_RRCReconfiguration(rrc, ue_p, xid, dedicatedNAS_MessageList, buffer, sizeof(buffer), false);
|
||||
DevAssert(size > 0 && size <= sizeof(buffer));
|
||||
|
||||
LOG_UE_DL_EVENT(ue_p, "Generate RRCReconfiguration (bytes %d, xid %d)\n", size, xid);
|
||||
LOG_UE_DL_EVENT(ue_p, "Generate RRCReconfiguration (bytes %ld, xid %d)\n", msg.len, params.transaction_id);
|
||||
const uint32_t msg_id = NR_DL_DCCH_MessageType__c1_PR_rrcReconfiguration;
|
||||
nr_rrc_transfer_protected_rrc_message(rrc, ue_p, DL_SCH_LCID_DCCH, msg_id, buffer, size);
|
||||
nr_rrc_transfer_protected_rrc_message(rrc, ue_p, DL_SCH_LCID_DCCH, msg_id, msg.buf, msg.len);
|
||||
free_RRCReconfiguration_params(params);
|
||||
free_byte_array(msg);
|
||||
}
|
||||
|
||||
void rrc_gNB_modify_dedicatedRRCReconfiguration(gNB_RRC_INST *rrc, gNB_RRC_UE_t *ue_p)
|
||||
@@ -690,8 +692,8 @@ void rrc_gNB_modify_dedicatedRRCReconfiguration(gNB_RRC_INST *rrc, gNB_RRC_UE_t
|
||||
uint8_t xid = rrc_gNB_get_next_transaction_identifier(rrc->module_id);
|
||||
ue_p->xids[xid] = RRC_PDUSESSION_MODIFY;
|
||||
|
||||
struct NR_RRCReconfiguration_v1530_IEs__dedicatedNAS_MessageList *dedicatedNAS_MessageList =
|
||||
CALLOC(1, sizeof(*dedicatedNAS_MessageList));
|
||||
NR_DRB_ToAddModList_t *DRBs = createDRBlist(ue_p, false);
|
||||
nr_rrc_reconfig_param_t params = {.drb_config_list = DRBs, .transaction_id = xid};
|
||||
|
||||
for (int i = 0; i < ue_p->nb_of_pdusessions; i++) {
|
||||
rrc_pdu_session_param_t *session = &ue_p->pduSession[i];
|
||||
@@ -753,42 +755,27 @@ void rrc_gNB_modify_dedicatedRRCReconfiguration(gNB_RRC_INST *rrc, gNB_RRC_UE_t
|
||||
session->status = PDU_SESSION_STATUS_DONE;
|
||||
session->xid = xid;
|
||||
|
||||
if (session->param.nas_pdu.buf != NULL) {
|
||||
asn1cSequenceAdd(dedicatedNAS_MessageList->list,NR_DedicatedNAS_Message_t, dedicatedNAS_Message);
|
||||
OCTET_STRING_fromBuf(dedicatedNAS_Message, (char *)session->param.nas_pdu.buf, session->param.nas_pdu.len);
|
||||
LOG_I(NR_RRC, "add NAS info with size %ld (pdusession id %d)\n", session->param.nas_pdu.len, session->param.pdusession_id);
|
||||
if (ue_p->pduSession[i].param.nas_pdu.buf != NULL) {
|
||||
params.dedicated_NAS_msg_list[params.num_nas_msg++] = ue_p->pduSession[i].param.nas_pdu;
|
||||
}
|
||||
}
|
||||
|
||||
/* If list is empty free the list and reset the address */
|
||||
if (dedicatedNAS_MessageList->list.count == 0) {
|
||||
free(dedicatedNAS_MessageList);
|
||||
dedicatedNAS_MessageList = NULL;
|
||||
byte_array_t msg = do_RRCReconfiguration(¶ms);
|
||||
if (msg.len <= 0) {
|
||||
LOG_E(NR_RRC, "UE %d: Failed to generate RRCReconfiguration\n", ue_p->rrc_ue_id);
|
||||
return;
|
||||
}
|
||||
|
||||
NR_DRB_ToAddModList_t *DRBs = createDRBlist(ue_p, false);
|
||||
uint8_t buffer[NR_RRC_BUF_SIZE];
|
||||
int size = do_RRCReconfiguration(ue_p->rrc_ue_id,
|
||||
buffer,
|
||||
NR_RRC_BUF_SIZE,
|
||||
xid,
|
||||
NULL,
|
||||
DRBs,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
dedicatedNAS_MessageList,
|
||||
NULL);
|
||||
LOG_DUMPMSG(NR_RRC, DEBUG_RRC, (char *)buffer, size, "[MSG] RRC Reconfiguration\n");
|
||||
freeDRBlist(DRBs);
|
||||
LOG_DUMPMSG(NR_RRC, DEBUG_RRC, msg.buf, msg.len, "[MSG] RRC Reconfiguration\n");
|
||||
|
||||
/* Free all NAS PDUs */
|
||||
for (int i = 0; i < ue_p->nb_of_pdusessions; i++)
|
||||
FREE_AND_ZERO_BYTE_ARRAY(ue_p->pduSession[i].param.nas_pdu);
|
||||
|
||||
LOG_I(NR_RRC, "UE %d: Generate RRCReconfiguration (bytes %d)\n", ue_p->rrc_ue_id, size);
|
||||
LOG_I(NR_RRC, "UE %d: Generate RRCReconfiguration (bytes %ld)\n", ue_p->rrc_ue_id, msg.len);
|
||||
const uint32_t msg_id = NR_DL_DCCH_MessageType__c1_PR_rrcReconfiguration;
|
||||
nr_rrc_transfer_protected_rrc_message(rrc, ue_p, DL_SCH_LCID_DCCH, msg_id, buffer, size);
|
||||
nr_rrc_transfer_protected_rrc_message(rrc, ue_p, DL_SCH_LCID_DCCH, msg_id, msg.buf, msg.len);
|
||||
free_RRCReconfiguration_params(params);
|
||||
free_byte_array(msg);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@@ -808,40 +795,22 @@ void rrc_gNB_generate_dedicatedRRCReconfiguration_release(gNB_RRC_INST *rrc,
|
||||
}
|
||||
}
|
||||
|
||||
/* If list is empty free the list and reset the address */
|
||||
struct NR_RRCReconfiguration_v1530_IEs__dedicatedNAS_MessageList *dedicatedNAS_MessageList = NULL;
|
||||
nr_rrc_reconfig_param_t params = {.drb_release_list = DRB_Release_configList2, .transaction_id = xid};
|
||||
if (nas_length > 0) {
|
||||
dedicatedNAS_MessageList = CALLOC(1, sizeof(*dedicatedNAS_MessageList));
|
||||
asn1cSequenceAdd(dedicatedNAS_MessageList->list, NR_DedicatedNAS_Message_t, dedicatedNAS_Message);
|
||||
OCTET_STRING_fromBuf(dedicatedNAS_Message, (char *)nas_buffer, nas_length);
|
||||
LOG_I(NR_RRC,"add NAS info with size %d\n", nas_length);
|
||||
} else {
|
||||
LOG_W(NR_RRC,"dedlicated NAS list is empty\n");
|
||||
params.dedicated_NAS_msg_list[params.num_nas_msg].buf = nas_buffer;
|
||||
params.dedicated_NAS_msg_list[params.num_nas_msg++].len = nas_length;
|
||||
}
|
||||
|
||||
uint8_t buffer[NR_RRC_BUF_SIZE] = {0};
|
||||
int size = do_RRCReconfiguration(ue_p->rrc_ue_id,
|
||||
buffer,
|
||||
NR_RRC_BUF_SIZE,
|
||||
xid,
|
||||
NULL,
|
||||
NULL,
|
||||
DRB_Release_configList2,
|
||||
NULL,
|
||||
NULL,
|
||||
dedicatedNAS_MessageList,
|
||||
NULL);
|
||||
LOG_DUMPMSG(NR_RRC,DEBUG_RRC,(char *)buffer,size, "[MSG] RRC Reconfiguration\n");
|
||||
|
||||
/* Free all NAS PDUs */
|
||||
if (nas_length > 0) {
|
||||
/* Free the NAS PDU buffer and invalidate it */
|
||||
free(nas_buffer);
|
||||
byte_array_t msg = do_RRCReconfiguration(¶ms);
|
||||
if (msg.len <= 0) {
|
||||
LOG_E(NR_RRC, "UE %d: Failed to generate RRCReconfiguration\n", ue_p->rrc_ue_id);
|
||||
return;
|
||||
}
|
||||
|
||||
LOG_I(NR_RRC, "UE %d: Generate NR_RRCReconfiguration (bytes %d)\n", ue_p->rrc_ue_id, size);
|
||||
LOG_DUMPMSG(NR_RRC, DEBUG_RRC, msg.buf, msg.len, "[MSG] RRC Reconfiguration\n");
|
||||
LOG_I(NR_RRC, "UE %d: Generate NR_RRCReconfiguration (bytes %ld)\n", ue_p->rrc_ue_id, msg.len);
|
||||
const uint32_t msg_id = NR_DL_DCCH_MessageType__c1_PR_rrcReconfiguration;
|
||||
nr_rrc_transfer_protected_rrc_message(rrc, ue_p, DL_SCH_LCID_DCCH, msg_id, buffer, size);
|
||||
nr_rrc_transfer_protected_rrc_message(rrc, ue_p, DL_SCH_LCID_DCCH, msg_id, msg.buf, msg.len);
|
||||
free_RRCReconfiguration_params(params);
|
||||
free_byte_array(msg);
|
||||
}
|
||||
|
||||
static void fill_security_info(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE, security_information_t *secInfo)
|
||||
@@ -1081,32 +1050,26 @@ static void rrc_gNB_process_RRCReestablishmentComplete(gNB_RRC_INST *rrc, gNB_RR
|
||||
|
||||
uint8_t new_xid = rrc_gNB_get_next_transaction_identifier(rrc->module_id);
|
||||
ue_p->xids[new_xid] = RRC_REESTABLISH_COMPLETE;
|
||||
uint8_t buffer[NR_RRC_BUF_SIZE] = {0};
|
||||
int size = do_RRCReconfiguration(ue_p->rrc_ue_id,
|
||||
buffer,
|
||||
NR_RRC_BUF_SIZE,
|
||||
new_xid,
|
||||
SRBs,
|
||||
DRBs,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL, // MeasObj_list,
|
||||
NULL,
|
||||
cellGroupConfig);
|
||||
freeSRBlist(SRBs);
|
||||
freeDRBlist(DRBs);
|
||||
LOG_DUMPMSG(NR_RRC, DEBUG_RRC, (char *)buffer, size, "[MSG] RRC Reconfiguration\n");
|
||||
|
||||
AssertFatal(size > 0, "cannot encode RRC Reconfiguration\n");
|
||||
nr_rrc_reconfig_param_t params = {.cell_group_config = cellGroupConfig,
|
||||
.drb_config_list = DRBs,
|
||||
.srb_config_list = SRBs,
|
||||
.transaction_id = new_xid};
|
||||
byte_array_t msg = do_RRCReconfiguration(¶ms);
|
||||
if (msg.len <= 0) {
|
||||
LOG_E(NR_RRC, "UE %d: Failed to generate RRCReconfiguration\n", ue_p->rrc_ue_id);
|
||||
return;
|
||||
}
|
||||
LOG_DUMPMSG(NR_RRC, DEBUG_RRC, msg.buf, msg.len, "[MSG] RRC Reconfiguration\n");
|
||||
LOG_I(NR_RRC,
|
||||
"UE %d RNTI %04x: Generate NR_RRCReconfiguration after reestablishment complete (bytes %d)\n",
|
||||
"UE %d RNTI %04x: Generate NR_RRCReconfiguration after reestablishment complete (bytes %ld)\n",
|
||||
ue_p->rrc_ue_id,
|
||||
ue_p->rnti,
|
||||
size);
|
||||
msg.len);
|
||||
const uint32_t msg_id = NR_DL_DCCH_MessageType__c1_PR_rrcReconfiguration;
|
||||
nr_rrc_transfer_protected_rrc_message(rrc, ue_p, DL_SCH_LCID_DCCH, msg_id, buffer, size);
|
||||
nr_rrc_transfer_protected_rrc_message(rrc, ue_p, DL_SCH_LCID_DCCH, msg_id, msg.buf, msg.len);
|
||||
free_RRCReconfiguration_params(params);
|
||||
free_byte_array(msg);
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
int nr_rrc_reconfiguration_req(gNB_RRC_INST *rrc, gNB_RRC_UE_t *ue_p, const int dl_bwp_id, const int ul_bwp_id)
|
||||
{
|
||||
@@ -1123,22 +1086,16 @@ int nr_rrc_reconfiguration_req(gNB_RRC_INST *rrc, gNB_RRC_UE_t *ue_p, const int
|
||||
*masterCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->firstActiveUplinkBWP_Id = ul_bwp_id;
|
||||
}
|
||||
|
||||
uint8_t buffer[NR_RRC_BUF_SIZE];
|
||||
int size = do_RRCReconfiguration(ue_p->rrc_ue_id,
|
||||
buffer,
|
||||
NR_RRC_BUF_SIZE,
|
||||
xid,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
masterCellGroup);
|
||||
|
||||
nr_rrc_reconfig_param_t params = {.cell_group_config = masterCellGroup, .transaction_id = xid};
|
||||
byte_array_t msg = do_RRCReconfiguration(¶ms);
|
||||
if (msg.len <= 0) {
|
||||
LOG_E(NR_RRC, "UE %d: Failed to generate RRCReconfiguration\n", ue_p->rrc_ue_id);
|
||||
return -1;
|
||||
}
|
||||
const uint32_t msg_id = NR_DL_DCCH_MessageType__c1_PR_rrcReconfiguration;
|
||||
nr_rrc_transfer_protected_rrc_message(rrc, ue_p, DL_SCH_LCID_DCCH, msg_id, buffer, size);
|
||||
|
||||
nr_rrc_transfer_protected_rrc_message(rrc, ue_p, DL_SCH_LCID_DCCH, msg_id, msg.buf, msg.len);
|
||||
free_byte_array(msg);
|
||||
free_RRCReconfiguration_params(params);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -2192,14 +2149,23 @@ static void rrc_CU_process_ue_context_setup_response(MessageDef *msg_p, instance
|
||||
|
||||
uint8_t xid = rrc_gNB_get_next_transaction_identifier(rrc->module_id);
|
||||
UE->xids[xid] = RRC_DEDICATED_RECONF;
|
||||
uint8_t buffer[NR_RRC_BUF_SIZE] = {0};
|
||||
int size = rrc_gNB_encode_RRCReconfiguration(rrc, UE, xid, NULL, buffer, sizeof(buffer), true);
|
||||
DevAssert(size > 0 && size <= sizeof(buffer));
|
||||
/* 3GPP TS 38.331 specifies that PDCP shall be re-established whenever the security key
|
||||
* used for the radio bearer changes, with some expections for SRB1 (i.e. when resuming
|
||||
* an RRC connection, or at the first reconfiguration after RRC connection reestablishment
|
||||
* in NR, do not re-establish PDCP */
|
||||
nr_rrc_reconfig_param_t params = get_RRCReconfiguration_params(rrc, UE, true, true);
|
||||
params.transaction_id = xid;
|
||||
|
||||
byte_array_t msg = rrc_gNB_encode_RRCReconfiguration(rrc, UE, params);
|
||||
if (msg.len <= 0) {
|
||||
LOG_E(NR_RRC, "UE %d: Failed to generate RRCReconfiguration\n", UE->rrc_ue_id);
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO N2 38.413 sec 9.3.1.21: admitted PDU sessions (in UE), Target to
|
||||
// Source Transparent Container (9.3.1.21) which encodes the RRC
|
||||
// reconfiguration above
|
||||
UE->ho_context->target->ho_req_ack(rrc, UE, buffer, size);
|
||||
UE->ho_context->target->ho_req_ack(rrc, UE, msg.buf, msg.len);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user