From 5bde26246f543d2c1b3d2ad7dc0ec2684d4b72c1 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Wed, 10 Jul 2024 15:23:24 +0200 Subject: [PATCH 01/14] Create deep copy of ServingCellConfigCommon for UE-specific parameter Prior to this commit, upon a release of a UE at the gNB in NSA, the gNB fails with a segv. This is because the servingCellConfigCommon is used in the reconfigurationWithSync (through a simple pointer). At the release, the entire secondaryCellGroup is freed, leading to a free of the servingCellConfigCommon. The gNB then tries to use it (e.g., for looking up the numerology), and leading to a segv. To avoid this problem, make a "deep copy" of the ServingCellConfigCommon so that we can safely free the UEs secondaryCellGroup, without freeing the initial ServingCellConfigCommon. --- openair2/RRC/NR/nr_rrc_config.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/openair2/RRC/NR/nr_rrc_config.c b/openair2/RRC/NR/nr_rrc_config.c index de660f1765..4804a6c163 100644 --- a/openair2/RRC/NR/nr_rrc_config.c +++ b/openair2/RRC/NR/nr_rrc_config.c @@ -3057,6 +3057,20 @@ static void fix_servingcellconfigdedicated(NR_ServingCellConfig_t *scd) } } +static NR_ServingCellConfigCommon_t *clone_ServingCellConfigCommon(const NR_ServingCellConfigCommon_t *scc) +{ + if (scc == NULL) + return NULL; + + uint8_t buf[16384]; + asn_enc_rval_t enc_rval = uper_encode_to_buffer(&asn_DEF_NR_ServingCellConfigCommon, NULL, scc, buf, sizeof(buf)); + AssertFatal(enc_rval.encoded > 0 && enc_rval.encoded < sizeof(buf), "could not clone NR_ServingCellConfigCommon: problem while encoding\n"); + NR_ServingCellConfigCommon_t *clone = NULL; + asn_dec_rval_t dec_rval = uper_decode(NULL, &asn_DEF_NR_ServingCellConfigCommon, (void **)&clone, buf, enc_rval.encoded, 0, 0); + AssertFatal(dec_rval.code == RC_OK && dec_rval.consumed == enc_rval.encoded, "could not clone NR_ServingCellConfigCommon: problem while decoding\n"); + return clone; +} + NR_CellGroupConfig_t *get_default_secondaryCellGroup(const NR_ServingCellConfigCommon_t *servingcellconfigcommon, NR_ServingCellConfig_t *servingcellconfigdedicated, const NR_UE_NR_Capability_t *uecap, @@ -3097,8 +3111,7 @@ NR_CellGroupConfig_t *get_default_secondaryCellGroup(const NR_ServingCellConfigC calloc(1, sizeof(*secondaryCellGroup->spCellConfig->reconfigurationWithSync)); NR_ReconfigurationWithSync_t *reconfigurationWithSync = secondaryCellGroup->spCellConfig->reconfigurationWithSync; - reconfigurationWithSync->spCellConfigCommon = - (NR_ServingCellConfigCommon_t *)servingcellconfigcommon; + reconfigurationWithSync->spCellConfigCommon = clone_ServingCellConfigCommon(servingcellconfigcommon); reconfigurationWithSync->newUE_Identity = (get_softmodem_params()->phy_test == 1) ? 0x1234 : (taus() & 0xffff); reconfigurationWithSync->t304 = NR_ReconfigurationWithSync__t304_ms2000; From 98ebd0d71e9386de73d53ae28ad00fa99c8e01cb Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Wed, 10 Jul 2024 15:23:46 +0200 Subject: [PATCH 02/14] Revert "Add assertion for known segfault during teardown of gNB." This reverts commit 4c658cdd50a915b3ad7acd19aea1d2e0f66c624b. This commit was introduce to signal a known segfault. The bug has been fixed in the last commit, so this commit can be reverted as the AssertFatal is not necessary anymore. --- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c index 3cc612b98d..dbd64f524e 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c @@ -196,12 +196,6 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP, frame_t frame, sub_frame_ gNB_MAC_INST *gNB = RC.nrmac[module_idP]; NR_COMMON_channels_t *cc = gNB->common_channels; NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon; - // Assert to detect segfault during gNB teardown. scc->ssbSubcarrierSpacing pointer is most likely overwritten - AssertFatal( - *scc->ssbSubcarrierSpacing >= 0 && *scc->ssbSubcarrierSpacing < sizeofArray(nr_slots_per_frame), - "ssbSubcarrierSpacing %ld is out of range, ssbSubcarrierSpacing pointer (%p) might be overwritten, known segfault condition", - *scc->ssbSubcarrierSpacing, - scc->ssbSubcarrierSpacing); NR_SCHED_LOCK(&gNB->sched_lock); From 4cb0bd37127421ec20412eb7df69648b9fa93800 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 11 Jul 2024 11:24:00 +0200 Subject: [PATCH 03/14] Clean up servingCellConfigDedicated once after reading config get_default_secondaryCellGroup() would "sanitize" the servingCellConfig, i.e., remove BWP that are invalid. However, it is difficult to understand (we can do sanitization once at the beginning) and reason (why the servingCellConfig is modified in get_default_secondaryCellGroup(), because all we want is a new CellGroupConfig, without modifying other data structures). Instead, do sanitization once after reading the configuration in gnb_config.c. Also, modify physical simulators nr_dlsim and nr_ulsim to apply this sanitization before a call to get_default_secondaryCellGroup(), as the latter would have done the sanitization. --- openair1/SIMULATION/NR_PHY/dlsim.c | 5 ++--- openair1/SIMULATION/NR_PHY/ulsim.c | 5 ++--- openair2/GNB_APP/gnb_config.c | 10 +++++++++ openair2/RRC/NR/nr_rrc_config.c | 33 ------------------------------ 4 files changed, 14 insertions(+), 39 deletions(-) diff --git a/openair1/SIMULATION/NR_PHY/dlsim.c b/openair1/SIMULATION/NR_PHY/dlsim.c index 728163e049..2877e48ecc 100644 --- a/openair1/SIMULATION/NR_PHY/dlsim.c +++ b/openair1/SIMULATION/NR_PHY/dlsim.c @@ -708,6 +708,8 @@ int main(int argc, char **argv) NR_ServingCellConfig_t *scd = calloc(1,sizeof(*scd)); prepare_scd(scd); + /* removes unnecessary BWPs, if any */ + fix_scd(scd); gNB->ap_N1 = pdsch_AntennaPorts.N1; gNB->ap_N2 = pdsch_AntennaPorts.N2; @@ -720,9 +722,6 @@ int main(int argc, char **argv) NR_CellGroupConfig_t *secondaryCellGroup = get_default_secondaryCellGroup(scc, scd, UE_Capability_nr, 0, 1, &conf, 0); - /* RRC parameter validation for secondaryCellGroup */ - fix_scd(scd); - /* -U option modify DMRS */ if(modify_dmrs) { update_dmrs_config(secondaryCellGroup, dmrs_arg); diff --git a/openair1/SIMULATION/NR_PHY/ulsim.c b/openair1/SIMULATION/NR_PHY/ulsim.c index 822153fd14..b786fd27f7 100644 --- a/openair1/SIMULATION/NR_PHY/ulsim.c +++ b/openair1/SIMULATION/NR_PHY/ulsim.c @@ -627,6 +627,8 @@ int main(int argc, char *argv[]) NR_ServingCellConfig_t *scd = calloc(1,sizeof(NR_ServingCellConfig_t)); prepare_scd(scd); + /* removes unnecessary BWPs, if any */ + fix_scd(scd); NR_UE_NR_Capability_t* UE_Capability_nr = CALLOC(1,sizeof(NR_UE_NR_Capability_t)); prepare_sim_uecap(UE_Capability_nr,scc,mu, @@ -634,9 +636,6 @@ int main(int argc, char *argv[]) NR_CellGroupConfig_t *secondaryCellGroup = get_default_secondaryCellGroup(scc, scd, UE_Capability_nr, 0, 1, &conf, 0); - /* RRC parameter validation for secondaryCellGroup */ - fix_scd(scd); - NR_BCCH_BCH_Message_t *mib = get_new_MIB_NR(scc); // UE dedicated configuration diff --git a/openair2/GNB_APP/gnb_config.c b/openair2/GNB_APP/gnb_config.c index b732a88879..5c24d04e3b 100644 --- a/openair2/GNB_APP/gnb_config.c +++ b/openair2/GNB_APP/gnb_config.c @@ -621,6 +621,16 @@ void fix_scd(NR_ServingCellConfig_t *scd) { } } + + if (scd->downlinkBWP_ToAddModList->list.count == 0) { + free(scd->downlinkBWP_ToAddModList); + scd->downlinkBWP_ToAddModList = NULL; + } + + if (scd->uplinkConfig->uplinkBWP_ToAddModList->list.count == 0) { + free(scd->uplinkConfig->uplinkBWP_ToAddModList); + scd->uplinkConfig->uplinkBWP_ToAddModList = NULL; + } } static void verify_gnb_param_notset(paramdef_t *params, int paramidx, const char *paramname) diff --git a/openair2/RRC/NR/nr_rrc_config.c b/openair2/RRC/NR/nr_rrc_config.c index 4804a6c163..8cbf3d8adb 100644 --- a/openair2/RRC/NR/nr_rrc_config.c +++ b/openair2/RRC/NR/nr_rrc_config.c @@ -3025,38 +3025,6 @@ NR_CellGroupConfig_t *decode_cellGroupConfig(const uint8_t *buffer, int buffer_s return cellGroupConfig; } -/* TODO: this should disappear */ -static void fix_servingcellconfigdedicated(NR_ServingCellConfig_t *scd) -{ - int b = 0; - while (b < scd->downlinkBWP_ToAddModList->list.count) { - if (scd->downlinkBWP_ToAddModList->list.array[b]->bwp_Common->genericParameters.locationAndBandwidth == 0) { - asn_sequence_del(&scd->downlinkBWP_ToAddModList->list, b, 1); - } else { - b++; - } - } - - if (scd->downlinkBWP_ToAddModList->list.count == 0) { - free(scd->downlinkBWP_ToAddModList); - scd->downlinkBWP_ToAddModList = NULL; - } - - b = 0; - while (b < scd->uplinkConfig->uplinkBWP_ToAddModList->list.count) { - if (scd->uplinkConfig->uplinkBWP_ToAddModList->list.array[b]->bwp_Common->genericParameters.locationAndBandwidth == 0) { - asn_sequence_del(&scd->uplinkConfig->uplinkBWP_ToAddModList->list, b, 1); - } else { - b++; - } - } - - if (scd->uplinkConfig->uplinkBWP_ToAddModList->list.count == 0) { - free(scd->uplinkConfig->uplinkBWP_ToAddModList); - scd->uplinkConfig->uplinkBWP_ToAddModList = NULL; - } -} - static NR_ServingCellConfigCommon_t *clone_ServingCellConfigCommon(const NR_ServingCellConfigCommon_t *scc) { if (scc == NULL) @@ -3091,7 +3059,6 @@ NR_CellGroupConfig_t *get_default_secondaryCellGroup(const NR_ServingCellConfigC uint64_t bitmap = get_ssb_bitmap(servingcellconfigcommon); // See comment at the end of this function regarding ServingCellConfig - fix_servingcellconfigdedicated(servingcellconfigdedicated); NR_CellGroupConfig_t *secondaryCellGroup = calloc(1, sizeof(*secondaryCellGroup)); secondaryCellGroup->cellGroupId = scg_id; From c1668cd7c0717bcc5a32217b962375eb84d7b0b3 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 11 Jul 2024 11:18:19 +0200 Subject: [PATCH 04/14] Refactor fill_default_reconfig(): return reconfig Simplify code by returning an allocated object to an RRCReconfiguration. It leads to less code and is easier to reason about, because each call will return a new RRCReconfiguration, which can be freed, irrespective of other calls to fill_default_reconfig(). --- openair2/RRC/NR/nr_rrc_proto.h | 7 +------ openair2/RRC/NR/rrc_gNB_nsa.c | 4 +--- openair2/RRC/NR/rrc_gNB_reconfig.c | 13 +++++-------- 3 files changed, 7 insertions(+), 17 deletions(-) diff --git a/openair2/RRC/NR/nr_rrc_proto.h b/openair2/RRC/NR/nr_rrc_proto.h index d5aee94aab..c3f5dd7eb4 100644 --- a/openair2/RRC/NR/nr_rrc_proto.h +++ b/openair2/RRC/NR/nr_rrc_proto.h @@ -66,12 +66,7 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc, rrc_gNB_ue_context_t *ue_context_p, x2a void rrc_remove_nsa_user(gNB_RRC_INST *rrc, int rnti); void rrc_remove_ue(gNB_RRC_INST *rrc, rrc_gNB_ue_context_t *ue_context_p); -void fill_default_reconfig(NR_ServingCellConfigCommon_t *servingcellconfigcommon, - NR_ServingCellConfig_t *servingcellconfigdedicated, - NR_RRCReconfiguration_IEs_t *reconfig, - NR_CellGroupConfig_t *secondaryCellGroup, - NR_UE_NR_Capability_t *uecap, - int uid); +NR_RRCReconfiguration_IEs_t *get_default_reconfig(const NR_CellGroupConfig_t *secondaryCellGroup); int generate_CG_Config(gNB_RRC_INST *rrc, NR_CG_Config_t *cg_Config, diff --git a/openair2/RRC/NR/rrc_gNB_nsa.c b/openair2/RRC/NR/rrc_gNB_nsa.c index 4347b83a19..41e9700208 100644 --- a/openair2/RRC/NR/rrc_gNB_nsa.c +++ b/openair2/RRC/NR/rrc_gNB_nsa.c @@ -159,8 +159,6 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc, rrc_gNB_ue_context_t *ue_context_p, x2a memset((void *)UE->reconfig, 0, sizeof(NR_RRCReconfiguration_t)); UE->reconfig->rrc_TransactionIdentifier = 0; UE->reconfig->criticalExtensions.present = NR_RRCReconfiguration__criticalExtensions_PR_rrcReconfiguration; - NR_RRCReconfiguration_IEs_t *reconfig_ies=calloc(1,sizeof(NR_RRCReconfiguration_IEs_t)); - UE->reconfig->criticalExtensions.choice.rrcReconfiguration = reconfig_ies; if (get_softmodem_params()->phy_test == 1 || get_softmodem_params()->do_ra == 1 || get_softmodem_params()->sa == 1){ UE->rb_config = get_default_rbconfig(10 /* EPS bearer ID */, 1 /* drb ID */, NR_CipheringAlgorithm_nea0, NR_SecurityConfig__keyToUse_master); } else { @@ -259,7 +257,7 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc, rrc_gNB_ue_context_t *ue_context_p, x2a AssertFatal(UE->secondaryCellGroup != NULL, "out of memory\n"); xer_fprint(stdout, &asn_DEF_NR_CellGroupConfig, UE->secondaryCellGroup); - fill_default_reconfig(sccc, scc, reconfig_ies, UE->secondaryCellGroup, UE->UE_Capability_nr, ue_context_p->ue_context.rrc_ue_id); + UE->reconfig->criticalExtensions.choice.rrcReconfiguration = get_default_reconfig(UE->secondaryCellGroup); UE->rnti = UE->secondaryCellGroup->spCellConfig->reconfigurationWithSync->newUE_Identity; NR_CG_Config_t *CG_Config = calloc(1,sizeof(*CG_Config)); memset((void *)CG_Config,0,sizeof(*CG_Config)); diff --git a/openair2/RRC/NR/rrc_gNB_reconfig.c b/openair2/RRC/NR/rrc_gNB_reconfig.c index d2ef7443c3..d8e9593e08 100644 --- a/openair2/RRC/NR/rrc_gNB_reconfig.c +++ b/openair2/RRC/NR/rrc_gNB_reconfig.c @@ -49,14 +49,10 @@ #include "nr_rrc_config.h" #include "MESSAGES/asn1_msg.h" -void fill_default_reconfig(NR_ServingCellConfigCommon_t *servingcellconfigcommon, - NR_ServingCellConfig_t *servingcellconfigdedicated, - NR_RRCReconfiguration_IEs_t *reconfig, - NR_CellGroupConfig_t *secondaryCellGroup, - NR_UE_NR_Capability_t *uecap, - int uid) { - AssertFatal(servingcellconfigcommon!=NULL,"servingcellconfigcommon is null\n"); - AssertFatal(reconfig!=NULL,"reconfig is null\n"); +NR_RRCReconfiguration_IEs_t *get_default_reconfig(const NR_CellGroupConfig_t *secondaryCellGroup) +{ + NR_RRCReconfiguration_IEs_t *reconfig = calloc(1, sizeof(NR_RRCReconfiguration_IEs_t)); + AssertFatal(reconfig != NULL, "out of memory\n"); AssertFatal(secondaryCellGroup!=NULL,"secondaryCellGroup is null\n"); // radioBearerConfig reconfig->radioBearerConfig=NULL; @@ -74,6 +70,7 @@ void fill_default_reconfig(NR_ServingCellConfigCommon_t *servingcellconfigcommon reconfig->lateNonCriticalExtension = NULL; // nonCriticalExtension reconfig->nonCriticalExtension = NULL; + return reconfig; } /* Function to set or overwrite PTRS DL RRC parameters */ From 6b62c4378b9542f2dc501878421a0625c368fbc2 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Wed, 10 Jul 2024 19:01:24 +0200 Subject: [PATCH 05/14] Refactor generate_CG_Config(): return CG_Config Simplify code by returning an allocated object to a CG_Config. It leads to less code and is easier to reason about, because each call will return a new CG_Config, which can be freed, irrespective of other calls to fill_default_reconfig(). --- openair2/RRC/NR/nr_rrc_proto.h | 5 +---- openair2/RRC/NR/rrc_gNB_internode.c | 13 ++++--------- openair2/RRC/NR/rrc_gNB_nsa.c | 6 ++---- 3 files changed, 7 insertions(+), 17 deletions(-) diff --git a/openair2/RRC/NR/nr_rrc_proto.h b/openair2/RRC/NR/nr_rrc_proto.h index c3f5dd7eb4..235b774bde 100644 --- a/openair2/RRC/NR/nr_rrc_proto.h +++ b/openair2/RRC/NR/nr_rrc_proto.h @@ -68,10 +68,7 @@ void rrc_remove_ue(gNB_RRC_INST *rrc, rrc_gNB_ue_context_t *ue_context_p); NR_RRCReconfiguration_IEs_t *get_default_reconfig(const NR_CellGroupConfig_t *secondaryCellGroup); -int generate_CG_Config(gNB_RRC_INST *rrc, - NR_CG_Config_t *cg_Config, - NR_RRCReconfiguration_t *reconfig, - NR_RadioBearerConfig_t *rbconfig); +NR_CG_Config_t *generate_CG_Config(const NR_RRCReconfiguration_t *reconfig, const NR_RadioBearerConfig_t *rbconfig); int parse_CG_ConfigInfo(gNB_RRC_INST *rrc, NR_CG_ConfigInfo_t *CG_ConfigInfo, x2ap_ENDC_sgnb_addition_req_t *m); diff --git a/openair2/RRC/NR/rrc_gNB_internode.c b/openair2/RRC/NR/rrc_gNB_internode.c index 19230f179a..add6823e15 100644 --- a/openair2/RRC/NR/rrc_gNB_internode.c +++ b/openair2/RRC/NR/rrc_gNB_internode.c @@ -79,17 +79,14 @@ int parse_CG_ConfigInfo(gNB_RRC_INST *rrc, NR_CG_ConfigInfo_t *CG_ConfigInfo, x2 return(0); } - -int generate_CG_Config(gNB_RRC_INST *rrc, - NR_CG_Config_t *cg_Config, - NR_RRCReconfiguration_t *reconfig, - NR_RadioBearerConfig_t *rbconfig) { +NR_CG_Config_t *generate_CG_Config(const NR_RRCReconfiguration_t *reconfig, const NR_RadioBearerConfig_t *rbconfig) +{ + NR_CG_Config_t *cg_Config = calloc(1, sizeof(*cg_Config)); cg_Config->criticalExtensions.present = NR_CG_Config__criticalExtensions_PR_c1; cg_Config->criticalExtensions.choice.c1 = calloc(1,sizeof(*cg_Config->criticalExtensions.choice.c1)); cg_Config->criticalExtensions.choice.c1->present = NR_CG_Config__criticalExtensions__c1_PR_cg_Config; cg_Config->criticalExtensions.choice.c1->choice.cg_Config = calloc(1,sizeof(NR_CG_Config_IEs_t)); char buffer[1024]; - int total_size; asn_enc_rval_t enc_rval = uper_encode_to_buffer(&asn_DEF_NR_RRCReconfiguration, NULL, (void *)reconfig, buffer, 1024); AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %jd)!\n", enc_rval.failed_type->name, enc_rval.encoded); @@ -97,7 +94,6 @@ int generate_CG_Config(gNB_RRC_INST *rrc, OCTET_STRING_fromBuf(cg_Config->criticalExtensions.choice.c1->choice.cg_Config->scg_CellGroupConfig, (const char *)buffer, (enc_rval.encoded+7)>>3); - total_size = (enc_rval.encoded+7)>>3; FILE *fd; // file to be generated for nr-ue if (get_softmodem_params()->phy_test==1 || get_softmodem_params()->do_ra > 0 || get_softmodem_params()->sa == 1) { @@ -140,8 +136,7 @@ int generate_CG_Config(gNB_RRC_INST *rrc, } } - total_size = total_size + ((enc_rval.encoded+7)>>3); - return(total_size); + return cg_Config; } #endif diff --git a/openair2/RRC/NR/rrc_gNB_nsa.c b/openair2/RRC/NR/rrc_gNB_nsa.c index 41e9700208..816407322f 100644 --- a/openair2/RRC/NR/rrc_gNB_nsa.c +++ b/openair2/RRC/NR/rrc_gNB_nsa.c @@ -259,10 +259,8 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc, rrc_gNB_ue_context_t *ue_context_p, x2a UE->reconfig->criticalExtensions.choice.rrcReconfiguration = get_default_reconfig(UE->secondaryCellGroup); UE->rnti = UE->secondaryCellGroup->spCellConfig->reconfigurationWithSync->newUE_Identity; - NR_CG_Config_t *CG_Config = calloc(1,sizeof(*CG_Config)); - memset((void *)CG_Config,0,sizeof(*CG_Config)); - // int CG_Config_size = generate_CG_Config(rrc,CG_Config,UE->reconfig,UE->rb_config); - generate_CG_Config(rrc, CG_Config, UE->reconfig, UE->rb_config); + + NR_CG_Config_t *CG_Config = generate_CG_Config(UE->reconfig, UE->rb_config); if(m!=NULL) { uint8_t inde_list[m->nb_e_rabs_tobeadded]; From 3a18c17d5a3a7f1cca183cd24ad398aa9a01ff0f Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Wed, 10 Jul 2024 17:15:18 +0200 Subject: [PATCH 06/14] Remove "global" UE variable reconfig Variable reconfig is only used in function rrc_add_nsa_user(). Make it local to this function to prevent possible bugs (limit the possible scope as much as possible). --- openair2/RRC/NR/nr_rrc_defs.h | 1 - openair2/RRC/NR/rrc_gNB_nsa.c | 11 +++++------ 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/openair2/RRC/NR/nr_rrc_defs.h b/openair2/RRC/NR/nr_rrc_defs.h index fabcd51df0..502a21580c 100644 --- a/openair2/RRC/NR/nr_rrc_defs.h +++ b/openair2/RRC/NR/nr_rrc_defs.h @@ -271,7 +271,6 @@ typedef struct gNB_RRC_UE_s { NR_CellGroupConfig_t *secondaryCellGroup; NR_CellGroupConfig_t *masterCellGroup; - NR_RRCReconfiguration_t *reconfig; NR_RadioBearerConfig_t *rb_config; ImsiMobileIdentity_t imsi; diff --git a/openair2/RRC/NR/rrc_gNB_nsa.c b/openair2/RRC/NR/rrc_gNB_nsa.c index 816407322f..5d0668c4dc 100644 --- a/openair2/RRC/NR/rrc_gNB_nsa.c +++ b/openair2/RRC/NR/rrc_gNB_nsa.c @@ -155,10 +155,6 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc, rrc_gNB_ue_context_t *ue_context_p, x2a } // NR RRCReconfiguration - UE->reconfig = calloc(1, sizeof(NR_RRCReconfiguration_t)); - memset((void *)UE->reconfig, 0, sizeof(NR_RRCReconfiguration_t)); - UE->reconfig->rrc_TransactionIdentifier = 0; - UE->reconfig->criticalExtensions.present = NR_RRCReconfiguration__criticalExtensions_PR_rrcReconfiguration; if (get_softmodem_params()->phy_test == 1 || get_softmodem_params()->do_ra == 1 || get_softmodem_params()->sa == 1){ UE->rb_config = get_default_rbconfig(10 /* EPS bearer ID */, 1 /* drb ID */, NR_CipheringAlgorithm_nea0, NR_SecurityConfig__keyToUse_master); } else { @@ -257,10 +253,13 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc, rrc_gNB_ue_context_t *ue_context_p, x2a AssertFatal(UE->secondaryCellGroup != NULL, "out of memory\n"); xer_fprint(stdout, &asn_DEF_NR_CellGroupConfig, UE->secondaryCellGroup); - UE->reconfig->criticalExtensions.choice.rrcReconfiguration = get_default_reconfig(UE->secondaryCellGroup); + NR_RRCReconfiguration_t *reconfig = calloc(1, sizeof(NR_RRCReconfiguration_t)); + reconfig->rrc_TransactionIdentifier = 0; + reconfig->criticalExtensions.present = NR_RRCReconfiguration__criticalExtensions_PR_rrcReconfiguration; + reconfig->criticalExtensions.choice.rrcReconfiguration = get_default_reconfig(UE->secondaryCellGroup); UE->rnti = UE->secondaryCellGroup->spCellConfig->reconfigurationWithSync->newUE_Identity; - NR_CG_Config_t *CG_Config = generate_CG_Config(UE->reconfig, UE->rb_config); + NR_CG_Config_t *CG_Config = generate_CG_Config(reconfig, UE->rb_config); if(m!=NULL) { uint8_t inde_list[m->nb_e_rabs_tobeadded]; From 05aa348f80f45c15d935c25a00ca573a033f5a13 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Wed, 10 Jul 2024 19:05:21 +0200 Subject: [PATCH 07/14] Remove "global" UE variable spCellConfig Variable spCellConfig is only used in function rrc_add_nsa_user(). Make it local to this function to prevent possible bugs (limit the possible scope as much as possible). --- openair2/RRC/NR/nr_rrc_defs.h | 1 - openair2/RRC/NR/rrc_gNB.c | 3 --- openair2/RRC/NR/rrc_gNB_nsa.c | 4 +--- 3 files changed, 1 insertion(+), 7 deletions(-) diff --git a/openair2/RRC/NR/nr_rrc_defs.h b/openair2/RRC/NR/nr_rrc_defs.h index 502a21580c..7c8a1d68e4 100644 --- a/openair2/RRC/NR/nr_rrc_defs.h +++ b/openair2/RRC/NR/nr_rrc_defs.h @@ -317,7 +317,6 @@ typedef struct gNB_RRC_UE_s { uint32_t ue_rrc_inactivity_timer; uint32_t ue_reestablishment_counter; uint32_t ue_reconfiguration_counter; - struct NR_SpCellConfig *spCellConfig; /* NGUEContextSetup might come with PDU sessions, but setup needs to be * delayed after security (and capability); PDU sessions are stored here */ diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index 266728fd54..e45786396c 100644 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -228,9 +228,6 @@ static void init_NR_SI(gNB_RRC_INST *rrc) if (get_softmodem_params()->phy_test > 0 || get_softmodem_params()->do_ra > 0) { AssertFatal(NODE_IS_MONOLITHIC(rrc->node_type), "phy_test and do_ra only work in monolithic\n"); rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_allocate_new_ue_context(rrc); - gNB_RRC_UE_t *UE = &ue_context_p->ue_context; - UE->spCellConfig = calloc(1, sizeof(struct NR_SpCellConfig)); - UE->spCellConfig->spCellConfigDedicated = RC.nrmac[0]->common_channels[0].pre_ServingCellConfig; LOG_I(NR_RRC,"Adding new user (%p)\n",ue_context_p); if (!NODE_IS_CU(RC.nrrrc[0]->node_type)) { rrc_add_nsa_user(rrc,ue_context_p,NULL); diff --git a/openair2/RRC/NR/rrc_gNB_nsa.c b/openair2/RRC/NR/rrc_gNB_nsa.c index 5d0668c4dc..c1a43a9c97 100644 --- a/openair2/RRC/NR/rrc_gNB_nsa.c +++ b/openair2/RRC/NR/rrc_gNB_nsa.c @@ -106,8 +106,6 @@ void rrc_parse_ue_capabilities(gNB_RRC_INST *rrc, NR_UE_CapabilityRAT_ContainerL LOG_A(NR_RRC, "Successfully decoded UE NR capabilities (NR and MRDC)\n"); AssertFatal(NODE_IS_MONOLITHIC(rrc->node_type), "phy_test and do_ra only work in monolithic\n"); - UE->spCellConfig = calloc(1, sizeof(struct NR_SpCellConfig)); - UE->spCellConfig->spCellConfigDedicated = RC.nrmac[0]->common_channels[0].pre_ServingCellConfig; LOG_I(NR_RRC,"Adding new NSA user (%p)\n",ue_context_p); rrc_add_nsa_user(rrc,ue_context_p, m); } @@ -238,7 +236,7 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc, rrc_gNB_ue_context_t *ue_context_p, x2a UE->rb_config = get_default_rbconfig(m->e_rabs_tobeadded[0].e_rab_id, m->e_rabs_tobeadded[0].drb_ID, cipher_algo, NR_SecurityConfig__keyToUse_secondary); } - NR_ServingCellConfig_t *scc = UE->spCellConfig ? UE->spCellConfig->spCellConfigDedicated : NULL; + NR_ServingCellConfig_t *scc = RC.nrmac[0]->common_channels[0].pre_ServingCellConfig; // The MAC has the ServingCellConfigCommon; the below code is incorrect: the // CU should send a UE Context Setup Request to request the creating of the // MAC Context From 09675f654424497c7d7b03fbfb1469c545d99a97 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Wed, 10 Jul 2024 17:16:44 +0200 Subject: [PATCH 08/14] get_default_secondaryCellGroup(): make servingCellConfig const We simply don't need to modify the servingCellConfig, so don't do it. --- openair2/RRC/NR/nr_rrc_config.c | 8 +------- openair2/RRC/NR/nr_rrc_config.h | 2 +- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/openair2/RRC/NR/nr_rrc_config.c b/openair2/RRC/NR/nr_rrc_config.c index 8cbf3d8adb..597dba1cdd 100644 --- a/openair2/RRC/NR/nr_rrc_config.c +++ b/openair2/RRC/NR/nr_rrc_config.c @@ -3040,7 +3040,7 @@ static NR_ServingCellConfigCommon_t *clone_ServingCellConfigCommon(const NR_Serv } NR_CellGroupConfig_t *get_default_secondaryCellGroup(const NR_ServingCellConfigCommon_t *servingcellconfigcommon, - NR_ServingCellConfig_t *servingcellconfigdedicated, + const NR_ServingCellConfig_t *servingcellconfigdedicated, const NR_UE_NR_Capability_t *uecap, int scg_id, int servCellIndex, @@ -3058,7 +3058,6 @@ NR_CellGroupConfig_t *get_default_secondaryCellGroup(const NR_ServingCellConfigC LOG_E(RRC, "No UE Capabilities available when programming default CellGroup in NSA\n"); uint64_t bitmap = get_ssb_bitmap(servingcellconfigcommon); - // See comment at the end of this function regarding ServingCellConfig NR_CellGroupConfig_t *secondaryCellGroup = calloc(1, sizeof(*secondaryCellGroup)); secondaryCellGroup->cellGroupId = scg_id; @@ -3362,11 +3361,6 @@ NR_CellGroupConfig_t *get_default_secondaryCellGroup(const NR_ServingCellConfigC secondaryCellGroup->spCellConfig->spCellConfigDedicated->pathlossReferenceLinking = NULL; secondaryCellGroup->spCellConfig->spCellConfigDedicated->servingCellMO = NULL; - // this is pure evil: We should only pass in a ServingCellConfig, without - // modifying it! TODO: make a separate function that creates a - // ServingCellConfig, and reuse it here - *servingcellconfigdedicated = *secondaryCellGroup->spCellConfig->spCellConfigDedicated; - if (LOG_DEBUGFLAG(DEBUG_ASN1)) { xer_fprint(stdout, &asn_DEF_NR_SpCellConfig, (void *)secondaryCellGroup->spCellConfig); } diff --git a/openair2/RRC/NR/nr_rrc_config.h b/openair2/RRC/NR/nr_rrc_config.h index d46363c707..e3f4fed7cb 100644 --- a/openair2/RRC/NR/nr_rrc_config.h +++ b/openair2/RRC/NR/nr_rrc_config.h @@ -91,7 +91,7 @@ NR_CellGroupConfig_t *decode_cellGroupConfig(const uint8_t *buffer, int max_buff * configuration, but it will also overwrite the ServingCellConfig passed in * parameter servingcellconfigdedicated! */ NR_CellGroupConfig_t *get_default_secondaryCellGroup(const NR_ServingCellConfigCommon_t *servingcellconfigcommon, - NR_ServingCellConfig_t *servingcellconfigdedicated, + const NR_ServingCellConfig_t *servingcellconfigdedicated, const NR_UE_NR_Capability_t *uecap, int scg_id, int servCellIndex, From 3d2bf72efa3820eb6070f769939102d07bdc125b Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 11 Jul 2024 07:41:45 +0200 Subject: [PATCH 09/14] Use correct RRC UE ID for NSA UEs The RRC UE context has the RRC UE ID. Use that instead of hardcoding something that might be wrong (because the RRC UE ID can be reused, whereas the counter just blindly increases). The next commit will use that RRC UE ID to free the PDCP context for the UE. It might be wrong on reattach otherwise, because the RRC UE ID could again be 1. --- openair2/RRC/NR/rrc_gNB_nsa.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/openair2/RRC/NR/rrc_gNB_nsa.c b/openair2/RRC/NR/rrc_gNB_nsa.c index c1a43a9c97..a8bc072609 100644 --- a/openair2/RRC/NR/rrc_gNB_nsa.c +++ b/openair2/RRC/NR/rrc_gNB_nsa.c @@ -344,8 +344,7 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc, rrc_gNB_ue_context_t *ue_context_p, x2a // layers use different IDs (MAC/RLC use RNTI as DU UE ID, above use NGAP ID // as CU UE ID. uint32_t du_ue_id = ue_context_p->ue_context.rnti; - static uint32_t rrc_ue_id = 0; - rrc_ue_id++; + uint32_t rrc_ue_id = ue_context_p->ue_context.rrc_ue_id; f1_ue_data_t du_ue_data = {.secondary_ue = rrc_ue_id}; du_add_f1_ue_data(du_ue_id, &du_ue_data); f1_ue_data_t cu_ue_data = {.secondary_ue = du_ue_id}; From ef1c85e0996c2d85528f9dfc0e62d623f9aa51cd Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Tue, 16 Jul 2024 10:43:23 +0200 Subject: [PATCH 10/14] Use correct RRC UE ID for PDCP, print warning if not existing --- openair2/LAYER2/nr_pdcp/nr_pdcp_ue_manager.c | 2 +- openair2/RRC/NR/rrc_gNB_nsa.c | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_ue_manager.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_ue_manager.c index 7a240a3379..07edfb5814 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_ue_manager.c +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_ue_manager.c @@ -124,7 +124,7 @@ void nr_pdcp_manager_remove_ue(nr_pdcp_ue_manager_t *_m, ue_id_t UEid) break; if (i == m->ue_count) { - LOG_D(PDCP, "%s:%d:%s: warning: UE ID/RNTI 0x%" PRIx64 " not found\n", __FILE__, __LINE__, __FUNCTION__, UEid); + LOG_W(PDCP, "%s:%d:%s: warning: UE ID/RNTI 0x%" PRIx64 " not found\n", __FILE__, __LINE__, __FUNCTION__, UEid); return; } diff --git a/openair2/RRC/NR/rrc_gNB_nsa.c b/openair2/RRC/NR/rrc_gNB_nsa.c index a8bc072609..0c8423ead1 100644 --- a/openair2/RRC/NR/rrc_gNB_nsa.c +++ b/openair2/RRC/NR/rrc_gNB_nsa.c @@ -412,8 +412,7 @@ void rrc_remove_nsa_user(gNB_RRC_INST *rrc, int rnti) { return; } - nr_pdcp_remove_UE(ctxt.rntiMaybeUEid); - + nr_pdcp_remove_UE(ue_context->ue_context.rrc_ue_id); rrc_rlc_remove_ue(&ctxt); // lock the scheduler before removing the UE. Note: mac_remove_nr_ue() checks From 0a997ee08e82335870e80c4ceddd0763aaa6ec35 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 11 Jul 2024 09:31:12 +0200 Subject: [PATCH 11/14] Do not print all XnAP logs NSA is quite verbose, some messages are large and it is not very "interesting" for the average user. The logs can be enabled on demand, or directly seen in Wireshark instead. --- openair2/X2AP/x2ap_eNB_encoder.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openair2/X2AP/x2ap_eNB_encoder.c b/openair2/X2AP/x2ap_eNB_encoder.c index 392206e4d7..8b1c030d35 100644 --- a/openair2/X2AP/x2ap_eNB_encoder.c +++ b/openair2/X2AP/x2ap_eNB_encoder.c @@ -44,9 +44,9 @@ int x2ap_eNB_encode_pdu(X2AP_X2AP_PDU_t *pdu, uint8_t **buffer, uint32_t *len) DevAssert(buffer != NULL); DevAssert(len != NULL); - //if (asn1_xer_print) { + if (asn1_xer_print) { xer_fprint(stdout, &asn_DEF_X2AP_X2AP_PDU, (void *)pdu); - //} + } encoded = aper_encode_to_new_buffer(&asn_DEF_X2AP_X2AP_PDU, 0, pdu, (void **)buffer); From e77912a5b943f5bce46e1f3806b4102838ece98a Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 11 Jul 2024 09:44:42 +0200 Subject: [PATCH 12/14] Refactor: store secondaryCellGroup only at MAC Remove the secondaryCellGroup variable in RRC, as it is not used there. Note that in the case of F1, the secondaryCellGroup entirely belongs to the DU, i.e., MAC. Also, we don't do anything with it in RRC. --- openair2/RRC/NR/nr_rrc_defs.h | 1 - openair2/RRC/NR/rrc_gNB_nsa.c | 26 +++++++++----------------- 2 files changed, 9 insertions(+), 18 deletions(-) diff --git a/openair2/RRC/NR/nr_rrc_defs.h b/openair2/RRC/NR/nr_rrc_defs.h index 7c8a1d68e4..961406986a 100644 --- a/openair2/RRC/NR/nr_rrc_defs.h +++ b/openair2/RRC/NR/nr_rrc_defs.h @@ -269,7 +269,6 @@ typedef struct gNB_RRC_UE_s { NR_UE_MRDC_Capability_t* UE_Capability_MRDC; int UE_MRDC_Capability_size; - NR_CellGroupConfig_t *secondaryCellGroup; NR_CellGroupConfig_t *masterCellGroup; NR_RadioBearerConfig_t *rb_config; diff --git a/openair2/RRC/NR/rrc_gNB_nsa.c b/openair2/RRC/NR/rrc_gNB_nsa.c index 0c8423ead1..abe45dbdae 100644 --- a/openair2/RRC/NR/rrc_gNB_nsa.c +++ b/openair2/RRC/NR/rrc_gNB_nsa.c @@ -241,21 +241,15 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc, rrc_gNB_ue_context_t *ue_context_p, x2a // CU should send a UE Context Setup Request to request the creating of the // MAC Context NR_ServingCellConfigCommon_t *sccc = RC.nrmac[0]->common_channels[0].ServingCellConfigCommon; - UE->secondaryCellGroup = get_default_secondaryCellGroup(sccc, - scc, - UE->UE_Capability_nr, - 1, - 1, - configuration, - ue_context_p->ue_context.rrc_ue_id); - AssertFatal(UE->secondaryCellGroup != NULL, "out of memory\n"); - xer_fprint(stdout, &asn_DEF_NR_CellGroupConfig, UE->secondaryCellGroup); + NR_CellGroupConfig_t *secondaryCellGroup = + get_default_secondaryCellGroup(sccc, scc, UE->UE_Capability_nr, 1, 1, configuration, ue_context_p->ue_context.rrc_ue_id); + AssertFatal(secondaryCellGroup != NULL, "out of memory\n"); NR_RRCReconfiguration_t *reconfig = calloc(1, sizeof(NR_RRCReconfiguration_t)); reconfig->rrc_TransactionIdentifier = 0; reconfig->criticalExtensions.present = NR_RRCReconfiguration__criticalExtensions_PR_rrcReconfiguration; - reconfig->criticalExtensions.choice.rrcReconfiguration = get_default_reconfig(UE->secondaryCellGroup); - UE->rnti = UE->secondaryCellGroup->spCellConfig->reconfigurationWithSync->newUE_Identity; + reconfig->criticalExtensions.choice.rrcReconfiguration = get_default_reconfig(secondaryCellGroup); + UE->rnti = secondaryCellGroup->spCellConfig->reconfigurationWithSync->newUE_Identity; NR_CG_Config_t *CG_Config = generate_CG_Config(reconfig, UE->rb_config); @@ -328,7 +322,7 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc, rrc_gNB_ue_context_t *ue_context_p, x2a LOG_W(RRC, "No E-RAB to be added received from SgNB Addition Request message \n"); X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).MeNB_ue_x2_id = m->ue_x2_id; - X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).SgNB_ue_x2_id = UE->secondaryCellGroup->spCellConfig->reconfigurationWithSync->newUE_Identity; + X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).SgNB_ue_x2_id = secondaryCellGroup->spCellConfig->reconfigurationWithSync->newUE_Identity; //X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).rrc_buffer_size = CG_Config_size; //Need to verify correct value for the buffer_size // Send to X2 entity to transport to MeNB asn_enc_rval_t enc_rval = uper_encode_to_buffer(&asn_DEF_NR_CG_Config, @@ -355,15 +349,14 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc, rrc_gNB_ue_context_t *ue_context_p, x2a bool ret = false; if (get_softmodem_params()->phy_test) { // phytest mode: we don't set up RA, etc - ret = nr_mac_add_test_ue(RC.nrmac[rrc->module_id], du_ue_id, ue_context_p->ue_context.secondaryCellGroup); + ret = nr_mac_add_test_ue(RC.nrmac[rrc->module_id], du_ue_id, secondaryCellGroup); } else { - NR_CellGroupConfig_t *secondaryCellGroup = ue_context_p->ue_context.secondaryCellGroup; DevAssert(secondaryCellGroup->spCellConfig && secondaryCellGroup->spCellConfig->reconfigurationWithSync && secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated && secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra); NR_SCHED_LOCK(&RC.nrmac[rrc->module_id]->sched_lock); - ret = nr_mac_prepare_ra_ue(RC.nrmac[rrc->module_id], du_ue_id, ue_context_p->ue_context.secondaryCellGroup); + ret = nr_mac_prepare_ra_ue(RC.nrmac[rrc->module_id], du_ue_id, secondaryCellGroup); NR_SCHED_UNLOCK(&RC.nrmac[rrc->module_id]->sched_lock); } AssertFatal(ret, "cannot add NSA UE in MAC, aborting\n"); @@ -388,8 +381,7 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc, rrc_gNB_ue_context_t *ue_context_p, x2a const NR_DRB_ToAddModList_t *drb_list = ue_context_p->ue_context.rb_config->drb_ToAddModList; DevAssert(drb_list->list.count == 1); const NR_DRB_ToAddMod_t *drb = drb_list->list.array[0]; - const struct NR_CellGroupConfig__rlc_BearerToAddModList *bearer_list = - ue_context_p->ue_context.secondaryCellGroup->rlc_BearerToAddModList; + const struct NR_CellGroupConfig__rlc_BearerToAddModList *bearer_list = secondaryCellGroup->rlc_BearerToAddModList; const NR_RLC_BearerConfig_t *bearer = bearer_list->list.array[0]; DevAssert(bearer_list->list.count == 1); DevAssert(drb->drb_Identity == bearer->servedRadioBearer->choice.drb_Identity); From b12d3a4fc817e18bfdaaf225690b746d06251804 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Tue, 16 Jul 2024 10:02:15 +0200 Subject: [PATCH 13/14] Correct nr_clear_ra_proc() for SA+NSA case, fix memory leak In NSA, the RA process contains the RNTI of the UE to add. The previous implementation would not remove the RNTI in NSA/for CFRA, which is unclear (why should it stay? RA is over). Also, we did not clear all contents, which masked a bug, as we were reusing an RA process for a subsequent attach, leading to a segfault on reattach. That is fixed in this commit. Also, we were using the RA structure after having cleared it in _nr_rx_sdu(), which semantically makes no sense. To harmonize handling of the preambles: completely reset the RA processes inside nr_clear_ra_proc(). For SA, also add the initialization of allowed preambles. Finally, this commit fixes a memory leak: we always (also in SA) fill a list of preambles in a dynamically allocated preamble list. Since the total list is only up to 64 preambles of 1B each, put it directly into the struct instead of dynamically allocating it. --- openair2/LAYER2/NR_MAC_gNB/config.c | 20 ++++++------------- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c | 9 +++++---- .../LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c | 2 +- openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h | 2 +- 4 files changed, 13 insertions(+), 20 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/config.c b/openair2/LAYER2/NR_MAC_gNB/config.c index e165a717f7..77f794332a 100644 --- a/openair2/LAYER2/NR_MAC_gNB/config.c +++ b/openair2/LAYER2/NR_MAC_gNB/config.c @@ -603,7 +603,6 @@ void nr_mac_config_scc(gNB_MAC_INST *nrmac, NR_ServingCellConfigCommon_t *scc, c DevAssert(nrmac != NULL); DevAssert(scc != NULL); DevAssert(config != NULL); - //NR_SCHED_LOCK(&nrmac->sched_lock); AssertFatal(scc->ssb_PositionsInBurst->present > 0 && scc->ssb_PositionsInBurst->present < 4, "SSB Bitmap type %d is not valid\n", @@ -668,19 +667,13 @@ void nr_mac_config_scc(gNB_MAC_INST *nrmac, NR_ServingCellConfigCommon_t *scc, c nrmac->pre_processor_ul = nr_init_fr1_ulsch_preprocessor(0); } - if (get_softmodem_params()->sa > 0) { - NR_COMMON_channels_t *cc = &nrmac->common_channels[0]; - for (int n = 0; n < NR_NB_RA_PROC_MAX; n++) { - NR_RA_t *ra = &cc->ra[n]; - ra->cfra = false; - ra->rnti = 0; - ra->preambles.num_preambles = MAX_NUM_NR_PRACH_PREAMBLES; - ra->preambles.preamble_list = malloc(MAX_NUM_NR_PRACH_PREAMBLES * sizeof(*ra->preambles.preamble_list)); - for (int i = 0; i < MAX_NUM_NR_PRACH_PREAMBLES; i++) - ra->preambles.preamble_list[i] = i; - } + NR_COMMON_channels_t *cc = &nrmac->common_channels[0]; + NR_SCHED_LOCK(&nrmac->sched_lock); + for (int n = 0; n < NR_NB_RA_PROC_MAX; n++) { + NR_RA_t *ra = &cc->ra[n]; + nr_clear_ra_proc(ra); } - //NR_SCHED_UNLOCK(&nrmac->sched_lock); + NR_SCHED_UNLOCK(&nrmac->sched_lock); } void nr_mac_configure_sib1(gNB_MAC_INST *nrmac, const f1ap_plmn_t *plmn, uint64_t cellID, int tac) @@ -749,7 +742,6 @@ bool nr_mac_prepare_ra_ue(gNB_MAC_INST *nrmac, uint32_t rnti, NR_CellGroupConfig struct NR_CFRA *cfra = CellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra; uint8_t num_preamble = cfra->resources.choice.ssb->ssb_ResourceList.list.count; ra->preambles.num_preambles = num_preamble; - ra->preambles.preamble_list = calloc(ra->preambles.num_preambles, sizeof(*ra->preambles.preamble_list)); for (int i = 0; i < cc->num_active_ssb; i++) { for (int j = 0; j < num_preamble; j++) { if (cc->ssb_index[i] == cfra->resources.choice.ssb->ssb_ResourceList.list.array[j]->ssb) { diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c index 9daabdddaf..6fb183fb28 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c @@ -2017,11 +2017,12 @@ void nr_clear_ra_proc(NR_RA_t *ra) { /* we assume that this function is mutex-protected from outside */ NR_SCHED_ENSURE_LOCKED(&RC.nrmac[0]->sched_lock); + memset(ra, 0, sizeof(*ra)); ra->ra_state = nrRA_gNB_IDLE; - ra->timing_offset = 0; - ra->msg3_round = 0; - if(ra->cfra == false) { - ra->rnti = 0; + if (get_softmodem_params()->sa) { // in SA, prefill with allowed preambles + ra->preambles.num_preambles = MAX_NUM_NR_PRACH_PREAMBLES; + for (int i = 0; i < MAX_NUM_NR_PRACH_PREAMBLES; i++) + ra->preambles.preamble_list[i] = i; } } diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c index 89c684ee41..96d024dd70 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c @@ -851,8 +851,8 @@ static void _nr_rx_sdu(const module_id_t gnb_mod_idP, nr_mac_reset_ul_failure(UE_scheduling_control); reset_dl_harq_list(UE_scheduling_control); reset_ul_harq_list(UE_scheduling_control); - nr_clear_ra_proc(ra); process_addmod_bearers_cellGroupConfig(&UE->UE_sched_ctrl, ra->CellGroup->rlc_BearerToAddModList); + nr_clear_ra_proc(ra); } else { LOG_A(NR_MAC, "[RAPROC] RA-Msg3 received (sdu_lenP %d)\n", sdu_lenP); LOG_D(NR_MAC, "[RAPROC] Received Msg3:\n"); diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h index 7fe0c8994e..7c0095e243 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h +++ b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h @@ -159,7 +159,7 @@ typedef struct nr_mac_config_t { typedef struct NR_preamble_ue { uint8_t num_preambles; - uint8_t *preamble_list; + uint8_t preamble_list[MAX_NUM_NR_PRACH_PREAMBLES]; } NR_preamble_ue_t; typedef struct NR_sched_pdcch { From 32c238925ebc463cc8634bed9d2f8fa6898ec110 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 11 Jul 2024 11:55:10 +0200 Subject: [PATCH 14/14] Improve modes in FEATURE_SET.md and add NSA --- doc/FEATURE_SET.md | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/doc/FEATURE_SET.md b/doc/FEATURE_SET.md index ffacc9039b..b49c2e7a2f 100644 --- a/doc/FEATURE_SET.md +++ b/doc/FEATURE_SET.md @@ -36,13 +36,24 @@ The following features are valid for the gNB and the 5G-NR UE. * Encoder and decoder for short blocks * Support for UL transform precoding (SC-FDMA) -Furthermore, the gNB and UE support +These modes of operation are supported: -* "noS1" mode (DL and UL): +* "phy-test" mode (gNB, nrUE): + - gNB and nrUE have hardcoded RNTI and radio configuration + - gNB schedules the nrUE all the time, even if no UE connected + - can be used for performance evaluation +* "noS1" mode (DL and UL, gNB, nrUE): + - Connection setup stops after RA; RRC configuration is exchanged through + files - Creates TUN interface to PDCP to inject and receive user-place traffic - No connection to the core network -* Standalone (SA) mode: - - UE can register with the 5G Core Network through the gNB, establish a PDU Session and exchange user-plane traffic +* Standalone (SA) mode (gNB, nrUE): + - UE can register with the 5G Core Network through the gNB, establish a PDU + Session and exchange user-plane traffic + - Reestablishment supported +* Non-standalone (NSA) mode (gNB): + - UE can use the gNB for user plane traffic while connected to the 4G eNB + - is unstable (only one UE connection) ## gNB PHY