From e6719d7718ad5bbbdf671f9cda7f334fe9b57ae2 Mon Sep 17 00:00:00 2001 From: Thomas Schlichter Date: Tue, 9 Jul 2024 14:37:06 +0200 Subject: [PATCH 01/49] remove superfluous semicolon from multi-line macros in oai_asn1.h --- common/utils/oai_asn1.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/common/utils/oai_asn1.h b/common/utils/oai_asn1.h index cc8392b0cf..573fa94d75 100644 --- a/common/utils/oai_asn1.h +++ b/common/utils/oai_asn1.h @@ -34,7 +34,7 @@ TYPE *tmp = ORIGIN; \ ORIGIN = DESTINATION; \ DESTINATION = tmp; \ - } while(0); \ + } while (0) \ // Same as above but swapping ASN1 elements that are not pointers #define UPDATE_NP_IE(DESTINATION, ORIGIN, TYPE) \ @@ -42,7 +42,7 @@ TYPE tmp = ORIGIN; \ ORIGIN = DESTINATION; \ DESTINATION = tmp; \ - } while(0); \ + } while (0) \ // Macro handles reception of SetupRelease element ORIGIN (see NR_SetupRelease.h) // If release (NR_SetupRelease_xxx_PR_release equivalent to 1), removing structure from DESTINATION @@ -55,7 +55,7 @@ } \ if (ORIGIN->present == 2) \ UPDATE_IE(DESTINATION, ORIGIN->choice.setup, TYPE); \ - } while(0); \ + } while (0) \ // Macro handles reception of SetupRelease element ORIGIN (see NR_SetupRelease.h) // If release (NR_SetupRelease_xxx_PR_release equivalent to 1), removing structure from DESTINATION @@ -72,7 +72,7 @@ DESTINATION->present = ORIGIN->present; \ UPDATE_IE(DESTINATION->choice.setup, ORIGIN->choice.setup, TYPE); \ } \ - } while(0); \ + } while (0) \ // Macro releases entries in list TARGET if the corresponding ID is found in list SOURCE. // Prints an error if ID not found in list. From cbf84897072c18c79be59b38e2e83c60f80f6653 Mon Sep 17 00:00:00 2001 From: luis_pereira87 Date: Mon, 15 Jul 2024 13:34:13 +0100 Subject: [PATCH 02/49] Switch to BWP where RA is configured when Msg3 contains MAC CE for C-RNTI Switch to BWP where RA is configured, typically in the InitialBWP At this point, MAC CE for C-RNTI received at gNB, UE already switched and triggered RA in that BWP, need to do BWP switching also at gNB for that C-RNTI --- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c index 1048be2528..b60be4bd88 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c @@ -899,6 +899,22 @@ static void _nr_rx_sdu(const module_id_t gnb_mod_idP, reset_dl_harq_list(&UE->UE_sched_ctrl); reset_ul_harq_list(&UE->UE_sched_ctrl); + // Switch to BWP where RA is configured, typically in the InitialBWP + // At this point, UE already switched and triggered RA in that BWP, need to do BWP switching also at gNB for C-RNTI + if ((ra->DL_BWP.bwp_id != UE->current_DL_BWP.bwp_id) || (ra->UL_BWP.bwp_id != UE->current_UL_BWP.bwp_id)) { + LOG_I(NR_MAC, + "BWP switching at gNB from BWP id %ld to BWP id %ld due to RA configuration\n", + UE->current_DL_BWP.bwp_id, + ra->DL_BWP.bwp_id); + configure_UE_BWP(RC.nrmac[gnb_mod_idP], + RC.nrmac[gnb_mod_idP]->common_channels[CC_idP].ServingCellConfigCommon, + &UE->UE_sched_ctrl, + NULL, + UE, + ra->DL_BWP.bwp_id, + ra->UL_BWP.bwp_id); + } + if (UE->reconfigCellGroup) { // Nothing to do // A RRCReconfiguration message should be already pending (for example, an ongoing RRCReestablishment), and it will be From 5bde26246f543d2c1b3d2ad7dc0ec2684d4b72c1 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Wed, 10 Jul 2024 15:23:24 +0200 Subject: [PATCH 03/49] 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 04/49] 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 05/49] 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 06/49] 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 07/49] 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 08/49] 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 09/49] 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 10/49] 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 11/49] 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 12/49] 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 13/49] 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 14/49] 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 15/49] 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 16/49] 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 From 7ccc768805d334b4eab3785d121dc7e3cb0aaadf Mon Sep 17 00:00:00 2001 From: Fredrik Molander Date: Wed, 31 Jan 2024 23:12:03 +0000 Subject: [PATCH 17/49] missing sudo in Aerial entrypoint --- ci-scripts/yaml_files/sa_gnb_aerial/aerial_l1_entrypoint.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-scripts/yaml_files/sa_gnb_aerial/aerial_l1_entrypoint.sh b/ci-scripts/yaml_files/sa_gnb_aerial/aerial_l1_entrypoint.sh index f7d0cee7cd..8abb5b8b0e 100755 --- a/ci-scripts/yaml_files/sa_gnb_aerial/aerial_l1_entrypoint.sh +++ b/ci-scripts/yaml_files/sa_gnb_aerial/aerial_l1_entrypoint.sh @@ -15,7 +15,7 @@ export CUDA_MPS_PIPE_DIRECTORY=/var export CUDA_MPS_LOG_DIRECTORY=/var # Stop existing MPS -echo quit | nvidia-cuda-mps-control +sudo -E echo quit | sudo -E nvidia-cuda-mps-control # Start MPS sudo -E nvidia-cuda-mps-control -d From 2fa80efb52ea08e39bc95969eb37dad5f1f3bf51 Mon Sep 17 00:00:00 2001 From: Florian Kaltenberger Date: Tue, 21 May 2024 14:22:50 -0400 Subject: [PATCH 18/49] removing assert on RACH num_preambles>1. Instead we print an error and continue RA with only the first preamble. --- openair2/NR_PHY_INTERFACE/NR_IF_Module.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/openair2/NR_PHY_INTERFACE/NR_IF_Module.c b/openair2/NR_PHY_INTERFACE/NR_IF_Module.c index 869c0f9882..a4a6dbb973 100644 --- a/openair2/NR_PHY_INTERFACE/NR_IF_Module.c +++ b/openair2/NR_PHY_INTERFACE/NR_IF_Module.c @@ -80,7 +80,9 @@ void handle_nr_rach(NR_UL_IND_t *UL_info) LOG_D(MAC,"UL_info[Frame %d, Slot %d] Calling initiate_ra_proc RACH:SFN/SLOT:%d/%d\n", UL_info->frame, UL_info->slot, UL_info->rach_ind.sfn, UL_info->rach_ind.slot); for (int i = 0; i < UL_info->rach_ind.number_of_pdus; i++) { - AssertFatal(UL_info->rach_ind.pdu_list[i].num_preamble == 1, "More than 1 preamble not supported\n"); + if (UL_info->rach_ind.pdu_list[i].num_preamble > 1) { + LOG_E(MAC, "Not more than 1 preamble per RACH PDU supported, ignoring the rest\n"); + } nr_initiate_ra_proc(UL_info->module_id, UL_info->CC_id, UL_info->rach_ind.sfn, From 2bee8edcabdcc04e403f3bfd275eef4454502a31 Mon Sep 17 00:00:00 2001 From: Florian Kaltenberger Date: Wed, 3 Jul 2024 14:44:44 -0400 Subject: [PATCH 19/49] making nvIPC thread more configurable + cleanup making aerial shm prefix configurable (so we can use muliptle VNFs per PNF) making the nvipc thread affinity configurable and using threadCreate. removing aerial_vnf_nr_aerial_p7_start_thread --- executables/nr-softmodem.c | 4 +- nfapi/oai_integration/aerial/fapi_nvIPC.c | 38 ++------ nfapi/oai_integration/aerial/fapi_nvIPC.h | 2 +- nfapi/oai_integration/aerial/fapi_vnf_p5.c | 92 +------------------ nfapi/oai_integration/aerial/fapi_vnf_p5.h | 1 - openair2/GNB_APP/MACRLC_nr_paramdef.h | 8 ++ openair2/GNB_APP/gnb_config.c | 5 +- openair2/GNB_APP/gnb_paramdef.h | 2 + openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h | 2 + radio/COMMON/common_lib.h | 5 + .../CONF/gnb-vnf.sa.band78.273prb.aerial.conf | 7 +- 11 files changed, 45 insertions(+), 121 deletions(-) diff --git a/executables/nr-softmodem.c b/executables/nr-softmodem.c index ac6a2e88bd..e69f2dc0ad 100644 --- a/executables/nr-softmodem.c +++ b/executables/nr-softmodem.c @@ -79,6 +79,7 @@ unsigned short config_frames[4] = {2,9,11,13}; #include "nfapi/oai_integration/vendor_ext.h" #include "gnb_config.h" #include "openair2/E1AP/e1ap_common.h" +#include "LAYER2/NR_MAC_gNB/nr_mac_gNB.h" #ifdef ENABLE_AERIAL #include "nfapi/oai_integration/aerial/fapi_nvIPC.h" #endif @@ -748,7 +749,8 @@ int main( int argc, char **argv ) { if (RC.nb_RU > 0) start_NR_RU(); #ifdef ENABLE_AERIAL - nvIPC_Init(); + gNB_MAC_INST *nrmac = RC.nrmac[0]; + nvIPC_Init(nrmac->nvipc_params_s); #endif if (RC.nb_nr_L1_inst > 0) { printf("wait RUs\n"); diff --git a/nfapi/oai_integration/aerial/fapi_nvIPC.c b/nfapi/oai_integration/aerial/fapi_nvIPC.c index de6aae93dc..46a28c440e 100644 --- a/nfapi/oai_integration/aerial/fapi_nvIPC.c +++ b/nfapi/oai_integration/aerial/fapi_nvIPC.c @@ -590,24 +590,12 @@ static int aerial_recv_msg(nv_ipc_t *ipc, nv_ipc_msg_t *recv_msg) } bool recv_task_running = false; -int stick_this_thread_to_core(int core_id) -{ - int num_cores = sysconf(_SC_NPROCESSORS_ONLN); - if (core_id < 0 || core_id >= num_cores) - return EINVAL; - - cpu_set_t cpuset; - CPU_ZERO(&cpuset); - CPU_SET(core_id, &cpuset); - - pthread_t current_thread = pthread_self(); - return pthread_setaffinity_np(current_thread, sizeof(cpu_set_t), &cpuset); -} void *epoll_recv_task(void *arg) { struct epoll_event ev, events[MAX_EVENTS]; - stick_this_thread_to_core(10); + LOG_D(NFAPI_VNF,"Aerial recv task start \n"); + int epoll_fd = epoll_create1(0); if (epoll_fd == -1) { LOG_E(NFAPI_VNF, "%s epoll_create failed\n", __func__); @@ -649,19 +637,10 @@ void *epoll_recv_task(void *arg) return NULL; } -int create_recv_thread(void) +void create_recv_thread(int8_t affinity) { pthread_t thread_id; - - void *(*recv_task)(void *); - - recv_task = epoll_recv_task; - - int ret = pthread_create(&thread_id, NULL, recv_task, NULL); - if (ret != 0) { - LOG_E(NFAPI_VNF, "%s failed, ret = %d\n", __func__, ret); - } - return ret; + threadCreate(&thread_id, epoll_recv_task, NULL, "vnf_nvipc_aerial", affinity, OAI_PRIORITY_RT); } int load_hard_code_config(nv_ipc_config_t *config, int module_type, nv_ipc_transport_t _transport) @@ -689,17 +668,20 @@ int load_hard_code_config(nv_ipc_config_t *config, int module_type, nv_ipc_trans return 0; } -int nvIPC_Init() { -// Want to use transport SHM, type epoll, module secondary (reads the created shm from cuphycontroller) +int nvIPC_Init(nvipc_params_t nvipc_params_s) +{ + // Want to use transport SHM, type epoll, module secondary (reads the created shm from cuphycontroller) load_hard_code_config(&nv_ipc_config, NV_IPC_MODULE_SECONDARY, NV_IPC_TRANSPORT_SHM); // Create nv_ipc_t instance + LOG_I(NFAPI_VNF, "%s: creating IPC interface with prefix %s\n", __func__, nvipc_params_s.nvipc_shm_prefix); + strcpy(nv_ipc_config.transport_config.shm.prefix, nvipc_params_s.nvipc_shm_prefix); if ((ipc = create_nv_ipc_interface(&nv_ipc_config)) == NULL) { LOG_E(NFAPI_VNF, "%s: create IPC interface failed\n", __func__); return -1; } LOG_I(NFAPI_VNF, "%s: create IPC interface successful\n", __func__); sleep(1); - create_recv_thread(); + create_recv_thread(nvipc_params_s.nvipc_poll_core); while(!recv_task_running){usleep(100000);} aerial_pnf_nr_connection_indication_cb(vnf_config, 1); return 0; diff --git a/nfapi/oai_integration/aerial/fapi_nvIPC.h b/nfapi/oai_integration/aerial/fapi_nvIPC.h index 0fe559658c..6910370495 100644 --- a/nfapi/oai_integration/aerial/fapi_nvIPC.h +++ b/nfapi/oai_integration/aerial/fapi_nvIPC.h @@ -55,7 +55,7 @@ int aerial_send_P7_msg_with_data(void *packedBuf, uint32_t dataLength, nfapi_p7_message_header_t *header); void set_config(nfapi_vnf_config_t *conf); -int nvIPC_Init(); +int nvIPC_Init(nvipc_params_t); #endif // OPENAIRINTERFACE_FAPI_NVIPC_H #endif diff --git a/nfapi/oai_integration/aerial/fapi_vnf_p5.c b/nfapi/oai_integration/aerial/fapi_vnf_p5.c index 20236a2a85..fee8fd8f9e 100644 --- a/nfapi/oai_integration/aerial/fapi_vnf_p5.c +++ b/nfapi/oai_integration/aerial/fapi_vnf_p5.c @@ -43,38 +43,9 @@ extern uint16_t sf_ahead; extern uint16_t slot_ahead; -static pthread_t vnf_aerial_p7_start_pthread; -void *aerial_vnf_nr_aerial_p7_start_thread(void *ptr) +void *aerial_vnf_nr_p7_config_init(void *ptr) { - NFAPI_TRACE(NFAPI_TRACE_INFO, "%s()\n", __FUNCTION__); - pthread_setname_np(pthread_self(), "VNF_P7_AERIAL"); - nfapi_vnf_p7_config_t *config = (nfapi_vnf_p7_config_t *)ptr; - aerial_nfapi_nr_vnf_p7_start(config); - return config; -} - -void *aerial_vnf_nr_p7_thread_start(void *ptr) -{ - int s; - cpu_set_t cpuset; - -// CPU_SET(8, &cpuset); -// s = pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset); -// if (s != 0) -// printf("failed to set afinity\n"); - - pthread_attr_t ptAttr; - if (pthread_attr_setschedpolicy(&ptAttr, SCHED_RR) != 0) { - printf("Failed to set pthread sched policy SCHED_RR\n"); - } - - pthread_attr_setinheritsched(&ptAttr, PTHREAD_EXPLICIT_SCHED); - struct sched_param thread_params; - thread_params.sched_priority = 20; - - if (pthread_attr_setschedparam(&ptAttr, &thread_params) != 0) { - printf("failed to set sched param\n"); - } + vnf_p7_info *p7_vnf = (vnf_p7_info *)ptr; init_queue(&gnb_rach_ind_queue); init_queue(&gnb_rx_ind_queue); @@ -82,7 +53,6 @@ void *aerial_vnf_nr_p7_thread_start(void *ptr) init_queue(&gnb_uci_ind_queue); init_queue(&gnb_slot_ind_queue); - vnf_p7_info *p7_vnf = (vnf_p7_info *)ptr; p7_vnf->config->port = p7_vnf->local_port; p7_vnf->config->sync_indication = &aerial_phy_sync_indication; p7_vnf->config->slot_indication = &aerial_phy_slot_indication; @@ -112,8 +82,7 @@ void *aerial_vnf_nr_p7_thread_start(void *ptr) p7_vnf->config->codec_config.deallocate = &aerial_vnf_deallocate; p7_vnf->config->allocate_p7_vendor_ext = &aerial_phy_allocate_p7_vendor_ext; p7_vnf->config->deallocate_p7_vendor_ext = &aerial_phy_deallocate_p7_vendor_ext; - NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] Creating VNF NFAPI P7 start thread %s\n", __FUNCTION__); - threadCreate(&vnf_aerial_p7_start_pthread, &aerial_vnf_nr_aerial_p7_start_thread, p7_vnf->config, "aerial_p7_start", -1, OAI_PRIORITY_RT); + return 0; } @@ -223,13 +192,7 @@ int aerial_pnf_nr_start_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_nr vnf->p7_vnfs[0].config, vnf->p7_vnfs[0].thread_started); - if (p7_vnf->thread_started == 0) { - pthread_t vnf_p7_thread; - threadCreate(&vnf_p7_thread, &aerial_vnf_nr_p7_thread_start, p7_vnf, "aerial_p7_thread", -1, OAI_PRIORITY_RT); - p7_vnf->thread_started = 1; - } else { - // P7 thread already running. - } + aerial_vnf_nr_p7_config_init(p7_vnf); // start all the phys in the pnf. NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] Sending NFAPI_VNF_PARAM_REQUEST phy_id:%d\n", pnf->phys[0].id); @@ -566,13 +529,7 @@ void aerial_configure_nr_fapi_vnf() vnf->p7_vnfs[0].config, vnf->p7_vnfs[0].thread_started); - if (p7_vnf->thread_started == 0) { - pthread_t vnf_p7_thread; - threadCreate(&vnf_p7_thread, &aerial_vnf_nr_p7_thread_start, p7_vnf, "aerial_p7_thread", -1, OAI_PRIORITY_RT); - p7_vnf->thread_started = 1; - } else { - // P7 thread already running. - } + aerial_vnf_nr_p7_config_init(p7_vnf); } uint8_t aerial_unpack_nr_param_response(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t *config) { @@ -583,45 +540,6 @@ uint8_t aerial_unpack_nr_config_response(uint8_t **ppReadPackedMsg, uint8_t *end return unpack_nr_config_response(ppReadPackedMsg, end, msg, config); } -// monitor the p7 endpoints and the timing loop and -// send indications to mac -int aerial_nfapi_nr_vnf_p7_start(nfapi_vnf_p7_config_t *config) -{ - if (config == 0) - return -1; - - NFAPI_TRACE(NFAPI_TRACE_INFO, "%s()\n", __FUNCTION__); - - vnf_p7_t *vnf_p7 = (vnf_p7_t *)config; - - // Create p7 receive udp port - // todo : this needs updating for Ipv6 - - NFAPI_TRACE(NFAPI_TRACE_INFO, "Initialising VNF P7 port:%u\n", config->port); - - - struct timespec ref_time; - clock_gettime(CLOCK_MONOTONIC, &ref_time); - uint8_t setup_done = 0; - while (vnf_p7->terminate == 0) { - if (setup_done == 0) { - struct timespec curr_time; - clock_gettime(CLOCK_MONOTONIC, &curr_time); - uint8_t setup_time = curr_time.tv_sec - ref_time.tv_sec; - if (setup_time > 3) { - setup_done = 1; - } - } - - } - NFAPI_TRACE(NFAPI_TRACE_INFO, "Closing p7 socket\n"); - close(vnf_p7->socket); - - NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() returning\n", __FUNCTION__); - - return 0; -} - int oai_fapi_ul_tti_req(nfapi_nr_ul_tti_request_t *ul_tti_req) { nfapi_vnf_p7_config_t *p7_config = aerial_vnf.p7_vnfs[0].config; diff --git a/nfapi/oai_integration/aerial/fapi_vnf_p5.h b/nfapi/oai_integration/aerial/fapi_vnf_p5.h index ba315709bf..b67f959f8f 100644 --- a/nfapi/oai_integration/aerial/fapi_vnf_p5.h +++ b/nfapi/oai_integration/aerial/fapi_vnf_p5.h @@ -64,7 +64,6 @@ int oai_fapi_send_end_request(int cell_id, uint32_t frame, uint32_t slot); uint8_t aerial_unpack_nr_param_response(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t *config); uint8_t aerial_unpack_nr_config_response(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t *config); int aerial_pnf_nr_connection_indication_cb(nfapi_vnf_config_t *config, int p5_idx); -int aerial_nfapi_nr_vnf_p7_start(nfapi_vnf_p7_config_t *config); int oai_fapi_ul_tti_req(nfapi_nr_ul_tti_request_t *ul_tti_req); int oai_fapi_ul_dci_req(nfapi_nr_ul_dci_request_t *ul_dci_req); diff --git a/openair2/GNB_APP/MACRLC_nr_paramdef.h b/openair2/GNB_APP/MACRLC_nr_paramdef.h index e235de858f..b3f9711ed4 100644 --- a/openair2/GNB_APP/MACRLC_nr_paramdef.h +++ b/openair2/GNB_APP/MACRLC_nr_paramdef.h @@ -47,6 +47,8 @@ #define CONFIG_STRING_MACRLC_LOCAL_N_PORTD "local_n_portd" #define CONFIG_STRING_MACRLC_REMOTE_N_PORTD "remote_n_portd" #define CONFIG_STRING_MACRLC_TRANSPORT_S_PREFERENCE "tr_s_preference" +#define CONFIG_STRING_MACRLC_TRANSPORT_S_SHM_PREFIX "tr_s_shm_prefix" +#define CONFIG_STRING_MACRLC_TRANSPORT_S_POLL_CORE "tr_s_poll_core" #define CONFIG_STRING_MACRLC_LOCAL_S_ADDRESS "local_s_address" #define CONFIG_STRING_MACRLC_REMOTE_S_ADDRESS "remote_s_address" #define CONFIG_STRING_MACRLC_LOCAL_S_PORTC "local_s_portc" @@ -123,6 +125,8 @@ {CONFIG_STRING_MACRLC_MIN_GRANT_MCS, HLP_MACRLC_MIN_GRANT_MCS, 0, .u8ptr=NULL, .defintval=9, TYPE_UINT8, 0}, \ {CONFIG_STRING_MACRLC_IDENTITY_PM, HLP_MACRLC_IDENTITY_PM, PARAMFLAG_BOOL, .u8ptr=NULL, .defintval=0, TYPE_UINT8, 0}, \ {CONFIG_STRING_MACRLC_LOCAL_N_ADDRESS_F1U, NULL, 0, .strptr=NULL, .defstrval=NULL, TYPE_STRING, 0}, \ + {CONFIG_STRING_MACRLC_TRANSPORT_S_SHM_PREFIX, NULL, 0, .strptr=NULL, .defstrval="nvipc", TYPE_STRING, 0}, \ + {CONFIG_STRING_MACRLC_TRANSPORT_S_POLL_CORE, NULL, 0, .i8ptr=NULL, .defintval=-1, TYPE_INT8, 0}, \ } // clang-format off @@ -159,6 +163,8 @@ #define MACRLC_MIN_GRANT_MCS_IDX 30 #define MACRLC_IDENTITY_PM_IDX 31 #define MACRLC_LOCAL_N_ADDRESS_F1U_IDX 32 +#define MACRLC_TRANSPORT_S_SHM_PREFIX 33 +#define MACRLC_TRANSPORT_S_POLL_CORE 34 #define MACRLCPARAMS_CHECK { \ { .s5 = { NULL } }, \ @@ -194,6 +200,8 @@ { .s5 = { NULL } }, \ { .s2 = { NULL } }, \ { .s5 = { NULL } }, \ + { .s5 = { NULL } }, \ + { .s2 = { NULL } }, \ } /*---------------------------------------------------------------------------------------------------------------------------------------------------------*/ diff --git a/openair2/GNB_APP/gnb_config.c b/openair2/GNB_APP/gnb_config.c index b732a88879..259e8afe23 100644 --- a/openair2/GNB_APP/gnb_config.c +++ b/openair2/GNB_APP/gnb_config.c @@ -1349,7 +1349,10 @@ void RCconfig_nr_macrlc(configmodule_interface_t *cfg) printf("**************** RETURNED FROM configure_nfapi_vnf() vnf_port:%d\n", RC.nrmac[j]->eth_params_s.my_portc); } else if(strcmp(*(MacRLC_ParamList.paramarray[j][MACRLC_TRANSPORT_S_PREFERENCE_IDX].strptr), "aerial") == 0){ #ifdef ENABLE_AERIAL - printf("Configuring VNF for Aerial connection\n"); + RC.nrmac[j]->nvipc_params_s.nvipc_shm_prefix = + strdup(*(MacRLC_ParamList.paramarray[j][MACRLC_TRANSPORT_S_SHM_PREFIX].strptr)); + RC.nrmac[j]->nvipc_params_s.nvipc_poll_core = *(MacRLC_ParamList.paramarray[j][MACRLC_TRANSPORT_S_POLL_CORE].i8ptr); + printf("Configuring VNF for Aerial connection with prefix %s\n", RC.nrmac[j]->eth_params_s.local_if_name); aerial_configure_nr_fapi_vnf(); #endif } else { // other midhaul diff --git a/openair2/GNB_APP/gnb_paramdef.h b/openair2/GNB_APP/gnb_paramdef.h index ad8267e984..a56b64b407 100644 --- a/openair2/GNB_APP/gnb_paramdef.h +++ b/openair2/GNB_APP/gnb_paramdef.h @@ -559,6 +559,8 @@ typedef enum { #define CONFIG_STRING_MACRLC_LOCAL_N_PORTD "local_n_portd" #define CONFIG_STRING_MACRLC_REMOTE_N_PORTD "remote_n_portd" #define CONFIG_STRING_MACRLC_TRANSPORT_S_PREFERENCE "tr_s_preference" +#define CONFIG_STRING_MACRLC_TRANSPORT_S_SHM_PREFIX "tr_s_shm_prefix" +#define CONFIG_STRING_MACRLC_TRANSPORT_S_POLL_CORE "tr_s_poll_core" #define CONFIG_STRING_MACRLC_LOCAL_S_ADDRESS "local_s_address" #define CONFIG_STRING_MACRLC_REMOTE_S_ADDRESS "remote_s_address" #define CONFIG_STRING_MACRLC_LOCAL_S_PORTC "local_s_portc" diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h index 7fe0c8994e..74d0997a51 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h +++ b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h @@ -760,6 +760,8 @@ typedef struct gNB_MAC_INST_s { char *f1u_addr; /// Ethernet parameters for fronthaul interface eth_params_t eth_params_s; + /// Nvipc parameters for FAPI interface with Aerial + nvipc_params_t nvipc_params_s; /// Module module_id_t Mod_id; /// timing advance group diff --git a/radio/COMMON/common_lib.h b/radio/COMMON/common_lib.h index aa2d9e3189..80894c2a1d 100644 --- a/radio/COMMON/common_lib.h +++ b/radio/COMMON/common_lib.h @@ -336,6 +336,11 @@ typedef struct { uint8_t if_compress; } eth_params_t; +typedef struct { + char *nvipc_shm_prefix; + int8_t nvipc_poll_core; +} nvipc_params_t; + typedef struct { //! Tx buffer for if device, keep one per subframe now to allow multithreading void *tx[10]; diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb-vnf.sa.band78.273prb.aerial.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb-vnf.sa.band78.273prb.aerial.conf index 989cf66829..d52287dbbb 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb-vnf.sa.band78.273prb.aerial.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb-vnf.sa.band78.273prb.aerial.conf @@ -207,14 +207,17 @@ gNBs = MACRLCs = ( { num_cc = 1; - local_s_if_name = "lo:"; + + tr_s_preference = "aerial"; + tr_s_shm_prefix = "nvipc"; + tr_s_poll_core = 10; remote_s_address = "127.0.0.1"; // pnf addr [!] local_s_address = "127.0.0.2"; // vnf addr local_s_portc = 50001; // vnf p5 port remote_s_portc = 50000; // pnf p5 port [!] local_s_portd = 50011; // vnf p7 port [!] remote_s_portd = 50010; // pnf p7 port [!] - tr_s_preference = "aerial"; + tr_n_preference = "local_RRC"; pusch_FailureThres = 10; pusch_TargetSNRx10 = 280; # 150; From 612bbaeca62d6eef7067912716c4b9af2375822f Mon Sep 17 00:00:00 2001 From: Florian Kaltenberger Date: Wed, 3 Jul 2024 14:52:56 -0400 Subject: [PATCH 20/49] documentation update --- doc/Aerial_FAPI_Split_Tutorial.md | 10 ++++++++++ doc/NR_SA_Tutorial_OAI_nrUE.md | 2 ++ doc/README.md | 1 + 3 files changed, 13 insertions(+) diff --git a/doc/Aerial_FAPI_Split_Tutorial.md b/doc/Aerial_FAPI_Split_Tutorial.md index 46541fff95..0592eee7be 100644 --- a/doc/Aerial_FAPI_Split_Tutorial.md +++ b/doc/Aerial_FAPI_Split_Tutorial.md @@ -254,6 +254,16 @@ The gNB logs can be followed with: ```bash docker logs -f oai-gnb-aerial ``` +#### Running with multiple L2s +One L1 instance can support multiple L2 instances. See also the [aerial documentation](https://developer.nvidia.com/docs/gputelecom/aerial-sdk/text/cubb_quickstart/running_cubb-end-to-end.html#run-multiple-l2-instances-with-single-l1-instance) for more details. + +In OAI the share memory prefix must be configured in the configuration file. + +```bash + tr_s_preference = "aerial"; + tr_s_shm_prefix = "nvipc"; +``` + ### Stopping the setup diff --git a/doc/NR_SA_Tutorial_OAI_nrUE.md b/doc/NR_SA_Tutorial_OAI_nrUE.md index 30a8b52419..8c1b0afaf1 100644 --- a/doc/NR_SA_Tutorial_OAI_nrUE.md +++ b/doc/NR_SA_Tutorial_OAI_nrUE.md @@ -201,6 +201,8 @@ sudo ethtool -G enp1s0f0 tx 4096 rx 4096 - Sometimes, the nrUE would keep repeating RA procedure because of Msg3 failure at the gNB. If it happens, add the `-A` option at the nrUE and/or gNB side, e.g., `-A 45`. This modifies the timing advance (in samples). Adjust +/-5 if the issue persists. - This can be necessary since certain USRPs have larger signal delays than others; it is therefore specific to the used USRP model. - The x310 and B210 are found to work with the default configuration; N310 and x410 can benefit from setting this timing advance. +- For example if the OAI UE uses the X410 and the gNB based on [Nvidia Aerial and Foxconn](./Aerial_FAPI_Split_Tutorial.md) a timing advance of 90 has been found to work well. + ## 6.5 Lower latency on user plane - To lower latency on the user plane, you can force the UE to be scheduled constantly in uplink: `--MACRLCs.[0].ulsch_max_frame_inactivity 0` . diff --git a/doc/README.md b/doc/README.md index 3a71d9f51f..636c30d26b 100644 --- a/doc/README.md +++ b/doc/README.md @@ -52,6 +52,7 @@ There is some general information in the [OpenAirInterface Gitlab Wiki](https:// - [How to use device-to-device communication (D2D, 4G)](./d2d_emulator_setup.txt) - [How to run with E2 agent](../openair2/E2AP/README.md) - [How to run the physical simulators](./physical-simulators.md) +- [How to setup OAI with Nvidia Aerial and Foxconn](./Aerial_FAPI_Split_Tutorial.md) Legacy unmaintained files: - [`L2NFAPI_NOS1.md`](./L2NFAPI_NOS1.md), [`L2NFAPI_S1.md`](./L2NFAPI_S1.md): From 1f7ec847bce8980667d8fe4ea006c70e547acfe9 Mon Sep 17 00:00:00 2001 From: Bartosz Podrygajlo Date: Tue, 16 Jul 2024 18:37:48 +0200 Subject: [PATCH 21/49] Remove tddflag. Frame type depends on band. --- executables/nr-uesoftmodem.c | 6 ------ executables/nr-uesoftmodem.h | 1 - 2 files changed, 7 deletions(-) diff --git a/executables/nr-uesoftmodem.c b/executables/nr-uesoftmodem.c index 9e82c9aae8..61a7890fd0 100644 --- a/executables/nr-uesoftmodem.c +++ b/executables/nr-uesoftmodem.c @@ -115,7 +115,6 @@ extern int16_t nr_dlsch_demod_shift; static int tx_max_power[MAX_NUM_CCs] = {0}; int single_thread_flag = 1; -int tddflag = 0; int vcdflag = 0; double rx_gain_off = 0.0; @@ -303,11 +302,6 @@ void set_options(int CC_id, PHY_VARS_NR_UE *UE){ // Set FP variables - if (tddflag){ - fp->frame_type = TDD; - LOG_I(PHY, "Set UE frame_type %d\n", fp->frame_type); - } - fp->nb_antennas_rx = nrUE_params.nb_antennas_rx; fp->nb_antennas_tx = nrUE_params.nb_antennas_tx; fp->threequarter_fs = get_softmodem_params()->threequarter_fs; diff --git a/executables/nr-uesoftmodem.h b/executables/nr-uesoftmodem.h index 8e0650b4e4..df3d88449e 100644 --- a/executables/nr-uesoftmodem.h +++ b/executables/nr-uesoftmodem.h @@ -58,7 +58,6 @@ {"ue-max-power", NULL, 0, .iptr=&(tx_max_power[0]), .defintval=90, TYPE_INT, 0}, \ {"r" , CONFIG_HLP_PRB_SA, 0, .iptr=&(nrUE_params.N_RB_DL), .defintval=106, TYPE_UINT, 0}, \ {"ssb", CONFIG_HLP_SSC, 0, .iptr=&(nrUE_params.ssb_start_subcarrier), .defintval=516, TYPE_UINT16, 0}, \ - {"T" , CONFIG_HLP_TDD, PARAMFLAG_BOOL, .iptr=&tddflag, .defintval=0, TYPE_INT, 0}, \ {"if_freq" , CONFIG_HLP_IF_FREQ, 0, .u64ptr=&(nrUE_params.if_freq), .defuintval=0, TYPE_UINT64, 0}, \ {"if_freq_off" , CONFIG_HLP_IF_FREQ_OFF, 0, .iptr=&(nrUE_params.if_freq_off), .defuintval=0, TYPE_INT, 0}, \ {"chest-freq", CONFIG_HLP_CHESTFREQ, 0, .iptr=&(nrUE_params.chest_freq), .defintval=0, TYPE_INT, 0}, \ From dc91550e2c40d37d4e7404d605f29c73762c68b9 Mon Sep 17 00:00:00 2001 From: Bartosz Podrygajlo Date: Tue, 16 Jul 2024 19:05:01 +0200 Subject: [PATCH 22/49] Remove unused flag single_thread_flag from softmodems. --- common/config/DOC/config/rtusage.md | 1 - executables/lte-enb.c | 10 +++------- executables/lte-softmodem.c | 4 ++-- executables/lte-softmodem.h | 2 +- executables/nr-gnb.c | 5 ++--- executables/nr-softmodem-common.h | 1 - executables/nr-softmodem.c | 5 ++--- executables/nr-softmodem.h | 3 +-- executables/nr-uesoftmodem.c | 1 - executables/nr-uesoftmodem.h | 1 - executables/softmodem-common.h | 4 ---- nfapi/oai_integration/aerial/fapi_vnf_p5.c | 1 - nfapi/oai_integration/aerial/fapi_vnf_p7.c | 1 - nfapi/oai_integration/nfapi_vnf.c | 12 +++++++----- openair1/PHY/TOOLS/calibration_test.c | 1 - openair1/PHY/defs_L1_NB_IoT.h | 1 - openair1/PHY/defs_eNB.h | 1 - openair1/PHY/defs_gNB.h | 1 - 18 files changed, 18 insertions(+), 37 deletions(-) diff --git a/common/config/DOC/config/rtusage.md b/common/config/DOC/config/rtusage.md index 6a092b340f..42ef93bffc 100644 --- a/common/config/DOC/config/rtusage.md +++ b/common/config/DOC/config/rtusage.md @@ -58,7 +58,6 @@ To get help on supported parameters you can use specific options: --emulate-rf: Emulated RF enabled(disable by defult) --clock: tells hardware to use a clock reference (0:internal, 1:external, 2:gpsdo) --wait-for-sync: Help string not specified - --single-thread-enable: Disables single-thread mode in lte-softmodem -C: Set the downlink frequency for all component carriers -a: Channel id offset -d: Enable soft scope and L1 and L2 stats (Xforms) diff --git a/executables/lte-enb.c b/executables/lte-enb.c index 5e686d6527..9c56c5f53e 100644 --- a/executables/lte-enb.c +++ b/executables/lte-enb.c @@ -134,7 +134,7 @@ static struct { extern double cpuf; -void init_eNB(int,int); +void init_eNB(int); void stop_eNB(int nb_inst); int wakeup_tx(PHY_VARS_eNB *eNB, int frame_rx, int subframe_rx, int frame_tx, int subframe_tx, uint64_t timestamp_tx); @@ -899,8 +899,6 @@ void init_eNB_proc(int inst) { pthread_cond_init( &proc->cond_prach_br, NULL); pthread_attr_init( &proc->attr_prach_br); - LOG_I(PHY,"eNB->single_thread_flag:%d\n", eNB->single_thread_flag); - if ((get_thread_parallel_conf() == PARALLEL_RU_L1_SPLIT) && NFAPI_MODE!=NFAPI_MODE_VNF) { pthread_create( &L1_proc->pthread, attr0, L1_thread, proc ); } else if ((get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT) && NFAPI_MODE!=NFAPI_MODE_VNF) { @@ -1224,8 +1222,7 @@ void init_eNB_afterRU(void) { } -void init_eNB(int single_thread_flag, - int wait_for_sync) { +void init_eNB(int wait_for_sync) { int CC_id; int inst; PHY_VARS_eNB *eNB; @@ -1244,8 +1241,7 @@ void init_eNB(int single_thread_flag, eNB = RC.eNB[inst][CC_id]; eNB->abstraction_flag = 0; - eNB->single_thread_flag = single_thread_flag; - LOG_I(PHY,"Initializing eNB %d CC_id %d single_thread_flag:%d\n",inst,CC_id,single_thread_flag); + LOG_I(PHY,"Initializing eNB %d CC_id %d\n",inst,CC_id); LOG_I(PHY,"Initializing eNB %d CC_id %d\n",inst,CC_id); LOG_I(PHY,"Registering with MAC interface module\n"); AssertFatal((eNB->if_inst = IF_Module_init(inst))!=NULL,"Cannot register interface"); diff --git a/executables/lte-softmodem.c b/executables/lte-softmodem.c index 43b1f5c675..e5530765a5 100644 --- a/executables/lte-softmodem.c +++ b/executables/lte-softmodem.c @@ -542,8 +542,8 @@ int main ( int argc, char **argv ) printf("RC.nb_L1_inst:%d\n", RC.nb_L1_inst); if (RC.nb_L1_inst > 0) { - printf("Initializing eNB threads single_thread_flag:%d wait_for_sync:%d\n", get_softmodem_params()->single_thread_flag,get_softmodem_params()->wait_for_sync); - init_eNB(get_softmodem_params()->single_thread_flag,get_softmodem_params()->wait_for_sync); + printf("Initializing eNB threads wait_for_sync:%d\n", get_softmodem_params()->wait_for_sync); + init_eNB(get_softmodem_params()->wait_for_sync); } for (int x=0; x < RC.nb_L1_inst; x++) for (int CC_id=0; CC_idabstraction_flag = 0; - gNB->single_thread_flag = single_thread_flag; /*nr_polar_init(&gNB->nrPolar_params, NR_POLAR_PBCH_MESSAGE_TYPE, NR_POLAR_PBCH_PAYLOAD_BITS, NR_POLAR_PBCH_AGGREGATION_LEVEL);*/ - LOG_I(PHY,"Initializing gNB %d single_thread_flag:%d\n",inst,gNB->single_thread_flag); + LOG_I(PHY,"Initializing gNB %d\n",inst); LOG_I(PHY,"Initializing gNB %d\n",inst); LOG_I(PHY,"Registering with MAC interface module (before %p)\n",gNB->if_inst); diff --git a/executables/nr-softmodem-common.h b/executables/nr-softmodem-common.h index e84ca015cc..56d92497cc 100644 --- a/executables/nr-softmodem-common.h +++ b/executables/nr-softmodem-common.h @@ -55,7 +55,6 @@ #define CONFIG_HLP_DMAMAP "use DMA memory mapping\n" #define CONFIG_HLP_EXCCLK "tells hardware to use a clock reference (0:internal(default), 1:external, 2:gpsdo)\n" #define CONFIG_HLP_USIM "use XOR autentication algo in case of test usim mode\n" -#define CONFIG_HLP_NOSNGLT "Disables single-thread mode in lte-softmodem\n" #define CONFIG_HLP_DLF "Set the downlink frequency for all component carriers\n" #define CONFIG_HLP_ULOFF "Set the uplink frequnecy offset for all component carriers\n" #define CONFIG_HLP_CHOFF "Channel id offset\n" diff --git a/executables/nr-softmodem.c b/executables/nr-softmodem.c index ac6a2e88bd..958161252a 100644 --- a/executables/nr-softmodem.c +++ b/executables/nr-softmodem.c @@ -106,7 +106,6 @@ int NB_UE_INST = 0; static int wait_for_sync = 0; unsigned int mmapped_dma=0; -int single_thread_flag=1; uint64_t downlink_frequency[MAX_NUM_CCs][4]; int32_t uplink_frequency_offset[MAX_NUM_CCs][4]; @@ -697,8 +696,8 @@ int main( int argc, char **argv ) { printf("RC.nb_nr_L1_inst:%d\n", RC.nb_nr_L1_inst); if (RC.nb_nr_L1_inst > 0) { - printf("Initializing gNB threads single_thread_flag:%d wait_for_sync:%d\n", single_thread_flag,wait_for_sync); - init_gNB(single_thread_flag,wait_for_sync); + printf("Initializing gNB threads wait_for_sync:%d\n", wait_for_sync); + init_gNB(wait_for_sync); } printf("wait_gNBs()\n"); diff --git a/executables/nr-softmodem.h b/executables/nr-softmodem.h index 6f2a54f2e8..1047c56ffd 100644 --- a/executables/nr-softmodem.h +++ b/executables/nr-softmodem.h @@ -17,7 +17,6 @@ /*----------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ // clang-format off #define CMDLINE_PARAMS_DESC_GNB { \ - {"single-thread-disable", CONFIG_HLP_NOSNGLT, PARAMFLAG_BOOL, .iptr=&single_thread_flag, .defintval=1, TYPE_INT, 0}, \ {"m" , CONFIG_HLP_DLMCS_PHYTEST, 0, .uptr=&target_dl_mcs, .defintval=0, TYPE_UINT, 0}, \ {"l" , CONFIG_HLP_DLNL_PHYTEST, 0, .uptr=&target_dl_Nl, .defintval=0, TYPE_UINT, 0}, \ {"L" , CONFIG_HLP_ULNL_PHYTEST, 0, .uptr=&target_ul_Nl, .defintval=0, TYPE_UINT, 0}, \ @@ -42,7 +41,7 @@ extern uint64_t ulsch_slot_bitmap; extern char *uecap_file; // In nr-gnb.c -extern void init_gNB(int single_thread_flag,int wait_for_sync); +extern void init_gNB(int wait_for_sync); extern void stop_gNB(int); // In nr-ru.c diff --git a/executables/nr-uesoftmodem.c b/executables/nr-uesoftmodem.c index 61a7890fd0..a36667f2b7 100644 --- a/executables/nr-uesoftmodem.c +++ b/executables/nr-uesoftmodem.c @@ -114,7 +114,6 @@ int oai_exit = 0; extern int16_t nr_dlsch_demod_shift; static int tx_max_power[MAX_NUM_CCs] = {0}; -int single_thread_flag = 1; int vcdflag = 0; double rx_gain_off = 0.0; diff --git a/executables/nr-uesoftmodem.h b/executables/nr-uesoftmodem.h index df3d88449e..9505bfd6b3 100644 --- a/executables/nr-uesoftmodem.h +++ b/executables/nr-uesoftmodem.h @@ -36,7 +36,6 @@ {"usrp-args", CONFIG_HLP_USRP_ARGS, 0, .strptr=&usrp_args, .defstrval="type=b200", TYPE_STRING, 0}, \ {"tx_subdev", CONFIG_HLP_TX_SUBDEV, 0, .strptr=&tx_subdev, .defstrval=NULL, TYPE_STRING, 0}, \ {"rx_subdev", CONFIG_HLP_RX_SUBDEV, 0, .strptr=&rx_subdev, .defstrval=NULL, TYPE_STRING, 0}, \ - {"single-thread-disable", CONFIG_HLP_NOSNGLT, PARAMFLAG_BOOL, .iptr=&single_thread_flag, .defintval=1, TYPE_INT, 0}, \ {"dlsch-parallel", CONFIG_HLP_DLSCH_PARA, 0, .u8ptr=NULL, .defintval=0, TYPE_UINT8, 0}, \ {"offset-divisor", CONFIG_HLP_OFFSET_DIV, 0, .uptr=&nrUE_params.ofdm_offset_divisor, .defuintval=8, TYPE_UINT32, 0}, \ {"max-ldpc-iterations", CONFIG_HLP_MAX_LDPC_ITERATIONS, 0, .iptr=&nrUE_params.max_ldpc_iterations, .defuintval=8, TYPE_UINT8, 0}, \ diff --git a/executables/softmodem-common.h b/executables/softmodem-common.h index 61438e6b1d..a696c064a4 100644 --- a/executables/softmodem-common.h +++ b/executables/softmodem-common.h @@ -125,7 +125,6 @@ extern "C" #define SA softmodem_params.sa #define SL_MODE softmodem_params.sl_mode #define WAIT_FOR_SYNC softmodem_params.wait_for_sync -#define SINGLE_THREAD_FLAG softmodem_params.single_thread_flag #define CHAIN_OFFSET softmodem_params.chain_offset #define NUMEROLOGY softmodem_params.numerology #define BAND softmodem_params.band @@ -162,7 +161,6 @@ extern int usrp_tx_thread; {"time-source", CONFIG_HLP_TME, 0, .uptr=&TIMING_SOURCE, .defintval=0, TYPE_UINT, 0}, \ {"tune-offset", CONFIG_HLP_TUNE_OFFSET, 0, .dblptr=&TUNE_OFFSET, .defintval=0, TYPE_DOUBLE, 0}, \ {"wait-for-sync", NULL, PARAMFLAG_BOOL, .iptr=&WAIT_FOR_SYNC, .defintval=0, TYPE_INT, 0}, \ - {"single-thread-enable", CONFIG_HLP_NOSNGLT, PARAMFLAG_BOOL, .iptr=&SINGLE_THREAD_FLAG, .defintval=0, TYPE_INT, 0}, \ {"C" , CONFIG_HLP_DLF, 0, .u64ptr=&(downlink_frequency[0][0]), .defuintval=0, TYPE_UINT64, 0}, \ {"CO" , CONFIG_HLP_ULF, 0, .iptr=&(uplink_frequency_offset[0][0]), .defintval=0, TYPE_INT, 0}, \ {"a" , CONFIG_HLP_CHOFF, 0, .iptr=&CHAIN_OFFSET, .defintval=0, TYPE_INT, 0}, \ @@ -227,7 +225,6 @@ extern int usrp_tx_thread; { .s5 = { NULL } }, \ { .s5 = { NULL } }, \ { .s5 = { NULL } }, \ - { .s5 = { NULL } }, \ { .s3a = { config_checkstr_assign_integer, \ {"MONOLITHIC", "PNF", "VNF", "AERIAL","UE_STUB_PNF","UE_STUB_OFFNET","STANDALONE_PNF"}, \ {NFAPI_MONOLITHIC, NFAPI_MODE_PNF, NFAPI_MODE_VNF, NFAPI_MODE_AERIAL,NFAPI_UE_STUB_PNF,NFAPI_UE_STUB_OFFNET,NFAPI_MODE_STANDALONE_PNF}, \ @@ -328,7 +325,6 @@ typedef struct { uint8_t usim_test; int emulate_rf; int wait_for_sync; //eNodeB only - int single_thread_flag; //eNodeB only int chain_offset; int numerology; int band; diff --git a/nfapi/oai_integration/aerial/fapi_vnf_p5.c b/nfapi/oai_integration/aerial/fapi_vnf_p5.c index 20236a2a85..796f4054d3 100644 --- a/nfapi/oai_integration/aerial/fapi_vnf_p5.c +++ b/nfapi/oai_integration/aerial/fapi_vnf_p5.c @@ -38,7 +38,6 @@ extern RAN_CONTEXT_t RC; extern UL_RCC_IND_t UL_RCC_INFO; -extern int single_thread_flag; extern uint16_t sf_ahead; extern uint16_t slot_ahead; diff --git a/nfapi/oai_integration/aerial/fapi_vnf_p7.c b/nfapi/oai_integration/aerial/fapi_vnf_p7.c index 42a12d3cb4..790df64f94 100644 --- a/nfapi/oai_integration/aerial/fapi_vnf_p7.c +++ b/nfapi/oai_integration/aerial/fapi_vnf_p7.c @@ -35,7 +35,6 @@ extern RAN_CONTEXT_t RC; extern UL_RCC_IND_t UL_RCC_INFO; -extern int single_thread_flag; extern uint16_t sf_ahead; int aerial_wake_gNB_rxtx(PHY_VARS_gNB *gNB, uint16_t sfn, uint16_t slot) diff --git a/nfapi/oai_integration/nfapi_vnf.c b/nfapi/oai_integration/nfapi_vnf.c index dc9dd46b5c..c553053cd8 100644 --- a/nfapi/oai_integration/nfapi_vnf.c +++ b/nfapi/oai_integration/nfapi_vnf.c @@ -200,18 +200,21 @@ int vnf_unpack_vendor_extension_tlv(nfapi_tl_t *tl, uint8_t **ppReadPackedMessag } void install_nr_schedule_handlers(NR_IF_Module_t *if_inst); void install_schedule_handlers(IF_Module_t *if_inst); -extern int single_thread_flag; extern uint16_t sf_ahead; void oai_create_enb(void) { int bodge_counter=0; PHY_VARS_eNB *eNB = RC.eNB[0][0]; - NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] RC.eNB[0][0]. Mod_id:%d CC_id:%d nb_CC[0]:%d abstraction_flag:%d single_thread_flag:%d if_inst:%p\n", eNB->Mod_id, eNB->CC_id, RC.nb_CC[0], eNB->abstraction_flag, - eNB->single_thread_flag, eNB->if_inst); + NFAPI_TRACE(NFAPI_TRACE_INFO, + "[VNF] RC.eNB[0][0]. Mod_id:%d CC_id:%d nb_CC[0]:%d abstraction_flag:%d if_inst:%p\n", + eNB->Mod_id, + eNB->CC_id, + RC.nb_CC[0], + eNB->abstraction_flag, + eNB->if_inst); eNB->Mod_id = bodge_counter; eNB->CC_id = bodge_counter; eNB->abstraction_flag = 0; - eNB->single_thread_flag = 0;//single_thread_flag; RC.nb_CC[bodge_counter] = 1; if (eNB->if_inst==0) { @@ -260,7 +263,6 @@ void oai_create_gnb(void) { gNB->Mod_id = bodge_counter; gNB->CC_id = bodge_counter; gNB->abstraction_flag = 0; - gNB->single_thread_flag = 0;//single_thread_flag; RC.nb_nr_CC[bodge_counter] = 1; if (gNB->if_inst==0) { diff --git a/openair1/PHY/TOOLS/calibration_test.c b/openair1/PHY/TOOLS/calibration_test.c index fe4320eb6c..1bb97b5a2f 100644 --- a/openair1/PHY/TOOLS/calibration_test.c +++ b/openair1/PHY/TOOLS/calibration_test.c @@ -8,7 +8,6 @@ int oai_exit=false; unsigned int mmapped_dma=0; -int single_thread_flag; uint32_t timing_advance; int8_t threequarter_fs; uint64_t downlink_frequency[MAX_NUM_CCs][4]; diff --git a/openair1/PHY/defs_L1_NB_IoT.h b/openair1/PHY/defs_L1_NB_IoT.h index 3eb0ed044f..163e9e3d2b 100644 --- a/openair1/PHY/defs_L1_NB_IoT.h +++ b/openair1/PHY/defs_L1_NB_IoT.h @@ -488,7 +488,6 @@ typedef struct PHY_VARS_eNB_NB_IoT_s { eth_params_t eth_params_n; /// Ethernet parameters for fronthaul interface (upper L1 to Radio head) eth_params_t eth_params; - int single_thread_flag; openair0_rf_map rf_map; int abstraction_flag; openair0_timestamp ts_offset; diff --git a/openair1/PHY/defs_eNB.h b/openair1/PHY/defs_eNB.h index b872148dd2..a10956114a 100644 --- a/openair1/PHY/defs_eNB.h +++ b/openair1/PHY/defs_eNB.h @@ -519,7 +519,6 @@ typedef struct PHY_VARS_eNB_s { uint8_t CC_id; uint8_t configured; L1_proc_t proc; - int single_thread_flag; int abstraction_flag; int num_RU; RU_t *RU_list[MAX_NUM_RU_PER_eNB]; diff --git a/openair1/PHY/defs_gNB.h b/openair1/PHY/defs_gNB.h index 3cd3266a0a..5f76f90f8d 100644 --- a/openair1/PHY/defs_gNB.h +++ b/openair1/PHY/defs_gNB.h @@ -545,7 +545,6 @@ typedef struct PHY_VARS_gNB_s { uint8_t CC_id; uint8_t configured; gNB_L1_proc_t proc; - int single_thread_flag; int abstraction_flag; int num_RU; RU_t *RU_list[MAX_NUM_RU_PER_gNB]; From 2ff12533213995dbe4d82321f1abe21bb8201d2f Mon Sep 17 00:00:00 2001 From: Bartosz Podrygajlo Date: Sun, 7 Jul 2024 13:34:04 +0200 Subject: [PATCH 23/49] Move init_nr_bler_table out of nr-uesoftmodem.c --- executables/nr-uesoftmodem.c | 60 +------------------ openair1/SIMULATION/NR_PHY/dlsim.c | 2 - openair1/SIMULATION/NR_PHY/prachsim.c | 2 - openair1/SIMULATION/NR_PHY/psbchsim.c | 1 - openair1/SIMULATION/NR_PHY/ulsim.c | 2 - openair2/NR_UE_PHY_INTERFACE/NR_Packet_Drop.c | 56 +++++++++++++++++ openair2/NR_UE_PHY_INTERFACE/NR_Packet_Drop.h | 1 + 7 files changed, 59 insertions(+), 65 deletions(-) diff --git a/executables/nr-uesoftmodem.c b/executables/nr-uesoftmodem.c index a36667f2b7..d78fe26206 100644 --- a/executables/nr-uesoftmodem.c +++ b/executables/nr-uesoftmodem.c @@ -165,10 +165,6 @@ unsigned int NTN_UE_Koffset = 0; */ uint8_t abstraction_flag=0; -nr_bler_struct nr_bler_data[NR_NUM_MCS]; - -static void init_bler_table(char*); - /*---------------------BMC: timespec helpers -----------------------------*/ struct timespec min_diff_time = { .tv_sec = 0, .tv_nsec = 0 }; @@ -421,9 +417,9 @@ static void get_channel_model_mode(configmodule_interface_t *cfg) int num_xp_antennas = *GNBParams[GNB_PDSCH_ANTENNAPORTS_XP_IDX].iptr; if (num_xp_antennas == 2) - init_bler_table("NR_MIMO2x2_AWGN_RESULTS_DIR"); + init_nr_bler_table("NR_MIMO2x2_AWGN_RESULTS_DIR"); else - init_bler_table("NR_AWGN_RESULTS_DIR"); + init_nr_bler_table("NR_AWGN_RESULTS_DIR"); } void start_oai_nrue_threads() @@ -639,55 +635,3 @@ int main(int argc, char **argv) return 0; } -// Read in each MCS file and build BLER-SINR-TB table -static void init_bler_table(char *env_string) { - memset(nr_bler_data, 0, sizeof(nr_bler_data)); - - const char *awgn_results_dir = getenv(env_string); - if (!awgn_results_dir) { - LOG_W(NR_MAC, "No %s\n", env_string); - return; - } - - for (unsigned int i = 0; i < NR_NUM_MCS; i++) { - char fName[1024]; - snprintf(fName, sizeof(fName), "%s/mcs%u_awgn_5G.csv", awgn_results_dir, i); - FILE *pFile = fopen(fName, "r"); - if (!pFile) { - LOG_E(NR_MAC, "%s: open %s: %s\n", __func__, fName, strerror(errno)); - continue; - } - size_t bufSize = 1024; - char * line = NULL; - char * token; - char * temp = NULL; - int nlines = 0; - while (getline(&line, &bufSize, pFile) > 0) { - if (!strncmp(line, "SNR", 3)) { - continue; - } - - if (nlines > NR_NUM_SINR) { - LOG_E(NR_MAC, "BLER FILE ERROR - num lines greater than expected - file: %s\n", fName); - abort(); - } - - token = strtok_r(line, ";", &temp); - int ncols = 0; - while (token != NULL) { - if (ncols > NUM_BLER_COL) { - LOG_E(NR_MAC, "BLER FILE ERROR - num of cols greater than expected\n"); - abort(); - } - - nr_bler_data[i].bler_table[nlines][ncols] = strtof(token, NULL); - ncols++; - - token = strtok_r(NULL, ";", &temp); - } - nlines++; - } - nr_bler_data[i].length = nlines; - fclose(pFile); - } -} diff --git a/openair1/SIMULATION/NR_PHY/dlsim.c b/openair1/SIMULATION/NR_PHY/dlsim.c index d6be222a9b..7747ffed26 100644 --- a/openair1/SIMULATION/NR_PHY/dlsim.c +++ b/openair1/SIMULATION/NR_PHY/dlsim.c @@ -119,8 +119,6 @@ void nr_derive_key(int alg_type, uint8_t alg_id, const uint8_t key[32], uint8_t void processSlotTX(void *arg) {} -nr_bler_struct nr_bler_data[NR_NUM_MCS]; - // needed for some functions openair0_config_t openair0_cfg[MAX_CARDS]; void update_ptrs_config(NR_CellGroupConfig_t *secondaryCellGroup, uint16_t *rbSize, uint8_t *mcsIndex,int8_t *ptrs_arg); diff --git a/openair1/SIMULATION/NR_PHY/prachsim.c b/openair1/SIMULATION/NR_PHY/prachsim.c index 785e8bb96f..f0dfa8c5bc 100644 --- a/openair1/SIMULATION/NR_PHY/prachsim.c +++ b/openair1/SIMULATION/NR_PHY/prachsim.c @@ -114,8 +114,6 @@ nrUE_params_t *get_nrUE_params(void) { return &nrUE_params; } -nr_bler_struct nr_bler_data[NR_NUM_MCS]; - void processSlotTX(void *arg) {} int NB_UE_INST = 1; configmodule_interface_t *uniqCfg = NULL; diff --git a/openair1/SIMULATION/NR_PHY/psbchsim.c b/openair1/SIMULATION/NR_PHY/psbchsim.c index f56735809d..684ed6d783 100644 --- a/openair1/SIMULATION/NR_PHY/psbchsim.c +++ b/openair1/SIMULATION/NR_PHY/psbchsim.c @@ -80,7 +80,6 @@ int8_t nr_mac_rrc_data_req_ue(const module_id_t Mod_idP, return 0; } -nr_bler_struct nr_bler_data[NR_NUM_MCS]; void get_nrUE_params(void) { return; diff --git a/openair1/SIMULATION/NR_PHY/ulsim.c b/openair1/SIMULATION/NR_PHY/ulsim.c index b191301513..d5374774d8 100644 --- a/openair1/SIMULATION/NR_PHY/ulsim.c +++ b/openair1/SIMULATION/NR_PHY/ulsim.c @@ -121,8 +121,6 @@ int DU_send_INITIAL_UL_RRC_MESSAGE_TRANSFER(module_id_t module_idP, return 0; } -nr_bler_struct nr_bler_data[NR_NUM_MCS]; - void nr_derive_key(int alg_type, uint8_t alg_id, const uint8_t key[32], uint8_t out[16]) { (void)alg_type; diff --git a/openair2/NR_UE_PHY_INTERFACE/NR_Packet_Drop.c b/openair2/NR_UE_PHY_INTERFACE/NR_Packet_Drop.c index 52aedfbccc..8a6bd3118c 100644 --- a/openair2/NR_UE_PHY_INTERFACE/NR_Packet_Drop.c +++ b/openair2/NR_UE_PHY_INTERFACE/NR_Packet_Drop.c @@ -23,6 +23,8 @@ #include "executables/softmodem-common.h" #include "NR_MAC_UE/mac_proto.h" + +nr_bler_struct nr_bler_data[NR_NUM_MCS]; slot_rnti_mcs_s slot_rnti_mcs[NUM_NFAPI_SLOT]; void read_channel_param(const nfapi_nr_dl_tti_pdsch_pdu_rel15_t * pdu, int slot, int index) { @@ -204,3 +206,57 @@ int get_mcs_from_sinr(nr_bler_struct *nr_bler_data, float sinr) LOG_E(NR_MAC, "Unable to get an MCS value.\n"); abort(); } + +// Read in each MCS file and build BLER-SINR-TB table +void init_nr_bler_table(const char *env_string) +{ + memset(nr_bler_data, 0, sizeof(nr_bler_data)); + + const char *awgn_results_dir = getenv(env_string); + if (!awgn_results_dir) { + LOG_W(NR_MAC, "No %s\n", env_string); + return; + } + + for (unsigned int i = 0; i < NR_NUM_MCS; i++) { + char fName[1024]; + snprintf(fName, sizeof(fName), "%s/mcs%u_awgn_5G.csv", awgn_results_dir, i); + FILE *pFile = fopen(fName, "r"); + if (!pFile) { + LOG_E(NR_MAC, "%s: open %s: %s\n", __func__, fName, strerror(errno)); + continue; + } + size_t bufSize = 1024; + char *line = NULL; + char *token; + char *temp = NULL; + int nlines = 0; + while (getline(&line, &bufSize, pFile) > 0) { + if (!strncmp(line, "SNR", 3)) { + continue; + } + + if (nlines > NR_NUM_SINR) { + LOG_E(NR_MAC, "BLER FILE ERROR - num lines greater than expected - file: %s\n", fName); + abort(); + } + + token = strtok_r(line, ";", &temp); + int ncols = 0; + while (token != NULL) { + if (ncols > NUM_BLER_COL) { + LOG_E(NR_MAC, "BLER FILE ERROR - num of cols greater than expected\n"); + abort(); + } + + nr_bler_data[i].bler_table[nlines][ncols] = strtof(token, NULL); + ncols++; + + token = strtok_r(NULL, ";", &temp); + } + nlines++; + } + nr_bler_data[i].length = nlines; + fclose(pFile); + } +} diff --git a/openair2/NR_UE_PHY_INTERFACE/NR_Packet_Drop.h b/openair2/NR_UE_PHY_INTERFACE/NR_Packet_Drop.h index 6658eec595..02907f9940 100644 --- a/openair2/NR_UE_PHY_INTERFACE/NR_Packet_Drop.h +++ b/openair2/NR_UE_PHY_INTERFACE/NR_Packet_Drop.h @@ -77,5 +77,6 @@ float get_bler_val(uint8_t mcs, int sinr); bool should_drop_transport_block(int slot, uint16_t rnti); bool is_channel_modeling(void); int get_mcs_from_sinr(nr_bler_struct *nr_bler_data, float sinr); +void init_nr_bler_table(const char *env_string); #endif From ead066d630fd07a52177de0698a7cbb344237149 Mon Sep 17 00:00:00 2001 From: Bartosz Podrygajlo Date: Tue, 16 Jul 2024 21:44:06 +0200 Subject: [PATCH 24/49] Remove unused abstraction_flag from NR UE --- executables/nr-ue.c | 5 +---- executables/nr-uesoftmodem.c | 7 +------ executables/nr-uesoftmodem.h | 2 +- 3 files changed, 3 insertions(+), 11 deletions(-) diff --git a/executables/nr-ue.c b/executables/nr-ue.c index 447c99182b..37fc3390d8 100644 --- a/executables/nr-ue.c +++ b/executables/nr-ue.c @@ -138,11 +138,8 @@ static void *nrL1_UE_stats_thread(void *param) return NULL; } -void init_nr_ue_vars(PHY_VARS_NR_UE *ue, - uint8_t UE_id, - uint8_t abstraction_flag) +void init_nr_ue_vars(PHY_VARS_NR_UE *ue, uint8_t UE_id) { - int nb_connected_gNB = 1; ue->Mod_id = UE_id; diff --git a/executables/nr-uesoftmodem.c b/executables/nr-uesoftmodem.c index d78fe26206..a4e02a56aa 100644 --- a/executables/nr-uesoftmodem.c +++ b/executables/nr-uesoftmodem.c @@ -160,11 +160,6 @@ uint32_t N_RB_DL = 106; // NTN cellSpecificKoffset-r17, but in slots for DL SCS unsigned int NTN_UE_Koffset = 0; -/* see file openair2/LAYER2/MAC/main.c for why abstraction_flag is needed - * this is very hackish - find a proper solution - */ -uint8_t abstraction_flag=0; - /*---------------------BMC: timespec helpers -----------------------------*/ struct timespec min_diff_time = { .tv_sec = 0, .tv_nsec = 0 }; @@ -563,7 +558,7 @@ int main(int argc, char **argv) } UE[CC_id]->sl_mode = get_softmodem_params()->sl_mode; - init_nr_ue_vars(UE[CC_id], inst, abstraction_flag); + init_nr_ue_vars(UE[CC_id], inst); if (UE[CC_id]->sl_mode) { AssertFatal(UE[CC_id]->sl_mode == 2, "Only Sidelink mode 2 supported. Mode 1 not yet supported\n"); diff --git a/executables/nr-uesoftmodem.h b/executables/nr-uesoftmodem.h index 9505bfd6b3..5f01bfdf3a 100644 --- a/executables/nr-uesoftmodem.h +++ b/executables/nr-uesoftmodem.h @@ -103,6 +103,6 @@ extern void reset_opp_meas(void); extern void print_opp_meas(void); void start_oai_nrue_threads(void); void *UE_thread(void *arg); -void init_nr_ue_vars(PHY_VARS_NR_UE *ue, uint8_t UE_id, uint8_t abstraction_flag); +void init_nr_ue_vars(PHY_VARS_NR_UE *ue, uint8_t UE_id); void init_nrUE_standalone_thread(int ue_idx); #endif From 19033ca822cd86a699afd71d8645ab0b8a7e0596 Mon Sep 17 00:00:00 2001 From: Bartosz Podrygajlo Date: Tue, 16 Jul 2024 21:48:37 +0200 Subject: [PATCH 25/49] Remove num_missed_slots from softmodems and some extra unused functions from NRUE. --- executables/lte-softmodem.c | 2 -- executables/lte-softmodem.h | 1 - executables/lte-uesoftmodem.c | 2 -- executables/nr-softmodem-common.h | 1 - executables/nr-softmodem.c | 2 -- executables/nr-uesoftmodem.c | 24 ------------------------ 6 files changed, 32 deletions(-) diff --git a/executables/lte-softmodem.c b/executables/lte-softmodem.c index e5530765a5..4b278bec4b 100644 --- a/executables/lte-softmodem.c +++ b/executables/lte-softmodem.c @@ -143,8 +143,6 @@ char channels[128] = "0"; int rx_input_level_dBm; int otg_enabled; -uint64_t num_missed_slots=0; // counter for the number of missed slots - RU_t **RCconfig_RU(int nb_RU,int nb_L1_inst,PHY_VARS_eNB ***eNB,uint64_t *ru_mask,pthread_mutex_t *ru_mutex,pthread_cond_t *ru_cond); RU_t **RCconfig_RU(int nb_RU,int nb_L1_inst,PHY_VARS_eNB ***eNB,uint64_t *ru_mask,pthread_mutex_t *ru_mutex,pthread_cond_t *ru_cond); diff --git a/executables/lte-softmodem.h b/executables/lte-softmodem.h index 2bd7576e16..678327ddb5 100644 --- a/executables/lte-softmodem.h +++ b/executables/lte-softmodem.h @@ -122,7 +122,6 @@ extern uint64_t downlink_frequency[MAX_NUM_CCs][4]; extern int32_t uplink_frequency_offset[MAX_NUM_CCs][4]; extern int rx_input_level_dBm; -extern uint64_t num_missed_slots; // counter for the number of missed slots extern int oaisim_flag; extern int oai_exit; diff --git a/executables/lte-uesoftmodem.c b/executables/lte-uesoftmodem.c index 600722f651..9336698bac 100644 --- a/executables/lte-uesoftmodem.c +++ b/executables/lte-uesoftmodem.c @@ -143,8 +143,6 @@ int rx_input_level_dBm; static LTE_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs]; -uint64_t num_missed_slots=0; // counter for the number of missed slots - // prototypes from function implemented in lte-ue.c, probably should be elsewhere in a include file. extern void init_UE_stub_single_thread(int nb_inst,int eMBMS_active, int uecap_xer_in, char *emul_iface); extern PHY_VARS_UE *init_ue_vars(LTE_DL_FRAME_PARMS *frame_parms, uint8_t UE_id, uint8_t abstraction_flag); diff --git a/executables/nr-softmodem-common.h b/executables/nr-softmodem-common.h index 56d92497cc..1ef5e4ecfe 100644 --- a/executables/nr-softmodem-common.h +++ b/executables/nr-softmodem-common.h @@ -134,7 +134,6 @@ extern uint64_t downlink_frequency[MAX_NUM_CCs][4]; extern int32_t uplink_frequency_offset[MAX_NUM_CCs][4]; extern int rx_input_level_dBm; -extern uint64_t num_missed_slots; // counter for the number of missed slots extern int oaisim_flag; extern int oai_exit; diff --git a/executables/nr-softmodem.c b/executables/nr-softmodem.c index 958161252a..9f67b1cada 100644 --- a/executables/nr-softmodem.c +++ b/executables/nr-softmodem.c @@ -141,8 +141,6 @@ int rx_input_level_dBm; int otg_enabled; -uint64_t num_missed_slots=0; // counter for the number of missed slots - #include extern void reset_opp_meas(void); diff --git a/executables/nr-uesoftmodem.c b/executables/nr-uesoftmodem.c index a4e02a56aa..7575d37e3b 100644 --- a/executables/nr-uesoftmodem.c +++ b/executables/nr-uesoftmodem.c @@ -151,7 +151,6 @@ double cpuf; int chain_offset = 0; int card_offset = 0; -uint64_t num_missed_slots = 0; // counter for the number of missed slots int numerology = 0; int oaisim_flag = 0; int emulate_rf = 0; @@ -160,29 +159,6 @@ uint32_t N_RB_DL = 106; // NTN cellSpecificKoffset-r17, but in slots for DL SCS unsigned int NTN_UE_Koffset = 0; -/*---------------------BMC: timespec helpers -----------------------------*/ - -struct timespec min_diff_time = { .tv_sec = 0, .tv_nsec = 0 }; -struct timespec max_diff_time = { .tv_sec = 0, .tv_nsec = 0 }; - -struct timespec clock_difftime(struct timespec start, struct timespec end) { - struct timespec temp; - - if ((end.tv_nsec-start.tv_nsec)<0) { - temp.tv_sec = end.tv_sec-start.tv_sec-1; - temp.tv_nsec = 1000000000+end.tv_nsec-start.tv_nsec; - } else { - temp.tv_sec = end.tv_sec-start.tv_sec; - temp.tv_nsec = end.tv_nsec-start.tv_nsec; - } - - return temp; -} - -void print_difftimes(void) { - LOG_I(HW,"difftimes min = %lu ns ; max = %lu ns\n", min_diff_time.tv_nsec, max_diff_time.tv_nsec); -} - int create_tasks_nrue(uint32_t ue_nb) { LOG_D(NR_RRC, "%s(ue_nb:%d)\n", __FUNCTION__, ue_nb); itti_wait_ready(1); From b2a46e3b76f258b322c65c4870c3eff38d6bc35b Mon Sep 17 00:00:00 2001 From: Bartosz Podrygajlo Date: Tue, 16 Jul 2024 21:59:01 +0200 Subject: [PATCH 26/49] Remove unused variables from softmodems, focusing on NR UE: chain_offset, card_offset, numerology, oaisim_flag, dumpframe, rx_input_level_dBm, emulate_rf --- executables/lte-enb.c | 2 -- executables/lte-softmodem.c | 1 - executables/lte-softmodem.h | 1 - executables/lte-uesoftmodem.c | 1 - executables/nr-softmodem-common.h | 3 --- executables/nr-softmodem.c | 2 -- executables/nr-uesoftmodem.c | 13 ++----------- 7 files changed, 2 insertions(+), 21 deletions(-) diff --git a/executables/lte-enb.c b/executables/lte-enb.c index 9c56c5f53e..8f50dfc63d 100644 --- a/executables/lte-enb.c +++ b/executables/lte-enb.c @@ -107,8 +107,6 @@ extern int oai_exit; extern int transmission_mode; -extern int oaisim_flag; - #include "executables/thread-common.h" //extern PARALLEL_CONF_t get_thread_parallel_conf(void); //extern WORKER_CONF_t get_thread_worker_conf(void); diff --git a/executables/lte-softmodem.c b/executables/lte-softmodem.c index 4b278bec4b..a895b7b614 100644 --- a/executables/lte-softmodem.c +++ b/executables/lte-softmodem.c @@ -157,7 +157,6 @@ eth_params_t *eth_params; double cpuf; -int oaisim_flag=0; /* hardcoded into gtp_itf.cpp */ bool sdap_data_req(protocol_ctxt_t *ctxt_p, diff --git a/executables/lte-softmodem.h b/executables/lte-softmodem.h index 678327ddb5..6bc6d27f21 100644 --- a/executables/lte-softmodem.h +++ b/executables/lte-softmodem.h @@ -123,7 +123,6 @@ extern int32_t uplink_frequency_offset[MAX_NUM_CCs][4]; extern int rx_input_level_dBm; -extern int oaisim_flag; extern int oai_exit; extern openair0_config_t openair0_cfg[MAX_CARDS]; diff --git a/executables/lte-uesoftmodem.c b/executables/lte-uesoftmodem.c index 9336698bac..fa32d877f6 100644 --- a/executables/lte-uesoftmodem.c +++ b/executables/lte-uesoftmodem.c @@ -165,7 +165,6 @@ double cpuf; extern char uecap_xer[1024]; char uecap_xer_in=0; -int oaisim_flag=0; /* see file openair2/LAYER2/MAC/main.c for why abstraction_flag is needed * this is very hackish - find a proper solution diff --git a/executables/nr-softmodem-common.h b/executables/nr-softmodem-common.h index 1ef5e4ecfe..41c3b60682 100644 --- a/executables/nr-softmodem-common.h +++ b/executables/nr-softmodem-common.h @@ -133,9 +133,6 @@ extern int sync_var; extern uint64_t downlink_frequency[MAX_NUM_CCs][4]; extern int32_t uplink_frequency_offset[MAX_NUM_CCs][4]; -extern int rx_input_level_dBm; - -extern int oaisim_flag; extern int oai_exit; extern openair0_config_t openair0_cfg[MAX_CARDS]; diff --git a/executables/nr-softmodem.c b/executables/nr-softmodem.c index 9f67b1cada..f0a3e71464 100644 --- a/executables/nr-softmodem.c +++ b/executables/nr-softmodem.c @@ -137,8 +137,6 @@ uint8_t dci_Format = 0; uint8_t nb_antenna_tx = 1; uint8_t nb_antenna_rx = 1; -int rx_input_level_dBm; - int otg_enabled; #include diff --git a/executables/nr-uesoftmodem.c b/executables/nr-uesoftmodem.c index 7575d37e3b..8e7ce84b2e 100644 --- a/executables/nr-uesoftmodem.c +++ b/executables/nr-uesoftmodem.c @@ -124,12 +124,10 @@ char *rrc_config_path = NULL; char *reconfig_file = NULL; char *rbconfig_file = NULL; char *uecap_file = NULL; -int dumpframe = 0; uint64_t downlink_frequency[MAX_NUM_CCs][4]; int32_t uplink_frequency_offset[MAX_NUM_CCs][4]; uint64_t sidelink_frequency[MAX_NUM_CCs][4]; -int rx_input_level_dBm; #if MAX_NUM_CCs == 1 rx_gain_t rx_gain_mode[MAX_NUM_CCs][4] = {{max_gain,max_gain,max_gain,max_gain}}; @@ -147,13 +145,6 @@ openair0_config_t openair0_cfg[MAX_CARDS]; int16_t node_synch_ref[MAX_NUM_CCs]; int otg_enabled; double cpuf; - - -int chain_offset = 0; -int card_offset = 0; -int numerology = 0; -int oaisim_flag = 0; -int emulate_rf = 0; uint32_t N_RB_DL = 106; // NTN cellSpecificKoffset-r17, but in slots for DL SCS @@ -251,8 +242,8 @@ void set_options(int CC_id, PHY_VARS_NR_UE *UE){ UE->rx_total_gain_dB = (int)rx_gain[CC_id][0] + rx_gain_off; UE->tx_total_gain_dB = (int)tx_gain[CC_id][0]; UE->tx_power_max_dBm = tx_max_power[CC_id]; - UE->rf_map.card = card_offset; - UE->rf_map.chain = CC_id + chain_offset; + UE->rf_map.card = 0; + UE->rf_map.chain = CC_id + 0; UE->max_ldpc_iterations = nrUE_params.max_ldpc_iterations; UE->ldpc_offload_enable = nrUE_params.ldpc_offload_flag; UE->UE_scan_carrier = nrUE_params.UE_scan_carrier; From 93280a3e75c759aa07aa0d50e4ee8b0c3b40584b Mon Sep 17 00:00:00 2001 From: Bartosz Podrygajlo Date: Tue, 16 Jul 2024 22:22:35 +0200 Subject: [PATCH 27/49] Remove unused nr_dlsch_demod_shift command line parameter from NR UE --- executables/nr-softmodem-common.h | 1 - executables/nr-uesoftmodem.c | 1 - executables/nr-uesoftmodem.h | 1 - openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c | 7 ------- 4 files changed, 10 deletions(-) diff --git a/executables/nr-softmodem-common.h b/executables/nr-softmodem-common.h index 41c3b60682..21dd057a64 100644 --- a/executables/nr-softmodem-common.h +++ b/executables/nr-softmodem-common.h @@ -49,7 +49,6 @@ #define CONFIG_HLP_UESCAN "set UE to scan all possible GSCN in current bandwidth\n" #define CONFIG_HLP_UEFO "set UE to enable estimation and compensation of frequency offset\n" #define CONFIG_HLP_DUMPFRAME "dump UE received frame to rxsig_frame0.dat and exit\n" -#define CONFIG_HLP_DLSHIFT "dynamic shift for LLR compuation for TM3/4 (default 0)\n" #define CONFIG_HLP_PHYTST "test UE phy layer, mac disabled\n" #define CONFIG_HLP_DORA "test gNB and UE with RA procedures\n" #define CONFIG_HLP_DMAMAP "use DMA memory mapping\n" diff --git a/executables/nr-uesoftmodem.c b/executables/nr-uesoftmodem.c index 8e7ce84b2e..105ffdbbaa 100644 --- a/executables/nr-uesoftmodem.c +++ b/executables/nr-uesoftmodem.c @@ -111,7 +111,6 @@ RAN_CONTEXT_t RC; int oai_exit = 0; -extern int16_t nr_dlsch_demod_shift; static int tx_max_power[MAX_NUM_CCs] = {0}; int vcdflag = 0; diff --git a/executables/nr-uesoftmodem.h b/executables/nr-uesoftmodem.h index 5f01bfdf3a..9d14a8d74b 100644 --- a/executables/nr-uesoftmodem.h +++ b/executables/nr-uesoftmodem.h @@ -40,7 +40,6 @@ {"offset-divisor", CONFIG_HLP_OFFSET_DIV, 0, .uptr=&nrUE_params.ofdm_offset_divisor, .defuintval=8, TYPE_UINT32, 0}, \ {"max-ldpc-iterations", CONFIG_HLP_MAX_LDPC_ITERATIONS, 0, .iptr=&nrUE_params.max_ldpc_iterations, .defuintval=8, TYPE_UINT8, 0}, \ {"ldpc-offload-enable", CONFIG_HLP_LDPC_OFFLOAD, PARAMFLAG_BOOL, .iptr=&(nrUE_params.ldpc_offload_flag), .defintval=0, TYPE_INT, 0}, \ - {"nr-dlsch-demod-shift", CONFIG_HLP_DLSHIFT, 0, .iptr=(int32_t *)&nr_dlsch_demod_shift, .defintval=0, TYPE_INT, 0}, \ {"V" , CONFIG_HLP_VCD, PARAMFLAG_BOOL, .iptr=&vcdflag, .defintval=0, TYPE_INT, 0}, \ {"uecap_file", CONFIG_HLP_UECAP_FILE, 0, .strptr=&uecap_file, .defstrval="./uecap_ports1.xml", TYPE_STRING, 0}, \ {"rrc_config_path", CONFIG_HLP_RRC_CFG_PATH, 0, .strptr=&rrc_config_path, .defstrval=NULL, TYPE_STRING, 0}, \ diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c index be69351d8f..7476309ad8 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c @@ -42,13 +42,6 @@ #include "openair1/PHY/TOOLS/phy_scope_interface.h" #include "nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface.h" -/* dynamic shift for LLR computation for TM3/4 - * set as command line argument, see lte-softmodem.c - * default value: 0 - */ -int32_t nr_dlsch_demod_shift = 0; -//int16_t interf_unaw_shift = 13; - // #define DEBUG_HARQ(a...) printf(a) #define DEBUG_HARQ(...) //#define DEBUG_DLSCH_DEMOD From 3dd0d4590782148686516f8dc8d8855ee06b6b05 Mon Sep 17 00:00:00 2001 From: andrewse Date: Tue, 16 Jul 2024 13:44:18 +0200 Subject: [PATCH 28/49] 7.2 xran: notification generation code in ru_thread excluded from compilation --- executables/nr-gnb.c | 2 ++ executables/nr-ru.c | 7 +++++-- radio/fhi_72/CMakeLists.txt | 3 +++ 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/executables/nr-gnb.c b/executables/nr-gnb.c index 2e9716c40c..6df84f2057 100644 --- a/executables/nr-gnb.c +++ b/executables/nr-gnb.c @@ -266,6 +266,7 @@ static void rx_func(processingData_L1_t *info) gNB->if_inst->NR_UL_indication(&gNB->UL_INFO); stop_meas(&gNB->ul_indication_stats); +#ifndef OAI_FHI72 notifiedFIFO_elt_t *res = newNotifiedFIFO_elt(sizeof(processingData_L1_t), 0, &gNB->L1_rx_out, NULL); processingData_L1_t *syncMsg = NotifiedFifoData(res); syncMsg->gNB = gNB; @@ -274,6 +275,7 @@ static void rx_func(processingData_L1_t *info) res->key = slot_rx; LOG_D(NR_PHY, "Signaling completion for %d.%d (mod_slot %d) on L1_rx_out\n", frame_rx, slot_rx, slot_rx % RU_RX_SLOT_DEPTH); pushNotifiedFIFO(&gNB->L1_rx_out, res); +#endif } stop_meas(&softmodem_stats_rxtx_sf); diff --git a/executables/nr-ru.c b/executables/nr-ru.c index 991c59e110..24a1ecd719 100644 --- a/executables/nr-ru.c +++ b/executables/nr-ru.c @@ -1146,8 +1146,9 @@ void *ru_thread( void *param ) { int initial_wait=0; int opp_enabled0 = opp_enabled; +#ifndef OAI_FHI72 bool rx_tti_busy[RU_RX_SLOT_DEPTH] = {false}; - nfapi_nr_config_request_scf_t *cfg = &ru->config; +#endif // set default return value ru_thread_status = 0; // set default return value @@ -1319,8 +1320,9 @@ void *ru_thread( void *param ) { if (ru->idx != 0) proc->frame_tx = (proc->frame_tx + proc->frame_offset) & 1023; +#ifndef OAI_FHI72 // do RX front-end processing (frequency-shift, dft) if needed - int slot_type = nr_slot_select(cfg, proc->frame_rx, proc->tti_rx); + int slot_type = nr_slot_select(&ru->config, proc->frame_rx, proc->tti_rx); if (slot_type == NR_UPLINK_SLOT || slot_type == NR_MIXED_SLOT) { if (ru->feprx) { if (rx_tti_busy[proc->tti_rx % RU_RX_SLOT_DEPTH]) { @@ -1393,6 +1395,7 @@ void *ru_thread( void *param ) { memset(&ru->rt_ru_profiling.return_RU_prachrx[rt_prof_idx],0,sizeof(struct timespec)); } } // end if (slot_type == NR_UPLINK_SLOT || slot_type == NR_MIXED_SLOT) { +#endif notifiedFIFO_elt_t *resTx = newNotifiedFIFO_elt(sizeof(processingData_L1tx_t), 0, &gNB->L1_tx_out, NULL); processingData_L1tx_t *syncMsgTx = NotifiedFifoData(resTx); diff --git a/radio/fhi_72/CMakeLists.txt b/radio/fhi_72/CMakeLists.txt index ba28d4c448..5794848afd 100644 --- a/radio/fhi_72/CMakeLists.txt +++ b/radio/fhi_72/CMakeLists.txt @@ -36,3 +36,6 @@ set_target_properties(oran_fhlib_5g PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMAKE_ add_custom_command(TARGET oran_fhlib_5g POST_BUILD COMMAND ${CMAKE_COMMAND} -E create_symlink liboran_fhlib_5g.so liboai_transpro.so WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) + +message(STATUS "Temporary added -DOAI_FHI72") +target_compile_definitions(nr-softmodem PUBLIC OAI_FHI72) From 6bc486f504ec17866fdb613d9d83467aa0d7f487 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 18 Jul 2024 13:19:37 +0200 Subject: [PATCH 29/49] Fixup: Simplify code --- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c index b60be4bd88..19dcad7045 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c @@ -901,18 +901,10 @@ static void _nr_rx_sdu(const module_id_t gnb_mod_idP, // Switch to BWP where RA is configured, typically in the InitialBWP // At this point, UE already switched and triggered RA in that BWP, need to do BWP switching also at gNB for C-RNTI - if ((ra->DL_BWP.bwp_id != UE->current_DL_BWP.bwp_id) || (ra->UL_BWP.bwp_id != UE->current_UL_BWP.bwp_id)) { - LOG_I(NR_MAC, - "BWP switching at gNB from BWP id %ld to BWP id %ld due to RA configuration\n", - UE->current_DL_BWP.bwp_id, - ra->DL_BWP.bwp_id); - configure_UE_BWP(RC.nrmac[gnb_mod_idP], - RC.nrmac[gnb_mod_idP]->common_channels[CC_idP].ServingCellConfigCommon, - &UE->UE_sched_ctrl, - NULL, - UE, - ra->DL_BWP.bwp_id, - ra->UL_BWP.bwp_id); + if (ra->DL_BWP.bwp_id != UE->current_DL_BWP.bwp_id || ra->UL_BWP.bwp_id != UE->current_UL_BWP.bwp_id) { + LOG_D(NR_MAC, "UE %04x Switch BWP from %ld to BWP id %ld\n", UE->rnti, UE->current_DL_BWP.bwp_id, ra->DL_BWP.bwp_id); + NR_ServingCellConfigCommon_t *scc = gNB_mac->common_channels[CC_idP].ServingCellConfigCommon; + configure_UE_BWP(gNB_mac, scc, &UE->UE_sched_ctrl, NULL, UE, ra->DL_BWP.bwp_id, ra->UL_BWP.bwp_id); } if (UE->reconfigCellGroup) { From f28f9e52acf72a65270d304d36dbaff730cbe39c Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 18 Jul 2024 13:48:20 +0200 Subject: [PATCH 30/49] Use gNB_mac consistently --- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c index 19dcad7045..bab839622b 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c @@ -880,13 +880,13 @@ static void _nr_rx_sdu(const module_id_t gnb_mod_idP, nr_mac_trigger_release_timer(&UE->UE_sched_ctrl, UE->current_UL_BWP.scs); // Replace the current UE by the UE identified by C-RNTI - UE = find_nr_UE(&RC.nrmac[gnb_mod_idP]->UE_info, crnti); + UE = find_nr_UE(&gNB_mac->UE_info, crnti); if (!UE) { // The UE identified by C-RNTI no longer exists at the gNB // Let's abort the current RA, so the UE will trigger a new RA later but using RRCSetupRequest instead. A better // solution may be implemented LOG_W(NR_MAC, "No UE found with C-RNTI %04x, ignoring Msg3 to have UE come back with new RA attempt\n", ra->rnti); - mac_remove_nr_ue(RC.nrmac[gnb_mod_idP], ra->rnti); + mac_remove_nr_ue(gNB_mac, ra->rnti); nr_clear_ra_proc(ra); return; } @@ -914,7 +914,7 @@ static void _nr_rx_sdu(const module_id_t gnb_mod_idP, } else { // Trigger RRC Reconfiguration LOG_I(NR_MAC, "Received UL_SCH_LCID_C_RNTI with C-RNTI 0x%04x, triggering RRC Reconfiguration\n", UE->rnti); - nr_mac_trigger_reconfiguration(RC.nrmac[gnb_mod_idP], UE); + nr_mac_trigger_reconfiguration(gNB_mac, UE); } } else { // UE Contention Resolution Identity From a6ce2896f77cb51271d126870c3c4d7a65a40dff Mon Sep 17 00:00:00 2001 From: Jaroslava Fiedlerova Date: Wed, 26 Jun 2024 21:17:33 +0200 Subject: [PATCH 31/49] CI: Create Iperf2 unidirectional function Add new function to run iperf v2 test. Supports testing with 1 UE, unidirectional traffic. Currently used in RFSim-4G, FeMBMS testcase. --- ci-scripts/cls_oaicitest.py | 40 +++++++++++++++++++ ci-scripts/main.py | 10 +++++ ci-scripts/xml_class_list.yml | 1 + .../xml_files/container_4g_rfsim_fembms.xml | 4 +- 4 files changed, 53 insertions(+), 2 deletions(-) diff --git a/ci-scripts/cls_oaicitest.py b/ci-scripts/cls_oaicitest.py index a9d3652f9d..0ff0f9e223 100644 --- a/ci-scripts/cls_oaicitest.py +++ b/ci-scripts/cls_oaicitest.py @@ -872,6 +872,46 @@ class OaiCiTest(): HTML.CreateHtmlTestRowQueue(self.iperf_args, 'KO', messages) self.AutoTerminateUEandeNB(HTML,RAN,EPC,CONTAINERS) + def Iperf2_Unidir(self,HTML,RAN,EPC,CONTAINERS): + if self.ue_ids == [] or self.svr_id == None or len(self.ue_ids) != 1: + raise Exception("no module names in self.ue_ids or/and self.svr_id provided, multi UE scenario not supported") + ue = cls_module.Module_UE(self.ue_ids[0].strip()) + svr = cls_module.Module_UE(self.svr_id) + ueIP = ue.getIP() + if not ueIP: + return (False, f"UE {ue.getName()} has no IP address") + svrIP = svr.getIP() + if not svrIP: + return (False, f"Iperf server {ue.getName()} has no IP address") + server_filename = f'iperf_server_{self.testCase_id}_{ue.getName()}.log' + ymlPath = CONTAINERS.yamlPath[0].split('/') + logPath = f'../cmake_targets/log/{ymlPath[-1]}' + iperf_time = Iperf_ComputeTime(self.iperf_args) + target_bitrate, iperf_opt = Iperf_ComputeModifiedBW(0, 1, self.iperf_profile, self.iperf_args) + t = iperf_time*2.5 + with cls_cmd.getConnection('localhost') as local: + local.run(f'mkdir -p {logPath}') + with cls_cmd.getConnection(ue.getHost()) as cmd_ue, cls_cmd.getConnection(EPC.IPAddress) as cmd_svr: + cmd_ue.run(f'rm /tmp/{server_filename}', reportNonZero=False) + cmd_ue.run(f'{ue.getCmdPrefix()} timeout -vk3 {t} iperf -B {ueIP} -s -u -i1 >> /tmp/{server_filename} &', timeout=t) + cmd_svr.run(f'{svr.getCmdPrefix()} timeout -vk3 {t} iperf -c {ueIP} -B {svrIP} {iperf_opt} -i1', timeout=t) + localPath = f'{os.getcwd()}' + # note: copy iperf2 log to the directory for log collection + cmd_ue.copyin(f'/tmp/{server_filename}', f'{localPath}/{logPath}/{server_filename}') + # note: copy iperf2 log to the current directory for log analysis and log collection + cmd_ue.copyin(f'/tmp/{server_filename}', f'{localPath}/{server_filename}') + cmd_ue.run(f'rm /tmp/{server_filename}', reportNonZero=False) + success, msg = Iperf_analyzeV2UDP(server_filename, self.iperf_bitrate_threshold, self.iperf_packetloss_threshold, target_bitrate) + ue_header = f'UE {ue.getName()} ({ueIP})' + logging.info(f'\u001B[1;37;45m iperf result for {ue_header}\u001B[0m') + for l in msg.split('\n'): + logging.info(f'\u001B[1;35m {l} \u001B[0m') + if success: + HTML.CreateHtmlTestRowQueue(self.iperf_args, 'OK', [f'{ue_header}\n{msg}']) + else: + HTML.CreateHtmlTestRowQueue(self.iperf_args, 'KO', [f'{ue_header}\n{msg}']) + self.AutoTerminateUEandeNB(HTML,RAN,EPC,CONTAINERS) + def AnalyzeLogFile_UE(self, UElogFile,HTML,RAN): if (not os.path.isfile(f'./{UElogFile}')): return -1 diff --git a/ci-scripts/main.py b/ci-scripts/main.py index 03c99d9741..8f1235d8b4 100644 --- a/ci-scripts/main.py +++ b/ci-scripts/main.py @@ -281,6 +281,14 @@ def GetParametersFromXML(action): logging.error('test-case has wrong option ' + CiTestObj.iperf_options) CiTestObj.iperf_options = 'check' + elif action == 'Iperf2_Unidir': + CiTestObj.iperf_args = test.findtext('iperf_args') + CiTestObj.ue_ids = test.findtext('id').split(' ') + CiTestObj.svr_id = test.findtext('svr_id') or None + CiTestObj.iperf_packetloss_threshold = test.findtext('iperf_packetloss_threshold') + CiTestObj.iperf_bitrate_threshold = test.findtext('iperf_bitrate_threshold') or '90' + CiTestObj.iperf_profile = test.findtext('iperf_profile') or 'balanced' + elif action == 'IdleSleep': string_field = test.findtext('idle_sleep_time_in_sec') if (string_field is None): @@ -770,6 +778,8 @@ elif re.match('^TesteNB$', mode, re.IGNORECASE) or re.match('^TestUE$', mode, re CiTestObj.Ping(HTML,RAN,EPC,CONTAINERS) elif action == 'Iperf': CiTestObj.Iperf(HTML,RAN,EPC,CONTAINERS) + elif action == 'Iperf2_Unidir': + CiTestObj.Iperf2_Unidir(HTML,RAN,EPC,CONTAINERS) elif action == 'Initialize_HSS': EPC.InitializeHSS(HTML) elif action == 'Terminate_HSS': diff --git a/ci-scripts/xml_class_list.yml b/ci-scripts/xml_class_list.yml index 1b6b88147d..6a3908004d 100755 --- a/ci-scripts/xml_class_list.yml +++ b/ci-scripts/xml_class_list.yml @@ -21,6 +21,7 @@ - CheckStatusUE - Ping - Iperf + - Iperf2_Unidir - Deploy_EPC - Undeploy_EPC - Initialize_HSS diff --git a/ci-scripts/xml_files/container_4g_rfsim_fembms.xml b/ci-scripts/xml_files/container_4g_rfsim_fembms.xml index 941b59a040..bd15657c23 100644 --- a/ci-scripts/xml_files/container_4g_rfsim_fembms.xml +++ b/ci-scripts/xml_files/container_4g_rfsim_fembms.xml @@ -72,8 +72,8 @@ - Iperf - Iperf UDP DL + Iperf2_Unidir + Iperf2 UDP DL rfsim4g_ue_fembms rfsim4g_enb_fembms -u -t 30 -b 2M From b790150e5465cd567346b3be29bdf8638ed11862 Mon Sep 17 00:00:00 2001 From: Jaroslava Fiedlerova Date: Wed, 26 Jun 2024 21:20:06 +0200 Subject: [PATCH 32/49] CI: Simplify Iperf_Module() Remove code related to "rfsim4g_enb_fembms" testcase from Iperf_Module() - replaced by Iperf2_Unidir(). Use copyin() for both remote and local commands - no need to check if running on localhost anymore. Create directory for log collection on executor node - used for log collection in pipelines running on localhost. Copy the iperf3 report to the executor machine for log collection. The report needs to be copied to two different directories to ensure proper log collection across all pipelines. Using absolute paths ensures compatibility with both remote and local commands. --- ci-scripts/cls_oaicitest.py | 53 +++++++++++++++---------------------- 1 file changed, 22 insertions(+), 31 deletions(-) diff --git a/ci-scripts/cls_oaicitest.py b/ci-scripts/cls_oaicitest.py index 0ff0f9e223..81bd035733 100644 --- a/ci-scripts/cls_oaicitest.py +++ b/ci-scripts/cls_oaicitest.py @@ -790,10 +790,8 @@ class OaiCiTest(): udpIperf = re.search('-u', iperf_opt) is not None bidirIperf = re.search('--bidir', iperf_opt) is not None client_filename = f'iperf_client_{self.testCase_id}_{ue.getName()}.log' - server_filename = f'iperf_server_{self.testCase_id}_{ue.getName()}.log' ymlPath = CONTAINERS.yamlPath[0].split('/') logPath = f'../cmake_targets/log/{ymlPath[1]}' - if udpIperf: target_bitrate, iperf_opt = Iperf_ComputeModifiedBW(idx, ue_num, self.iperf_profile, self.iperf_args) # note: for UDP testing we don't want to use json report - reports 0 Mbps received bitrate @@ -805,36 +803,29 @@ class OaiCiTest(): # hack: the ADB UEs don't have iperf in $PATH, so we need to hardcode for the moment iperf_ue = '/data/local/tmp/iperf3' if re.search('adb', ue.getName()) else 'iperf3' ue_header = f'UE {ue.getName()} ({ueIP})' - - if svr.getName() == "rfsim4g_enb_fembms": - with cls_cmd.getConnection(ue.getHost()) as cmd_ue, cls_cmd.getConnection(EPC.IPAddress) as cmd_svr: - port = 5002 + idx - cmd_ue.run(f'{ue.getCmdPrefix()} iperf -B {ueIP} -s -u -i1 >> {server_filename} &', timeout=iperf_time*1.5) - cmd_svr.run(f'{svr.getCmdPrefix()} iperf -c {ueIP} -B {svrIP} {iperf_opt} -i1 2>&1 | tee {client_filename}', timeout=iperf_time*2.5) - cmd_ue.run(f'cp {client_filename} {logPath}/{client_filename}') - cmd_ue.run(f'cp {server_filename} {logPath}/{server_filename}') - status, msg = Iperf_analyzeV2UDP(server_filename, self.iperf_bitrate_threshold, self.iperf_packetloss_threshold, target_bitrate) + # create log directory on executor node + with cls_cmd.getConnection('localhost') as local: + local.run(f'mkdir -p {logPath}') + with cls_cmd.getConnection(ue.getHost()) as cmd_ue, cls_cmd.getConnection(EPC.IPAddress) as cmd_svr: + port = 5002 + idx + # note: some core setups start an iperf3 server automatically, indicated in ci_infra by runIperf3Server: False` + t = iperf_time * 2.5 + cmd_ue.run(f'rm /tmp/{client_filename}', reportNonZero=False) + if runIperf3Server: + cmd_svr.run(f'{svr.getCmdPrefix()} nohup timeout -vk3 {t} iperf3 -s -B {svrIP} -p {port} -1 {jsonReport} &', timeout=t) + cmd_ue.run(f'{ue.getCmdPrefix()} timeout -vk3 {t} {iperf_ue} -B {ueIP} -c {svrIP} -p {port} {iperf_opt} {jsonReport} {serverReport} -O 5 >> /tmp/{client_filename}', timeout=t) + localPath = f'{os.getcwd()}' + # note: copy iperf3 log to the directory for log collection, used by pipelines running on executor machine + cmd_ue.copyin(f'/tmp/{client_filename}', f'{localPath}/{logPath}/{client_filename}') + # note: copy iperf3 log to the current directory for log analysis and log collection + cmd_ue.copyin(f'/tmp/{client_filename}', f'{localPath}/{client_filename}') + cmd_ue.run(f'rm /tmp/{client_filename}', reportNonZero=False) + if udpIperf: + status, msg = Iperf_analyzeV3UDP(client_filename, self.iperf_bitrate_threshold, self.iperf_packetloss_threshold, target_bitrate) + elif bidirIperf: + status, msg = Iperf_analyzeV3BIDIRJson(client_filename) else: - with cls_cmd.getConnection(ue.getHost()) as cmd_ue, cls_cmd.getConnection(EPC.IPAddress) as cmd_svr: - port = 5002 + idx - # note: some core setups start an iperf3 server automatically, indicated in ci_infra by runIperf3Server: False` - t = iperf_time * 2.5 - if runIperf3Server: - cmd_svr.run(f'{svr.getCmdPrefix()} nohup timeout -vk3 {t} iperf3 -s -B {svrIP} -p {port} -1 {jsonReport} &', timeout=t) - cmd_ue.run(f'rm /tmp/{client_filename}', reportNonZero=False) - cmd_ue.run(f'{ue.getCmdPrefix()} timeout -vk3 {t} {iperf_ue} -B {ueIP} -c {svrIP} -p {port} {iperf_opt} {jsonReport} {serverReport} -O 5 >> /tmp/{client_filename}', timeout=t) - if svr.getHost() == 'localhost': - cmd_ue.run(f'mkdir -p {logPath}') - cmd_ue.run(f'cp /tmp/{client_filename} {logPath}/{client_filename}') - cmd_ue.run(f'cp /tmp/{client_filename} {client_filename}') - else: - cmd_ue.copyin(f'/tmp/{client_filename}', client_filename) - if udpIperf: - status, msg = Iperf_analyzeV3UDP(client_filename, self.iperf_bitrate_threshold, self.iperf_packetloss_threshold, target_bitrate) - elif bidirIperf: - status, msg = Iperf_analyzeV3BIDIRJson(client_filename) - else: - status, msg = Iperf_analyzeV3TCPJson(client_filename, self.iperf_tcp_rate_target) + status, msg = Iperf_analyzeV3TCPJson(client_filename, self.iperf_tcp_rate_target) logging.info(f'\u001B[1;37;45m iperf result for {ue_header}\u001B[0m') for l in msg.split('\n'): From c9a40c464eb113123ee4e5426c354b125d4bbb68 Mon Sep 17 00:00:00 2001 From: Jaroslava Fiedlerova Date: Tue, 16 Jul 2024 15:09:47 +0200 Subject: [PATCH 33/49] Minor fix of Iperf_analyzeV2UDP() Don't break after first occurence of status template (interval "0.0- 1.0 sec"). With this modification we get final result, which is at the last line of log (for interval "0.0-30.2 sec"). --- ci-scripts/cls_oaicitest.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/ci-scripts/cls_oaicitest.py b/ci-scripts/cls_oaicitest.py index 81bd035733..b7e61c06cd 100644 --- a/ci-scripts/cls_oaicitest.py +++ b/ci-scripts/cls_oaicitest.py @@ -202,8 +202,6 @@ def Iperf_analyzeV2UDP(server_filename, iperf_bitrate_threshold, iperf_packetlos with open(server_filename, 'r') as server_file: for line in server_file.readlines(): result = re.search(statusTemplate, str(line)) - if result is not None: - break if result is None: return (False, 'Could not parse server report!') bitrate = float(result.group('bitrate')) From ae4cbcfb0cd325cfdccc9ca25e78dbbec361b569 Mon Sep 17 00:00:00 2001 From: Thomas Schlichter Date: Tue, 9 Jul 2024 14:56:18 +0200 Subject: [PATCH 34/49] gNB: add config file option "disable_harq" and set pdsch_servingcellconfig->ext3->downlinkHARQ_FeedbackDisabled_r17 accordingly --- openair2/GNB_APP/gnb_config.c | 18 ++++++++++---- openair2/GNB_APP/gnb_paramdef.h | 17 ++++++++----- openair2/LAYER2/NR_MAC_COMMON/nr_mac.h | 1 + openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c | 11 +++++++++ openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h | 2 ++ .../NR_MAC_gNB/gNB_scheduler_primitives.c | 3 +++ openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h | 1 + openair2/RRC/NR/nr_rrc_config.c | 24 +++++++++++++++++++ .../gnb.sa.band66.fr1.24PRB.usrpx300.conf | 1 + .../gnb.sa.band66.fr1.25PRB.usrpx300.conf | 1 + 10 files changed, 69 insertions(+), 10 deletions(-) diff --git a/openair2/GNB_APP/gnb_config.c b/openair2/GNB_APP/gnb_config.c index b732a88879..1d638dd91c 100644 --- a/openair2/GNB_APP/gnb_config.c +++ b/openair2/GNB_APP/gnb_config.c @@ -1250,13 +1250,17 @@ void RCconfig_nr_macrlc(configmodule_interface_t *cfg) config.force_UL256qam_off = *GNBParamList.paramarray[0][GNB_FORCEUL256QAMOFF_IDX].iptr; config.use_deltaMCS = *GNBParamList.paramarray[0][GNB_USE_DELTA_MCS_IDX].iptr != 0; config.maxMIMO_layers = *GNBParamList.paramarray[0][GNB_MAXMIMOLAYERS_IDX].iptr; + config.disable_harq = *GNBParamList.paramarray[0][GNB_DISABLE_HARQ_IDX].iptr; + if (config.disable_harq) + LOG_W(GNB_APP, "\"disable_harq\" is a REL17 feature and is incompatible with REL15 and REL16 UEs!\n"); LOG_I(GNB_APP, - "CSI-RS %d, SRS %d, 256 QAM %s, delta_MCS %s, maxMIMO_Layers %d\n", + "CSI-RS %d, SRS %d, 256 QAM %s, delta_MCS %s, maxMIMO_Layers %d, HARQ feedback %s\n", config.do_CSIRS, config.do_SRS, config.force_256qam_off ? "force off" : "may be on", config.use_deltaMCS ? "on" : "off", - config.maxMIMO_layers); + config.maxMIMO_layers, + config.disable_harq ? "disabled" : "enabled"); int tot_ant = config.pdsch_AntennaPorts.N1 * config.pdsch_AntennaPorts.N2 * config.pdsch_AntennaPorts.XP; AssertFatal(config.maxMIMO_layers != 0 && config.maxMIMO_layers <= tot_ant, "Invalid maxMIMO_layers %d\n", config.maxMIMO_layers); @@ -1360,12 +1364,18 @@ void RCconfig_nr_macrlc(configmodule_interface_t *cfg) dl_bler_options->upper = *(MacRLC_ParamList.paramarray[j][MACRLC_DL_BLER_TARGET_UPPER_IDX].dblptr); dl_bler_options->lower = *(MacRLC_ParamList.paramarray[j][MACRLC_DL_BLER_TARGET_LOWER_IDX].dblptr); dl_bler_options->max_mcs = *(MacRLC_ParamList.paramarray[j][MACRLC_DL_MAX_MCS_IDX].u8ptr); - dl_bler_options->harq_round_max = *(MacRLC_ParamList.paramarray[j][MACRLC_DL_HARQ_ROUND_MAX_IDX].u8ptr); + if (config.disable_harq) + dl_bler_options->harq_round_max = 1; + else + dl_bler_options->harq_round_max = *(MacRLC_ParamList.paramarray[j][MACRLC_DL_HARQ_ROUND_MAX_IDX].u8ptr); NR_bler_options_t *ul_bler_options = &RC.nrmac[j]->ul_bler; ul_bler_options->upper = *(MacRLC_ParamList.paramarray[j][MACRLC_UL_BLER_TARGET_UPPER_IDX].dblptr); ul_bler_options->lower = *(MacRLC_ParamList.paramarray[j][MACRLC_UL_BLER_TARGET_LOWER_IDX].dblptr); ul_bler_options->max_mcs = *(MacRLC_ParamList.paramarray[j][MACRLC_UL_MAX_MCS_IDX].u8ptr); - ul_bler_options->harq_round_max = *(MacRLC_ParamList.paramarray[j][MACRLC_UL_HARQ_ROUND_MAX_IDX].u8ptr); + if (config.disable_harq) + ul_bler_options->harq_round_max = 1; + else + ul_bler_options->harq_round_max = *(MacRLC_ParamList.paramarray[j][MACRLC_UL_HARQ_ROUND_MAX_IDX].u8ptr); RC.nrmac[j]->min_grant_prb = *(MacRLC_ParamList.paramarray[j][MACRLC_MIN_GRANT_PRB_IDX].u8ptr); RC.nrmac[j]->min_grant_mcs = *(MacRLC_ParamList.paramarray[j][MACRLC_MIN_GRANT_MCS_IDX].u8ptr); RC.nrmac[j]->identity_pm = *(MacRLC_ParamList.paramarray[j][MACRLC_IDENTITY_PM_IDX].u8ptr); diff --git a/openair2/GNB_APP/gnb_paramdef.h b/openair2/GNB_APP/gnb_paramdef.h index ad8267e984..144fca43d7 100644 --- a/openair2/GNB_APP/gnb_paramdef.h +++ b/openair2/GNB_APP/gnb_paramdef.h @@ -126,6 +126,7 @@ typedef enum { #define GNB_CONFIG_STRING_UMONDEFAULTDRB "um_on_default_drb" #define GNB_CONFIG_STRING_FORCE256QAMOFF "force_256qam_off" #define GNB_CONFIG_STRING_MAXMIMOLAYERS "maxMIMO_layers" +#define GNB_CONFIG_STRING_DISABLE_HARQ "disable_harq" #define GNB_CONFIG_STRING_ENABLE_SDAP "enable_sdap" #define GNB_CONFIG_STRING_DRBS "drbs" #define GNB_CONFIG_STRING_USE_DELTA_MCS "use_deltaMCS" @@ -138,6 +139,7 @@ typedef enum { #define GNB_CONFIG_HLP_STRING_ENABLE_SDAP "enable the SDAP layer\n" #define GNB_CONFIG_HLP_FORCE256QAMOFF "suppress activation of 256 QAM despite UE support" #define GNB_CONFIG_HLP_MAXMIMOLAYERS "limit on maxMIMO-layers for DL" +#define GNB_CONFIG_HLP_DISABLE_HARQ "disable feedback for all HARQ processes (REL17 feature)" #define GNB_CONFIG_HLP_STRING_DRBS "Number of total DRBs to establish, including the mandatory for PDU SEssion (default=1)\n" #define GNB_CONFIG_HLP_GNB_DU_ID "defines the gNB-DU ID (only applicable for DU)" #define GNB_CONFIG_HLP_GNB_CU_UP_ID "defines the gNB-CU-UP ID (only applicable for CU-UP)" @@ -172,14 +174,15 @@ typedef enum { {GNB_CONFIG_STRING_MINRXTXTIME, NULL, 0, .iptr=NULL, .defintval=2, TYPE_INT, 0}, \ {GNB_CONFIG_STRING_ULPRBBLACKLIST, NULL, 0, .strptr=NULL,.defstrval="", TYPE_STRING, 0}, \ {GNB_CONFIG_STRING_UMONDEFAULTDRB, NULL, PARAMFLAG_BOOL, .uptr=NULL, .defuintval=0, TYPE_UINT, 0}, \ -{GNB_CONFIG_STRING_FORCE256QAMOFF, GNB_CONFIG_HLP_FORCE256QAMOFF, PARAMFLAG_BOOL, .iptr=NULL, .defintval=0, TYPE_INT, 0}, \ +{GNB_CONFIG_STRING_FORCE256QAMOFF, GNB_CONFIG_HLP_FORCE256QAMOFF, PARAMFLAG_BOOL, .iptr=NULL, .defintval=0, TYPE_INT, 0}, \ {GNB_CONFIG_STRING_ENABLE_SDAP, GNB_CONFIG_HLP_STRING_ENABLE_SDAP, PARAMFLAG_BOOL,.iptr=NULL, .defintval=0, TYPE_INT, 0}, \ -{GNB_CONFIG_STRING_DRBS, GNB_CONFIG_HLP_STRING_DRBS, 0, .iptr=NULL, .defintval=1, TYPE_INT, 0}, \ -{GNB_CONFIG_STRING_GNB_DU_ID, GNB_CONFIG_HLP_GNB_DU_ID, 0, .u64ptr=NULL, .defint64val=1, TYPE_UINT64, 0}, \ +{GNB_CONFIG_STRING_DRBS, GNB_CONFIG_HLP_STRING_DRBS, 0, .iptr=NULL, .defintval=1, TYPE_INT, 0}, \ +{GNB_CONFIG_STRING_GNB_DU_ID, GNB_CONFIG_HLP_GNB_DU_ID, 0, .u64ptr=NULL, .defint64val=1, TYPE_UINT64, 0}, \ {GNB_CONFIG_STRING_GNB_CU_UP_ID, GNB_CONFIG_HLP_GNB_CU_UP_ID, 0, .u64ptr=NULL, .defint64val=1, TYPE_UINT64, 0}, \ -{GNB_CONFIG_STRING_USE_DELTA_MCS, GNB_CONFIG_HLP_USE_DELTA_MCS, 0, .iptr=NULL, .defintval=0, TYPE_INT, 0}, \ -{GNB_CONFIG_STRING_FORCEUL256QAMOFF, GNB_CONFIG_HLP_FORCEUL256QAMOFF, 0, .iptr=NULL, .defintval=0, TYPE_INT, 0}, \ -{GNB_CONFIG_STRING_MAXMIMOLAYERS, GNB_CONFIG_HLP_MAXMIMOLAYERS, 0, .iptr=NULL, .defintval=-1, TYPE_INT, 0}, \ +{GNB_CONFIG_STRING_USE_DELTA_MCS, GNB_CONFIG_HLP_USE_DELTA_MCS, 0, .iptr=NULL, .defintval=0, TYPE_INT, 0}, \ +{GNB_CONFIG_STRING_FORCEUL256QAMOFF, GNB_CONFIG_HLP_FORCEUL256QAMOFF, 0,.iptr=NULL, .defintval=0, TYPE_INT, 0}, \ +{GNB_CONFIG_STRING_MAXMIMOLAYERS, GNB_CONFIG_HLP_MAXMIMOLAYERS, 0, .iptr=NULL, .defintval=-1, TYPE_INT, 0}, \ +{GNB_CONFIG_STRING_DISABLE_HARQ, GNB_CONFIG_HLP_DISABLE_HARQ, PARAMFLAG_BOOL, .iptr=NULL, .defintval=0, TYPE_INT, 0}, \ } // clang-format on @@ -216,6 +219,7 @@ typedef enum { #define GNB_USE_DELTA_MCS_IDX 29 #define GNB_FORCEUL256QAMOFF_IDX 30 #define GNB_MAXMIMOLAYERS_IDX 31 +#define GNB_DISABLE_HARQ_IDX 32 #define TRACKING_AREA_CODE_OKRANGE {0x0001,0xFFFD} #define GNBPARAMS_CHECK { \ @@ -251,6 +255,7 @@ typedef enum { { .s5 = { NULL } }, \ { .s5 = { NULL } }, \ { .s5 = { NULL } }, \ + { .s5 = { NULL } }, \ } /*-------------------------------------------------------------------------------------------------------------------------------------------------*/ diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h b/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h index e43b038266..d141215846 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h @@ -599,6 +599,7 @@ typedef struct { int dl_bw_tbslbrm; int ul_bw_tbslbrm; NR_NTN_Config_r17_t *ntn_Config_r17; + NR_DownlinkHARQ_FeedbackDisabled_r17_t *downlinkHARQ_FeedbackDisabled_r17; } NR_UE_ServingCell_Info_t; typedef enum { diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c index 151cee026d..acbc1ff1ca 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c @@ -5243,3 +5243,14 @@ rnti_t nr_get_ra_rnti(uint8_t s_id, uint8_t t_id, uint8_t f_id, uint8_t ul_carri return ra_rnti; } + +int get_FeedbackDisabled(NR_DownlinkHARQ_FeedbackDisabled_r17_t *downlinkHARQ_FeedbackDisabled_r17, int harq_pid) +{ + if (downlinkHARQ_FeedbackDisabled_r17 == NULL) + return 0; + + const int byte_index = harq_pid / 8; + const int bit_index = harq_pid % 8; + + return (downlinkHARQ_FeedbackDisabled_r17->buf[byte_index] >> (7 - bit_index)) & 1; +} diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h index e809c3e521..72872a7e1f 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h @@ -317,4 +317,6 @@ rnti_t nr_get_ra_rnti(uint8_t s_id, uint8_t t_id, uint8_t f_id, uint8_t ul_carri bool supported_bw_comparison(int bw_mhz, NR_SupportedBandwidth_t *supported_BW, long *support_90mhz); +int get_FeedbackDisabled(NR_DownlinkHARQ_FeedbackDisabled_r17_t *downlinkHARQ_FeedbackDisabled_r17, int harq_pid); + #endif diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c index 8ae9c3dcc5..4c67bfdf35 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c @@ -2345,6 +2345,9 @@ void configure_UE_BWP(gNB_MAC_INST *nr_mac, sc_info->nrofHARQ_ProcessesForPDSCH = pdsch_servingcellconfig->nrofHARQ_ProcessesForPDSCH; if (pdsch_servingcellconfig->ext1) sc_info->maxMIMO_Layers_PDSCH = pdsch_servingcellconfig->ext1->maxMIMO_Layers; + if (pdsch_servingcellconfig->ext3 && + pdsch_servingcellconfig->ext3->downlinkHARQ_FeedbackDisabled_r17) + sc_info->downlinkHARQ_FeedbackDisabled_r17 = &pdsch_servingcellconfig->ext3->downlinkHARQ_FeedbackDisabled_r17->choice.setup; if (pdsch_servingcellconfig->codeBlockGroupTransmission && pdsch_servingcellconfig->codeBlockGroupTransmission->choice.setup) sc_info->pdsch_CGB_Transmission = pdsch_servingcellconfig->codeBlockGroupTransmission->choice.setup; diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h index 7fe0c8994e..a1c75dfe76 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h +++ b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h @@ -152,6 +152,7 @@ typedef struct nr_mac_config_t { bool force_UL256qam_off; bool use_deltaMCS; int maxMIMO_layers; + bool disable_harq; //int pusch_TargetSNRx10; //int pucch_TargetSNRx10; nr_mac_timers_t timer_config; diff --git a/openair2/RRC/NR/nr_rrc_config.c b/openair2/RRC/NR/nr_rrc_config.c index de660f1765..edd192eee9 100644 --- a/openair2/RRC/NR/nr_rrc_config.c +++ b/openair2/RRC/NR/nr_rrc_config.c @@ -2685,6 +2685,18 @@ static NR_SpCellConfig_t *get_initial_SpCellConfig(int uid, *pdsch_servingcellconfig->nrofHARQ_ProcessesForPDSCH = NR_PDSCH_ServingCellConfig__nrofHARQ_ProcessesForPDSCH_n16; pdsch_servingcellconfig->pucch_Cell = NULL; set_dl_maxmimolayers(pdsch_servingcellconfig, scc, NULL, configuration->maxMIMO_layers); + if (configuration->disable_harq) { + pdsch_servingcellconfig->ext3 = calloc(1, sizeof(*pdsch_servingcellconfig->ext3)); + pdsch_servingcellconfig->ext3->downlinkHARQ_FeedbackDisabled_r17 = calloc(1, sizeof(*pdsch_servingcellconfig->ext3->downlinkHARQ_FeedbackDisabled_r17)); + pdsch_servingcellconfig->ext3->downlinkHARQ_FeedbackDisabled_r17->present = NR_SetupRelease_DownlinkHARQ_FeedbackDisabled_r17_PR_setup; + pdsch_servingcellconfig->ext3->downlinkHARQ_FeedbackDisabled_r17->choice.setup.buf = calloc(4, sizeof(uint8_t)); + pdsch_servingcellconfig->ext3->downlinkHARQ_FeedbackDisabled_r17->choice.setup.size = 4; + pdsch_servingcellconfig->ext3->downlinkHARQ_FeedbackDisabled_r17->choice.setup.bits_unused = 0; + pdsch_servingcellconfig->ext3->downlinkHARQ_FeedbackDisabled_r17->choice.setup.buf[0] = 0xFF; + pdsch_servingcellconfig->ext3->downlinkHARQ_FeedbackDisabled_r17->choice.setup.buf[1] = 0xFF; + pdsch_servingcellconfig->ext3->downlinkHARQ_FeedbackDisabled_r17->choice.setup.buf[2] = 0xFF; + pdsch_servingcellconfig->ext3->downlinkHARQ_FeedbackDisabled_r17->choice.setup.buf[3] = 0xFF; + } // Downlink BWPs int n_dl_bwp = 0; @@ -3289,6 +3301,18 @@ NR_CellGroupConfig_t *get_default_secondaryCellGroup(const NR_ServingCellConfigC pdsch_servingcellconfig->pucch_Cell = NULL; set_dl_maxmimolayers(pdsch_servingcellconfig, servingcellconfigcommon, uecap, configuration->maxMIMO_layers); pdsch_servingcellconfig->ext1->processingType2Enabled = NULL; + if (configuration->disable_harq) { + pdsch_servingcellconfig->ext3 = calloc(1, sizeof(*pdsch_servingcellconfig->ext3)); + pdsch_servingcellconfig->ext3->downlinkHARQ_FeedbackDisabled_r17 = calloc(1, sizeof(*pdsch_servingcellconfig->ext3->downlinkHARQ_FeedbackDisabled_r17)); + pdsch_servingcellconfig->ext3->downlinkHARQ_FeedbackDisabled_r17->present = NR_SetupRelease_DownlinkHARQ_FeedbackDisabled_r17_PR_setup; + pdsch_servingcellconfig->ext3->downlinkHARQ_FeedbackDisabled_r17->choice.setup.buf = calloc(4, sizeof(uint8_t)); + pdsch_servingcellconfig->ext3->downlinkHARQ_FeedbackDisabled_r17->choice.setup.size = 4; + pdsch_servingcellconfig->ext3->downlinkHARQ_FeedbackDisabled_r17->choice.setup.bits_unused = 0; + pdsch_servingcellconfig->ext3->downlinkHARQ_FeedbackDisabled_r17->choice.setup.buf[0] = 0xFF; + pdsch_servingcellconfig->ext3->downlinkHARQ_FeedbackDisabled_r17->choice.setup.buf[1] = 0xFF; + pdsch_servingcellconfig->ext3->downlinkHARQ_FeedbackDisabled_r17->choice.setup.buf[2] = 0xFF; + pdsch_servingcellconfig->ext3->downlinkHARQ_FeedbackDisabled_r17->choice.setup.buf[3] = 0xFF; + } secondaryCellGroup->spCellConfig->spCellConfigDedicated->csi_MeasConfig = NULL; secondaryCellGroup->spCellConfig->spCellConfigDedicated->csi_MeasConfig = diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band66.fr1.24PRB.usrpx300.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band66.fr1.24PRB.usrpx300.conf index 0ad01d6e93..602c31f42c 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band66.fr1.24PRB.usrpx300.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band66.fr1.24PRB.usrpx300.conf @@ -34,6 +34,7 @@ gNBs = sib1_tda = 5; min_rxtxtime = 6; +# disable_harq = 1; servingCellConfigCommon = ( { diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band66.fr1.25PRB.usrpx300.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band66.fr1.25PRB.usrpx300.conf index f29bbf9cf6..0934508e91 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band66.fr1.25PRB.usrpx300.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band66.fr1.25PRB.usrpx300.conf @@ -34,6 +34,7 @@ gNBs = sib1_tda = 5; min_rxtxtime = 6; +# disable_harq = 1; servingCellConfigCommon = ( { From bf2baf2ffec87b51ad4659f31921d2dab7168756 Mon Sep 17 00:00:00 2001 From: Thomas Schlichter Date: Wed, 22 May 2024 10:48:07 +0200 Subject: [PATCH 35/49] immediately reuse DL HARQ ID and don't wait for feedback if DL HARQ feedback is disabled --- .../LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c index 95832f5158..a182a9e2c1 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c @@ -999,12 +999,21 @@ void nr_schedule_ue_spec(module_id_t module_id, NR_tda_info_t *tda_info = &sched_pdsch->tda_info; NR_pdsch_dmrs_t *dmrs_parms = &sched_pdsch->dmrs_parms; NR_UE_harq_t *harq = &sched_ctrl->harq_processes[current_harq_pid]; - DevAssert(!harq->is_waiting); - add_tail_nr_list(&sched_ctrl->feedback_dl_harq, current_harq_pid); NR_sched_pucch_t *pucch = &sched_ctrl->sched_pucch[sched_pdsch->pucch_allocation]; - harq->feedback_frame = pucch->frame; - harq->feedback_slot = pucch->ul_slot; - harq->is_waiting = true; + DevAssert(!harq->is_waiting); + if (get_FeedbackDisabled(UE->sc_info.downlinkHARQ_FeedbackDisabled_r17, current_harq_pid)) { + add_tail_nr_list(&sched_ctrl->available_dl_harq, current_harq_pid); + harq->feedback_frame = -1; + harq->feedback_slot = -1; + harq->is_waiting = false; + harq->ndi ^= 1; + harq->round = 0; + } else { + add_tail_nr_list(&sched_ctrl->feedback_dl_harq, current_harq_pid); + harq->feedback_frame = pucch->frame; + harq->feedback_slot = pucch->ul_slot; + harq->is_waiting = true; + } UE->mac_stats.dl.rounds[harq->round]++; LOG_D(NR_MAC, "%4d.%2d [DLSCH/PDSCH/PUCCH] RNTI %04x DCI L %d start %3d RBs %3d startSymbol %2d nb_symbol %2d dmrspos %x MCS %2d nrOfLayers %d TBS %4d HARQ PID %2d round %d RV %d NDI %d dl_data_to_ULACK %d (%d.%d) PUCCH allocation %d TPC %d\n", From 4baac21ec612188530a567bb82e9e6979afe2ac7 Mon Sep 17 00:00:00 2001 From: Thomas Schlichter Date: Wed, 22 May 2024 10:52:14 +0200 Subject: [PATCH 36/49] immediately reuse UL HARQ ID and don't wait for feedback if disable_harq == 1 --- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c index 1048be2528..66ff87e80f 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c @@ -2270,9 +2270,17 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot, n } NR_UE_ul_harq_t *cur_harq = &sched_ctrl->ul_harq_processes[harq_id]; DevAssert(!cur_harq->is_waiting); - add_tail_nr_list(&sched_ctrl->feedback_ul_harq, harq_id); - cur_harq->feedback_slot = sched_pusch->slot; - cur_harq->is_waiting = true; + if (nr_mac->radio_config.disable_harq) { + add_tail_nr_list(&sched_ctrl->available_ul_harq, harq_id); + cur_harq->feedback_slot = -1; + cur_harq->is_waiting = false; + cur_harq->ndi ^= 1; + cur_harq->round = 0; + } else { + add_tail_nr_list(&sched_ctrl->feedback_ul_harq, harq_id); + cur_harq->feedback_slot = sched_pusch->slot; + cur_harq->is_waiting = true; + } /* Statistics */ AssertFatal(cur_harq->round < nr_mac->ul_bler.harq_round_max, "Indexing ulsch_rounds[%d] is out of bounds\n", cur_harq->round); From 9a0408a5c7d34afeffbbb9b876f53daefa59077b Mon Sep 17 00:00:00 2001 From: Thomas Schlichter Date: Wed, 22 May 2024 10:54:07 +0200 Subject: [PATCH 37/49] immediately reuse Msg4 HARQ ID and don't wait for Msg4 feedback if DL HARQ feedback is disabled --- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c | 39 +++++++++++++++---- 1 file changed, 32 insertions(+), 7 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c index 9daabdddaf..f8ad0aa9a2 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c @@ -1880,15 +1880,24 @@ static void nr_generate_Msg4(module_id_t module_idP, remove_front_nr_list(&sched_ctrl->available_dl_harq); } NR_UE_harq_t *harq = &sched_ctrl->harq_processes[current_harq_pid]; + NR_sched_pucch_t *pucch = &sched_ctrl->sched_pucch[alloc]; DevAssert(!harq->is_waiting); - add_tail_nr_list(&sched_ctrl->feedback_dl_harq, current_harq_pid); - harq->is_waiting = true; + if (get_FeedbackDisabled(UE->sc_info.downlinkHARQ_FeedbackDisabled_r17, current_harq_pid)) { + add_tail_nr_list(&sched_ctrl->available_dl_harq, current_harq_pid); + harq->feedback_frame = -1; + harq->feedback_slot = -1; + harq->is_waiting = false; + harq->ndi ^= 1; + harq->round = 0; + } else { + add_tail_nr_list(&sched_ctrl->feedback_dl_harq, current_harq_pid); + harq->feedback_slot = pucch->ul_slot; + harq->feedback_frame = pucch->frame; + harq->is_waiting = true; + } ra->harq_pid = current_harq_pid; UE->mac_stats.dl.rounds[harq->round]++; - NR_sched_pucch_t *pucch = &sched_ctrl->sched_pucch[alloc]; - harq->feedback_slot = pucch->ul_slot; - harq->feedback_frame = pucch->frame; harq->tb_size = tb_size; uint8_t *buf = (uint8_t *) harq->transportBlock; @@ -1967,8 +1976,24 @@ static void nr_generate_Msg4(module_id_t module_idP, vrb_map[BWPStart + rb + rbStart] |= SL_to_bitmap(msg4_tda.startSymbolIndex, msg4_tda.nrOfSymbols); } - ra->ra_state = nrRA_WAIT_Msg4_ACK; - LOG_I(NR_MAC,"UE %04x Generate msg4: feedback at %4d.%2d, payload %d bytes, next state WAIT_Msg4_ACK\n", ra->rnti, pucch->frame, pucch->ul_slot, harq->tb_size); + if (get_FeedbackDisabled(UE->sc_info.downlinkHARQ_FeedbackDisabled_r17, current_harq_pid)) { + LOG_I(NR_MAC,"UE %04x Generate msg4: feedback at %4d.%2d, payload %d bytes\n", ra->rnti, pucch->frame, pucch->ul_slot, harq->tb_size); + + LOG_A(NR_MAC, "(UE RNTI 0x%04x) Skipping Ack of RA-Msg4. CBRA procedure succeeded!\n", ra->rnti); + UE->Msg4_ACKed = true; + + // Pause scheduling according to: + // 3GPP TS 38.331 Section 12 Table 12.1-1: UE performance requirements for RRC procedures for UEs + // Msg4 may transmit a RRCReconfiguration, for example when UE sends RRCReestablishmentComplete and MAC CE for C-RNTI in Msg3. + // In that case, gNB will generate a RRCReconfiguration that will be transmitted in Msg4, so we need to apply CellGroup after the Ack, + // UE->apply_cellgroup was already set when processing RRCReestablishment message + nr_mac_enable_ue_rrc_processing_timer(nr_mac, UE, UE->apply_cellgroup); + + nr_clear_ra_proc(ra); + } else { + ra->ra_state = nrRA_WAIT_Msg4_ACK; + LOG_I(NR_MAC,"UE %04x Generate msg4: feedback at %4d.%2d, payload %d bytes, next state WAIT_Msg4_ACK\n", ra->rnti, pucch->frame, pucch->ul_slot, harq->tb_size); + } } } From f7665357fcb7b5c8910ccbb0b53524e937cb0057 Mon Sep 17 00:00:00 2001 From: Thomas Schlichter Date: Wed, 22 May 2024 10:57:02 +0200 Subject: [PATCH 38/49] dont't print warning in handle_nr_ul_harq() if disable_harq == 1 --- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c index 66ff87e80f..3b097e5e32 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c @@ -566,6 +566,11 @@ void handle_nr_ul_harq(const int CC_idP, LOG_E(NR_MAC, "no RA proc for RNTI 0x%04x in Msg3/PUSCH\n", crc_pdu->rnti); return; } + if (nrmac->radio_config.disable_harq) { + LOG_D(NR_MAC, "skipping UL feedback handling as HARQ is disabled\n"); + NR_SCHED_UNLOCK(&nrmac->sched_lock); + return; + } NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; int8_t harq_pid = sched_ctrl->feedback_ul_harq.head; LOG_D(NR_MAC, "Comparing crc_pdu->harq_id vs feedback harq_pid = %d %d\n",crc_pdu->harq_id, harq_pid); From b331ad21f4d421511446b20c60293119307c7392 Mon Sep 17 00:00:00 2001 From: Thomas Schlichter Date: Wed, 22 May 2024 11:12:56 +0200 Subject: [PATCH 39/49] in nr_rx_sdu() use HARQ ID from nfapi_nr_crc_t instead of feedback_ul_harq --- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c | 5 +++-- openair2/LAYER2/NR_MAC_gNB/mac_proto.h | 1 + openair2/NR_PHY_INTERFACE/NR_IF_Module.c | 4 ++++ 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c index 3b097e5e32..094d7aafe5 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c @@ -656,6 +656,7 @@ static void _nr_rx_sdu(const module_id_t gnb_mod_idP, const rnti_t rntiP, uint8_t *sduP, const uint32_t sdu_lenP, + const int8_t harq_pid, const uint16_t timing_advance, const uint8_t ul_cqi, const uint16_t rssi) @@ -673,7 +674,6 @@ static void _nr_rx_sdu(const module_id_t gnb_mod_idP, if (UE && UE_waiting_CFRA_msg3 == false) { NR_UE_sched_ctrl_t *UE_scheduling_control = &UE->UE_sched_ctrl; - const int8_t harq_pid = UE_scheduling_control->feedback_ul_harq.head; if (sduP) T(T_GNB_MAC_UL_PDU_WITH_DATA, T_INT(gnb_mod_idP), T_INT(CC_idP), @@ -951,13 +951,14 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP, const rnti_t rntiP, uint8_t *sduP, const uint32_t sdu_lenP, + const int8_t harq_pid, const uint16_t timing_advance, const uint8_t ul_cqi, const uint16_t rssi) { gNB_MAC_INST *gNB_mac = RC.nrmac[gnb_mod_idP]; NR_SCHED_LOCK(&gNB_mac->sched_lock); - _nr_rx_sdu(gnb_mod_idP, CC_idP, frameP, slotP, rntiP, sduP, sdu_lenP, timing_advance, ul_cqi, rssi); + _nr_rx_sdu(gnb_mod_idP, CC_idP, frameP, slotP, rntiP, sduP, sdu_lenP, harq_pid, timing_advance, ul_cqi, rssi); NR_SCHED_UNLOCK(&gNB_mac->sched_lock); } diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h index fe2fec8ab1..5c998f4d2a 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h @@ -344,6 +344,7 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP, const rnti_t rntiP, uint8_t * sduP, const uint32_t sdu_lenP, + const int8_t harq_pid, const uint16_t timing_advance, const uint8_t ul_cqi, const uint16_t rssi); diff --git a/openair2/NR_PHY_INTERFACE/NR_IF_Module.c b/openair2/NR_PHY_INTERFACE/NR_IF_Module.c index 869c0f9882..c685bb47af 100644 --- a/openair2/NR_PHY_INTERFACE/NR_IF_Module.c +++ b/openair2/NR_PHY_INTERFACE/NR_IF_Module.c @@ -192,6 +192,9 @@ void handle_nr_ulsch(NR_UL_IND_t *UL_info) AssertFatal(crc->rnti == rx->rnti, "mis-match between CRC RNTI %04x and RX RNTI %04x\n", crc->rnti, rx->rnti); + AssertFatal(crc->harq_id == rx->harq_id, "mis-match between CRC HARQ ID %04x and RX HARQ ID %04x\n", + crc->harq_id, rx->harq_id); + LOG_D(NR_MAC, "%4d.%2d Calling rx_sdu (CRC %s/tb_crc_status %d)\n", UL_info->frame, @@ -207,6 +210,7 @@ void handle_nr_ulsch(NR_UL_IND_t *UL_info) crc->rnti, crc->tb_crc_status ? NULL : rx->pdu, rx->pdu_length, + crc->harq_id, crc->timing_advance, crc->ul_cqi, crc->rssi); From a6fb797477b4ca66033494472945799cfeb64864 Mon Sep 17 00:00:00 2001 From: Thomas Schlichter Date: Wed, 22 May 2024 11:18:10 +0200 Subject: [PATCH 40/49] improve tracking of sched_ul_bytes in nr_rx_sdu() by using sdu_lenP instead of sched_pusch.tb_size sched_ul_bytes tracks the volume of in-flight data. When data is successfully received, sched_ul_bytes is decreased in nr_rx_sdu(). In case of reusing HARQ processes, the tb_size stored there is not correct. Therefore use the actual SDU size instead. --- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c index 094d7aafe5..610a58deb3 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c @@ -749,8 +749,7 @@ static void _nr_rx_sdu(const module_id_t gnb_mod_idP, LOG_D(NR_MAC, "Received PDU at MAC gNB \n"); UE->UE_sched_ctrl.pusch_consecutive_dtx_cnt = 0; - const uint32_t tb_size = UE_scheduling_control->ul_harq_processes[harq_pid].sched_pusch.tb_size; - UE_scheduling_control->sched_ul_bytes -= tb_size; + UE_scheduling_control->sched_ul_bytes -= sdu_lenP; if (UE_scheduling_control->sched_ul_bytes < 0) UE_scheduling_control->sched_ul_bytes = 0; From 44410df5988bcc600830b8559cb129ec87ccdda0 Mon Sep 17 00:00:00 2001 From: Thomas Schlichter Date: Wed, 22 May 2024 11:47:14 +0200 Subject: [PATCH 41/49] fix double reduction of sched_ul_bytes in case of failing 4th HARQ round sched_ul_bytes is reduced already in case the last HARQ round fails through handle_nr_ul_harq() -> abort_nr_ul_harq(). Therefore, the reduction in nr_rx_sdu() is wrong, and btw. it wrongly assumes the max. UL HARQ rounds to 4. So simply remove this peace of code in nr_rx_sdu(). --- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c index 610a58deb3..02770f2b2d 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c @@ -756,14 +756,6 @@ static void _nr_rx_sdu(const module_id_t gnb_mod_idP, nr_process_mac_pdu(gnb_mod_idP, UE, CC_idP, frameP, slotP, sduP, sdu_lenP, harq_pid); } else { - NR_UE_ul_harq_t *cur_harq = &UE_scheduling_control->ul_harq_processes[harq_pid]; - /* reduce sched_ul_bytes when cur_harq->round == 3 */ - if (cur_harq->round == 3) { - const uint32_t tb_size = UE_scheduling_control->ul_harq_processes[harq_pid].sched_pusch.tb_size; - UE_scheduling_control->sched_ul_bytes -= tb_size; - if (UE_scheduling_control->sched_ul_bytes < 0) - UE_scheduling_control->sched_ul_bytes = 0; - } if (ul_cqi == 0xff || ul_cqi <= 128) { UE->UE_sched_ctrl.pusch_consecutive_dtx_cnt++; UE->mac_stats.ulsch_DTX++; From fe7be3f130635589b7e39650f584c8dcc33745d3 Mon Sep 17 00:00:00 2001 From: Thomas Schlichter Date: Wed, 22 May 2024 12:47:02 +0200 Subject: [PATCH 42/49] Make handle_nr_uci_pucch_2_3_4() more consistent regarding logs with handle_nr_uci_pucch_0_1() --- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c index 1e133a028b..2d59e72db2 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c @@ -1105,11 +1105,14 @@ void handle_nr_uci_pucch_2_3_4(module_id_t mod_id, for (int harq_bit = 0; harq_bit < uci_234->harq.harq_bit_len; harq_bit++) { const int acknack = ((uci_234->harq.harq_payload[harq_bit >> 3]) >> harq_bit) & 0x01; NR_UE_harq_t *harq = find_harq(frame, slot, UE, RC.nrmac[mod_id]->dl_bler.harq_round_max); - if (!harq) + if (!harq) { + LOG_E(NR_MAC, "UE %04x: Could not find a HARQ process at %4d.%2d!\n", UE->rnti, frame, slot); break; + } DevAssert(harq->is_waiting); const int8_t pid = sched_ctrl->feedback_dl_harq.head; remove_front_nr_list(&sched_ctrl->feedback_dl_harq); + LOG_D(NR_MAC,"%4d.%2d bit %d pid %d ack/nack %d\n",frame, slot, harq_bit, pid, acknack); handle_dl_harq(UE, pid, uci_234->harq.harq_crc != 1 && acknack, nrmac->dl_bler.harq_round_max); } free(uci_234->harq.harq_payload); From 3a014e199f990cd281ac069e7b75a195b8e7f161 Mon Sep 17 00:00:00 2001 From: Thomas Schlichter Date: Tue, 9 Jul 2024 17:39:41 +0200 Subject: [PATCH 43/49] NR UE: skip DLSCH ACK/NACK reporting for harq pid where feedback is disabled --- openair2/LAYER2/NR_MAC_UE/config_ue.c | 24 ++++++++++++++++++++ openair2/LAYER2/NR_MAC_UE/main_ue_nr.c | 1 + openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c | 13 +++++++++-- 3 files changed, 36 insertions(+), 2 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_UE/config_ue.c b/openair2/LAYER2/NR_MAC_UE/config_ue.c index 507b45ebd3..c6c69311f7 100644 --- a/openair2/LAYER2/NR_MAC_UE/config_ue.c +++ b/openair2/LAYER2/NR_MAC_UE/config_ue.c @@ -2064,6 +2064,8 @@ static void configure_servingcell_info(NR_UE_MAC_INST_t *mac, NR_ServingCellConf free(sc_info->maxMIMO_Layers_PDSCH); sc_info->maxMIMO_Layers_PDSCH = NULL; } + if (sc_info->downlinkHARQ_FeedbackDisabled_r17) + asn1cFreeStruc(asn_DEF_NR_DownlinkHARQ_FeedbackDisabled_r17, sc_info->downlinkHARQ_FeedbackDisabled_r17); break; case NR_SetupRelease_PDSCH_ServingCellConfig_PR_setup: { NR_PDSCH_ServingCellConfig_t *pdsch_servingcellconfig = scd->pdsch_ServingCellConfig->choice.setup; @@ -2075,6 +2077,28 @@ static void configure_servingcell_info(NR_UE_MAC_INST_t *mac, NR_ServingCellConf UPDATE_IE(sc_info->xOverhead_PDSCH, pdsch_servingcellconfig->xOverhead, long); if (pdsch_servingcellconfig->ext1 && pdsch_servingcellconfig->ext1->maxMIMO_Layers) UPDATE_IE(sc_info->maxMIMO_Layers_PDSCH, pdsch_servingcellconfig->ext1->maxMIMO_Layers, long); + if (pdsch_servingcellconfig->ext3 && pdsch_servingcellconfig->ext3->downlinkHARQ_FeedbackDisabled_r17) { + switch (pdsch_servingcellconfig->ext3->downlinkHARQ_FeedbackDisabled_r17->present) { + case NR_SetupRelease_DownlinkHARQ_FeedbackDisabled_r17_PR_NOTHING: + break; + case NR_SetupRelease_DownlinkHARQ_FeedbackDisabled_r17_PR_release: + if (sc_info->downlinkHARQ_FeedbackDisabled_r17) + asn1cFreeStruc(asn_DEF_NR_DownlinkHARQ_FeedbackDisabled_r17, sc_info->downlinkHARQ_FeedbackDisabled_r17); + break; + case NR_SetupRelease_DownlinkHARQ_FeedbackDisabled_r17_PR_setup: + if (sc_info->downlinkHARQ_FeedbackDisabled_r17 == NULL) { + sc_info->downlinkHARQ_FeedbackDisabled_r17 = calloc(1, sizeof(*sc_info->downlinkHARQ_FeedbackDisabled_r17)); + sc_info->downlinkHARQ_FeedbackDisabled_r17->buf = calloc(4, sizeof(*sc_info->downlinkHARQ_FeedbackDisabled_r17->buf)); + } + sc_info->downlinkHARQ_FeedbackDisabled_r17->size = pdsch_servingcellconfig->ext3->downlinkHARQ_FeedbackDisabled_r17->choice.setup.size; + sc_info->downlinkHARQ_FeedbackDisabled_r17->bits_unused = pdsch_servingcellconfig->ext3->downlinkHARQ_FeedbackDisabled_r17->choice.setup.bits_unused; + for (int i = 0; i < sc_info->downlinkHARQ_FeedbackDisabled_r17->size; i++) + sc_info->downlinkHARQ_FeedbackDisabled_r17->buf[i] = pdsch_servingcellconfig->ext3->downlinkHARQ_FeedbackDisabled_r17->choice.setup.buf[i]; + break; + default: + AssertFatal(false, "Invalid case\n"); + } + } break; } default: diff --git a/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c b/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c index f67e8d25c3..b6a289cc45 100644 --- a/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c +++ b/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c @@ -269,6 +269,7 @@ void release_mac_configuration(NR_UE_MAC_INST_t *mac, asn1cFreeStruc(asn_DEF_NR_CSI_MeasConfig, sc->csi_MeasConfig); asn1cFreeStruc(asn_DEF_NR_CSI_AperiodicTriggerStateList, sc->aperiodicTriggerStateList); asn1cFreeStruc(asn_DEF_NR_NTN_Config_r17, sc->ntn_Config_r17); + asn1cFreeStruc(asn_DEF_NR_DownlinkHARQ_FeedbackDisabled_r17, sc->downlinkHARQ_FeedbackDisabled_r17); free(sc->xOverhead_PDSCH); free(sc->nrofHARQ_ProcessesForPDSCH); free(sc->rateMatching_PUSCH); diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c index af148e6bd5..c7903a9666 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c @@ -2341,7 +2341,17 @@ bool get_downlink_ack(NR_UE_MAC_INST_t *mac, frame_t frame, int slot, PUCCH_sche "Value of pucch_resource_indicator %d not matching with what set before %d (Possibly due to a false DCI) \n", current_harq->pucch_resource_indicator, res_ind); - else{ + else { + if (!current_harq->ack_received) + LOG_E(NR_MAC, "DLSCH ACK/NACK reporting initiated for harq pid %d before DLSCH decoding completed\n", dl_harq_pid); + + if (get_FeedbackDisabled(mac->sc_info.downlinkHARQ_FeedbackDisabled_r17, dl_harq_pid)) { + LOG_D(NR_MAC, "skipping DLSCH ACK/NACK reporting for harq pid %d\n", dl_harq_pid); + current_harq->active = false; + current_harq->ack_received = false; + continue; + } + if (current_harq->dai_cumul == 0) { LOG_E(NR_MAC,"PUCCH Downlink DAI is invalid\n"); return false; @@ -2356,7 +2366,6 @@ bool get_downlink_ack(NR_UE_MAC_INST_t *mac, frame_t frame, int slot, PUCCH_sche current_harq->active = false; current_harq->ack_received = false; } else { - LOG_E(NR_MAC, "DLSCH ACK/NACK reporting initiated for harq pid %d before DLSCH decoding completed\n", dl_harq_pid); ack_data[code_word][dai_index] = 0; } dai[code_word][dai_index] = (dai_index % 4) + 1; // value between 1 and 4 From cd052951d54e8e72313e142cec85e176b42e4e0e Mon Sep 17 00:00:00 2001 From: Thomas Schlichter Date: Tue, 16 Jul 2024 13:22:51 +0200 Subject: [PATCH 44/49] gNB: do not schedule DLSCH ACK/NACK reporting in PUCCH for harq pid where feedback is disabled --- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c | 36 ++++++------ .../LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c | 55 +++++++++++-------- .../LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c | 28 ++++++---- openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h | 2 +- 4 files changed, 69 insertions(+), 52 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c index f8ad0aa9a2..9f7199d7d5 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c @@ -1861,17 +1861,6 @@ static void nr_generate_Msg4(module_id_t module_idP, return; } - const int delta_PRI = 0; - int r_pucch = nr_get_pucch_resource(coreset, ra->UL_BWP.pucch_Config, CCEIndex); - - LOG_D(NR_MAC, "Msg4 r_pucch %d (CCEIndex %d, delta_PRI %d)\n", r_pucch, CCEIndex, delta_PRI); - - int alloc = nr_acknack_scheduling(nr_mac, UE, frameP, slotP, r_pucch, 1); - if (alloc < 0) { - LOG_D(NR_MAC,"Couldn't find a pucch allocation for ack nack (msg4) in frame %d slot %d\n",frameP,slotP); - return; - } - // HARQ management if (current_harq_pid < 0) { AssertFatal(sched_ctrl->available_dl_harq.head >= 0, @@ -1879,10 +1868,26 @@ static void nr_generate_Msg4(module_id_t module_idP, current_harq_pid = sched_ctrl->available_dl_harq.head; remove_front_nr_list(&sched_ctrl->available_dl_harq); } + + const int delta_PRI = 0; + + int alloc = -1; + if (!get_FeedbackDisabled(UE->sc_info.downlinkHARQ_FeedbackDisabled_r17, current_harq_pid)) { + int r_pucch = nr_get_pucch_resource(coreset, ra->UL_BWP.pucch_Config, CCEIndex); + + LOG_D(NR_MAC, "Msg4 r_pucch %d (CCEIndex %d, delta_PRI %d)\n", r_pucch, CCEIndex, delta_PRI); + + alloc = nr_acknack_scheduling(nr_mac, UE, frameP, slotP, r_pucch, 1); + if (alloc < 0) { + LOG_D(NR_MAC,"Couldn't find a pucch allocation for ack nack (msg4) in frame %d slot %d\n",frameP,slotP); + return; + } + } + NR_UE_harq_t *harq = &sched_ctrl->harq_processes[current_harq_pid]; - NR_sched_pucch_t *pucch = &sched_ctrl->sched_pucch[alloc]; + NR_sched_pucch_t *pucch = NULL; DevAssert(!harq->is_waiting); - if (get_FeedbackDisabled(UE->sc_info.downlinkHARQ_FeedbackDisabled_r17, current_harq_pid)) { + if (alloc < 0) { add_tail_nr_list(&sched_ctrl->available_dl_harq, current_harq_pid); harq->feedback_frame = -1; harq->feedback_slot = -1; @@ -1890,6 +1895,7 @@ static void nr_generate_Msg4(module_id_t module_idP, harq->ndi ^= 1; harq->round = 0; } else { + pucch = &sched_ctrl->sched_pucch[alloc]; add_tail_nr_list(&sched_ctrl->feedback_dl_harq, current_harq_pid); harq->feedback_slot = pucch->ul_slot; harq->feedback_frame = pucch->frame; @@ -1976,9 +1982,7 @@ static void nr_generate_Msg4(module_id_t module_idP, vrb_map[BWPStart + rb + rbStart] |= SL_to_bitmap(msg4_tda.startSymbolIndex, msg4_tda.nrOfSymbols); } - if (get_FeedbackDisabled(UE->sc_info.downlinkHARQ_FeedbackDisabled_r17, current_harq_pid)) { - LOG_I(NR_MAC,"UE %04x Generate msg4: feedback at %4d.%2d, payload %d bytes\n", ra->rnti, pucch->frame, pucch->ul_slot, harq->tb_size); - + if (pucch == NULL) { LOG_A(NR_MAC, "(UE RNTI 0x%04x) Skipping Ack of RA-Msg4. CBRA procedure succeeded!\n", ra->rnti); UE->Msg4_ACKed = true; diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c index a182a9e2c1..7e80ff7dfd 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c @@ -556,14 +556,17 @@ static bool allocate_dl_retransmission(module_id_t module_id, /* Find PUCCH occasion: if it fails, undo CCE allocation (undoing PUCCH * allocation after CCE alloc fail would be more complex) */ - int r_pucch = nr_get_pucch_resource(sched_ctrl->coreset, ul_bwp->pucch_Config, CCEIndex); - const int alloc = nr_acknack_scheduling(nr_mac, UE, frame, slot, r_pucch, 0); - if (alloc<0) { - LOG_D(NR_MAC, "[UE %04x][%4d.%2d] could not find PUCCH for DL DCI retransmission\n", - UE->rnti, - frame, - slot); - return false; + int alloc = -1; + if (!get_FeedbackDisabled(UE->sc_info.downlinkHARQ_FeedbackDisabled_r17, current_harq_pid)) { + int r_pucch = nr_get_pucch_resource(sched_ctrl->coreset, ul_bwp->pucch_Config, CCEIndex); + alloc = nr_acknack_scheduling(nr_mac, UE, frame, slot, r_pucch, 0); + if (alloc<0) { + LOG_D(NR_MAC, "[UE %04x][%4d.%2d] could not find PUCCH for DL DCI retransmission\n", + UE->rnti, + frame, + slot); + return false; + } } sched_ctrl->cce_index = CCEIndex; @@ -724,6 +727,8 @@ static void pf_dl(module_id_t module_id, iterator++; continue; } + NR_sched_pdsch_t *sched_pdsch = &sched_ctrl->sched_pdsch; + sched_pdsch->dl_harq_pid = sched_ctrl->available_dl_harq.head; int CCEIndex = get_cce_index(mac, CC_id, slot, iterator->UE->rnti, @@ -744,16 +749,18 @@ static void pf_dl(module_id_t module_id, /* Find PUCCH occasion: if it fails, undo CCE allocation (undoing PUCCH * allocation after CCE alloc fail would be more complex) */ - int r_pucch = nr_get_pucch_resource(sched_ctrl->coreset, ul_bwp->pucch_Config, CCEIndex); - const int alloc = nr_acknack_scheduling(mac, iterator->UE, frame, slot, r_pucch, 0); - - if (alloc<0) { - LOG_D(NR_MAC, "[UE %04x][%4d.%2d] could not find PUCCH for DL DCI\n", - rnti, - frame, - slot); - iterator++; - continue; + int alloc = -1; + if (!get_FeedbackDisabled(iterator->UE->sc_info.downlinkHARQ_FeedbackDisabled_r17, sched_pdsch->dl_harq_pid)) { + int r_pucch = nr_get_pucch_resource(sched_ctrl->coreset, ul_bwp->pucch_Config, CCEIndex); + alloc = nr_acknack_scheduling(mac, iterator->UE, frame, slot, r_pucch, 0); + if (alloc<0) { + LOG_D(NR_MAC, "[UE %04x][%4d.%2d] could not find PUCCH for DL DCI\n", + rnti, + frame, + slot); + iterator++; + continue; + } } sched_ctrl->cce_index = CCEIndex; @@ -764,7 +771,6 @@ static void pf_dl(module_id_t module_id, sched_ctrl->aggregation_level); /* MCS has been set above */ - NR_sched_pdsch_t *sched_pdsch = &sched_ctrl->sched_pdsch; sched_pdsch->time_domain_allocation = get_dl_tda(mac, scc, slot); AssertFatal(sched_pdsch->time_domain_allocation>=0,"Unable to find PDSCH time domain allocation in list\n"); @@ -999,9 +1005,9 @@ void nr_schedule_ue_spec(module_id_t module_id, NR_tda_info_t *tda_info = &sched_pdsch->tda_info; NR_pdsch_dmrs_t *dmrs_parms = &sched_pdsch->dmrs_parms; NR_UE_harq_t *harq = &sched_ctrl->harq_processes[current_harq_pid]; - NR_sched_pucch_t *pucch = &sched_ctrl->sched_pucch[sched_pdsch->pucch_allocation]; + NR_sched_pucch_t *pucch = NULL; DevAssert(!harq->is_waiting); - if (get_FeedbackDisabled(UE->sc_info.downlinkHARQ_FeedbackDisabled_r17, current_harq_pid)) { + if (sched_pdsch->pucch_allocation < 0) { add_tail_nr_list(&sched_ctrl->available_dl_harq, current_harq_pid); harq->feedback_frame = -1; harq->feedback_slot = -1; @@ -1009,6 +1015,7 @@ void nr_schedule_ue_spec(module_id_t module_id, harq->ndi ^= 1; harq->round = 0; } else { + pucch = &sched_ctrl->sched_pucch[sched_pdsch->pucch_allocation]; add_tail_nr_list(&sched_ctrl->feedback_dl_harq, current_harq_pid); harq->feedback_frame = pucch->frame; harq->feedback_slot = pucch->ul_slot; @@ -1205,10 +1212,10 @@ void nr_schedule_ue_spec(module_id_t module_id, dci_payload.rv = pdsch_pdu->rvIndex[0]; dci_payload.harq_pid = current_harq_pid; dci_payload.ndi = harq->ndi; - dci_payload.dai[0].val = (pucch->dai_c-1)&3; + dci_payload.dai[0].val = pucch ? (pucch->dai_c-1)&3 : 0; dci_payload.tpc = sched_ctrl->tpc1; // TPC for PUCCH: table 7.2.1-1 in 38.213 - dci_payload.pucch_resource_indicator = pucch->resource_indicator; - dci_payload.pdsch_to_harq_feedback_timing_indicator.val = pucch->timing_indicator; // PDSCH to HARQ TI + dci_payload.pucch_resource_indicator = pucch ? pucch->resource_indicator : 0; + dci_payload.pdsch_to_harq_feedback_timing_indicator.val = pucch ? pucch->timing_indicator : 0; // PDSCH to HARQ TI dci_payload.antenna_ports.val = dmrs_parms->dmrs_ports_id; dci_payload.dmrs_sequence_initialization.val = pdsch_pdu->SCID; LOG_D(NR_MAC, diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c index 4dbcdd72e7..c02691e82c 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c @@ -142,16 +142,23 @@ void nr_preprocessor_phytest(module_id_t module_id, __func__, UE->rnti); - int r_pucch = nr_get_pucch_resource(sched_ctrl->coreset, UE->current_UL_BWP.pucch_Config, CCEIndex); - const int alloc = nr_acknack_scheduling(RC.nrmac[module_id], UE, frame, slot, r_pucch, 0); - if (alloc < 0) { - LOG_D(MAC, - "%s(): could not find PUCCH for UE %04x@%d.%d\n", - __func__, - rnti, - frame, - slot); - return; + NR_sched_pdsch_t *sched_pdsch = &sched_ctrl->sched_pdsch; + if (sched_pdsch->dl_harq_pid == -1) + sched_pdsch->dl_harq_pid = sched_ctrl->available_dl_harq.head; + + int alloc = -1; + if (!get_FeedbackDisabled(UE->sc_info.downlinkHARQ_FeedbackDisabled_r17, sched_pdsch->dl_harq_pid)) { + int r_pucch = nr_get_pucch_resource(sched_ctrl->coreset, UE->current_UL_BWP.pucch_Config, CCEIndex); + alloc = nr_acknack_scheduling(RC.nrmac[module_id], UE, frame, slot, r_pucch, 0); + if (alloc < 0) { + LOG_D(MAC, + "%s(): could not find PUCCH for UE %04x@%d.%d\n", + __func__, + rnti, + frame, + slot); + return; + } } sched_ctrl->cce_index = CCEIndex; @@ -166,7 +173,6 @@ void nr_preprocessor_phytest(module_id_t module_id, // "could not find uplink slot for PUCCH (RNTI %04x@%d.%d)!\n", // rnti, frame, slot); - NR_sched_pdsch_t *sched_pdsch = &sched_ctrl->sched_pdsch; sched_pdsch->pucch_allocation = alloc; sched_pdsch->rbStart = rbStart; sched_pdsch->rbSize = rbSize; diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h index a1c75dfe76..127b19ee2f 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h +++ b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h @@ -437,7 +437,7 @@ typedef struct NR_sched_pdsch { int8_t dl_harq_pid; // pucch format allocation - uint16_t pucch_allocation; + int16_t pucch_allocation; uint16_t pm_index; uint8_t nrOfLayers; From c4570bc829d1b94f6d9f276603fa208b2cbdb3d2 Mon Sep 17 00:00:00 2001 From: Guido Casati Date: Fri, 12 Jul 2024 17:28:23 +0200 Subject: [PATCH 45/49] Avoid segfault in SRS modulation when ue-nb-ant-tx (fp) does not match UE capabilities * the mismatch between UE capabilities, passed to PHY by NFAPI PDU, and --ue-nb-ant-tx causes a segfault in SRS modulation * issue with indexing txdataF[p_index], which fails due to an out-of-bounds access since first dimension of txdataF is sized based on ue->frame_parms.nb_antennas_tx * N_ap used in SRS modulation is based on the number of antenna ports in the SRS configuration (srs_config_pdu->num_ant_ports) --- openair1/PHY/NR_UE_TRANSPORT/srs_modulation_nr.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/openair1/PHY/NR_UE_TRANSPORT/srs_modulation_nr.c b/openair1/PHY/NR_UE_TRANSPORT/srs_modulation_nr.c index 4af545b931..02ad38cc0e 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/srs_modulation_nr.c +++ b/openair1/PHY/NR_UE_TRANSPORT/srs_modulation_nr.c @@ -205,7 +205,9 @@ int generate_srs_nr(nfapi_nr_srs_pdu_t *srs_config_pdu, uint16_t T_SRS = srs_config_pdu->t_srs; uint16_t T_offset = srs_config_pdu->t_offset; uint8_t R = 1<num_repetitions; - uint8_t N_ap = 1<num_ant_ports; // Number of antenna port for transmission + /* Number of antenna ports (M) can't be higher than number of physical antennas (N): M <= N */ + uint8_t num_ant_ports = 1 << srs_config_pdu->num_ant_ports; // Number of antenna port for transmission + int N_ap = num_ant_ports > frame_parms->nb_antennas_tx ? frame_parms->nb_antennas_tx : num_ant_ports; uint8_t N_symb_SRS = 1<num_symbols; // Number of consecutive OFDM symbols uint8_t l0 = frame_parms->symbols_per_slot - 1 - l_offset; // Starting symbol position in the time domain uint8_t n_SRS_cs_max = srs_max_number_cs[srs_config_pdu->comb_size]; From b76eb194715e702e621d00c19b5d83d9307b36ae Mon Sep 17 00:00:00 2001 From: Thomas Schlichter Date: Fri, 19 Jul 2024 16:09:04 +0200 Subject: [PATCH 46/49] gNB: refactor code to handle end of using a specific HARQ process - finish_nr_dl_harq() and finish_nr_ul_harq() --- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c | 7 +----- .../LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c | 23 +++++++++--------- .../LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c | 9 ++++--- .../LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c | 24 ++++++++++--------- openair2/LAYER2/NR_MAC_gNB/mac_proto.h | 1 + 5 files changed, 31 insertions(+), 33 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c index 9f7199d7d5..c51e1209b5 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c @@ -1888,12 +1888,7 @@ static void nr_generate_Msg4(module_id_t module_idP, NR_sched_pucch_t *pucch = NULL; DevAssert(!harq->is_waiting); if (alloc < 0) { - add_tail_nr_list(&sched_ctrl->available_dl_harq, current_harq_pid); - harq->feedback_frame = -1; - harq->feedback_slot = -1; - harq->is_waiting = false; - harq->ndi ^= 1; - harq->round = 0; + finish_nr_dl_harq(sched_ctrl, current_harq_pid); } else { pucch = &sched_ctrl->sched_pucch[alloc]; add_tail_nr_list(&sched_ctrl->feedback_dl_harq, current_harq_pid); diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c index 7e80ff7dfd..cd4fc9b197 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c @@ -371,17 +371,23 @@ static void nr_store_dlsch_buffer(module_id_t module_id, frame_t frame, sub_fram } } -void abort_nr_dl_harq(NR_UE_info_t* UE, int8_t harq_pid) +void finish_nr_dl_harq(NR_UE_sched_ctrl_t *sched_ctrl, int harq_pid) { - /* already mutex protected through handle_dl_harq() */ - NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; NR_UE_harq_t *harq = &sched_ctrl->harq_processes[harq_pid]; harq->ndi ^= 1; harq->round = 0; - UE->mac_stats.dl.errors++; - add_tail_nr_list(&sched_ctrl->available_dl_harq, harq_pid); + add_tail_nr_list(&sched_ctrl->available_dl_harq, harq_pid); +} + +void abort_nr_dl_harq(NR_UE_info_t* UE, int8_t harq_pid) +{ + /* already mutex protected through handle_dl_harq() */ + NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; + + finish_nr_dl_harq(sched_ctrl, harq_pid); + UE->mac_stats.dl.errors++; } static void get_start_stop_allocation(gNB_MAC_INST *mac, @@ -1008,12 +1014,7 @@ void nr_schedule_ue_spec(module_id_t module_id, NR_sched_pucch_t *pucch = NULL; DevAssert(!harq->is_waiting); if (sched_pdsch->pucch_allocation < 0) { - add_tail_nr_list(&sched_ctrl->available_dl_harq, current_harq_pid); - harq->feedback_frame = -1; - harq->feedback_slot = -1; - harq->is_waiting = false; - harq->ndi ^= 1; - harq->round = 0; + finish_nr_dl_harq(sched_ctrl, current_harq_pid); } else { pucch = &sched_ctrl->sched_pucch[sched_pdsch->pucch_allocation]; add_tail_nr_list(&sched_ctrl->feedback_dl_harq, current_harq_pid); diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c index 2d59e72db2..3de5c1ea7a 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c @@ -385,19 +385,18 @@ static void handle_dl_harq(NR_UE_info_t * UE, bool success, int harq_round_max) { - NR_UE_harq_t *harq = &UE->UE_sched_ctrl.harq_processes[harq_pid]; + NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; + NR_UE_harq_t *harq = &sched_ctrl->harq_processes[harq_pid]; harq->feedback_slot = -1; harq->is_waiting = false; if (success) { - add_tail_nr_list(&UE->UE_sched_ctrl.available_dl_harq, harq_pid); - harq->round = 0; - harq->ndi ^= 1; + finish_nr_dl_harq(sched_ctrl, harq_pid); } else if (harq->round >= harq_round_max - 1) { abort_nr_dl_harq(UE, harq_pid); LOG_D(NR_MAC, "retransmission error for UE %04x (total %"PRIu64")\n", UE->rnti, UE->mac_stats.dl.errors); } else { LOG_D(PHY,"NACK for: pid %d, ue %04x\n",harq_pid, UE->rnti); - add_tail_nr_list(&UE->UE_sched_ctrl.retrans_dl_harq, harq_pid); + add_tail_nr_list(&sched_ctrl->retrans_dl_harq, harq_pid); harq->round++; } } diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c index 02770f2b2d..d5a03c4cd7 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c @@ -511,15 +511,23 @@ static int nr_process_mac_pdu(instance_t module_idP, return 0; } +static void finish_nr_ul_harq(NR_UE_sched_ctrl_t *sched_ctrl, int harq_pid) +{ + NR_UE_ul_harq_t *harq = &sched_ctrl->ul_harq_processes[harq_pid]; + + harq->ndi ^= 1; + harq->round = 0; + + add_tail_nr_list(&sched_ctrl->available_ul_harq, harq_pid); +} + static void abort_nr_ul_harq(NR_UE_info_t *UE, int8_t harq_pid) { NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; NR_UE_ul_harq_t *harq = &sched_ctrl->ul_harq_processes[harq_pid]; - harq->ndi ^= 1; - harq->round = 0; + finish_nr_ul_harq(sched_ctrl, harq_pid); UE->mac_stats.ul.errors++; - add_tail_nr_list(&sched_ctrl->available_ul_harq, harq_pid); /* the transmission failed: the UE won't send the data we expected initially, * so retrieve to correctly schedule after next BSR */ @@ -602,13 +610,11 @@ void handle_nr_ul_harq(const int CC_idP, harq->feedback_slot = -1; harq->is_waiting = false; if (!crc_pdu->tb_crc_status) { - harq->ndi ^= 1; - harq->round = 0; + finish_nr_ul_harq(sched_ctrl, harq_pid); LOG_D(NR_MAC, "Ulharq id %d crc passed for RNTI %04x\n", harq_pid, crc_pdu->rnti); - add_tail_nr_list(&sched_ctrl->available_ul_harq, harq_pid); } else if (harq->round >= RC.nrmac[mod_id]->ul_bler.harq_round_max - 1) { abort_nr_ul_harq(UE, harq_pid); LOG_D(NR_MAC, @@ -2268,11 +2274,7 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot, n NR_UE_ul_harq_t *cur_harq = &sched_ctrl->ul_harq_processes[harq_id]; DevAssert(!cur_harq->is_waiting); if (nr_mac->radio_config.disable_harq) { - add_tail_nr_list(&sched_ctrl->available_ul_harq, harq_id); - cur_harq->feedback_slot = -1; - cur_harq->is_waiting = false; - cur_harq->ndi ^= 1; - cur_harq->round = 0; + finish_nr_ul_harq(sched_ctrl, harq_id); } else { add_tail_nr_list(&sched_ctrl->feedback_ul_harq, harq_id); cur_harq->feedback_slot = sched_pusch->slot; diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h index 5c998f4d2a..84f06c873c 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h @@ -433,6 +433,7 @@ long get_lcid_from_srbid(int srb_id); void prepare_initial_ul_rrc_message(gNB_MAC_INST *mac, NR_UE_info_t *UE); void send_initial_ul_rrc_message(int rnti, const uint8_t *sdu, sdu_size_t sdu_len, void *data); +void finish_nr_dl_harq(NR_UE_sched_ctrl_t *sched_ctrl, int harq_pid); void abort_nr_dl_harq(NR_UE_info_t* UE, int8_t harq_pid); void nr_mac_trigger_release_timer(NR_UE_sched_ctrl_t *sched_ctrl, NR_SubcarrierSpacing_t subcarrier_spacing); From 383eb9f5a12fedd35acca4c96d7311984aafe791 Mon Sep 17 00:00:00 2001 From: Nick Hedberg Date: Wed, 17 Jul 2024 06:33:52 -0700 Subject: [PATCH 47/49] Add Aerial VNF configuration file for CBRS RU --- .../CONF/gnb-vnf.sa.cbrs.aerial.conf | 239 ++++++++++++++++++ 1 file changed, 239 insertions(+) create mode 100644 targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb-vnf.sa.cbrs.aerial.conf diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb-vnf.sa.cbrs.aerial.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb-vnf.sa.cbrs.aerial.conf new file mode 100644 index 0000000000..602760b518 --- /dev/null +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb-vnf.sa.cbrs.aerial.conf @@ -0,0 +1,239 @@ +Active_gNBs = ( "gNB-OAI"); +# Asn1_verbosity, choice in: none, info, annoying +Asn1_verbosity = "none"; + +sa = 1; +nfapi = "AERIAL"; + +gNBs = +( + { + ////////// Identification parameters: + gNB_ID = 0xe00; + gNB_name = "gNB-OAI"; + + // Tracking area code, 0x0000 and 0xfffe are reserved values + tracking_area_code = 1; + plmn_list = ({ mcc = 001; mnc = 01; mnc_length = 2; snssaiList = ({ sst = 1; }); }); + + nr_cellid = 52L; + + ////////// Physical parameters: + + pdsch_AntennaPorts_XP = 2; + pdsch_AntennaPorts_N1 = 2; #Uncomment for 4 layers + pusch_AntennaPorts = 2; + do_CSIRS = 1; + do_SRS = 0; + min_rxtxtime = 3; + + pdcch_ConfigSIB1 = ( + { + controlResourceSetZero = 12; + searchSpaceZero = 0; + } + ); + + servingCellConfigCommon = ( + { + #spCellConfigCommon + + physCellId = 52; + +# downlinkConfigCommon + #frequencyInfoDL + # this is 3300.24 + 134*12*30e3 = 3348.48 MHz (5G NR GSCN: 7741) + absoluteFrequencySSB = 643296; + dl_frequencyBand = 78; + # this is 3300.24 MHz + dl_absoluteFrequencyPointA = 640000; + #scs-SpecificCarrierList + dl_offstToCarrier = 0; + # subcarrierSpacing + # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + dl_subcarrierSpacing = 1; + dl_carrierBandwidth = 273; + #initialDownlinkBWP + #genericParameters + # this is RBstart=0,L=162 (275*(275-L+1))+(274-RBstart)) + initialDLBWPlocationAndBandwidth = 1099; + + # subcarrierSpacing + # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + initialDLBWPsubcarrierSpacing = 1; + #pdcch-ConfigCommon + initialDLBWPcontrolResourceSetZero = 12; + initialDLBWPsearchSpaceZero = 0; + + #uplinkConfigCommon + #frequencyInfoUL + ul_frequencyBand = 78; + #scs-SpecificCarrierList + ul_offstToCarrier = 0; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + ul_subcarrierSpacing = 1; + ul_carrierBandwidth = 273; + pMax = 20; + #initialUplinkBWP + #genericParameters + initialULBWPlocationAndBandwidth = 1099; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + initialULBWPsubcarrierSpacing = 1; + #rach-ConfigCommon + #rach-ConfigGeneric + prach_ConfigurationIndex = 159;# testMAC 158; OAI gNB 98 +#prach_msg1_FDM +#0 = one, 1=two, 2=four, 3=eight + prach_msg1_FDM = 0; + prach_msg1_FrequencyStart = 0; + zeroCorrelationZoneConfig = 12; + preambleReceivedTargetPower = -96; +#preamblTransMax (0...10) = (3,4,5,6,7,8,10,20,50,100,200) + preambleTransMax = 6; +#powerRampingStep +# 0=dB0,1=dB2,2=dB4,3=dB6 + powerRampingStep = 1; +#ra_ReponseWindow +#1,2,4,8,10,20,40,80 + ra_ResponseWindow = 5; +#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR +#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen + ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 3; +#oneHalf (0..15) 4,8,12,16,...60,64 + ssb_perRACH_OccasionAndCB_PreamblesPerSSB = 15; +#ra_ContentionResolutionTimer +#(0..7) 8,16,24,32,40,48,56,64 + ra_ContentionResolutionTimer = 7; + rsrp_ThresholdSSB = 19; +#prach-RootSequenceIndex_PR +#1 = 839, 2 = 139 + prach_RootSequenceIndex_PR = 2; + prach_RootSequenceIndex = 1; + # SCS for msg1, can only be 15 for 30 kHz < 6 GHz, takes precendence over the one derived from prach-ConfigIndex + # + msg1_SubcarrierSpacing = 1, +# restrictedSetConfig +# 0=unrestricted, 1=restricted type A, 2=restricted type B + restrictedSetConfig = 0, + + msg3_DeltaPreamble = 1; + p0_NominalWithGrant = -90; + +# pucch-ConfigCommon setup : +# pucchGroupHopping +# 0 = neither, 1= group hopping, 2=sequence hopping + pucchGroupHopping = 0; + hoppingId = 40; + p0_nominal = -90; +# ssb_PositionsInBurs_BitmapPR +# 1=short, 2=medium, 3=long + ssb_PositionsInBurst_PR = 2; + ssb_PositionsInBurst_Bitmap = 1; + +# ssb_periodicityServingCell +# 0 = ms5, 1=ms10, 2=ms20, 3=ms40, 4=ms80, 5=ms160, 6=spare2, 7=spare1 + ssb_periodicityServingCell = 2; + +# dmrs_TypeA_position +# 0 = pos2, 1 = pos3 + dmrs_TypeA_Position = 0; + +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + subcarrierSpacing = 1; + + + #tdd-UL-DL-ConfigurationCommon +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + referenceSubcarrierSpacing = 1; + # pattern1 + # dl_UL_TransmissionPeriodicity + # 0=ms0p5, 1=ms0p625, 2=ms1, 3=ms1p25, 4=ms2, 5=ms2p5, 6=ms5, 7=ms10 + dl_UL_TransmissionPeriodicity = 6; + nrofDownlinkSlots = 6; + nrofDownlinkSymbols = 10; + nrofUplinkSlots = 3; + nrofUplinkSymbols = 0; + + ssPBCH_BlockPower = -40; + } + + ); + + + # ------- SCTP definitions + SCTP : + { + # Number of streams to use in input/output + SCTP_INSTREAMS = 2; + SCTP_OUTSTREAMS = 2; + }; + + + ////////// AMF parameters: + amf_ip_address = ( { ipv4 = "192.168.70.132"; }); + + NETWORK_INTERFACES : + { + GNB_IPV4_ADDRESS_FOR_NG_AMF = "192.168.70.129/24"; + GNB_IPV4_ADDRESS_FOR_NGU = "192.168.70.129/24"; + GNB_PORT_FOR_S1U = 2152; # Spec 2152 + }; + + } +); + +MACRLCs = ( +{ + num_cc = 1; + local_s_if_name = "lo:"; + remote_s_address = "127.0.0.1"; // pnf addr [!] + local_s_address = "127.0.0.2"; // vnf addr + local_s_portc = 50001; // vnf p5 port + remote_s_portc = 50000; // pnf p5 port [!] + local_s_portd = 50011; // vnf p7 port [!] + remote_s_portd = 50010; // pnf p7 port [!] + tr_s_preference = "aerial"; + tr_n_preference = "local_RRC"; + pusch_FailureThres = 10; + pusch_TargetSNRx10 = 280; # 150; + pucch_TargetSNRx10 = 100; #200; + ulsch_max_frame_inactivity = 10; + dl_max_mcs = 27; + ul_max_mcs = 27; +} +); + + +security = { + # preferred ciphering algorithms + # the first one of the list that an UE supports in chosen + # valid values: nea0, nea1, nea2, nea3 + ciphering_algorithms = ( "nea0" ); + + # preferred integrity algorithms + # the first one of the list that an UE supports in chosen + # valid values: nia0, nia1, nia2, nia3 + integrity_algorithms = ( "nia2", "nia0" ); + + # setting 'drb_ciphering' to "no" disables ciphering for DRBs, no matter + # what 'ciphering_algorithms' configures; same thing for 'drb_integrity' + drb_ciphering = "yes"; + drb_integrity = "no"; +}; + +log_config : +{ + global_log_level = "info"; + global_log_options = "wall_clock"; + mac_log_level = "info"; + nr_mac_log_level = "info"; + rlc_log_level = "info"; + pdcp_log_level = "info"; + rrc_log_level = "info"; + ngap_log_level = "debug"; + f1ap_log_level = "debug"; +}; From 101f178c3ef426ebb0ba1f6744415dffed3c8913 Mon Sep 17 00:00:00 2001 From: Guido Casati Date: Mon, 15 Jul 2024 16:23:20 +0200 Subject: [PATCH 48/49] Verify UE capabilities at RRC UE initialization * number of configured SRS antenna ports M <= N (number of physical antenna ports) --- executables/nr-ue.c | 2 +- openair2/RRC/NR_UE/rrc_UE.c | 16 +++++++++++++++- openair2/RRC/NR_UE/rrc_proto.h | 2 +- 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/executables/nr-ue.c b/executables/nr-ue.c index 8a73bdd311..431bf26e3d 100644 --- a/executables/nr-ue.c +++ b/executables/nr-ue.c @@ -989,7 +989,7 @@ void *UE_thread(void *arg) void init_NR_UE(int nb_inst, char *uecap_file, char *reconfig_file, char *rbconfig_file) { - NR_UE_RRC_INST_t *rrc_inst = nr_rrc_init_ue(uecap_file, nb_inst); + NR_UE_RRC_INST_t *rrc_inst = nr_rrc_init_ue(uecap_file, nb_inst, get_nrUE_params()->nb_antennas_tx); NR_UE_MAC_INST_t *mac_inst = nr_l2_init_ue(nb_inst); AssertFatal(mac_inst, "Couldn't allocate MAC module\n"); diff --git a/openair2/RRC/NR_UE/rrc_UE.c b/openair2/RRC/NR_UE/rrc_UE.c index c4efe51e8b..cab08077ce 100644 --- a/openair2/RRC/NR_UE/rrc_UE.c +++ b/openair2/RRC/NR_UE/rrc_UE.c @@ -297,7 +297,19 @@ void process_nsa_message(NR_UE_RRC_INST_t *rrc, nsa_message_t nsa_message_type, } } -NR_UE_RRC_INST_t* nr_rrc_init_ue(char* uecap_file, int nb_inst) +/** + * @brief Verify UE capabilities parameters against CL-fed params + * (e.g. number of physical TX antennas) + */ +static bool verify_ue_cap(NR_UE_NR_Capability_t *UE_NR_Capability, int nb_antennas_tx) +{ + NR_FeatureSetUplink_t *ul_feature_setup = UE_NR_Capability->featureSets->featureSetsUplink->list.array[0]; + int srs_ant_ports = 1 << ul_feature_setup->supportedSRS_Resources->maxNumberSRS_Ports_PerResource; + AssertFatal(srs_ant_ports <= nb_antennas_tx, "SRS antenna ports (%d) > nb_antennas_tx (%d)\n", srs_ant_ports, nb_antennas_tx); + return true; +} + +NR_UE_RRC_INST_t* nr_rrc_init_ue(char* uecap_file, int nb_inst, int num_ant_tx) { NR_UE_rrc_inst = (NR_UE_RRC_INST_t *)calloc(nb_inst, sizeof(NR_UE_RRC_INST_t)); AssertFatal(NR_UE_rrc_inst, "Couldn't allocate %d instances of RRC module\n", nb_inst); @@ -328,6 +340,8 @@ NR_UE_RRC_INST_t* nr_rrc_init_ue(char* uecap_file, int nb_inst) assert(dec_rval.code == RC_OK); } fclose(f); + /* Verify consistency of num PHY antennas vs UE Capabilities */ + verify_ue_cap(rrc->UECap.UE_NR_Capability, num_ant_tx); } memset(&rrc->timers_and_constants, 0, sizeof(rrc->timers_and_constants)); diff --git a/openair2/RRC/NR_UE/rrc_proto.h b/openair2/RRC/NR_UE/rrc_proto.h index 1de5c19122..739d81cb4e 100644 --- a/openair2/RRC/NR_UE/rrc_proto.h +++ b/openair2/RRC/NR_UE/rrc_proto.h @@ -53,7 +53,7 @@ extern queue_t nr_tx_req_queue; extern queue_t nr_ul_dci_req_queue; extern queue_t nr_ul_tti_req_queue; -NR_UE_RRC_INST_t *nr_rrc_init_ue(char* uecap_file, int nb_inst); +NR_UE_RRC_INST_t *nr_rrc_init_ue(char* uecap_file, int nb_inst, int num_ant_tx); void init_nsa_message (NR_UE_RRC_INST_t *rrc, char* reconfig_file, char* rbconfig_file); void process_nsa_message(NR_UE_RRC_INST_t *rrc, nsa_message_t nsa_message_type, void *message, int msg_len); From fae529b384c2ff1b56cad38ebc1db16fa4ce6b89 Mon Sep 17 00:00:00 2001 From: Thomas Schlichter Date: Tue, 23 Jul 2024 10:42:10 +0200 Subject: [PATCH 49/49] add documentation for `disable_harq` flag in NTN section of doc/RUNMODEM.md --- doc/RUNMODEM.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/doc/RUNMODEM.md b/doc/RUNMODEM.md index 9ee9083e6d..b1b5090ae7 100644 --- a/doc/RUNMODEM.md +++ b/doc/RUNMODEM.md @@ -182,6 +182,20 @@ Besides this, some timers, e.g. `sr_ProhibitTimer_v1700`, `t300`, `t301` and `t3 ... ``` +To improve the achievable UL and DL throughput in conditions with large RTT, there is a feature defined in REL17 to disable HARQ feedback. +This allows to reuse HARQ processes immediately, but it breaks compatibility with UEs not supporting this REL17 feature. +To enable this feature, the `disable_harq` flag has to be added to the gNB conf file in the section `gNBs.[0]` +``` +... + sib1_tda = 5; + min_rxtxtime = 6; + disable_harq = 1; // <-- + + servingCellConfigCommon = ( + { +... +``` + So with these modifications to the file `targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band66.fr1.25PRB.usrpx300.conf` an example gNB command for FDD, 5 MHz BW, 15 kHz SCS, GEO satellite 5G NR NTN is this: ``` cd cmake_targets