From b285f9196879bf4f87fe7b00f73bb24b721da8e1 Mon Sep 17 00:00:00 2001 From: Reem Bahsoun Date: Thu, 5 Feb 2026 10:13:01 +0100 Subject: [PATCH 01/83] Change Aerial config file in targets to match Nvidia's CI setup --- .../CONF/gnb-vnf.sa.band78.273prb.aerial.conf | 40 +++++++++---------- 1 file changed, 19 insertions(+), 21 deletions(-) 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 046db5a780..cd229ac38f 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 @@ -13,7 +13,7 @@ gNBs = // Tracking area code, 0x0000 and 0xfffe are reserved values tracking_area_code = 1; - plmn_list = ({ mcc = 208; mnc = 99; mnc_length = 2; snssaiList = ({ sst = 1; }) }); + plmn_list = ({ mcc = 001; mnc = 01; mnc_length = 2; snssaiList = ({ sst = 1; }) }); nr_cellid = 12345678L; @@ -24,7 +24,7 @@ gNBs = pusch_AntennaPorts = 2; do_CSIRS = 1; do_SRS = 1; - min_rxtxtime = 2; + min_rxtxtime = 3; servingCellConfigCommon = ( { @@ -34,12 +34,11 @@ gNBs = # downlinkConfigCommon #frequencyInfoDL - # center frequency = 3350.01 MHz - # selected SSB frequency = 3349.92 MHz - absoluteFrequencySSB = 653376; - dl_frequencyBand = 77; - # frequency point A = 3300.87 MHz - dl_absoluteFrequencyPointA = 650056; + # Selected SSB frequency = 3748.8 MHz + absoluteFrequencySSB = 649920; + dl_frequencyBand = 78; + # Selected point A = 3700.86 MHz + dl_absoluteFrequencyPointA = 646724; #scs-SpecificCarrierList dl_offstToCarrier = 0; # subcarrierSpacing @@ -60,7 +59,7 @@ gNBs = #uplinkConfigCommon #frequencyInfoUL - ul_frequencyBand = 77; + ul_frequencyBand = 78; #scs-SpecificCarrierList ul_offstToCarrier = 0; # subcarrierSpacing @@ -140,13 +139,13 @@ gNBs = # pattern1 # dl_UL_TransmissionPeriodicity # 0=ms0p5, 1=ms0p625, 2=ms1, 3=ms1p25, 4=ms2, 5=ms2p5, 6=ms5, 7=ms10 - dl_UL_TransmissionPeriodicity = 6; #5; - nrofDownlinkSlots = 6; #3; - nrofDownlinkSymbols = 10; #6; - nrofUplinkSlots = 3; #1; + dl_UL_TransmissionPeriodicity = 6; + nrofDownlinkSlots = 6; + nrofDownlinkSymbols = 10; + nrofUplinkSlots = 3; nrofUplinkSymbols = 0; - ssPBCH_BlockPower = -15; + ssPBCH_BlockPower = -34; } ); @@ -162,13 +161,12 @@ gNBs = ////////// AMF parameters: - amf_ip_address = ({ ipv4 = "172.21.6.5"; }); - + amf_ip_address = ({ ipv4 = "192.168.70.132"; }); NETWORK_INTERFACES : { - GNB_IPV4_ADDRESS_FOR_NG_AMF = "172.21.8.120"; - GNB_IPV4_ADDRESS_FOR_NGU = "172.21.8.120"; + 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 }; @@ -187,9 +185,9 @@ MACRLCs = ( tr_s_preference = "aerial"; tr_n_preference = "local_RRC"; pusch_TargetSNRx10 = 280; # 150; - pucch_TargetSNRx10 = 200; #200; - dl_max_mcs = 28; - ul_max_mcs = 28; + pucch_TargetSNRx10 = 100; #200; + dl_max_mcs = 25; + ul_max_mcs = 25; } ); From 8f9abfb7f49c708cd2ce08e763e5211c1486882f Mon Sep 17 00:00:00 2001 From: Reem Bahsoun Date: Thu, 12 Feb 2026 14:37:56 +0100 Subject: [PATCH 02/83] Tutorial improvement --- doc/Aerial_FAPI_Split_Tutorial.md | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/doc/Aerial_FAPI_Split_Tutorial.md b/doc/Aerial_FAPI_Split_Tutorial.md index 24a085c8e4..d3d1f41878 100644 --- a/doc/Aerial_FAPI_Split_Tutorial.md +++ b/doc/Aerial_FAPI_Split_Tutorial.md @@ -164,15 +164,18 @@ WantedBy=multi-user.target - Follow these [instructions](https://github.com/NVIDIA/aerial-cuda-accelerated-ran) to - clone the `aerial-cuda-accelerated-ran` repository, pull and build the cuBB - image. -- The CMake flags we use to compile the L1 are: + clone the `aerial-cuda-accelerated-ran` repository, pull cuBB image. +- The CMake flags we use to build the SDK are: - `-DSCF_FAPI_10_04_SRS=ON` this flag must be used as of OAI tag `2025.w36` and this is due to the usage of the FAPI 10.04 version of the SRS PDU, and RX_Beamforming PDU. - `-DENABLE_CONFORMANCE_TM_PDSCH_PDCCH=OFF` this option should only be enabled when doing conformance testing with testmac. +```bash +./testBenches/phase4_test_scripts/build_aerial_sdk.sh --preset 10_02 -- -DSCF_FAPI_10_04_SRS=ON -DENABLE_CONFORMANCE_TM_PDSCH_PDCCH=OFF +``` + ## Build OAI gNB If it's not already cloned, the first step is to clone OAI repository @@ -195,8 +198,8 @@ and install this library when building the L2 docker image. ./cuPHY-CP/container/run_aerial.sh # Pack the nvIPC sources and copy them to the host ( the command creates a `tar.gz` file with the following name format: `nvipc_src.YYYY.MM.DD.tar.gz`) -aerial@c_aerial_oaicicd:/opt/nvidia/cuBB# cd cuPHY-CP/gt_common_libs -aerial@c_aerial_oaicicd:/opt/nvidia/cuBB/cuPHY-CP/gt_common_libs#./pack_nvipc.sh +aerial@c_aerial_:/opt/nvidia/cuBB# cd cuPHY-CP/gt_common_libs +aerial@c_aerial_:/opt/nvidia/cuBB/cuPHY-CP/gt_common_libs#./pack_nvipc.sh nvipc_src.YYYY.MM.DD/ ... --------------------------------------------- Pack nvipc source code finished:/opt/nvidia/cuBB/cuPHY-CP/gt_common_libs/nvipc_src.YYYY.MM.DD.tar.gz ``` @@ -218,7 +221,9 @@ With the nvIPC sources in the project directory, the L2 docker image can be buil ### Building OAI gNB docker image In order to build the target image (`oai-gnb-aerial`), first you should build a -common shared image (`ran-base`) +common shared image (`ran-base`). For more information about `docker build` +files please refer to this +[tutorial](https://gitlab.eurecom.fr/oai/openairinterface5g/-/blob/ARC1.7_integration/docker/README.md?ref_type=heads) ```bash ~$ cd ~/openairinterface5g/ @@ -297,7 +302,7 @@ vlan: ### Docker compose -We recommend the user to apply the patch below for `docker-compose.yaml`. +Apply the patch below to include the Aerial repository cloned earlier in this tutorial. ```patch diff --git a/ci-scripts/yaml_files/sa_gnb_aerial/docker-compose.yaml b/ci-scripts/yaml_files/sa_gnb_aerial/docker-compose.yaml index 985fe9a6a3..0774d826ac 100644 From 9e7822cf1c26bf2b8cc06164f6af1a8cbe4bea1b Mon Sep 17 00:00:00 2001 From: alexjiao Date: Thu, 18 Dec 2025 11:16:31 +0800 Subject: [PATCH 03/83] NR UE: fix PRACH k1 calculation at MAC when handover The k1 for PRACH calculation in config_common_ue() should be the same as in config_common_ue_sa(), otherwise k1 is wrong when handover to target cell if msg1-FDM not 0 in reconfigurationWithSync. --- openair2/LAYER2/NR_MAC_UE/config_ue.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/openair2/LAYER2/NR_MAC_UE/config_ue.c b/openair2/LAYER2/NR_MAC_UE/config_ue.c index b3195894a4..a1ff274f37 100644 --- a/openair2/LAYER2/NR_MAC_UE/config_ue.c +++ b/openair2/LAYER2/NR_MAC_UE/config_ue.c @@ -608,6 +608,16 @@ static void config_common_ue(NR_UE_MAC_INST_t *mac, NR_ServingCellConfigCommon_t cfg->prach_config.num_prach_fd_occasions_list = (fapi_nr_num_prach_fd_occasions_t *)malloc( cfg->prach_config.num_prach_fd_occasions * sizeof(fapi_nr_num_prach_fd_occasions_t)); + + // Get UL carrier SCS for PRACH k1 calculation + int ul_carrier_scs; + if (scc->uplinkConfigCommon->frequencyInfoUL + && scc->uplinkConfigCommon->frequencyInfoUL->scs_SpecificCarrierList.list.count > 0) { + ul_carrier_scs = scc->uplinkConfigCommon->frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing; + } else { + ul_carrier_scs = scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.subcarrierSpacing; + } + for (int i = 0; i < cfg->prach_config.num_prach_fd_occasions; i++) { fapi_nr_num_prach_fd_occasions_t *prach_fd_occasion = &cfg->prach_config.num_prach_fd_occasions_list[i]; prach_fd_occasion->num_prach_fd_occasions = i; @@ -616,7 +626,8 @@ static void config_common_ue(NR_UE_MAC_INST_t *mac, NR_ServingCellConfigCommon_t else prach_fd_occasion->prach_root_sequence_index = rach_ConfigCommon->prach_RootSequenceIndex.choice.l839; - prach_fd_occasion->k1 = rach_ConfigCommon->rach_ConfigGeneric.msg1_FrequencyStart; + prach_fd_occasion->k1 = rach_ConfigCommon->rach_ConfigGeneric.msg1_FrequencyStart + + (get_N_RA_RB(cfg->prach_config.prach_sub_c_spacing, ul_carrier_scs) * i); prach_fd_occasion->prach_zero_corr_conf = rach_ConfigCommon->rach_ConfigGeneric.zeroCorrelationZoneConfig; prach_fd_occasion->num_root_sequences = compute_nr_root_seq(rach_ConfigCommon, nb_preambles, frame_type, mac->frequency_range); From 82315ead3ed2497290f4127864af422de3a22deb Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 19 Feb 2026 14:40:13 +0100 Subject: [PATCH 04/83] Fail early if configuration module can not initialize properly In the case that the config module cannot load the driver for libconfig or yaml, currently, there might be a cascade of errors that are difficult for users to understand. For instance (partially redacted for clarity): [CONFIG] Error calling dlopen(libparams_libconfig.so): libparams_libconfig.so: cannot open shared object file: No such file or directory [CONFIG] config module "libconfig" couldn't be loaded [CONFIG] config_get, section log_config skipped, config module not properly initialized [LOG] init aborted, configuration couldn't be performed [CONFIG] config_get, section (null) skipped, config module not properly initialized [CONFIG] /home/francesco/openairinterface5g/common/config/config_userapi.c 68 nfapi has no processed integer availablle [CONFIG] config_get, section (null) skipped, config module not properly initialized Assertion (get_softmodem_params()->default_pdu_session_id == -1) failed! In get_common_options() /home/francesco/openairinterface5g/executables/softmodem-common.c:161 Use uicc0.pdu_sessions.[0].id to change the requested PDU session ID (is 0) Here, the error is the missing shared object, but a user is more likely to look at the last error instead of the first. This commit addresses it by checking early for CONFIG_ISFLAGSET(CONFIG_ABORT), and stopping if it is set. Additionally changes include making functions static, removing late CONFIG_ISFLAGSET() checks, and the CONFIG_ISFLAGSET() in load_configmodule(), because at that time "uniqCfg" is not set yet and thus does not do anything (this is likely a regression of an earlier cleanup). See-also: f50d5f5a9b5 ("make multiple config instead of one implicit global") --- common/config/config_load_configmodule.c | 10 +++------- executables/nr-softmodem.c | 7 +------ executables/nr-uesoftmodem.c | 2 +- 3 files changed, 5 insertions(+), 14 deletions(-) diff --git a/common/config/config_load_configmodule.c b/common/config/config_load_configmodule.c index 14f4a4c81d..988e993dc6 100644 --- a/common/config/config_load_configmodule.c +++ b/common/config/config_load_configmodule.c @@ -63,7 +63,8 @@ static paramdef_t Config_Params[] = { }; // clang-format on -int load_config_sharedlib(configmodule_interface_t *cfgptr) { +static int load_config_sharedlib(configmodule_interface_t *cfgptr) +{ void *lib_handle; char fname[128]; char libname[FILENAME_MAX]; @@ -380,7 +381,7 @@ configmodule_interface_t *load_configmodule(int argc, Config_Params[idx].strptr = &(cfgptr->tmpdir); config_get(cfgptr, Config_Params, sizeofArray(Config_Params), CONFIG_SECTIONNAME); } else { - fprintf(stderr,"[CONFIG] %s %d config module \"%s\" couldn't be loaded\n", __FILE__, __LINE__,cfgmode); + fprintf(stderr, "[CONFIG] config module \"%s\" couldn't be loaded\n", cfgmode); cfgptr->rtflags = cfgptr->rtflags | CONFIG_HELP | CONFIG_ABORT; } } else { @@ -396,11 +397,6 @@ configmodule_interface_t *load_configmodule(int argc, if (cfgmode != NULL) free(cfgmode); - if (CONFIG_ISFLAGSET(CONFIG_ABORT)) { - config_printhelp(Config_Params, sizeofArray(Config_Params), CONFIG_SECTIONNAME); - // exit(-1); - } - return cfgptr; } diff --git a/executables/nr-softmodem.c b/executables/nr-softmodem.c index 614fecad62..938bbeee88 100644 --- a/executables/nr-softmodem.c +++ b/executables/nr-softmodem.c @@ -514,7 +514,7 @@ int main( int argc, char **argv ) { start_background_system(); ///static configuration for NR at the moment - if ((uniqCfg = load_configmodule(argc, argv, CONFIG_ENABLECMDLINEONLY)) == NULL) { + if ((uniqCfg = load_configmodule(argc, argv, CONFIG_ENABLECMDLINEONLY)) == NULL || CONFIG_ISFLAGSET(CONFIG_ABORT)) { exit_fun("[SOFTMODEM] Error, configuration module init failed\n"); } @@ -528,11 +528,6 @@ int main( int argc, char **argv ) { lock_memory_to_ram(); get_options(uniqCfg); - if (CONFIG_ISFLAGSET(CONFIG_ABORT) ) { - fprintf(stderr,"Getting configuration failed\n"); - exit(-1); - } - if (!has_cap_sys_nice()) LOG_W(UTIL, "no SYS_NICE capability: cannot set thread priority and affinity, consider running with sudo for optimum performance\n"); diff --git a/executables/nr-uesoftmodem.c b/executables/nr-uesoftmodem.c index a0e06850b7..50d3f6946e 100644 --- a/executables/nr-uesoftmodem.c +++ b/executables/nr-uesoftmodem.c @@ -248,7 +248,7 @@ int main(int argc, char **argv) { start_background_system(); - if ((uniqCfg = load_configmodule(argc, argv, CONFIG_ENABLECMDLINEONLY)) == NULL) { + if ((uniqCfg = load_configmodule(argc, argv, CONFIG_ENABLECMDLINEONLY)) == NULL || CONFIG_ISFLAGSET(CONFIG_ABORT)) { exit_fun("[SOFTMODEM] Error, configuration module init failed\n"); } //set_softmodem_sighandler(); From e129fd0ede11644f8fcf344982b403b9c8055a02 Mon Sep 17 00:00:00 2001 From: Raghavendra Dinavahi Date: Wed, 18 Feb 2026 14:59:03 +0100 Subject: [PATCH 05/83] GNB: RESET NDI only after usage in case of disable HARQ solves this warnings seen in the trace NDI indicates re-transmission but computed TBS 3968 doesn't match with what previously stored 3368 --- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c index 921003d110..8ad9d4f6bc 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c @@ -1079,9 +1079,7 @@ void post_process_dlsch(gNB_MAC_INST *nr_mac, post_process_pdsch_t *pdsch, NR_UE NR_UE_harq_t *harq = &sched_ctrl->harq_processes[current_harq_pid]; NR_sched_pucch_t *pucch = NULL; DevAssert(!harq->is_waiting); - if (sched_pdsch->pucch_allocation < 0) { - finish_nr_dl_harq(sched_ctrl, current_harq_pid); - } else { + if (sched_pdsch->pucch_allocation >= 0) { 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; @@ -1414,6 +1412,12 @@ void post_process_dlsch(gNB_MAC_INST *nr_mac, post_process_pdsch_t *pdsch, NR_UE pdsch->TX_req->Number_of_PDUs++; pdsch->TX_req->SFN = frame; pdsch->TX_req->Slot = slot; + + // RESET HARQ NDI and ROUND once they are used. + // as HARQ is disabled and there will no PUCCH being received. + if (sched_pdsch->pucch_allocation < 0) { + finish_nr_dl_harq(sched_ctrl, current_harq_pid); + } } void nr_schedule_ue_spec(module_id_t module_id, From b1f32ea049113e4f4cbedefecbddd1fd942e9ed7 Mon Sep 17 00:00:00 2001 From: Rakesh Mundlamuri Date: Fri, 30 Jan 2026 12:04:55 +0530 Subject: [PATCH 06/83] Synchronize multiple gNBs by aliging to the slot boundary Currently, we derive frame and slot number based on `proc->timestamp_rx` using `proc->frame_rx = (proc->timestamp_rx / (fp->samples_per_subframe*10))&1023;` and `proc->tti_rx = get_slot_from_timestamp(proc->timestamp_rx, fp);` This ignores the samples `proc->timestamp_rx % fp->samples_per_frame` while computing the frame and slot number creating a mis-alignment with the slot boundaries. We fix this alignment by compensating these samples during the first reception. --- executables/nr-ru.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/executables/nr-ru.c b/executables/nr-ru.c index 397f940745..cd91abb086 100644 --- a/executables/nr-ru.c +++ b/executables/nr-ru.c @@ -609,6 +609,25 @@ static void rx_rf(RU_t *ru, int *frame, int *slot) proc->first_rx = 0; *frame = proc->frame_rx; *slot = proc->tti_rx; + + // Align to slot boundary + uint64_t samples_to_slot_boundary = 0; + uint64_t sample_offset_within_frame = proc->timestamp_rx % fp->samples_per_frame; + uint64_t sample_offset_within_slot = sample_offset_within_frame - get_samples_slot_timestamp(fp, *slot); + if (sample_offset_within_slot > 0) { + samples_to_slot_boundary = get_samples_per_slot(*slot, fp) - sample_offset_within_slot; + LOG_A(NR_PHY, "Aligning to the slot boundary %lu\n", samples_to_slot_boundary); + + // Read and discard the samples in the first_rx to align to the slot boundary + rxs = ru->rfdevice.trx_read_func(&ru->rfdevice, &ts, rxp, samples_to_slot_boundary, nb); + if (rxs != samples_to_slot_boundary) + LOG_E(PHY, "rx_rf: Asked for %ld samples, got %d from USRP\n", samples_to_slot_boundary, rxs); + + proc->timestamp_rx += samples_to_slot_boundary; + if (*slot + 1 >= fp->slots_per_frame) + *frame = *frame + 1; + *slot = (*slot + 1) % fp->slots_per_frame; + } } metadata mt = {.slot = *slot, .frame = *frame}; From 5e0e359dd616aeb92455891b57751061eb432bae Mon Sep 17 00:00:00 2001 From: Rakesh Mundlamuri Date: Wed, 4 Feb 2026 14:20:27 +0530 Subject: [PATCH 07/83] Update PRS configuration files to test multi gNB synchronization --- .../CONF/channelmod_rfsimu.conf | 33 +++ .../gnb0.prs.band78.fr1.106PRB.usrpx310.conf | 251 ++++++++---------- .../gnb1.prs.band78.fr1.106PRB.usrpx310.conf | 250 ++++++++--------- 3 files changed, 259 insertions(+), 275 deletions(-) create mode 100644 targets/PROJECTS/GENERIC-NR-5GC/CONF/channelmod_rfsimu.conf diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/channelmod_rfsimu.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/channelmod_rfsimu.conf new file mode 100644 index 0000000000..d0bd408030 --- /dev/null +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/channelmod_rfsimu.conf @@ -0,0 +1,33 @@ +channelmod = { + max_chan = 10; + modellist = "modellist_rfsimu_1"; + modellist_rfsimu_1 = ( + { # DL, modify on UE side + model_name = "rfsimu_channel_enB0" + type = "AWGN"; + ploss_dB = 0; + noise_power_dB = -10; + forgetfact = 0; + offset = 0; + ds_tdl = 0; + }, + { # DL, modify on UE side + model_name = "rfsimu_channel_enB1" + type = "AWGN"; + ploss_dB = 0; + noise_power_dB = -10; + forgetfact = 0; + offset = 0; + ds_tdl = 0; + }, + { # UL, modify on gNB side + model_name = "rfsimu_channel_ue0" + type = "AWGN"; + ploss_dB = 0; + noise_power_dB = -10; + forgetfact = 0; + offset = 0; + ds_tdl = 0; + } + ); +}; diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb0.prs.band78.fr1.106PRB.usrpx310.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb0.prs.band78.fr1.106PRB.usrpx310.conf index d64bd8e472..0a9ed68f89 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb0.prs.band78.fr1.106PRB.usrpx310.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb0.prs.band78.fr1.106PRB.usrpx310.conf @@ -6,43 +6,18 @@ gNBs = ( { ////////// Identification parameters: - gNB_ID = 0xe00; - -# cell_type = "CELL_MACRO_GNB"; - + 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; }) }); - plmn_list = ({ - mcc = 208; - mnc = 97; - mnc_length = 2; - snssaiList = ( - { - sst = 1; - sd = 0x010203; // 0 false, else true - }, - { - sst = 1; - sd = 0x112233; // 0 false, else true - } - ); - }); - - nr_cellid = 12345678L - -# tr_s_preference = "local_mac" + nr_cellid = 12345678L; ////////// Physical parameters: - #pusch_TargetSNRx10 = 200; - #pucch_TargetSNRx10 = 200; - ul_prbblacklist = "51,52,53,54" - min_rxtxtime = 6; - do_SRS = 0; - + do_SRS = 1; servingCellConfigCommon = ( { @@ -50,133 +25,119 @@ gNBs = physCellId = 0; -# downlinkConfigCommon +# downlinkConfigCommon #frequencyInfoDL - # this is 3301.68 MHz + 22*12*30e-3 MHz = 3309.6 - #absoluteFrequencySSB = 620640; - # this is 3300.60 MHz + 53*12*30e-3 MHz = 3319.68 - absoluteFrequencySSB = 621312; - # this is 3503.28 MHz + 22*12*30e-3 MHz = 3511.2 - #absoluteFrequencySSB = 634080; - # this is 3600.48 MHz - #absoluteFrequencySSB = 640032; - #dl_frequencyBand = 78; - # this is 3301.68 MHz - #dl_absoluteFrequencyPointA = 620112; - # this is 3300.60 MHz - dl_absoluteFrequencyPointA = 620040; - # this is 3502.56 MHz - #dl_absoluteFrequencyPointA = 633552; - # this is 3600.48 MHz - #dl_absoluteFrequencyPointA = 640032; + # this is 3600 MHz + 43 PRBs@30kHz SCS (same as initial BWP) + absoluteFrequencySSB = 641280; + dl_frequencyBand = 78; + # this is 3600 MHz + dl_absoluteFrequencyPointA = 640008; #scs-SpecificCarrierList - dl_offstToCarrier = 0; + dl_offstToCarrier = 0; # subcarrierSpacing # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 - dl_subcarrierSpacing = 1; - dl_carrierBandwidth = 106; + dl_subcarrierSpacing = 1; + dl_carrierBandwidth = 106; #initialDownlinkBWP #genericParameters - # this is RBstart=0,L=106 (275*(L-1))+RBstart - initialDLBWPlocationAndBandwidth = 28875; + # this is RBstart=27,L=48 (275*(L-1))+RBstart + initialDLBWPlocationAndBandwidth = 28875; # 6366 12925 12956 28875 12952 # subcarrierSpacing # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 - initialDLBWPsubcarrierSpacing = 1; + initialDLBWPsubcarrierSpacing = 1; #pdcch-ConfigCommon - initialDLBWPcontrolResourceSetZero = 11; - initialDLBWPsearchSpaceZero = 0; + initialDLBWPcontrolResourceSetZero = 12; + initialDLBWPsearchSpaceZero = 0; - - -#uplinkConfigCommon + #uplinkConfigCommon #frequencyInfoUL - ul_frequencyBand = 78; + ul_frequencyBand = 78; #scs-SpecificCarrierList - ul_offstToCarrier = 0; + ul_offstToCarrier = 0; # subcarrierSpacing # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 - ul_subcarrierSpacing = 1; - ul_carrierBandwidth = 106; - pMax = 20; + ul_subcarrierSpacing = 1; + ul_carrierBandwidth = 106; + pMax = 20; #initialUplinkBWP #genericParameters - initialULBWPlocationAndBandwidth = 28875; + initialULBWPlocationAndBandwidth = 28875; # subcarrierSpacing # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 - initialULBWPsubcarrierSpacing = 1; + initialULBWPsubcarrierSpacing = 1; #rach-ConfigCommon #rach-ConfigGeneric - prach_ConfigurationIndex = 98; + prach_ConfigurationIndex = 98; #prach_msg1_FDM #0 = one, 1=two, 2=four, 3=eight - prach_msg1_FDM = 0; - prach_msg1_FrequencyStart = 0; - zeroCorrelationZoneConfig = 12; - preambleReceivedTargetPower = -104; + prach_msg1_FDM = 0; + prach_msg1_FrequencyStart = 0; + zeroCorrelationZoneConfig = 13; + preambleReceivedTargetPower = -96; #preamblTransMax (0...10) = (3,4,5,6,7,8,10,20,50,100,200) - preambleTransMax = 6; + preambleTransMax = 6; #powerRampingStep # 0=dB0,1=dB2,2=dB4,3=dB6 - powerRampingStep = 1; + powerRampingStep = 1; #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 = 4; +#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen + ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 4; #one (0..15) 4,8,12,16,...60,64 - ssb_perRACH_OccasionAndCB_PreamblesPerSSB = 15; + ssb_perRACH_OccasionAndCB_PreamblesPerSSB = 14; #ra_ContentionResolutionTimer #(0..7) 8,16,24,32,40,48,56,64 - ra_ContentionResolutionTimer = 7; - rsrp_ThresholdSSB = 19; + ra_ContentionResolutionTimer = 7; + rsrp_ThresholdSSB = 19; #prach-RootSequenceIndex_PR #1 = 839, 2 = 139 - prach_RootSequenceIndex_PR = 2; - prach_RootSequenceIndex = 1; + 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, + msg1_SubcarrierSpacing = 1, # restrictedSetConfig # 0=unrestricted, 1=restricted type A, 2=restricted type B - restrictedSetConfig = 0, + restrictedSetConfig = 0, - msg3_DeltaPreamble = 1; - p0_NominalWithGrant =-90; + 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; + pucchGroupHopping = 0; + hoppingId = 40; + p0_nominal = -90; - ssb_PositionsInBurst_Bitmap = 1; + ssb_PositionsInBurst_Bitmap = 1; # ssb_periodicityServingCell -# 0 = ms5, 1=ms10, 2=ms20, 3=ms40, 4=ms80, 5=ms160, 6=spare2, 7=spar e1 - ssb_periodicityServingCell = 2; +# 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; + dmrs_TypeA_Position = 0; # subcarrierSpacing # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 - subcarrierSpacing = 1; + subcarrierSpacing = 1; -#tdd-UL-DL-ConfigurationCommon + #tdd-UL-DL-ConfigurationCommon # subcarrierSpacing # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 - referenceSubcarrierSpacing = 1; + 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 = 7; - nrofDownlinkSymbols = 6; - nrofUplinkSlots = 2; - nrofUplinkSymbols = 4; + dl_UL_TransmissionPeriodicity = 6; + nrofDownlinkSlots = 7; + nrofDownlinkSymbols = 6; + nrofUplinkSlots = 2; + nrofUplinkSymbols = 4; - ssPBCH_BlockPower = -25; + ssPBCH_BlockPower = -25; } ); @@ -190,27 +151,53 @@ gNBs = SCTP_OUTSTREAMS = 2; }; + ////////// AMF parameters: - amf_ip_address = ({ ipv4 = "CI_MME_IP_ADDR"; }); + amf_ip_address = ({ ipv4 = "192.168.70.132"; }); - NETWORK_INTERFACES : - { - GNB_IPV4_ADDRESS_FOR_NG_AMF = "CI_GNB_IP_ADDR"; - GNB_IPV4_ADDRESS_FOR_NGU = "CI_GNB_IP_ADDR"; - GNB_PORT_FOR_S1U = 2152; # Spec 2152 - }; + 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; - tr_s_preference = "local_L1"; - tr_n_preference = "local_RRC"; - pusch_TargetSNRx10 = 200; - pucch_TargetSNRx10 = 200; + num_cc = 1; + tr_s_preference = "local_L1"; + tr_n_preference = "local_RRC"; + pusch_TargetSNRx10 = 150; + pucch_TargetSNRx10 = 200; +} +); + +L1s = ( +{ + num_cc = 1; + tr_n_preference = "local_mac"; + prach_dtx_threshold = 120; + pucch0_dtx_threshold = 100; + ofdm_offset_divisor = 8; #set this to UINT_MAX for offset 0 +} +); + +RUs = ( +{ + local_rf = "yes" + nb_tx = 1 + nb_rx = 1 + att_tx = 12; + att_rx = 12; + bands = [78]; + max_pdschReferenceSignalPower = -27; + max_rxgain = 114; + eNB_instances = [0]; + clock_src = "internal"; } ); @@ -234,32 +221,6 @@ prs_config = ( } ); -L1s = ( -{ - num_cc = 1; - tr_n_preference = "local_mac"; - prach_dtx_threshold = 120; - #pucch0_dtx_threshold = 150; -} -); - -RUs = ( -{ - local_rf = "yes" - nb_tx = 1 - nb_rx = 1 - att_tx = 0 - att_rx = 0; - bands = [78]; - max_pdschReferenceSignalPower = -27; - max_rxgain = 75; - eNB_instances = [0]; - sf_extension = 0 - sdr_addrs = "mgmt_addr=172.21.19.14,addr=192.168.10.2,second_addr=192.168.20.2,clock_source=internal,time_source=internal" -} -); - - rfsimulator : { serveraddr = "server"; @@ -295,5 +256,19 @@ log_config : rlc_log_level ="info"; pdcp_log_level ="info"; rrc_log_level ="info"; - f1ap_log_level ="debug"; + ngap_log_level ="debug"; + f1ap_log_level ="debug"; }; + +e2_agent = { + near_ric_ip_addr = "127.0.0.1"; + #sm_dir = "/path/where/the/SMs/are/located/" + sm_dir = "/usr/local/lib/flexric/" +}; + +telnetsrv = { + listenport = 9080 + listenaddr= "127.0.0.80" +} + +@include "channelmod_rfsimu.conf" diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb1.prs.band78.fr1.106PRB.usrpx310.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb1.prs.band78.fr1.106PRB.usrpx310.conf index bc8af31818..d530f06cff 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb1.prs.band78.fr1.106PRB.usrpx310.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb1.prs.band78.fr1.106PRB.usrpx310.conf @@ -6,42 +6,18 @@ gNBs = ( { ////////// Identification parameters: - gNB_ID = 0xe00; - -# cell_type = "CELL_MACRO_GNB"; - + 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; }) }); - plmn_list = ({ - mcc = 208; - mnc = 97; - mnc_length = 2; - snssaiList = ( - { - sst = 1; - sd = 0x010203; // 0 false, else true - }, - { - sst = 1; - sd = 0x112233; // 0 false, else true - } - ); - }); - - nr_cellid = 12345678L - -# tr_s_preference = "local_mac" + nr_cellid = 12345678L; ////////// Physical parameters: - #pusch_TargetSNRx10 = 200; - #pucch_TargetSNRx10 = 200; - ul_prbblacklist = "51,52,53,54" - min_rxtxtime = 6; - do_SRS = 0; + do_SRS = 1; servingCellConfigCommon = ( { @@ -49,133 +25,119 @@ gNBs = physCellId = 0; -# downlinkConfigCommon +# downlinkConfigCommon #frequencyInfoDL - # this is 3301.68 MHz + 22*12*30e-3 MHz = 3309.6 - #absoluteFrequencySSB = 620640; - # this is 3300.60 MHz + 53*12*30e-3 MHz = 3319.68 - absoluteFrequencySSB = 621312; - # this is 3503.28 MHz + 22*12*30e-3 MHz = 3511.2 - #absoluteFrequencySSB = 634080; - # this is 3600.48 MHz - #absoluteFrequencySSB = 640032; - #dl_frequencyBand = 78; - # this is 3301.68 MHz - #dl_absoluteFrequencyPointA = 620112; - # this is 3300.60 MHz - dl_absoluteFrequencyPointA = 620040; - # this is 3502.56 MHz - #dl_absoluteFrequencyPointA = 633552; - # this is 3600.48 MHz - #dl_absoluteFrequencyPointA = 640032; + # this is 3600 MHz + 43 PRBs@30kHz SCS (same as initial BWP) + absoluteFrequencySSB = 641280; + dl_frequencyBand = 78; + # this is 3600 MHz + dl_absoluteFrequencyPointA = 640008; #scs-SpecificCarrierList - dl_offstToCarrier = 0; + dl_offstToCarrier = 0; # subcarrierSpacing # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 - dl_subcarrierSpacing = 1; - dl_carrierBandwidth = 106; + dl_subcarrierSpacing = 1; + dl_carrierBandwidth = 106; #initialDownlinkBWP #genericParameters - # this is RBstart=0,L=106 (275*(L-1))+RBstart - initialDLBWPlocationAndBandwidth = 28875; + # this is RBstart=27,L=48 (275*(L-1))+RBstart + initialDLBWPlocationAndBandwidth = 28875; # 6366 12925 12956 28875 12952 # subcarrierSpacing # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 - initialDLBWPsubcarrierSpacing = 1; + initialDLBWPsubcarrierSpacing = 1; #pdcch-ConfigCommon - initialDLBWPcontrolResourceSetZero = 11; - initialDLBWPsearchSpaceZero = 0; + initialDLBWPcontrolResourceSetZero = 12; + initialDLBWPsearchSpaceZero = 0; - - -#uplinkConfigCommon + #uplinkConfigCommon #frequencyInfoUL - ul_frequencyBand = 78; + ul_frequencyBand = 78; #scs-SpecificCarrierList - ul_offstToCarrier = 0; + ul_offstToCarrier = 0; # subcarrierSpacing # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 - ul_subcarrierSpacing = 1; - ul_carrierBandwidth = 106; - pMax = 20; + ul_subcarrierSpacing = 1; + ul_carrierBandwidth = 106; + pMax = 20; #initialUplinkBWP #genericParameters - initialULBWPlocationAndBandwidth = 28875; + initialULBWPlocationAndBandwidth = 28875; # subcarrierSpacing # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 - initialULBWPsubcarrierSpacing = 1; + initialULBWPsubcarrierSpacing = 1; #rach-ConfigCommon #rach-ConfigGeneric - prach_ConfigurationIndex = 98; + prach_ConfigurationIndex = 98; #prach_msg1_FDM #0 = one, 1=two, 2=four, 3=eight - prach_msg1_FDM = 0; - prach_msg1_FrequencyStart = 0; - zeroCorrelationZoneConfig = 12; - preambleReceivedTargetPower = -104; + prach_msg1_FDM = 0; + prach_msg1_FrequencyStart = 0; + zeroCorrelationZoneConfig = 13; + preambleReceivedTargetPower = -96; #preamblTransMax (0...10) = (3,4,5,6,7,8,10,20,50,100,200) - preambleTransMax = 6; + preambleTransMax = 6; #powerRampingStep # 0=dB0,1=dB2,2=dB4,3=dB6 - powerRampingStep = 1; + powerRampingStep = 1; #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 = 4; +#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen + ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 4; #one (0..15) 4,8,12,16,...60,64 - ssb_perRACH_OccasionAndCB_PreamblesPerSSB = 15; + ssb_perRACH_OccasionAndCB_PreamblesPerSSB = 14; #ra_ContentionResolutionTimer #(0..7) 8,16,24,32,40,48,56,64 - ra_ContentionResolutionTimer = 7; - rsrp_ThresholdSSB = 19; + ra_ContentionResolutionTimer = 7; + rsrp_ThresholdSSB = 19; #prach-RootSequenceIndex_PR #1 = 839, 2 = 139 - prach_RootSequenceIndex_PR = 2; - prach_RootSequenceIndex = 1; + 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, + msg1_SubcarrierSpacing = 1, # restrictedSetConfig # 0=unrestricted, 1=restricted type A, 2=restricted type B - restrictedSetConfig = 0, + restrictedSetConfig = 0, - msg3_DeltaPreamble = 1; - p0_NominalWithGrant =-90; + 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; + pucchGroupHopping = 0; + hoppingId = 40; + p0_nominal = -90; - ssb_PositionsInBurst_Bitmap = 2; + ssb_PositionsInBurst_Bitmap = 2; # ssb_periodicityServingCell -# 0 = ms5, 1=ms10, 2=ms20, 3=ms40, 4=ms80, 5=ms160, 6=spare2, 7=spar e1 - ssb_periodicityServingCell = 2; +# 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; + dmrs_TypeA_Position = 0; # subcarrierSpacing # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 - subcarrierSpacing = 1; + subcarrierSpacing = 1; -#tdd-UL-DL-ConfigurationCommon + #tdd-UL-DL-ConfigurationCommon # subcarrierSpacing # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 - referenceSubcarrierSpacing = 1; + 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 = 7; - nrofDownlinkSymbols = 6; - nrofUplinkSlots = 2; - nrofUplinkSymbols = 4; + dl_UL_TransmissionPeriodicity = 6; + nrofDownlinkSlots = 7; + nrofDownlinkSymbols = 6; + nrofUplinkSlots = 2; + nrofUplinkSymbols = 4; - ssPBCH_BlockPower = -25; + ssPBCH_BlockPower = -25; } ); @@ -189,27 +151,53 @@ gNBs = SCTP_OUTSTREAMS = 2; }; + ////////// AMF parameters: - amf_ip_address = ({ ipv4 = "CI_MME_IP_ADDR"; }); + amf_ip_address = ({ ipv4 = "192.168.70.132"; }); - NETWORK_INTERFACES : - { - GNB_IPV4_ADDRESS_FOR_NG_AMF = "CI_GNB_IP_ADDR"; - GNB_IPV4_ADDRESS_FOR_NGU = "CI_GNB_IP_ADDR"; - GNB_PORT_FOR_S1U = 2152; # Spec 2152 - }; + 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; - tr_s_preference = "local_L1"; - tr_n_preference = "local_RRC"; - pusch_TargetSNRx10 = 200; - pucch_TargetSNRx10 = 200; + num_cc = 1; + tr_s_preference = "local_L1"; + tr_n_preference = "local_RRC"; + pusch_TargetSNRx10 = 150; + pucch_TargetSNRx10 = 200; +} +); + +L1s = ( +{ + num_cc = 1; + tr_n_preference = "local_mac"; + prach_dtx_threshold = 120; + pucch0_dtx_threshold = 100; + ofdm_offset_divisor = 8; #set this to UINT_MAX for offset 0 +} +); + +RUs = ( +{ + local_rf = "yes" + nb_tx = 1 + nb_rx = 1 + att_tx = 12; + att_rx = 12; + bands = [78]; + max_pdschReferenceSignalPower = -27; + max_rxgain = 114; + eNB_instances = [0]; + clock_src = "internal"; } ); @@ -233,32 +221,6 @@ prs_config = ( } ); -L1s = ( -{ - num_cc = 1; - tr_n_preference = "local_mac"; - prach_dtx_threshold = 120; - #pucch0_dtx_threshold = 150; -} -); - -RUs = ( -{ - local_rf = "yes" - nb_tx = 1 - nb_rx = 1 - att_tx = 0 - att_rx = 0; - bands = [78]; - max_pdschReferenceSignalPower = -27; - max_rxgain = 75; - eNB_instances = [0]; - sf_extension = 0 - sdr_addrs = "mgmt_addr=172.21.19.14,addr=192.168.10.2,second_addr=192.168.20.2,clock_source=internal,time_source=internal" -} -); - - rfsimulator : { serveraddr = "server"; @@ -294,5 +256,19 @@ log_config : rlc_log_level ="info"; pdcp_log_level ="info"; rrc_log_level ="info"; - f1ap_log_level ="debug"; + ngap_log_level ="debug"; + f1ap_log_level ="debug"; }; + +e2_agent = { + near_ric_ip_addr = "127.0.0.1"; + #sm_dir = "/path/where/the/SMs/are/located/" + sm_dir = "/usr/local/lib/flexric/" +}; + +telnetsrv = { + listenport = 9081 + listenaddr= "127.0.0.81" +} + +@include "channelmod_rfsimu.conf" From 1707aafc2ca8ab46ca5d0b8ea9cd07de27f6ad68 Mon Sep 17 00:00:00 2001 From: Thomas Schlichter Date: Tue, 13 Jan 2026 16:15:59 +0100 Subject: [PATCH 08/83] NR UE: make fp pointer to a _constant_ NR_DL_FRAME_PARMS in nr-ue.c --- executables/nr-ue.c | 22 ++++++++++--------- openair1/PHY/NR_UE_TRANSPORT/nr_ntn_l1.c | 2 +- .../NR_UE_TRANSPORT/nr_transport_proto_ue.h | 2 +- 3 files changed, 14 insertions(+), 12 deletions(-) diff --git a/executables/nr-ue.c b/executables/nr-ue.c index 0d1ae421f0..daacc443a3 100644 --- a/executables/nr-ue.c +++ b/executables/nr-ue.c @@ -216,7 +216,7 @@ static void UE_synch(void *arg) { LOG_I(PHY, "[UE thread Synch] Running Initial Synch \n"); uint64_t dl_carrier, ul_carrier; - NR_DL_FRAME_PARMS *fp = &UE->frame_parms; + const NR_DL_FRAME_PARMS *fp = &UE->frame_parms; nr_initial_sync_t ret = {false, 0, 0}; if (UE->sl_mode == 2) { fp = &UE->SL_UE_PHY_PARAMS.sl_frame_params; @@ -298,7 +298,7 @@ static void RU_write(nr_rxtx_thread_data_t *rxtxD, bool sl_tx_action, c16_t **tx const fapi_nr_config_request_t *cfg = &UE->nrUE_config; const UE_nr_rxtx_proc_t *proc = &rxtxD->proc; - NR_DL_FRAME_PARMS *fp = &UE->frame_parms; + const NR_DL_FRAME_PARMS *fp = &UE->frame_parms; if (UE->sl_mode == 2) fp = &UE->SL_UE_PHY_PARAMS.sl_frame_params; @@ -399,7 +399,7 @@ void processSlotTX(void *arg) LOG_D(PHY, "SlotTx %d.%d => slot type %d\n", proc->frame_tx, proc->nr_slot_tx, proc->tx_slot_type); - NR_DL_FRAME_PARMS *fp = &UE->frame_parms; + const NR_DL_FRAME_PARMS *fp = &UE->frame_parms; c16_t *txp[fp->nb_antennas_tx]; for (int i = 0; i < fp->nb_antennas_tx; i++) { txp[i] = UE->common_vars.txData[i] + get_samples_slot_timestamp(fp, proc->nr_slot_tx); @@ -533,7 +533,7 @@ static int UE_dl_preprocessing(PHY_VARS_NR_UE *UE, { TracyCZone(ctx, true); int sampleShift = INT_MAX; - NR_DL_FRAME_PARMS *fp = &UE->frame_parms; + const NR_DL_FRAME_PARMS *fp = &UE->frame_parms; if (UE->sl_mode == 2) fp = &UE->SL_UE_PHY_PARAMS.sl_frame_params; @@ -621,7 +621,7 @@ void UE_dl_processing(void *arg) { void dummyWrite(PHY_VARS_NR_UE *UE, openair0_timestamp_t timestamp, int writeBlockSize) { - NR_DL_FRAME_PARMS *fp = &UE->frame_parms; + const NR_DL_FRAME_PARMS *fp = &UE->frame_parms; if (UE->sl_mode == 2) fp = &UE->SL_UE_PHY_PARAMS.sl_frame_params; @@ -638,7 +638,7 @@ void dummyWrite(PHY_VARS_NR_UE *UE, openair0_timestamp_t timestamp, int writeBlo void readFrame(PHY_VARS_NR_UE *UE, openair0_timestamp_t *timestamp, int duration_rx_to_tx, bool toTrash) { - NR_DL_FRAME_PARMS *fp = &UE->frame_parms; + const NR_DL_FRAME_PARMS *fp = &UE->frame_parms; // two frames for initial sync int num_frames = 2; // In Sidelink worst case SL-SSB can be sent once in 16 frames @@ -681,7 +681,7 @@ void readFrame(PHY_VARS_NR_UE *UE, openair0_timestamp_t *timestamp, int duration static void syncInFrame(PHY_VARS_NR_UE *UE, openair0_timestamp_t *timestamp, int duration_rx_to_tx, openair0_timestamp_t rx_offset) { - NR_DL_FRAME_PARMS *fp = &UE->frame_parms; + const NR_DL_FRAME_PARMS *fp = &UE->frame_parms; if (UE->sl_mode == 2) fp = &UE->SL_UE_PHY_PARAMS.sl_frame_params; @@ -704,11 +704,13 @@ static void syncInFrame(PHY_VARS_NR_UE *UE, openair0_timestamp_t *timestamp, int } } -static inline int get_firstSymSamp(uint16_t slot, NR_DL_FRAME_PARMS *fp) { +static inline int get_firstSymSamp(uint16_t slot, const NR_DL_FRAME_PARMS *fp) +{ return get_samples_symbol_duration(fp, slot, 0, 1); } -static inline int get_readBlockSize(uint16_t slot, NR_DL_FRAME_PARMS *fp) { +static inline int get_readBlockSize(uint16_t slot, const NR_DL_FRAME_PARMS *fp) +{ int rem_samples = get_samples_per_slot(slot, fp) - get_firstSymSamp(slot, fp); int next_slot_first_symbol = 0; if (slot < (fp->slots_per_frame-1)) @@ -720,11 +722,11 @@ void *UE_thread(void *arg) { //this thread should be over the processing thread to keep in real time PHY_VARS_NR_UE *UE = (PHY_VARS_NR_UE *)arg; + const NR_DL_FRAME_PARMS *fp = &UE->frame_parms; // int tx_enabled = 0; void *rxp[NB_ANTENNAS_RX]; enum stream_status_e stream_status = STREAM_STATUS_UNSYNC; fapi_nr_config_request_t *cfg = &UE->nrUE_config; - NR_DL_FRAME_PARMS *fp = &UE->frame_parms; sl_nr_phy_config_request_t *sl_cfg = NULL; if (UE->sl_mode == 2) { fp = &UE->SL_UE_PHY_PARAMS.sl_frame_params; diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ntn_l1.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ntn_l1.c index deae817a36..9a95bae820 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_ntn_l1.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ntn_l1.c @@ -140,7 +140,7 @@ void apply_ntn_timing_advance_and_doppler(PHY_VARS_NR_UE *UE, const NR_DL_FRAME_ // apply values based on the NTN-Config void apply_ntn_config(PHY_VARS_NR_UE *UE, - NR_DL_FRAME_PARMS *fp, + const NR_DL_FRAME_PARMS *fp, int hfn_rx, int frame_rx, int slot_rx, diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h index b0df82c467..3daaaf0eee 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h @@ -331,7 +331,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, int frame, uint8_t slot, c16_t **txData); void apply_ntn_config(PHY_VARS_NR_UE *UE, - NR_DL_FRAME_PARMS *fp, + const NR_DL_FRAME_PARMS *fp, int hfn_rx, int frame_rx, int slot_rx, From 09b3fc03c75b989e6ccab57ea74a9597b6e92645 Mon Sep 17 00:00:00 2001 From: Thomas Schlichter Date: Tue, 13 Jan 2026 16:30:48 +0100 Subject: [PATCH 09/83] NR UE: make RX and TX pointer arrays of type c16_t instead of void in nr-ue.c --- executables/nr-ue.c | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/executables/nr-ue.c b/executables/nr-ue.c index daacc443a3..2ed9de6c96 100644 --- a/executables/nr-ue.c +++ b/executables/nr-ue.c @@ -625,14 +625,13 @@ void dummyWrite(PHY_VARS_NR_UE *UE, openair0_timestamp_t timestamp, int writeBlo if (UE->sl_mode == 2) fp = &UE->SL_UE_PHY_PARAMS.sl_frame_params; - void *dummy_tx[fp->nb_antennas_tx]; - // 2 because the function we call use pairs of int16_t implicitly as complex numbers - int16_t dummy_tx_data[2 * writeBlockSize]; + c16_t *dummy_tx[fp->nb_antennas_tx]; + c16_t dummy_tx_data[writeBlockSize]; memset(dummy_tx_data, 0, sizeof(dummy_tx_data)); for (int i = 0; i < fp->nb_antennas_tx; i++) dummy_tx[i] = dummy_tx_data; - int tmp = nrue_ru_write(UE, timestamp, dummy_tx, writeBlockSize, fp->nb_antennas_tx, 4); + int tmp = nrue_ru_write(UE, timestamp, (void **)dummy_tx, writeBlockSize, fp->nb_antennas_tx, 4); AssertFatal(writeBlockSize == tmp, ""); } @@ -647,9 +646,9 @@ void readFrame(PHY_VARS_NR_UE *UE, openair0_timestamp_t *timestamp, int duration num_frames = SL_NR_PSBCH_REPETITION_IN_FRAMES; } - void *rxp[NB_ANTENNAS_RX]; + c16_t *rxp[fp->nb_antennas_rx]; if (toTrash) { - rxp[0] = malloc16(get_samples_per_slot(0, fp) * 4); + rxp[0] = malloc16(get_samples_per_slot(0, fp) * sizeof(c16_t)); for (int i = 1; i < fp->nb_antennas_rx; i++) rxp[i] = rxp[0]; } @@ -658,11 +657,10 @@ void readFrame(PHY_VARS_NR_UE *UE, openair0_timestamp_t *timestamp, int duration for (int slot = 0; slot < fp->slots_per_subframe; slot++) { if (!toTrash) for (int i = 0; i < fp->nb_antennas_rx; i++) - rxp[i] = - ((void *)&UE->common_vars.rxdata[i][0]) + 4 * ((x * fp->samples_per_subframe) + get_samples_slot_timestamp(fp, slot)); + rxp[i] = &UE->common_vars.rxdata[i][x * fp->samples_per_subframe + get_samples_slot_timestamp(fp, slot)]; int read_block_size = get_samples_per_slot(slot, fp); - int tmp = nrue_ru_read(UE, timestamp, rxp, read_block_size, fp->nb_antennas_rx); + int tmp = nrue_ru_read(UE, timestamp, (void **)rxp, read_block_size, fp->nb_antennas_rx); UEscopeCopy(UE, ueTimeDomainSamplesBeforeSync, rxp[0], sizeof(c16_t), 1, read_block_size, 0); AssertFatal(read_block_size == tmp, ""); @@ -724,7 +722,7 @@ void *UE_thread(void *arg) PHY_VARS_NR_UE *UE = (PHY_VARS_NR_UE *)arg; const NR_DL_FRAME_PARMS *fp = &UE->frame_parms; // int tx_enabled = 0; - void *rxp[NB_ANTENNAS_RX]; + c16_t *rxp[fp->nb_antennas_rx]; enum stream_status_e stream_status = STREAM_STATUS_UNSYNC; fapi_nr_config_request_t *cfg = &UE->nrUE_config; sl_nr_phy_config_request_t *sl_cfg = NULL; @@ -945,7 +943,7 @@ void *UE_thread(void *arg) int firstSymSamp = get_firstSymSamp(slot_nr, fp); for (int i = 0; i < fp->nb_antennas_rx; i++) - rxp[i] = (void *)&UE->common_vars.rxdata[i][firstSymSamp + get_samples_slot_timestamp(fp, slot_nr)]; + rxp[i] = &UE->common_vars.rxdata[i][firstSymSamp + get_samples_slot_timestamp(fp, slot_nr)]; int iq_shift_to_apply = 0; if (slot_nr == nb_slot_frame - 1) { @@ -966,9 +964,9 @@ void *UE_thread(void *arg) const int readBlockSize = get_readBlockSize(slot_nr, fp) - iq_shift_to_apply; openair0_timestamp_t rx_timestamp; - int tmp = nrue_ru_read(UE, &rx_timestamp, rxp, readBlockSize, fp->nb_antennas_rx); + int tmp = nrue_ru_read(UE, &rx_timestamp, (void **)rxp, readBlockSize, fp->nb_antennas_rx); metadata meta = {.slot = curMsg.proc.nr_slot_rx, .frame = curMsg.proc.frame_rx}; - UEscopeCopyWithMetadata(UE, ueTimeDomainSamples, rxp[0] - firstSymSamp * sizeof(c16_t), sizeof(c16_t), 1, readBlockSize, 0, &meta); + UEscopeCopyWithMetadata(UE, ueTimeDomainSamples, rxp[0] - firstSymSamp, sizeof(c16_t), 1, readBlockSize, 0, &meta); AssertFatal(readBlockSize == tmp, ""); struct timespec current_time; if (clock_gettime(CLOCK_REALTIME, ¤t_time)) { From ba0ead6809aad15975ba4d5078275ceee0d931e2 Mon Sep 17 00:00:00 2001 From: Thomas Schlichter Date: Tue, 13 Jan 2026 16:52:06 +0100 Subject: [PATCH 10/83] NR UE: correctly compute the writeBlockSize in readFrame() and the writeTimestamp in syncInFrame() --- executables/nr-ue.c | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/executables/nr-ue.c b/executables/nr-ue.c index 2ed9de6c96..ef53351047 100644 --- a/executables/nr-ue.c +++ b/executables/nr-ue.c @@ -654,21 +654,23 @@ void readFrame(PHY_VARS_NR_UE *UE, openair0_timestamp_t *timestamp, int duration } for (int x = 0; x < num_frames * NR_NUMBER_OF_SUBFRAMES_PER_FRAME; x++) { // two frames for initial sync - for (int slot = 0; slot < fp->slots_per_subframe; slot++) { + for (int slot_rx = 0; slot_rx < fp->slots_per_subframe; slot_rx++) { if (!toTrash) for (int i = 0; i < fp->nb_antennas_rx; i++) - rxp[i] = &UE->common_vars.rxdata[i][x * fp->samples_per_subframe + get_samples_slot_timestamp(fp, slot)]; + rxp[i] = &UE->common_vars.rxdata[i][x * fp->samples_per_subframe + get_samples_slot_timestamp(fp, slot_rx)]; - int read_block_size = get_samples_per_slot(slot, fp); - int tmp = nrue_ru_read(UE, timestamp, (void **)rxp, read_block_size, fp->nb_antennas_rx); - UEscopeCopy(UE, ueTimeDomainSamplesBeforeSync, rxp[0], sizeof(c16_t), 1, read_block_size, 0); - AssertFatal(read_block_size == tmp, ""); + int readBlockSize = get_samples_per_slot(slot_rx, fp); + int tmp = nrue_ru_read(UE, timestamp, (void **)rxp, readBlockSize, fp->nb_antennas_rx); + UEscopeCopy(UE, ueTimeDomainSamplesBeforeSync, rxp[0], sizeof(c16_t), 1, readBlockSize, 0); + AssertFatal(readBlockSize == tmp, ""); if (IS_SOFTMODEM_RFSIM) { + int slot_tx = (slot_rx + duration_rx_to_tx) % fp->slots_per_frame; + int writeBlockSize = get_samples_per_slot(slot_tx, fp); int ta = UE->timing_advance + UE->timing_advance_ntn; const openair0_timestamp_t writeTimestamp = - *timestamp + get_samples_slot_duration(fp, slot, duration_rx_to_tx) - UE->N_TA_offset - ta; - dummyWrite(UE, writeTimestamp, get_samples_per_slot(slot, fp)); + *timestamp + get_samples_slot_duration(fp, slot_rx, duration_rx_to_tx) - UE->N_TA_offset - ta; + dummyWrite(UE, writeTimestamp, writeBlockSize); } } } @@ -685,19 +687,18 @@ static void syncInFrame(PHY_VARS_NR_UE *UE, openair0_timestamp_t *timestamp, int LOG_I(PHY, "Resynchronizing RX by %ld samples\n", rx_offset); - int slot = 0; int size = rx_offset; while (size > 0) { - const int unitTransfer = min(get_samples_per_slot(slot, fp), size); + // Set a maximum transfer size. As we usually read/write single slots, we use the size of slot 0 as maximum here. + const int unitTransfer = min(get_samples_per_slot(0, fp), size); const int res = nrue_ru_read(UE, timestamp, (void **)UE->common_vars.rxdata, unitTransfer, fp->nb_antennas_rx); DevAssert(unitTransfer == res); if (IS_SOFTMODEM_RFSIM) { int ta = UE->timing_advance + UE->timing_advance_ntn; const openair0_timestamp_t writeTimestamp = - *timestamp + get_samples_slot_duration(fp, slot, duration_rx_to_tx) - UE->N_TA_offset - ta; + *timestamp + get_samples_slot_duration(fp, 0, duration_rx_to_tx) - UE->N_TA_offset - ta; dummyWrite(UE, writeTimestamp, unitTransfer); } - slot = (slot + 1) % fp->slots_per_subframe; size -= unitTransfer; } } From f7265977ad94ff12399e8acae64030201dfceaf4 Mon Sep 17 00:00:00 2001 From: Thomas Schlichter Date: Tue, 13 Jan 2026 16:56:56 +0100 Subject: [PATCH 11/83] NR UE: when compensating for large timing_advance changes, set writeBlockSize to 0 instead of 1 --- executables/nr-ue.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/executables/nr-ue.c b/executables/nr-ue.c index ef53351047..f66d11f4c3 100644 --- a/executables/nr-ue.c +++ b/executables/nr-ue.c @@ -294,6 +294,10 @@ static int nr_ue_slot_select(const fapi_nr_config_request_t *cfg, int nr_slot) static void RU_write(nr_rxtx_thread_data_t *rxtxD, bool sl_tx_action, c16_t **txp) { + int writeBlockSize = rxtxD->writeBlockSize; + if (writeBlockSize == 0) + return; + PHY_VARS_NR_UE *UE = rxtxD->UE; const fapi_nr_config_request_t *cfg = &UE->nrUE_config; const UE_nr_rxtx_proc_t *proc = &rxtxD->proc; @@ -353,7 +357,6 @@ static void RU_write(nr_rxtx_thread_data_t *rxtxD, bool sl_tx_action, c16_t **tx } openair0_timestamp_t writeTimestamp = proc->timestamp_tx; - int writeBlockSize = rxtxD->writeBlockSize; // if writeBlockSize gets longer that slot size, fill with dummy const int maxWriteBlockSize = get_samples_per_slot(proc->nr_slot_tx, fp); while (writeBlockSize > maxWriteBlockSize) { @@ -1010,9 +1013,9 @@ void *UE_thread(void *arg) UE->N_TA_offset = new_N_TA_offset; } if (writeBlockSize < 0) { - timing_advance += writeBlockSize - 1; - LOG_I(PHY, "writeBlockSize is %d, setting it to 1 and changing timing_advance to %d\n", writeBlockSize, timing_advance); - writeBlockSize = 1; + timing_advance += writeBlockSize; + LOG_I(PHY, "writeBlockSize is %d, setting it to 0 and changing timing_advance to %d\n", writeBlockSize, timing_advance); + writeBlockSize = 0; } if (curMsg.proc.nr_slot_rx == 0) From b53f4a6e377f0e28750ca57edbd321522716e64f Mon Sep 17 00:00:00 2001 From: francescomani Date: Thu, 21 Nov 2024 17:04:04 +0100 Subject: [PATCH 12/83] using constants for FAPI precoding weigths instead of hardcoded values --- common/utils/nr/nr_common.h | 1 + nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h | 3 ++- openair1/PHY/INIT/nr_init_ue.c | 6 +++--- openair1/PHY/defs_nr_common.h | 2 -- openair2/GNB_APP/gnb_config.c | 3 +++ 5 files changed, 9 insertions(+), 6 deletions(-) diff --git a/common/utils/nr/nr_common.h b/common/utils/nr/nr_common.h index f1a48766a9..d2b78725c9 100644 --- a/common/utils/nr/nr_common.h +++ b/common/utils/nr/nr_common.h @@ -87,6 +87,7 @@ static inline const char *rnti_types(nr_rnti_type_t rr) #define NR_NUMBER_OF_SYMBOLS_PER_SLOT 14 #define NR_NUMBER_OF_SYMBOLS_PER_SLOT_EXTENDED_CP 12 #define NR_MAX_NB_LAYERS 4 // 8 +#define NR_MAX_CSI_PORTS 4 // Since the IQ samples are represented by SQ15 R+I (see https://en.wikipedia.org/wiki/Q_(number_format)) we need to compensate when // calcualting signal energy. Instead of shifting each sample right by 15, we can normalize the result in dB scale once its diff --git a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h index fcd1968c25..3485c6430d 100644 --- a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h +++ b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h @@ -11,6 +11,7 @@ #include "stddef.h" #include "common/platform_types.h" +#include "common/utils/nr/nr_common.h" #include "nfapi_interface.h" #include "nfapi_nr_interface.h" @@ -495,7 +496,7 @@ typedef struct { uint16_t pm_idx; uint16_t numLayers; uint16_t num_ant_ports; - nfapi_nr_pm_weights_t weights[4][4]; // TODO temporary hardcoding + nfapi_nr_pm_weights_t weights[NR_MAX_NB_LAYERS][NR_MAX_CSI_PORTS]; } nfapi_nr_pm_pdu_t; diff --git a/openair1/PHY/INIT/nr_init_ue.c b/openair1/PHY/INIT/nr_init_ue.c index 7b21102bbf..c40d8b1096 100644 --- a/openair1/PHY/INIT/nr_init_ue.c +++ b/openair1/PHY/INIT/nr_init_ue.c @@ -262,8 +262,8 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB) // ceil((NB_RB*8(max allocation per RB)*2(QPSK))/32) ue->nr_csi_info = malloc16_clear(sizeof(nr_csi_info_t)); - ue->nr_csi_info->csi_rs_generated_signal = malloc16(NR_MAX_NB_PORTS * sizeof(*ue->nr_csi_info->csi_rs_generated_signal)); - for (int i = 0; i < NR_MAX_NB_PORTS; i++) { + ue->nr_csi_info->csi_rs_generated_signal = malloc16(NR_MAX_CSI_PORTS * sizeof(*ue->nr_csi_info->csi_rs_generated_signal)); + for (int i = 0; i < NR_MAX_CSI_PORTS; i++) { ue->nr_csi_info->csi_rs_generated_signal[i] = malloc16_clear(fp->samples_per_frame_wCP * sizeof(**ue->nr_csi_info->csi_rs_generated_signal)); } @@ -311,7 +311,7 @@ void term_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB) for (int gNB_id = 0; gNB_id < ue->n_connected_gNB; gNB_id++) { - for (int i=0; inr_csi_info->csi_rs_generated_signal[i]); } free_and_zero(ue->nr_csi_info->csi_rs_generated_signal); diff --git a/openair1/PHY/defs_nr_common.h b/openair1/PHY/defs_nr_common.h index dc2630348c..01677594cd 100644 --- a/openair1/PHY/defs_nr_common.h +++ b/openair1/PHY/defs_nr_common.h @@ -68,8 +68,6 @@ #define NR_MAX_PDCCH_AGG_LEVEL 16 // 3GPP TS 38.211 V15.8 Section 7.3.2 Table 7.3.2.1-1: Supported PDCCH aggregation levels -#define NR_MAX_NB_PORTS 32 - #define MAX_NUM_NR_DLSCH_SEGMENTS_PER_LAYER 36 #define MAX_NUM_NR_ULSCH_SEGMENTS_PER_LAYER 34 diff --git a/openair2/GNB_APP/gnb_config.c b/openair2/GNB_APP/gnb_config.c index f9e8261c0f..667ab25093 100644 --- a/openair2/GNB_APP/gnb_config.c +++ b/openair2/GNB_APP/gnb_config.c @@ -879,6 +879,9 @@ void RCconfig_NR_L1(void) // Antenna ports set_antenna_ports(&GNBParamList, &gNB->ap_N1, &gNB->ap_N2, &gNB->ap_XP); + AssertFatal(gNB->ap_N1 * gNB->ap_N2 * gNB->ap_XP <= NR_MAX_CSI_PORTS, + "Number of antenna ports set in config file exceeds the supported value of %d\n", + NR_MAX_CSI_PORTS); } // L1 params From 7a59f28ae314f5b16f2c517f82f34f8facc7f4f6 Mon Sep 17 00:00:00 2001 From: francescomani Date: Thu, 21 Nov 2024 18:10:46 +0100 Subject: [PATCH 13/83] RRC CSI-RS config for 8 and 12 ports --- common/utils/nr/nr_common.h | 2 +- openair2/LAYER2/NR_MAC_gNB/nr_radio_config.c | 20 +++++++++++++++++++- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/common/utils/nr/nr_common.h b/common/utils/nr/nr_common.h index d2b78725c9..b6e7a474bb 100644 --- a/common/utils/nr/nr_common.h +++ b/common/utils/nr/nr_common.h @@ -87,7 +87,7 @@ static inline const char *rnti_types(nr_rnti_type_t rr) #define NR_NUMBER_OF_SYMBOLS_PER_SLOT 14 #define NR_NUMBER_OF_SYMBOLS_PER_SLOT_EXTENDED_CP 12 #define NR_MAX_NB_LAYERS 4 // 8 -#define NR_MAX_CSI_PORTS 4 +#define NR_MAX_CSI_PORTS 12 // Since the IQ samples are represented by SQ15 R+I (see https://en.wikipedia.org/wiki/Q_(number_format)) we need to compensate when // calcualting signal energy. Instead of shifting each sample right by 15, we can normalize the result in dB scale once its diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_radio_config.c b/openair2/LAYER2/NR_MAC_gNB/nr_radio_config.c index fe4a64da2b..a7376d69ec 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_radio_config.c +++ b/openair2/LAYER2/NR_MAC_gNB/nr_radio_config.c @@ -479,8 +479,26 @@ static void config_csirs(const NR_ServingCellConfigCommon_t *servingcellconfigco resourceMapping.nrofPorts = NR_CSI_RS_ResourceMapping__nrofPorts_p4; resourceMapping.cdm_Type = NR_CSI_RS_ResourceMapping__cdm_Type_fd_CDM2; break; + case 8: + resourceMapping.frequencyDomainAllocation.present = NR_CSI_RS_ResourceMapping__frequencyDomainAllocation_PR_other; + resourceMapping.frequencyDomainAllocation.choice.other.buf = calloc(1, sizeof(uint8_t)); + resourceMapping.frequencyDomainAllocation.choice.other.size = 1; + resourceMapping.frequencyDomainAllocation.choice.other.bits_unused = 2; + resourceMapping.frequencyDomainAllocation.choice.other.buf[0] = 60; + resourceMapping.nrofPorts = NR_CSI_RS_ResourceMapping__nrofPorts_p8; + resourceMapping.cdm_Type = NR_CSI_RS_ResourceMapping__cdm_Type_fd_CDM2; + break; + case 12: + resourceMapping.frequencyDomainAllocation.present = NR_CSI_RS_ResourceMapping__frequencyDomainAllocation_PR_other; + resourceMapping.frequencyDomainAllocation.choice.other.buf = calloc(1, sizeof(uint8_t)); + resourceMapping.frequencyDomainAllocation.choice.other.size = 1; + resourceMapping.frequencyDomainAllocation.choice.other.bits_unused = 2; + resourceMapping.frequencyDomainAllocation.choice.other.buf[0] = 252; + resourceMapping.nrofPorts = NR_CSI_RS_ResourceMapping__nrofPorts_p12; + resourceMapping.cdm_Type = NR_CSI_RS_ResourceMapping__cdm_Type_fd_CDM2; + break; default: - AssertFatal(1==0,"Number of ports not yet supported\n"); + AssertFatal(false, "Number of ports not yet supported\n"); } resourceMapping.firstOFDMSymbolInTimeDomain = 13; // last symbol of slot resourceMapping.firstOFDMSymbolInTimeDomain2 = NULL; From db2bcf0eee1b283792d4c14abd30a9e7e72fb7fe Mon Sep 17 00:00:00 2001 From: francescomani Date: Fri, 23 Jan 2026 13:48:52 +0100 Subject: [PATCH 14/83] preventing include of log.h in nr_common.h by moving function in nr_common.c --- common/utils/nr/nr_common.c | 13 +++++++++++++ common/utils/nr/nr_common.h | 14 +------------- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/common/utils/nr/nr_common.c b/common/utils/nr/nr_common.c index a3a8520c86..8d61498f9e 100644 --- a/common/utils/nr/nr_common.c +++ b/common/utils/nr/nr_common.c @@ -796,6 +796,19 @@ int get_subband_size(int NPRB,int size) { } +void warn_higher_threequarter_fs(const int n_rb, const int mu) +{ + LOG_W(NR_PHY, + "3/4 sampling is not possible for current PRB size: %d and numerology: %d.\n " + "So 6/4 sampling is chosen to support x3xx type USRPs.\n " + "Note that this sampling rate increases fronthaul traffic, FFT buffer size and processing time by a factor of two compared " + "to 3/4 sampling rate.\n " + "Some PRACH configuration might not be supported with 6/4 FFT size.\n " + "Consider reducing the PRB size that would fit within the FFT size of 3/4 sampling\n", + n_rb, + mu); +} + void get_samplerate_and_bw(int mu, int n_rb, int8_t threequarter_fs, diff --git a/common/utils/nr/nr_common.h b/common/utils/nr/nr_common.h index ca867fa694..f1a48766a9 100644 --- a/common/utils/nr/nr_common.h +++ b/common/utils/nr/nr_common.h @@ -37,7 +37,6 @@ #include #include "assertions.h" #include "common/utils/utils.h" -#include "common/utils/LOG/log.h" #define MAX_SI_GROUPS 3 #define NR_MAX_PDSCH_TBS 3824 @@ -273,18 +272,7 @@ static __attribute__((always_inline)) inline int count_bits64_with_mask(uint64_t return count_bits64(v & mask); } -static inline void warn_higher_threequarter_fs(const int n_rb, const int mu) -{ - LOG_W(PHY, - "3/4 sampling is not possible for current PRB size: %d and numerology: %d.\n " - "So 6/4 sampling is chosen to support x3xx type USRPs.\n " - "Note that this sampling rate increases fronthaul traffic, FFT buffer size and processing time by a factor of two compared " - "to 3/4 sampling rate.\n " - "Some PRACH configuration might not be supported with 6/4 FFT size.\n " - "Consider reducing the PRB size that would fit within the FFT size of 3/4 sampling\n", - n_rb, - mu); -} +void warn_higher_threequarter_fs(const int n_rb, const int mu); uint64_t from_nrarfcn(int nr_bandP, uint8_t scs_index, uint32_t dl_nrarfcn); uint32_t to_nrarfcn(int nr_bandP, uint64_t dl_CarrierFreq, uint8_t scs_index, uint32_t bw); From 46d4659706984ab52ae9db86793a1861d310a50f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=BAben=20Soares=20Silva?= Date: Fri, 20 Feb 2026 13:28:44 +0000 Subject: [PATCH 15/83] Add missing packing for CONFIG.request parameter BetaPSS Adds the packing procedure for the parameter BetaPSS, as well as adding this parameter to the utility functions where it is missing --- nfapi/open-nFAPI/fapi/src/nr_fapi_p5.c | 4 ++++ nfapi/open-nFAPI/fapi/src/nr_fapi_p5_utils.c | 4 ++++ nfapi/tests/p5/nr_fapi_config_request_test.c | 5 +++++ 3 files changed, 13 insertions(+) diff --git a/nfapi/open-nFAPI/fapi/src/nr_fapi_p5.c b/nfapi/open-nFAPI/fapi/src/nr_fapi_p5.c index 9bbda9d519..4470b5eece 100644 --- a/nfapi/open-nFAPI/fapi/src/nr_fapi_p5.c +++ b/nfapi/open-nFAPI/fapi/src/nr_fapi_p5.c @@ -1031,6 +1031,10 @@ uint8_t pack_nr_config_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *e &pack_uint16_tlv_value); numTLVs++; #endif + retval &= + pack_nr_tlv(NFAPI_NR_CONFIG_BETA_PSS_TAG, &(pNfapiMsg->ssb_table.beta_pss), ppWritePackedMsg, end, &pack_uint8_tlv_value); + numTLVs++; + retval &= pack_nr_tlv(NFAPI_NR_CONFIG_SSB_PERIOD_TAG, &(pNfapiMsg->ssb_table.ssb_period), ppWritePackedMsg, end, &pack_uint8_tlv_value); numTLVs++; diff --git a/nfapi/open-nFAPI/fapi/src/nr_fapi_p5_utils.c b/nfapi/open-nFAPI/fapi/src/nr_fapi_p5_utils.c index 1ef65b664c..696d9c0a97 100644 --- a/nfapi/open-nFAPI/fapi/src/nr_fapi_p5_utils.c +++ b/nfapi/open-nFAPI/fapi/src/nr_fapi_p5_utils.c @@ -226,6 +226,8 @@ bool eq_config_request(const nfapi_nr_config_request_scf_t *unpacked_req, const EQ_TLV(unpacked_req->ssb_table.ssb_offset_point_a, req->ssb_table.ssb_offset_point_a); + EQ_TLV(unpacked_req->ssb_table.beta_pss, req->ssb_table.beta_pss); + EQ_TLV(unpacked_req->ssb_table.ssb_period, req->ssb_table.ssb_period); EQ_TLV(unpacked_req->ssb_table.ssb_subcarrier_offset, req->ssb_table.ssb_subcarrier_offset); @@ -772,6 +774,8 @@ void copy_config_request(const nfapi_nr_config_request_scf_t *src, nfapi_nr_conf COPY_TLV(dst->ssb_table.ssb_offset_point_a, src->ssb_table.ssb_offset_point_a); + COPY_TLV(dst->ssb_table.beta_pss, src->ssb_table.beta_pss); + COPY_TLV(dst->ssb_table.ssb_period, src->ssb_table.ssb_period); COPY_TLV(dst->ssb_table.ssb_subcarrier_offset, src->ssb_table.ssb_subcarrier_offset); diff --git a/nfapi/tests/p5/nr_fapi_config_request_test.c b/nfapi/tests/p5/nr_fapi_config_request_test.c index ed57a64d62..8e791c46c4 100644 --- a/nfapi/tests/p5/nr_fapi_config_request_test.c +++ b/nfapi/tests/p5/nr_fapi_config_request_test.c @@ -156,6 +156,9 @@ static void fill_config_request_tlv_tdd_rand(nfapi_nr_config_request_scf_t *nfap FILL_TLV(nfapi_resp->ssb_table.ssb_offset_point_a, NFAPI_NR_CONFIG_SSB_OFFSET_POINT_A_TAG, rand16()); nfapi_resp->num_tlv++; + FILL_TLV(nfapi_resp->ssb_table.beta_pss, NFAPI_NR_CONFIG_BETA_PSS_TAG, rand8()); + nfapi_resp->num_tlv++; + FILL_TLV(nfapi_resp->ssb_table.ssb_period, NFAPI_NR_CONFIG_SSB_PERIOD_TAG, rand16()); nfapi_resp->num_tlv++; @@ -437,6 +440,8 @@ static void fill_config_request_tlv_fdd(nfapi_nr_config_request_scf_t *req) /* SSB table */ FILL_TLV(req->ssb_table.ssb_offset_point_a, NFAPI_NR_CONFIG_SSB_OFFSET_POINT_A_TAG, 4); req->num_tlv++; + FILL_TLV(req->ssb_table.beta_pss, NFAPI_NR_CONFIG_BETA_PSS_TAG, 0); + req->num_tlv++; FILL_TLV(req->ssb_table.ssb_period, NFAPI_NR_CONFIG_SSB_PERIOD_TAG, 2); req->num_tlv++; FILL_TLV(req->ssb_table.ssb_subcarrier_offset, NFAPI_NR_CONFIG_SSB_SUBCARRIER_OFFSET_TAG, 0); From 66efe925514d96095d64ae5dc9fc173844f34332 Mon Sep 17 00:00:00 2001 From: Laurent THOMAS Date: Wed, 21 Jan 2026 14:09:24 +0100 Subject: [PATCH 16/83] separate report list from each report as a table of struct instead of a struct of tables --- .../NR_MAC_gNB/gNB_scheduler_primitives.c | 4 +- .../LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c | 46 +++++++++---------- openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h | 24 ++++++---- 3 files changed, 39 insertions(+), 35 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c index 7742b06294..c4dfa019aa 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c @@ -3750,8 +3750,8 @@ void beam_selection_procedures(gNB_MAC_INST *mac, NR_UE_info_t *UE) // simple beam switching algorithm -> we select beam with highest RSRP from CSI report NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; - RSRP_report_t *rsrp_report = &sched_ctrl->CSI_report.ssb_rsrp_report; - int new_bf_index = get_beam_from_ssbidx(mac, rsrp_report->resource_id[0]); + RSRP_report_list_t *rsrp_report = &sched_ctrl->CSI_report.ssb_rsrp_report; + int new_bf_index = get_beam_from_ssbidx(mac, rsrp_report->r[0].resource_id); if (!mac->radio_config.do_TCI) { // if not TCI is configure we switch beam directly if (UE->UE_beam_index != new_bf_index) beam_switching_procedure(UE, new_bf_index); diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c index ac0803e1e3..32f2a2e669 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c @@ -495,7 +495,7 @@ static void evaluate_sinr_report(gNB_MAC_INST *nrmac, */ nr_csi_report_t *csi_report = &UE->csi_report_template[csi_report_id]; - RSRP_report_t *sinr_report; + RSRP_report_list_t *sinr_report; long **index_list; switch (reportQuantity_type_r16) { case NR_CSI_ReportConfig__ext2__reportQuantity_r16_PR_ssb_Index_SINR_r16: @@ -510,13 +510,13 @@ static void evaluate_sinr_report(gNB_MAC_INST *nrmac, AssertFatal(false, "Invalid RSRP report type\n"); } - sinr_report->nr_reports = csi_report->CSI_report_bitlen.nb_ssbri_cri; + sinr_report->nb = csi_report->CSI_report_bitlen.nb_ssbri_cri; uint16_t curr_payload; - for (int i = 0; i < sinr_report->nr_reports; i++) { + for (RSRP_report_t *i = sinr_report->r; i < sinr_report->r + sinr_report->nb; i++) { int bitlen = csi_report->CSI_report_bitlen.cri_ssbri_bitlen; curr_payload = pickandreverse_bits(payload, bitlen, *cumul_bits); - sinr_report->resource_id[i] = *(index_list[bitlen > 0 ? ((curr_payload) & ~(~1U << (bitlen - 1))) : bitlen]); - LOG_D(MAC, "SSB/CSI-RS index = %d\n", sinr_report->resource_id[i]); + i->resource_id = *(index_list[bitlen > 0 ? (curr_payload & ~(~1U << (bitlen - 1))) : bitlen]); + LOG_D(MAC, "SSB/CSI-RS index = %d\n", i->resource_id); *cumul_bits += bitlen; } @@ -525,29 +525,29 @@ static void evaluate_sinr_report(gNB_MAC_INST *nrmac, *cumul_bits += 7; csi_report->nb_of_csi_ssb_report++; - int SINRx10 = get_measured_sinr(sinr_index); + const int SINRx10 = get_measured_sinr(sinr_index); if (SINRx10 == INT_MAX) { LOG_E(NR_MAC, "UE %04x: reported SINR index %d invalid\n", UE->rnti, sinr_index); return; } - sinr_report->SINRx10[0] = SINRx10; + sinr_report->r[0].SINRx10 = SINRx10; - for (int i = 1; i < sinr_report->nr_reports; i++) { + for (RSRP_report_t *i = sinr_report->r + 1; i < sinr_report->r + sinr_report->nb; i++) { curr_payload = pickandreverse_bits(payload, 4, *cumul_bits); - sinr_report->SINRx10[i] = get_diff_sinr(curr_payload & 0x0f, sinr_report->SINRx10[0]); + i->SINRx10 = get_diff_sinr(curr_payload & 0x0f, SINRx10); *cumul_bits += 4; } NR_mac_stats_t *stats = &UE->mac_stats; // including ssb SINR in mac stats - stats->cumul_sinrx10 += sinr_report->SINRx10[0]; + stats->cumul_sinrx10 += sinr_report->r[0].SINRx10; stats->num_sinr_meas++; const int mcs_table = UE->current_DL_BWP.mcsTableIdx; const int nrOfLayers = get_dl_nrOfLayers(sched_ctrl, UE->current_DL_BWP.dci_format); - sched_ctrl->dl_max_mcs = get_mcs_from_SINRx10(mcs_table, sinr_report->SINRx10[0], nrOfLayers); + sched_ctrl->dl_max_mcs = get_mcs_from_SINRx10(mcs_table, sinr_report->r[0].SINRx10, nrOfLayers); - LOG_D(MAC, "Reported SSB-SINR = %d.%d, dl_max_mcs %d\n", sinr_report->SINRx10[0] / 10, sinr_report->SINRx10[0] % 10, sched_ctrl->dl_max_mcs); + LOG_D(MAC, "Reported SSB-SINR = %01f, dl_max_mcs %d\n", sinr_report->r[0].SINRx10 / 10.0, sched_ctrl->dl_max_mcs); } static void evaluate_rsrp_report(gNB_MAC_INST *nrmac, @@ -576,7 +576,7 @@ static void evaluate_rsrp_report(gNB_MAC_INST *nrmac, multiple simultaneous spatial domain receive filter */ nr_csi_report_t *csi_report = &UE->csi_report_template[csi_report_id]; - RSRP_report_t *rsrp_report; + RSRP_report_list_t *rsrp_report; long **index_list; switch (reportQuantity_type) { case NR_CSI_ReportConfig__reportQuantity_PR_ssb_Index_RSRP: @@ -591,11 +591,11 @@ static void evaluate_rsrp_report(gNB_MAC_INST *nrmac, AssertFatal(false, "Invalid RSRP report type\n"); } - rsrp_report->nr_reports = csi_report->CSI_report_bitlen.nb_ssbri_cri; + rsrp_report->nb = csi_report->CSI_report_bitlen.nb_ssbri_cri; int bitlen = csi_report->CSI_report_bitlen.cri_ssbri_bitlen; - for (int i = 0; i < rsrp_report->nr_reports; i++) { + for (RSRP_report_t *i = rsrp_report->r; i < rsrp_report->r + rsrp_report->nb; i++) { uint8_t idx_payload = pickandreverse_bits(payload, bitlen, *cumul_bits); - rsrp_report->resource_id[i] = *(index_list[bitlen > 0 ? ((idx_payload) & ~(~1U << (bitlen - 1))) : bitlen]); + i->resource_id = *(index_list[bitlen > 0 ? (idx_payload & ~(~1U << (bitlen - 1))) : bitlen]); *cumul_bits += bitlen; } @@ -603,24 +603,24 @@ static void evaluate_rsrp_report(gNB_MAC_INST *nrmac, int rsrp = curr_payload & 0x7f; *cumul_bits += 7; csi_report->nb_of_csi_ssb_report++; - bool valid = get_measured_rsrp(rsrp, &rsrp_report->RSRP[0]); - LOG_D(NR_MAC, "SSB/CSI-RS index %d RSRP %d\n", rsrp_report->resource_id[0], rsrp_report->RSRP[0]); + bool valid = get_measured_rsrp(rsrp, &rsrp_report->r[0].RSRP); + LOG_D(NR_MAC, "SSB/CSI-RS index %d RSRP %d\n", rsrp_report->r[0].resource_id, rsrp_report->r[0].RSRP); if (!valid) { - LOG_E(NR_MAC, "UE %04x: reported RSRP index %d invalid\n", UE->rnti, rsrp); + LOG_E(NR_MAC, "UE %04x: reported RSRP out of 5G usable range %d dBm\n", UE->rnti, rsrp_report->r[0].RSRP); return; } - for (int i = 1; i < rsrp_report->nr_reports; i++) { + for (RSRP_report_t *i = rsrp_report->r + 1; i < rsrp_report->r + rsrp_report->nb; i++) { curr_payload = pickandreverse_bits(payload, 4, *cumul_bits); csi_report->nb_of_csi_ssb_report++; - rsrp_report->RSRP[i] = get_diff_rsrp(curr_payload & 0x0f, rsrp_report->RSRP[0]); - LOG_D(NR_MAC, "SSB/CSI-RS index %d RSRP %d\n", rsrp_report->resource_id[i], rsrp_report->RSRP[i]); + i->RSRP = get_diff_rsrp(curr_payload & 0x0f, rsrp_report->r[0].RSRP); + LOG_D(NR_MAC, "SSB/CSI-RS index %d RSRP %d\n", i->resource_id, i->RSRP); *cumul_bits += 4; } NR_mac_stats_t *stats = &UE->mac_stats; // including ssb rsrp in mac stats - stats->cumul_rsrp += rsrp_report->RSRP[0]; + stats->cumul_rsrp += rsrp_report->r[0].RSRP; stats->num_rsrp_meas++; } diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h index e620e2f37d..40ed4c6a50 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h +++ b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h @@ -552,18 +552,22 @@ struct CRI_RI_LI_PMI_CQI { bool print_report; }; -typedef struct RSRP_report { - uint8_t nr_reports; - uint8_t resource_id[MAX_NR_OF_REPORTED_RS]; - int RSRP[MAX_NR_OF_REPORTED_RS]; - int SINRx10[MAX_NR_OF_REPORTED_RS]; +typedef struct { + uint8_t resource_id; + int RSRP; + int SINRx10; } RSRP_report_t; -struct CSI_Report { +typedef struct { + int nb; + RSRP_report_t r[MAX_NR_OF_REPORTED_RS]; +} RSRP_report_list_t; + +typedef struct CSI_Report { struct CRI_RI_LI_PMI_CQI cri_ri_li_pmi_cqi_report; - RSRP_report_t ssb_rsrp_report; - RSRP_report_t csirs_rsrp_report; -}; + RSRP_report_list_t ssb_rsrp_report; + RSRP_report_list_t csirs_rsrp_report; +} CSI_report_t; typedef enum { INACTIVE = 0, @@ -661,7 +665,7 @@ typedef struct { bool ul_failure; int ul_failure_timer; int release_timer; - struct CSI_Report CSI_report; + CSI_report_t CSI_report; bool SR; /// information about every HARQ process NR_UE_harq_t harq_processes[NR_MAX_HARQ_PROCESSES]; From 59aed14153d13c6ba22abb39dfa63e15e963c2a6 Mon Sep 17 00:00:00 2001 From: Laurent THOMAS Date: Wed, 21 Jan 2026 14:10:24 +0100 Subject: [PATCH 17/83] print better message for rsrp: invalid doesn't mean it is not measures, it means it is out of usable range --- .../LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c | 37 ++----------------- 1 file changed, 4 insertions(+), 33 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c index 32f2a2e669..65de51e0ba 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c @@ -98,28 +98,6 @@ static void nr_fill_nfapi_pucch(gNB_MAC_INST *nrmac, frame_t frame, slot_t slot, nrmac->beam_info.beam_mode); } -#define MIN_RSRP_VALUE -141 -#define MAX_RSRP_VALUE -43 - -//Measured RSRP Values Table 10.1.16.1-1 from 38.133 -//Stored all the upper limits[Max RSRP Value of corresponding index] -//stored -1 for invalid values -static const int L1_SSB_CSI_RSRP_measReport_mapping_38133_10_1_6_1_1[128] = { - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 0 - 9 - -1, -1, -1, -1, -1, -1, MIN_RSRP_VALUE, -140, -139, -138, // 10 - 19 - -137, -136, -135, -134, -133, -132, -131, -130, -129, -128, // 20 - 29 - -127, -126, -125, -124, -123, -122, -121, -120, -119, -118, // 30 - 39 - -117, -116, -115, -114, -113, -112, -111, -110, -109, -108, // 40 - 49 - -107, -106, -105, -104, -103, -102, -101, -100, -99, -98, // 50 - 59 - -97, -96, -95, -94, -93, -92, -91, -90, -89, -88, // 60 - 69 - -87, -86, -85, -84, -83, -82, -81, -80, -79, -78, // 70 - 79 - -77, -76, -75, -74, -73, -72, -71, -70, -69, -68, // 80 - 89 - -67, -66, -65, -64, -63, -62, -61, -60, -59, -58, // 90 - 99 - -57, -56, -55, -54, -53, -52, -51, -50, -49, -48, // 100 - 109 - -47, -46, -45, -44, MAX_RSRP_VALUE, -1, -1, -1, -1, -1, // 110 - 119 - -1, -1, -1, -1, -1, -1, -1, -1 // 120 - 127 -}; - //Differential RSRP values Table 10.1.6.1-2 from 38.133 //Stored the upper limits[MAX RSRP Value] static const int diff_rsrp_ssb_csi_meas_10_1_6_1_2[16] = { @@ -440,23 +418,16 @@ static int get_diff_sinr(int index, int best_SINRx10) //returns the measured RSRP value (upper limit) static bool get_measured_rsrp(uint8_t index, int *rsrp) { - //if index is invalid returning minimum rsrp -140 - if (index <= 15) + *rsrp = -156 + index; + if (index < 16 || index > 113) return false; - if (index >= 114) - return false; - - *rsrp = L1_SSB_CSI_RSRP_measReport_mapping_38133_10_1_6_1_1[index]; return true; } //returns the differential RSRP value (upper limit) static int get_diff_rsrp(uint8_t index, int strongest_rsrp) { - if(strongest_rsrp != -1) - return strongest_rsrp + diff_rsrp_ssb_csi_meas_10_1_6_1_2[index]; - else - return MIN_RSRP_VALUE; + return strongest_rsrp + diff_rsrp_ssb_csi_meas_10_1_6_1_2[index]; } static uint8_t pickandreverse_bits(uint8_t *payload, uint16_t bitlen, uint8_t start_bit) @@ -606,7 +577,7 @@ static void evaluate_rsrp_report(gNB_MAC_INST *nrmac, bool valid = get_measured_rsrp(rsrp, &rsrp_report->r[0].RSRP); LOG_D(NR_MAC, "SSB/CSI-RS index %d RSRP %d\n", rsrp_report->r[0].resource_id, rsrp_report->r[0].RSRP); if (!valid) { - LOG_E(NR_MAC, "UE %04x: reported RSRP out of 5G usable range %d dBm\n", UE->rnti, rsrp_report->r[0].RSRP); + LOG_I(NR_MAC, "UE %04x: reported RSRP out of 5G usable range %d dBm\n", UE->rnti, rsrp_report->r[0].RSRP); return; } From 5fb9a9c66537a1e991a90df19e0dff998dc640b5 Mon Sep 17 00:00:00 2001 From: Nika Ghaderi Date: Tue, 23 Sep 2025 10:31:57 +0000 Subject: [PATCH 18/83] Integrate CUDA Channel Pipeline into DL Simulator This commit integrates the CUDA-based channel simulation pipeline into the nr_dlsim. A new `--cuda` command-line flag is added to enable the GPU path at runtime. When activated, the simulator will: - Allocate all necessary GPU and pinned host memory via the new `init_cuda_chsim_buffers` helper function. - In the main simulation loop, call the `run_channel_pipeline_cuda` function to perform the channel simulation on the GPU, bypassing the CPU-based functions. - Clean up all CUDA resources on exit using the `free_cuda_chsim_buffers` helper. Additionally, dlsim is now using the float version of channel_multipath and add_noise functions. Also, The input data is formatted as interleaved IQ, with separate antennas to ensure a fair comparison with the GPU operation. --- openair1/SIMULATION/NR_PHY/dlsim.c | 223 +++++++++++++++--- openair1/SIMULATION/TOOLS/channel_pipeline.cu | 147 ++++++++++++ openair1/SIMULATION/TOOLS/oai_cuda.h | 21 ++ 3 files changed, 355 insertions(+), 36 deletions(-) diff --git a/openair1/SIMULATION/NR_PHY/dlsim.c b/openair1/SIMULATION/NR_PHY/dlsim.c index f1461bc25d..75cebba300 100644 --- a/openair1/SIMULATION/NR_PHY/dlsim.c +++ b/openair1/SIMULATION/NR_PHY/dlsim.c @@ -90,6 +90,11 @@ #define inMicroS(a) (((double)(a))/(get_cpu_freq_GHz()*1000.0)) #include "SIMULATION/LTE_PHY/common_sim.h" +#ifdef ENABLE_CUDA +#include +#include "SIMULATION/TOOLS/oai_cuda.h" +#endif + const char *__asan_default_options() { /* don't do leak checking in nr_ulsim, not finished yet */ @@ -327,7 +332,7 @@ int main(int argc, char **argv) double eff_tp_check = 0.7; uint32_t TBS = 0; c16_t **txdata; - double **s_re,**s_im,**r_re,**r_im; + float **s_interleaved, **r_re, **r_im; //double iqim = 0.0; //unsigned char pbch_pdu[6]; // int sync_pos, sync_pos_slot; @@ -404,8 +409,26 @@ int main(int argc, char **argv) FILE *scg_fd=NULL; - while ((c = getopt(argc, argv, "--:O:f:hA:p:f:g:i:n:s:S:t:v:x:y:z:o:H:M:N:F:GR:d:PI:L:a:b:e:m:w:T:U:q:X:Y:Z:")) != -1) { + int use_cuda = 0; + void *h_tx_sig_pinned = NULL; + +#ifdef ENABLE_CUDA + void *d_tx_sig = NULL, *d_intermediate_sig = NULL, *d_final_output = NULL; + void *d_curand_states = NULL; + void *h_final_output_pinned = NULL; + void *d_channel_coeffs_gpu = NULL; +#endif + + static struct option long_options[] = {{"cuda", no_argument, 0, 0}, {0, 0, 0, 0}}; + int option_index = 0; + + while ((c = getopt_long(argc, + argv, + "O:f:hA:p:g:i:n:s:S:t:v:x:y:z:o:H:M:N:F:GR:d:PI:L:a:b:e:m:w:T:U:q:X:Y:Z:", + long_options, + &option_index)) + != -1) { /* ignore long options starting with '--', option '-O' and their arguments that are handled by configmodule */ /* with this opstring getopt returns 1 for non-option arguments, refer to 'man 3 getopt' */ if (c == 1 || c == '-' || c == 'O') @@ -413,6 +436,14 @@ int main(int argc, char **argv) printf("handling optarg %c\n",c); switch (c) { + #ifdef ENABLE_CUDA + case 0: + if (strcmp(long_options[option_index].name, "cuda") == 0) { + use_cuda = 1; + } + #endif + break; + case 'f': scg_fd = fopen(optarg,"r"); @@ -664,6 +695,31 @@ int main(int argc, char **argv) /* initialize the sin table */ InitSinLUT(); +#ifdef ENABLE_CUDA + init_cuda_chsim_buffers(use_cuda, + n_tx, + n_rx, + &d_tx_sig, + &d_intermediate_sig, + &d_final_output, + &d_curand_states, + &h_tx_sig_pinned, + &h_final_output_pinned, + &d_channel_coeffs_gpu); +#endif + +#if !defined(ENABLE_CUDA) || !use_cuda + printf("Pre-allocating padded host memory for the CPU channel pipeline...\n"); + int num_samples_alloc = 153600; + const int max_padding_alloc = 256 - 1; + size_t padded_tx_alloc_bytes = n_tx * (num_samples_alloc + max_padding_alloc) * 2 * sizeof(float); + h_tx_sig_pinned = malloc(padded_tx_alloc_bytes); + if (h_tx_sig_pinned == NULL) { + printf("Error: Failed to allocate host buffer for CPU path\n"); + exit(-1); + } +#endif + get_softmodem_params()->phy_test = 1; get_softmodem_params()->do_ra = 0; IS_SOFTMODEM_DLSIM = true; @@ -873,6 +929,11 @@ int main(int argc, char **argv) 0, 0); + float *h_channel_coeffs = NULL; + if (use_cuda) { + int num_links = n_tx * n_rx; + h_channel_coeffs = (float *)malloc(num_links * gNB2UE->channel_length * sizeof(float) * 2); + } if (gNB2UE==NULL) { printf("Problem generating channel model. Exiting.\n"); exit(-1); @@ -883,23 +944,20 @@ int main(int argc, char **argv) int slot_offset = get_samples_slot_timestamp(frame_parms, slot); int slot_length = slot_offset - get_samples_slot_timestamp(frame_parms, slot - 1); - s_re = malloc(n_tx*sizeof(double*)); - s_im = malloc(n_tx*sizeof(double*)); - r_re = malloc(n_rx*sizeof(double*)); - r_im = malloc(n_rx*sizeof(double*)); - txdata = malloc(n_tx*sizeof(int*)); + s_interleaved = malloc(n_tx * sizeof(float *)); + r_re = malloc(n_rx * sizeof(float *)); + r_im = malloc(n_rx * sizeof(float *)); + txdata = malloc(n_tx * sizeof(int *)); for (i = 0; i < n_tx; i++) { - s_re[i] = calloc(1, slot_length * sizeof(double)); - s_im[i] = calloc(1, slot_length * sizeof(double)); - + s_interleaved[i] = malloc(slot_length * 2 * sizeof(float)); printf("Allocating %d samples for txdata\n", frame_length_complex_samples); txdata[i] = calloc(1, frame_length_complex_samples * sizeof(int)); } for (i = 0; i < n_rx; i++) { - r_re[i] = calloc(1, slot_length * sizeof(double)); - r_im[i] = calloc(1, slot_length * sizeof(double)); + r_re[i] = calloc(1, slot_length * sizeof(float)); + r_im[i] = calloc(1, slot_length * sizeof(float)); } if (pbch_file_fd!=NULL) { @@ -997,8 +1055,7 @@ int main(int argc, char **argv) csv_file = fopen(filename_csv, "a"); if (csv_file == NULL) { printf("Can't open file \"%s\", errno %d\n", filename_csv, errno); - free(s_re); - free(s_im); + free(s_interleaved); free(r_re); free(r_im); free(txdata); @@ -1018,6 +1075,10 @@ int main(int argc, char **argv) exit(1); } + time_stats_t channel_stats = {0}; + time_stats_t noise_stats = {0}; + time_stats_t pipeline_stats = {0}; + for (SNR = snr0; SNR < snr1 && !stop; SNR += .2) { varArray_t *table_tx=initVarArray(1000,sizeof(double)); @@ -1172,10 +1233,10 @@ int main(int argc, char **argv) int symbol_length = frame_parms->ofdm_symbol_size + frame_parms->nb_prefix_samples; double txlev_sum = compute_tx_energy_level(txdata, n_tx, symbol_offset, symbol_length, n_trials); - for (i = 0; i < slot_length; i++) { - for (aa=0; aanb_antennas_tx; aa++) { - s_re[aa][i] = ((double)(((short *)&txdata[aa][slot_offset]))[(i << 1)]); - s_im[aa][i] = ((double)(((short *)&txdata[aa][slot_offset]))[(i << 1) + 1]); + for (int aa = 0; aa < frame_parms->nb_antennas_tx; aa++) { + for (int i = 0; i < slot_length; i++) { + s_interleaved[aa][2 * i] = (float)((short *)&txdata[aa][slot_offset])[2 * i]; + s_interleaved[aa][2 * i + 1] = (float)((short *)&txdata[aa][slot_offset])[2 * i + 1]; } } @@ -1184,25 +1245,98 @@ int main(int argc, char **argv) // Estimate noise power from the transmitter level and SNR double sigma2 = compute_noise_variance(txlev_sum, UE->frame_parms.ofdm_symbol_size, pdsch_pdu_rel15->rbSize, 1, SNR, n_trials); + const int padding_len = gNB2UE->channel_length - 1; + const int padded_slot_length = slot_length + padding_len; + float *h_tx_ptr = (float *)h_tx_sig_pinned; + size_t total_padded_bytes_for_slot = n_tx * padded_slot_length * 2 * sizeof(float); + memset(h_tx_ptr, 0, total_padded_bytes_for_slot); + + for (int j = 0; j < n_tx; j++) { + float *data_start_ptr = h_tx_ptr + (j * padded_slot_length + padding_len) * 2; + memcpy(data_start_ptr, s_interleaved[j], slot_length * 2 * sizeof(float)); + } for (aa = 0; aa < n_rx; aa++) { - bzero(r_re[aa], slot_length * sizeof(double)); - bzero(r_im[aa], slot_length * sizeof(double)); + bzero(r_re[aa], slot_length * sizeof(float)); + bzero(r_im[aa], slot_length * sizeof(float)); } // Apply MIMO Channel - multipath_channel(gNB2UE, s_re, s_im, r_re, r_im, slot_length, 0, (n_trials == 1) ? 1 : 0); - add_noise(UE->common_vars.rxdata, - (const double **)r_re, - (const double **)r_im, - sigma2, - slot_length, - slot_offset, - ts, - delay, - pdu_bit_map, - 0x1, - UE->frame_parms.nb_antennas_rx); +#ifdef ENABLE_CUDA + if (use_cuda) { +#if defined(USE_UNIFIED_MEMORY) + int deviceId; + cudaGetDevice(&deviceId); + cudaMemPrefetchAsync(d_tx_sig, n_tx * padded_slot_length * sizeof(float) * 2, deviceId, 0); +#endif + start_meas(&pipeline_stats); + random_channel(gNB2UE, 0); + int num_links = gNB2UE->nb_tx * gNB2UE->nb_rx; + for (int link = 0; link < num_links; link++) { + for (int l = 0; l < gNB2UE->channel_length; l++) { + int idx = link * gNB2UE->channel_length + l; + ((float2 *)h_channel_coeffs)[idx].x = (float)gNB2UE->ch[link][l].r; + ((float2 *)h_channel_coeffs)[idx].y = (float)gNB2UE->ch[link][l].i; + } + } + run_channel_pipeline_cuda(UE->common_vars.rxdata, + n_tx, + n_rx, + gNB2UE->channel_length, + slot_length, + h_channel_coeffs, + (float)sigma2, + ts, + pdu_bit_map, + 0x1, + slot_offset, + delay, + d_tx_sig, + d_intermediate_sig, + d_final_output, + d_curand_states, + h_tx_sig_pinned, + h_final_output_pinned, + d_channel_coeffs_gpu); + cudaDeviceSynchronize(); + stop_meas(&pipeline_stats); + } else +#endif + { + float **tx_sig_for_cpu = malloc(n_tx * sizeof(float *)); + float *h_tx_ptr = (float *)h_tx_sig_pinned; + const int padding_len = gNB2UE->channel_length - 1; + const int padded_slot_length = slot_length + padding_len; + + for (int j = 0; j < n_tx; j++) { + tx_sig_for_cpu[j] = h_tx_ptr + (j * padded_slot_length + padding_len) * 2; + } + + for (aa = 0; aa < n_rx; aa++) { + bzero(r_re[aa], slot_length * sizeof(float)); + bzero(r_im[aa], slot_length * sizeof(float)); + } + start_meas(&channel_stats); + multipath_channel_float(gNB2UE, tx_sig_for_cpu, r_re, r_im, slot_length, 0, (n_trials == 1) ? 1 : 0); + stop_meas(&channel_stats); + + free(tx_sig_for_cpu); + + bool apply_phase_noise = (pdu_bit_map & 0x1); + start_meas(&noise_stats); + add_noise_float(UE->common_vars.rxdata, + (const float **)r_re, + (const float **)r_im, + (float)sigma2, + slot_length, + slot_offset, + ts, + delay, + apply_phase_noise, + UE->frame_parms.nb_antennas_rx); + stop_meas(&noise_stats); + } + dl_config.sfn = frame; dl_config.slot = slot; ue_dci_configuration(UE_mac, &dl_config, frame, slot); @@ -1342,6 +1476,13 @@ int main(int argc, char **argv) if (gNB->phase_comp) printStatIndent2(&gNB->phase_comp_stats, "Phase Compensation"); + if (use_cuda) { + printStatIndent(&pipeline_stats, "GPU Channel Pipeline"); + } else { + printStatIndent(&channel_stats, "Multipath Channel (CPU)"); + printStatIndent(&noise_stats, "Add Noise (CPU)"); + } + printf("\nUE function statistics (per %d us slot)\n", 1000 >> *scc->ssbSubcarrierSpacing); for (int i = RX_PDSCH_STATS; i <= DLSCH_PROCEDURES_STATS; i++) { printStatIndent(&UE->phy_cpu_stats.cpu_time_stats[i], UE->phy_cpu_stats.cpu_time_stats[i].meas_name); @@ -1412,8 +1553,7 @@ int main(int argc, char **argv) free_channel_desc_scm(gNB2UE); for (i = 0; i < n_tx; i++) { - free(s_re[i]); - free(s_im[i]); + free(s_interleaved[i]); free(txdata[i]); } for (i = 0; i < n_rx; i++) { @@ -1421,8 +1561,19 @@ int main(int argc, char **argv) free(r_im[i]); } - free(s_re); - free(s_im); +#ifdef ENABLE_CUDA + free_cuda_chsim_buffers(use_cuda, + &d_tx_sig, + &d_intermediate_sig, + &d_final_output, + &d_curand_states, + &h_tx_sig_pinned, + &h_final_output_pinned, + &h_channel_coeffs, + &d_channel_coeffs_gpu); +#endif + + free(s_interleaved); free(r_re); free(r_im); free(txdata); diff --git a/openair1/SIMULATION/TOOLS/channel_pipeline.cu b/openair1/SIMULATION/TOOLS/channel_pipeline.cu index 81c9ba0734..a01d7e1ad9 100644 --- a/openair1/SIMULATION/TOOLS/channel_pipeline.cu +++ b/openair1/SIMULATION/TOOLS/channel_pipeline.cu @@ -77,6 +77,153 @@ __global__ void sum_outputs_kernel(const short2 *__restrict__ *__restrict__ indi } extern "C" { + +void init_cuda_chsim_buffers(int use_cuda, + int n_tx, + int n_rx, + void **d_tx_sig, + void **d_intermediate_sig, + void **d_final_output, + void **d_curand_states, + void **h_tx_sig_pinned, + void **h_final_output_pinned, + void **d_channel_coeffs_gpu) +{ + if (use_cuda) { + int num_samples_alloc = 153600; + +#if defined(USE_UNIFIED_MEMORY) + printf("Allocating CUDA Unified Memory...\n"); + const int max_padding_alloc = 256 - 1; + size_t padded_tx_alloc_bytes = n_tx * (num_samples_alloc + max_padding_alloc) * 2 * sizeof(float); + CHECK_CUDA(cudaMallocManaged(d_tx_sig, padded_tx_alloc_bytes, cudaMemAttachGlobal)); + CHECK_CUDA(cudaMallocManaged(d_intermediate_sig, n_rx * num_samples_alloc * sizeof(float) * 2, cudaMemAttachGlobal)); + CHECK_CUDA(cudaMallocManaged(d_final_output, n_rx * num_samples_alloc * sizeof(short) * 2, cudaMemAttachGlobal)); + *h_tx_sig_pinned = *d_tx_sig; + *h_final_output_pinned = *d_final_output; + int deviceId; + CHECK_CUDA(cudaGetDevice(&deviceId)); + CHECK_CUDA(cudaMemAdvise(*d_tx_sig, padded_tx_alloc_bytes, cudaMemAdviseSetReadMostly, deviceId)); + CHECK_CUDA(cudaMemAdvise(*d_intermediate_sig, + n_rx * num_samples_alloc * sizeof(float) * 2, + cudaMemAdviseSetPreferredLocation, + deviceId)); + CHECK_CUDA( + cudaMemAdvise(*d_final_output, n_rx * num_samples_alloc * sizeof(short) * 2, cudaMemAdviseSetPreferredLocation, deviceId)); + CHECK_CUDA( + cudaMemAdvise(*d_final_output, n_rx * num_samples_alloc * sizeof(short) * 2, cudaMemAdviseSetAccessedBy, cudaCpuDeviceId)); + +#elif defined(USE_ATS_MEMORY) + printf("Allocating memory for ATS Hybrid path...\n"); + const int max_padding_alloc = 256 - 1; + size_t padded_tx_alloc_bytes = n_tx * (num_samples_alloc + max_padding_alloc) * 2 * sizeof(float); + *h_tx_sig_pinned = malloc(padded_tx_alloc_bytes); + CHECK_CUDA(cudaMalloc(d_intermediate_sig, n_rx * num_samples_alloc * sizeof(float) * 2)); + CHECK_CUDA(cudaMalloc(d_final_output, n_rx * num_samples_alloc * sizeof(short) * 2)); + *h_final_output_pinned = malloc(n_rx * num_samples_alloc * sizeof(short) * 2); + *d_tx_sig = NULL; +#else // Explicit copy method + printf("Pre-allocating GPU & Pinned memory for the channel pipeline...\n"); + const int max_padding_alloc = 256 - 1; + size_t padded_tx_alloc_bytes = n_tx * (num_samples_alloc + max_padding_alloc) * 2 * sizeof(float); + CHECK_CUDA(cudaMalloc(d_tx_sig, padded_tx_alloc_bytes)); + CHECK_CUDA(cudaMalloc(d_intermediate_sig, n_rx * num_samples_alloc * sizeof(float) * 2)); + CHECK_CUDA(cudaMalloc(d_final_output, n_rx * num_samples_alloc * sizeof(short) * 2)); + CHECK_CUDA(cudaMallocHost(h_tx_sig_pinned, padded_tx_alloc_bytes)); + CHECK_CUDA(cudaMallocHost(h_final_output_pinned, n_rx * num_samples_alloc * sizeof(short) * 2)); +#endif + const int max_taps_alloc = 256; // Upper bound for channel length + size_t channel_buffer_size = n_tx * n_rx * max_taps_alloc * sizeof(float) * 2; + CHECK_CUDA(cudaMalloc(d_channel_coeffs_gpu, channel_buffer_size)); + int num_rand_elements = n_rx * num_samples_alloc; + *d_curand_states = create_and_init_curand_states_cuda(num_rand_elements, time(NULL)); + } +} + +void free_cuda_chsim_buffers(int use_cuda, + void **d_tx_sig_p, + void **d_intermediate_sig_p, + void **d_final_output_p, + void **d_curand_states_p, + void **h_tx_sig_pinned_p, + void **h_final_output_pinned_p, + float **h_channel_coeffs_p, + void **d_channel_coeffs_gpu_p) +{ + if (use_cuda) { + printf("Freeing GPU and Pinned memory...\n"); +#if defined(USE_UNIFIED_MEMORY) + if (*d_tx_sig_p) { + cudaFree(*d_tx_sig_p); + *d_tx_sig_p = NULL; + *h_tx_sig_pinned_p = NULL; + } + if (*d_intermediate_sig_p) { + cudaFree(*d_intermediate_sig_p); + *d_intermediate_sig_p = NULL; + } + if (*d_final_output_p) { + cudaFree(*d_final_output_p); + *d_final_output_p = NULL; + *h_final_output_pinned_p = NULL; + } +#elif defined(USE_ATS_MEMORY) + if (*h_tx_sig_pinned_p) { + free(*h_tx_sig_pinned_p); + *h_tx_sig_pinned_p = NULL; + } + if (*d_intermediate_sig_p) { + cudaFree(*d_intermediate_sig_p); + *d_intermediate_sig_p = NULL; + } + if (*d_final_output_p) { + cudaFree(*d_final_output_p); + *d_final_output_p = NULL; + } + if (*h_final_output_pinned_p) { + free(*h_final_output_pinned_p); + *h_final_output_pinned_p = NULL; + } +#else + if (*d_tx_sig_p) { + cudaFree(*d_tx_sig_p); + *d_tx_sig_p = NULL; + } + if (*d_intermediate_sig_p) { + cudaFree(*d_intermediate_sig_p); + *d_intermediate_sig_p = NULL; + } + if (*d_final_output_p) { + cudaFree(*d_final_output_p); + *d_final_output_p = NULL; + } + if (*h_tx_sig_pinned_p) { + cudaFreeHost(*h_tx_sig_pinned_p); + *h_tx_sig_pinned_p = NULL; + } + if (*h_final_output_pinned_p) { + cudaFreeHost(*h_final_output_pinned_p); + *h_final_output_pinned_p = NULL; + } +#endif + if (*d_channel_coeffs_gpu_p) { + cudaFree(*d_channel_coeffs_gpu_p); + *d_channel_coeffs_gpu_p = NULL; + } + destroy_curand_states_cuda(*d_curand_states_p); + *d_curand_states_p = NULL; + if (*h_channel_coeffs_p) { + free(*h_channel_coeffs_p); + *h_channel_coeffs_p = NULL; + } + } else { + if (*h_tx_sig_pinned_p) { + free(*h_tx_sig_pinned_p); + *h_tx_sig_pinned_p = NULL; + } + } +} + void run_channel_pipeline_cuda(c16_t **output_signal, int nb_tx, int nb_rx, diff --git a/openair1/SIMULATION/TOOLS/oai_cuda.h b/openair1/SIMULATION/TOOLS/oai_cuda.h index 1b3f3d0ae1..91e546d4e8 100644 --- a/openair1/SIMULATION/TOOLS/oai_cuda.h +++ b/openair1/SIMULATION/TOOLS/oai_cuda.h @@ -59,6 +59,27 @@ __global__ void add_noise_and_phase_noise_kernel(const float2 *__restrict__ r_si extern "C" { #endif +void init_cuda_chsim_buffers(int use_cuda, + int n_tx, + int n_rx, + void **d_tx_sig_p, + void **d_intermediate_sig_p, + void **d_final_output_p, + void **d_curand_states_p, + void **h_tx_sig_pinned_p, + void **h_final_output_pinned_p, + void **d_channel_coeffs_gpu_p); + +void free_cuda_chsim_buffers(int use_cuda, + void **d_tx_sig_p, + void **d_intermediate_sig_p, + void **d_final_output_p, + void **d_curand_states_p, + void **h_tx_sig_pinned_p, + void **h_final_output_pinned_p, + float **h_channel_coeffs_p, + void **d_channel_coeffs_gpu_p); + void multipath_channel_cuda(float **rx_sig_re, float **rx_sig_im, int nb_tx, From 0a9c3a07eb8de3ce841f52ec7bf4c4c81150250e Mon Sep 17 00:00:00 2001 From: Shubhika Garg Date: Thu, 5 Feb 2026 15:30:34 +0100 Subject: [PATCH 19/83] ci: Pull `ubuntu:noble` image from our internal docker registry to build ubuntu images - This is to overcome the issue of pull rate limits from DockerHub - Make Ubuntu base image configurable via build-arg --- ci-scripts/cls_containerize.py | 10 ++++++++-- docker/Dockerfile.base.ubuntu | 4 +++- docker/Dockerfile.base.ubuntu.cross-arm64 | 3 ++- docker/Dockerfile.eNB.ubuntu | 4 +++- docker/Dockerfile.gNB.aerial.ubuntu | 3 ++- docker/Dockerfile.gNB.aerial.ubuntu.sanitize-address | 4 +++- docker/Dockerfile.gNB.aw2s.ubuntu | 3 ++- docker/Dockerfile.gNB.fhi72.ubuntu | 3 ++- docker/Dockerfile.gNB.ubuntu | 3 ++- docker/Dockerfile.lteRU.ubuntu | 3 ++- docker/Dockerfile.lteUE.ubuntu | 6 ++++-- docker/Dockerfile.nr-cuup.ubuntu | 5 +++-- docker/Dockerfile.nrORU.fhi72.ubuntu | 5 +++-- docker/Dockerfile.nrUE.ubuntu | 3 ++- 14 files changed, 41 insertions(+), 18 deletions(-) diff --git a/ci-scripts/cls_containerize.py b/ci-scripts/cls_containerize.py index 7826a32a61..ac76f3083b 100644 --- a/ci-scripts/cls_containerize.py +++ b/ci-scripts/cls_containerize.py @@ -372,12 +372,16 @@ class Containerize(): for image,pattern,name,option in imageNames: cmd.run(f"{self.cli} image rm {name}:{imageTag}", reportNonZero=False) + cmd.run(f'docker login -u oaicicd -p oaicicd {DEFAULT_REGISTRY}') + ubuntuImage = "ubuntu:noble" # Build the base image only on Push Events (not on Merge Requests) # On when the base image docker file is being modified. if forceBaseImageBuild: cmd.run(f"{self.cli} image rm {baseImage}:{baseTag}") logfile = f'{lSourcePath}/cmake_targets/log/ran-base.docker.log' - cmd.run(f"{self.cli} build {self.cliBuildOptions} --target {baseImage} --tag {baseImage}:{baseTag} --file docker/Dockerfile.base{self.dockerfileprefix} . &> {logfile}", timeout=1600) + if self.host == 'Ubuntu': + option = f" --build-arg UBUNTU_IMAGE={DEFAULT_REGISTRY}/{ubuntuImage}" + cmd.run(f"{self.cli} build {self.cliBuildOptions} --target {baseImage} --tag {baseImage}:{baseTag} --file docker/Dockerfile.base{self.dockerfileprefix} {option} . &> {logfile}", timeout=1600) t = ("ran-base", archiveArtifact(cmd, ctx, logfile)) log_files.append(t) @@ -420,6 +424,8 @@ class Containerize(): if image == 'oai-gnb-aerial': cmd.run('cp -f /opt/nvidia-ipc/nvipc_src.2026.01.07.tar.gz .') logfile = f'{lSourcePath}/cmake_targets/log/{name}.docker.log' + if self.host == 'Ubuntu': + option = option + f" --build-arg UBUNTU_IMAGE={DEFAULT_REGISTRY}/{ubuntuImage}" ret = cmd.run(f'{self.cli} build {self.cliBuildOptions} --target {image} --tag {name}:{imageTag} --file docker/Dockerfile.{pattern}{self.dockerfileprefix} {option} . > {logfile} 2>&1', timeout=1200) t = (name, archiveArtifact(cmd, ctx, logfile)) log_files.append(t) @@ -446,7 +452,7 @@ class Containerize(): allImagesSize[name] = 'unknown' # Now pruning dangling images in between target builds cmd.run(f"{self.cli} image prune --force") - + cmd.run(f'docker logout {DEFAULT_REGISTRY}') # Remove all intermediate build images and clean up cmd.run(f"{self.cli} image rm ran-build:{imageTag} ran-build-asan:{imageTag} ran-build-fhi72:{imageTag} || true") cmd.run(f"{self.cli} volume prune --force") diff --git a/docker/Dockerfile.base.ubuntu b/docker/Dockerfile.base.ubuntu index b0eb5c4d32..e13170d303 100644 --- a/docker/Dockerfile.base.ubuntu +++ b/docker/Dockerfile.base.ubuntu @@ -26,7 +26,9 @@ #--------------------------------------------------------------------- -FROM ubuntu:noble AS ran-base +ARG UBUNTU_IMAGE=ubuntu:noble +FROM ${UBUNTU_IMAGE} AS ran-base + ARG NEEDED_GIT_PROXY ARG TARGETARCH ENV DEBIAN_FRONTEND=noninteractive diff --git a/docker/Dockerfile.base.ubuntu.cross-arm64 b/docker/Dockerfile.base.ubuntu.cross-arm64 index fa9918eda8..ba94199d18 100644 --- a/docker/Dockerfile.base.ubuntu.cross-arm64 +++ b/docker/Dockerfile.base.ubuntu.cross-arm64 @@ -26,7 +26,8 @@ #--------------------------------------------------------------------- # Very important, the noble image shall not be using mirrors. A lot of them do NOT support ARM64. -FROM ubuntu:noble AS ran-base +ARG UBUNTU_IMAGE=ubuntu:noble +FROM ${UBUNTU_IMAGE} AS ran-base ENV DEBIAN_FRONTEND=noninteractive ENV TZ=Europe/Paris # Specifying a working version of SIMDE for ARM: diff --git a/docker/Dockerfile.eNB.ubuntu b/docker/Dockerfile.eNB.ubuntu index 6229bf9028..16a1e782a9 100644 --- a/docker/Dockerfile.eNB.ubuntu +++ b/docker/Dockerfile.eNB.ubuntu @@ -24,6 +24,7 @@ # Valid for Ubuntu 24.04 # #--------------------------------------------------------------------- +ARG UBUNTU_IMAGE=ubuntu:noble FROM ran-base:latest AS enb-base @@ -31,7 +32,8 @@ FROM ran-build:latest AS enb-build #start from scratch for target executable -FROM ubuntu:noble AS oai-enb +FROM ${UBUNTU_IMAGE} AS oai-enb + ARG BUILD_OPTION ENV DEBIAN_FRONTEND=noninteractive ENV TZ=Europe/Paris diff --git a/docker/Dockerfile.gNB.aerial.ubuntu b/docker/Dockerfile.gNB.aerial.ubuntu index 980c909c4d..1e2b41a71d 100644 --- a/docker/Dockerfile.gNB.aerial.ubuntu +++ b/docker/Dockerfile.gNB.aerial.ubuntu @@ -25,6 +25,7 @@ # #--------------------------------------------------------------------- +ARG UBUNTU_IMAGE=ubuntu:noble FROM ran-base:latest AS ran-build RUN apt-get update && \ @@ -59,7 +60,7 @@ RUN /bin/sh oaienv && \ #start from scratch for target executable -FROM ubuntu:noble AS oai-gnb-aerial +FROM ${UBUNTU_IMAGE} AS oai-gnb-aerial ENV DEBIAN_FRONTEND=noninteractive ENV TZ=Europe diff --git a/docker/Dockerfile.gNB.aerial.ubuntu.sanitize-address b/docker/Dockerfile.gNB.aerial.ubuntu.sanitize-address index 1792836b85..3357f4aab1 100644 --- a/docker/Dockerfile.gNB.aerial.ubuntu.sanitize-address +++ b/docker/Dockerfile.gNB.aerial.ubuntu.sanitize-address @@ -25,6 +25,8 @@ # #--------------------------------------------------------------------- +ARG UBUNTU_IMAGE=ubuntu:noble + FROM ran-base:latest AS ran-build RUN apt-get update && \ @@ -58,7 +60,7 @@ RUN /bin/sh oaienv && \ #start from scratch for target executable -FROM ubuntu:noble AS oai-gnb-aerial +FROM ${UBUNTU_IMAGE} AS oai-gnb-aerial ENV DEBIAN_FRONTEND=noninteractive ENV TZ=Europe diff --git a/docker/Dockerfile.gNB.aw2s.ubuntu b/docker/Dockerfile.gNB.aw2s.ubuntu index 7826afd794..229c5ac4b9 100644 --- a/docker/Dockerfile.gNB.aw2s.ubuntu +++ b/docker/Dockerfile.gNB.aw2s.ubuntu @@ -25,6 +25,7 @@ # #--------------------------------------------------------------------- +ARG UBUNTU_IMAGE=ubuntu:noble FROM ran-base:latest AS gnb-base FROM ran-build:latest AS gnb-build @@ -38,7 +39,7 @@ RUN /bin/sh oaienv && \ ./build_oai -w AW2SORI -t Ethernet #start from scratch for target executable -FROM ubuntu:noble AS oai-gnb-aw2s +FROM ${UBUNTU_IMAGE} AS oai-gnb-aw2s ENV DEBIAN_FRONTEND=noninteractive ENV TZ=Europe diff --git a/docker/Dockerfile.gNB.fhi72.ubuntu b/docker/Dockerfile.gNB.fhi72.ubuntu index 03e21e4688..6fbf84d460 100644 --- a/docker/Dockerfile.gNB.fhi72.ubuntu +++ b/docker/Dockerfile.gNB.fhi72.ubuntu @@ -24,6 +24,7 @@ # Valid for Ubuntu24.04 # #--------------------------------------------------------------------- +ARG UBUNTU_IMAGE=ubuntu:noble FROM ran-base:latest AS gnb-base @@ -31,7 +32,7 @@ FROM ran-build-fhi72:latest AS gnb-build #start from scratch for target executable -FROM ubuntu:noble AS oai-gnb +FROM ${UBUNTU_IMAGE} AS oai-gnb ARG BUILD_OPTION ENV DEBIAN_FRONTEND=noninteractive ENV TZ=Europe diff --git a/docker/Dockerfile.gNB.ubuntu b/docker/Dockerfile.gNB.ubuntu index 9156ce98c8..ded38324d7 100644 --- a/docker/Dockerfile.gNB.ubuntu +++ b/docker/Dockerfile.gNB.ubuntu @@ -25,13 +25,14 @@ # #--------------------------------------------------------------------- +ARG UBUNTU_IMAGE=ubuntu:noble FROM ran-base:latest AS gnb-base FROM ran-build:latest AS gnb-build #start from scratch for target executable -FROM ubuntu:noble AS oai-gnb +FROM ${UBUNTU_IMAGE} AS oai-gnb ARG BUILD_OPTION ENV DEBIAN_FRONTEND=noninteractive ENV TZ=Europe/Paris diff --git a/docker/Dockerfile.lteRU.ubuntu b/docker/Dockerfile.lteRU.ubuntu index 9bf886a096..23be653c58 100644 --- a/docker/Dockerfile.lteRU.ubuntu +++ b/docker/Dockerfile.lteRU.ubuntu @@ -25,13 +25,14 @@ # #--------------------------------------------------------------------- +ARG UBUNTU_IMAGE=ubuntu:noble FROM ran-base:latest AS ru-base FROM ran-build:latest AS ru-build #start from scratch for target executable -FROM ubuntu:noble AS oai-lte-ru +FROM ${UBUNTU_IMAGE} AS oai-lte-ru ENV DEBIAN_FRONTEND=noninteractive ENV TZ=Europe/Paris diff --git a/docker/Dockerfile.lteUE.ubuntu b/docker/Dockerfile.lteUE.ubuntu index 7c608c0077..7ce0b7bea5 100644 --- a/docker/Dockerfile.lteUE.ubuntu +++ b/docker/Dockerfile.lteUE.ubuntu @@ -25,13 +25,15 @@ # #--------------------------------------------------------------------- +ARG UBUNTU_IMAGE=ubuntu:noble + FROM ran-base:latest AS lte-ue-base -FROM ran-build:latest AS lte-ue-build +FROM ran-build:latest AS lte-ue-build #start from scratch for target executable -FROM ubuntu:noble AS oai-lte-ue +FROM ${UBUNTU_IMAGE} AS oai-lte-ue ARG BUILD_OPTION ENV DEBIAN_FRONTEND=noninteractive ENV TZ=Europe/Paris diff --git a/docker/Dockerfile.nr-cuup.ubuntu b/docker/Dockerfile.nr-cuup.ubuntu index ed00800582..af6911c22e 100644 --- a/docker/Dockerfile.nr-cuup.ubuntu +++ b/docker/Dockerfile.nr-cuup.ubuntu @@ -25,12 +25,13 @@ # #--------------------------------------------------------------------- +ARG UBUNTU_IMAGE=ubuntu:noble FROM ran-base:latest AS gnb-base FROM ran-build:latest AS gnb-build -FROM ubuntu:noble AS oai-nr-cuup +FROM ${UBUNTU_IMAGE} AS oai-nr-cuup ARG BUILD_OPTION ENV DEBIAN_FRONTEND=noninteractive ENV TZ=Europe @@ -46,7 +47,7 @@ RUN apt-get update && \ libyaml-cpp-dev && \ # if the --sanitize option was used to build, additional packages are required /bin/bash -c 'if [[ "$BUILD_OPTION" = "--sanitize" ]]; then DEBIAN_FRONTEND=noninteractive apt-get install --yes \ - libasan8 \ + libasan8 \ libubsan1; fi' && \ rm -rf /var/lib/apt/lists/* diff --git a/docker/Dockerfile.nrORU.fhi72.ubuntu b/docker/Dockerfile.nrORU.fhi72.ubuntu index dc014c70d8..67d2fc2da9 100644 --- a/docker/Dockerfile.nrORU.fhi72.ubuntu +++ b/docker/Dockerfile.nrORU.fhi72.ubuntu @@ -18,13 +18,14 @@ # * For more information about the OpenAirInterface (OAI) Software Alliance: # * contact@openairinterface.org # */ - +ARG UBUNTU_IMAGE=ubuntu:noble FROM ran-base:latest AS ran-base FROM ran-build-fhi72:latest AS ran-build #start from scratch for target executable -FROM ubuntu:noble AS oai-nr-oru +FROM ${UBUNTU_IMAGE} AS oai-nr-oru +ARG BUILD_OPTION ENV DEBIAN_FRONTEND=noninteractive ENV TZ=Europe diff --git a/docker/Dockerfile.nrUE.ubuntu b/docker/Dockerfile.nrUE.ubuntu index ef700825d1..08c83899b7 100644 --- a/docker/Dockerfile.nrUE.ubuntu +++ b/docker/Dockerfile.nrUE.ubuntu @@ -25,13 +25,14 @@ # #--------------------------------------------------------------------- +ARG UBUNTU_IMAGE=ubuntu:noble FROM ran-base:latest AS nr-ue-base FROM ran-build:latest AS nr-ue-build #start from scratch for target executable -FROM ubuntu:noble AS oai-nr-ue +FROM ${UBUNTU_IMAGE} AS oai-nr-ue ARG BUILD_OPTION ENV DEBIAN_FRONTEND=noninteractive ENV TZ=Europe/Paris From ac9232d6fcad73b87862e387c74be2bfd0140d88 Mon Sep 17 00:00:00 2001 From: aswanthkc Date: Mon, 23 Feb 2026 10:36:52 -0500 Subject: [PATCH 20/83] fix: updated the nssai_sd paramter in the ue.conf file Following the tutorial in the RF simulator, the PDU session cannot be established because the Slice Differentiator to request(nssai_sd) parameter in the ue.conf file is 1(integer) but in the documentation the default value of the nssai_sd is 0xFFFFF(meaning "no SD") Now the nssai_sd parameter is removed in the ue.conf to establish the PDU session. --- targets/PROJECTS/GENERIC-NR-5GC/CONF/ue.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/ue.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/ue.conf index d4f51cd6ea..09a01e1eb4 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/ue.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/ue.conf @@ -2,7 +2,7 @@ uicc0 = { imsi = "2089900007487"; key = "fec86ba6eb707ed08905757b1bb44b8f"; opc= "C42449363BBAD02B66D16BC975D77CC1"; -pdu_sessions = ({ dnn = "oai"; nssai_sst = 1; nssai_sd = 1; }); +pdu_sessions = ({ dnn = "oai"; nssai_sst = 1; }); } position0 = { From 90bf723eae568b5fc71f6202149a8e0ab9ac3331 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Tue, 24 Feb 2026 08:22:53 +0100 Subject: [PATCH 21/83] nr-uesoftmodem: end with Bye. Similarly to gNB, eNB, lteUE, end with a "Bye." that the CI (will) check for. The right way to do this would be to use the exit code, but most executables do not actually end with 0, such that we need to check for this. Thus, this commit is only to harmonize with other executables. --- executables/nr-uesoftmodem.c | 1 + 1 file changed, 1 insertion(+) diff --git a/executables/nr-uesoftmodem.c b/executables/nr-uesoftmodem.c index a0e06850b7..d19bd20da0 100644 --- a/executables/nr-uesoftmodem.c +++ b/executables/nr-uesoftmodem.c @@ -500,6 +500,7 @@ int main(int argc, char **argv) time_manager_finish(); free(pckg); + printf("Bye.\n"); return 0; } From 933984fab1ef8dca2b404c0803ab39089893201e Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Tue, 24 Feb 2026 08:37:36 +0100 Subject: [PATCH 22/83] Fix handling of IPv4v6 PDU sessions The code previously checked that the supplied PDU sessions's type is exactly what we requested. However, at least OAI 5GC will only give us an IPv4 PDU session if we request IPv4v6 (so the check would fail). Extend the validation to either check exact match, or, if IPv4v6 requested, that it is either IPv4 or IPv6. --- openair3/NAS/NR_UE/nr_nas_msg.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/openair3/NAS/NR_UE/nr_nas_msg.c b/openair3/NAS/NR_UE/nr_nas_msg.c index 64f9feef54..b52bb982fc 100644 --- a/openair3/NAS/NR_UE/nr_nas_msg.c +++ b/openair3/NAS/NR_UE/nr_nas_msg.c @@ -1556,7 +1556,9 @@ static void handle_pdu_session_accept(const nr_ue_nas_t *nas, uint8_t *pdu_buffe int idx; for (idx = 0; idx < nas->uicc->n_pdu_sessions; ++idx) { const pdu_session_config_t *pdu = &nas->uicc->pdu_sessions[idx]; - if (pdu->id == sm_header.pdu_session_id && pdu->type == msg.pdu_type) + bool msg_ipv4or6 = msg.pdu_type == PDU_SESSION_TYPE_IPV4 || msg.pdu_type == PDU_SESSION_TYPE_IPV6; + bool correct_type = pdu->type == msg.pdu_type || (pdu->type == PDU_SESSION_TYPE_IPV4V6 && msg_ipv4or6); + if (pdu->id == sm_header.pdu_session_id && correct_type) break; } if (idx == nas->uicc->n_pdu_sessions) { From dae251ddcb15c02c5d5dfb029a89e721082c78c5 Mon Sep 17 00:00:00 2001 From: Guido Casati Date: Tue, 24 Feb 2026 12:55:24 +0100 Subject: [PATCH 23/83] Fix DRB array offset when aggregating E1 DRBs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Ensure DRBs from multiple PDU sessions are appended into the F1 DRB array without overwriting previously filled entries. Update fill_drb_to_be_setup_from_e1_resp to call fill_f1_drbs_from_e1 with &drbs[nb_drb] so each PDU session’s DRBs are written after the current count --- openair2/RRC/NR/rrc_gNB.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index 0d5653bb1e..936f333124 100644 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -3050,7 +3050,7 @@ static int fill_drb_to_be_setup_from_e1_resp(const gNB_RRC_INST *rrc, const pdu_session_setup_t *session = &pduSession[p]; rrc_pdu_session_param_t *pdu = find_pduSession(&UE->pduSessions, session->id); DevAssert(pdu); - nb_drb += fill_f1_drbs_from_e1(rrc, UE, pdu, session->DRBnGRanList, session->numDRBSetup, drbs); + nb_drb += fill_f1_drbs_from_e1(rrc, UE, pdu, session->DRBnGRanList, session->numDRBSetup, &drbs[nb_drb]); } DevAssert(nb_drb < MAX_DRBS_PER_UE); return nb_drb; From 4e9a853696ee420910e0952cc43406dff587f154 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Tue, 24 Feb 2026 18:53:50 +0100 Subject: [PATCH 24/83] Fix ssb_PositionsInBurst_Bitmap to work with slot-synchronization Since the grand-parent commit, if possible, the gNBs synchronize on a slot-level boundary. Some configuration files/command line overrides left the same SSB position for two DUs in RFsim-based handover scenarios, which then makes that the UE cannot decode the SSB. This commit changes the positions such that this is possible again. In the F1 HO docker-compose (ci-scripts/yaml_files/5g_f1_rfsimulator/docker-compose.yaml), we set it to 2 to send only one SSB (not 2 with bitmap 3). --- ci-scripts/yaml_files/5g_f1_rfsimulator/docker-compose.yaml | 2 +- ci-scripts/yaml_files/5g_rfsimulator_n2_ho/docker-compose.yaml | 1 + .../CONF/gnb.sa.band78.fr1.106PRB.pci1.rfsim.conf | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/ci-scripts/yaml_files/5g_f1_rfsimulator/docker-compose.yaml b/ci-scripts/yaml_files/5g_f1_rfsimulator/docker-compose.yaml index 98eb1fb54c..8a70f35619 100644 --- a/ci-scripts/yaml_files/5g_f1_rfsimulator/docker-compose.yaml +++ b/ci-scripts/yaml_files/5g_f1_rfsimulator/docker-compose.yaml @@ -166,7 +166,7 @@ services: --gNBs.[0].servingCellConfigCommon.[0].physCellId 1 --gNBs.[0].servingCellConfigCommon.[0].absoluteFrequencySSB 643296 --gNBs.[0].servingCellConfigCommon.[0].dl_absoluteFrequencyPointA 642024 - --gNBs.[0].servingCellConfigCommon.[0].ssb_PositionsInBurst_Bitmap 3 + --gNBs.[0].servingCellConfigCommon.[0].ssb_PositionsInBurst_Bitmap 2 --MACRLCs.[0].local_n_address 192.168.71.172 --rfsimulator.[0].serveraddr 192.168.71.181 ASAN_OPTIONS: detect_leaks=0:detect_odr_violation=0 diff --git a/ci-scripts/yaml_files/5g_rfsimulator_n2_ho/docker-compose.yaml b/ci-scripts/yaml_files/5g_rfsimulator_n2_ho/docker-compose.yaml index 87fee22e6d..0159502c13 100644 --- a/ci-scripts/yaml_files/5g_rfsimulator_n2_ho/docker-compose.yaml +++ b/ci-scripts/yaml_files/5g_rfsimulator_n2_ho/docker-compose.yaml @@ -267,6 +267,7 @@ services: --gNBs.[0].servingCellConfigCommon.[0].physCellId 1 --gNBs.[0].servingCellConfigCommon.[0].absoluteFrequencySSB 621312 --gNBs.[0].servingCellConfigCommon.[0].dl_absoluteFrequencyPointA 620040 + --gNBs.[0].servingCellConfigCommon.[0].ssb_PositionsInBurst_Bitmap 2 --MACRLCs.[0].local_n_address 192.168.71.182 --MACRLCs.[0].remote_n_address 192.168.71.180 ASAN_OPTIONS: detect_leaks=0:detect_odr_violation=0 diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.pci1.rfsim.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.pci1.rfsim.conf index ae9b0ea5fc..1db01323f2 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.pci1.rfsim.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.pci1.rfsim.conf @@ -112,7 +112,7 @@ gNBs = hoppingId = 40; p0_nominal = -90; - ssb_PositionsInBurst_Bitmap = 1; + ssb_PositionsInBurst_Bitmap = 2; # ssb_periodicityServingCell # 0 = ms5, 1=ms10, 2=ms20, 3=ms40, 4=ms80, 5=ms160, 6=spare2, 7=spare1 From af438ef5e574d6a30689ff334745de14e55a416e Mon Sep 17 00:00:00 2001 From: Rakesh Mundlamuri Date: Wed, 25 Feb 2026 08:58:18 +0100 Subject: [PATCH 25/83] Handover doc: mention ssb_PositionsInBurst_Bitmap config --- doc/handover-tutorial.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/doc/handover-tutorial.md b/doc/handover-tutorial.md index 58c0808108..b7ccbc318c 100644 --- a/doc/handover-tutorial.md +++ b/doc/handover-tutorial.md @@ -104,6 +104,9 @@ information further below. A number of remarks: +1. DU0 and DU1 should use different SSBs, i.e., make sure that + `ssb_PositionsInBurst_Bitmap` is set to send SSB in different slots in the + configurataion files of DU0 (e.g., set to 1) and DU1 (e.g., set to 2). 1. It is important that you start DU0, UE, DU1 in order, and having UE connect to DU0 before starting DU1. This is because we don't employ any channel emulation, and the UE could not decode the SIB1 of DU0 to connect. @@ -433,6 +436,8 @@ a core-network-based handover. We assume: +* `ssb_PositionsInBurst_Bitmap` set to different values for gNB-PCI0 and + gNB-PCI1 as described further above. * Two independent gNBs connected to the same 5GC via N2 interface. * A UE initially connected to gNB-PCI0, which will be handed over to gNB-PCI1. * Handover is triggered by either a decision based measurement event (e.g. A3) From 3f4b72df67724a85bfc577f161585df4b9a9194e Mon Sep 17 00:00:00 2001 From: Guido Casati Date: Tue, 24 Feb 2026 12:57:20 +0100 Subject: [PATCH 26/83] Handle duplicate PDU sessions in NGAP InitialContextSetup Ensure the CU-CP only sets up PDU sessions that are not already established for the UE, skipping duplicates while keeping the NG UE context valid. This aligns with 3GPP TS 38.413 PDU Session setup semantics for duplicate session IDs Changes: - Change rrc_gNB_process_NGAP_INITIAL_CONTEXT_SETUP_REQ to scan requested PDU sessions and detect IDs that already exist in UE->pduSessions with PDU_SESSION_STATUS_ESTABLISHED - Log a warning and skip already established PDU session IDs so they are not added to UE->initial_pdus - Collect only non-established PDU sessions into a temporary stack array, allocate UE->initial_pdus with the exact count, copy them in, update UE->n_initial_pdu, and only refresh UE AMBR when there is at least one session to set up --- openair2/RRC/NR/rrc_gNB_NGAP.c | 40 +++++++++++++++++++++++++++------- 1 file changed, 32 insertions(+), 8 deletions(-) diff --git a/openair2/RRC/NR/rrc_gNB_NGAP.c b/openair2/RRC/NR/rrc_gNB_NGAP.c index dc9ec9c19a..76a96aa689 100644 --- a/openair2/RRC/NR/rrc_gNB_NGAP.c +++ b/openair2/RRC/NR/rrc_gNB_NGAP.c @@ -506,14 +506,38 @@ int rrc_gNB_process_NGAP_INITIAL_CONTEXT_SETUP_REQ(MessageDef *msg_p, instance_t if (req->nb_of_pdusessions > 0) { AssertFatal(req->has_ue_ambr, "UE aggregate maximum bitrate is required when there are PDU sessions to setup"); - /* if there are PDU sessions to setup, store them to be created once - * security (and UE capabilities) are received */ - UE->n_initial_pdu = req->nb_of_pdusessions; - UE->initial_pdus = calloc_or_fail(UE->n_initial_pdu, sizeof(*UE->initial_pdus)); - for (int i = 0; i < UE->n_initial_pdu; ++i) - cp_pdusession_resource_item_to_pdusession(&UE->initial_pdus[i], &req->pdusession[i]); - UE->ambr.dl_br = req->ue_ambr.br_dl; - UE->ambr.ul_br = req->ue_ambr.br_ul; + + /* Build the list of PDU sessions to actually set up, filtering out those + * whose PDU Session ID already identifies an active PDU session for this UE. + * According to TS 38.413, establishment of such a PDU session shall be + * reported as failed in the response. */ + int ps_count = 0; + pdusession_t psessions[NGAP_MAX_PDU_SESSION] = {0}; + + for (int i = 0; i < req->nb_of_pdusessions; ++i) { + const pdusession_resource_item_t *src = &req->pdusession[i]; + + rrc_pdu_session_param_t *existing = find_pduSession(&UE->pduSessions, src->pdusession_id); + if (existing != NULL && existing->status == PDU_SESSION_STATUS_ESTABLISHED) { + LOG_W(NR_RRC, "UE %d: InitialContextSetup contains already active PDU session ID %d\n", UE->rrc_ue_id, src->pdusession_id); + continue; + } + + /* This is a PDU session that is not yet active for this UE: add it to the list */ + DevAssert(ps_count < req->nb_of_pdusessions); + cp_pdusession_resource_item_to_pdusession(&psessions[ps_count++], src); + } + + UE->n_initial_pdu = 0; + if (ps_count > 0) { + UE->initial_pdus = calloc_or_fail(ps_count, sizeof(*UE->initial_pdus)); + memcpy(UE->initial_pdus, psessions, ps_count * sizeof(*UE->initial_pdus)); + UE->n_initial_pdu = ps_count; + + /* If we have at least one session to set up, store AMBR */ + UE->ambr.dl_br = req->ue_ambr.br_dl; + UE->ambr.ul_br = req->ue_ambr.br_ul; + } } /* security */ From 530b692208b104c7cd98eb78523812d50c26e412 Mon Sep 17 00:00:00 2001 From: francescomani Date: Wed, 11 Feb 2026 18:42:06 +0100 Subject: [PATCH 27/83] simplified version of to_nrarfcn function to remove not necessary checks for band consistency --- common/utils/nr/nr_common.c | 38 +++++-------------- common/utils/nr/nr_common.h | 2 +- openair1/SCHED_NR_UE/phy_procedures_nr_ue.c | 2 +- openair1/SIMULATION/NR_PHY/prachsim.c | 6 +-- radio/AW2SORI/oaiori.c | 11 ++---- radio/fhi_72/mplane/yang/create-yang-config.c | 4 +- 6 files changed, 19 insertions(+), 44 deletions(-) diff --git a/common/utils/nr/nr_common.c b/common/utils/nr/nr_common.c index a3a8520c86..1f7c25c2f0 100644 --- a/common/utils/nr/nr_common.c +++ b/common/utils/nr/nr_common.c @@ -595,44 +595,26 @@ void get_delta_arfcn(int i, uint32_t nrarfcn, uint64_t N_OFFs) LOG_E(NR_MAC, "nrarfcn %u is not on the channel raster for step size %lu\n", nrarfcn, nr_bandtable[i].step_size); } -uint32_t to_nrarfcn(int nr_bandP, uint64_t dl_CarrierFreq, uint8_t scs_index, uint32_t bw) +uint32_t to_nrarfcn(uint64_t CarrierFreq) { - uint64_t dl_CarrierFreq_by_1k = dl_CarrierFreq / 1000; - int bw_kHz = bw / 1000; - uint32_t nrarfcn; - int i = get_nr_table_idx(nr_bandP, scs_index); - - LOG_D(NR_MAC, "Searching for nr band %d DL Carrier frequency %llu bw %u\n", nr_bandP, (long long unsigned int)dl_CarrierFreq, bw); - - AssertFatal(dl_CarrierFreq_by_1k >= nr_bandtable[i].dl_min, - "Band %d, bw %u : DL carrier frequency %llu kHz < %llu\n", - nr_bandP, bw, (long long unsigned int)dl_CarrierFreq_by_1k, - (long long unsigned int)nr_bandtable[i].dl_min); - AssertFatal(dl_CarrierFreq_by_1k <= (nr_bandtable[i].dl_max - bw_kHz/2), - "Band %d, dl_CarrierFreq %llu bw %u: DL carrier frequency %llu kHz > %llu\n", - nr_bandP, (long long unsigned int)dl_CarrierFreq,bw, (long long unsigned int)dl_CarrierFreq_by_1k, - (long long unsigned int)(nr_bandtable[i].dl_max - bw_kHz/2)); - + uint64_t CarrierFreq_by_1k = CarrierFreq / 1000; + // FR2 int deltaFglobal = 60; uint32_t N_REF_Offs = 2016667; uint64_t F_REF_Offs_khz = 24250080; - - if (dl_CarrierFreq < 24.25e9) { + // FR1 + if (CarrierFreq < 3e9) { + deltaFglobal = 5; + N_REF_Offs = 0; + F_REF_Offs_khz = 0; + } else if (CarrierFreq < 24.25e9) { deltaFglobal = 15; N_REF_Offs = 600000; F_REF_Offs_khz = 3000000; } - if (dl_CarrierFreq < 3e9) { - deltaFglobal = 5; - N_REF_Offs = 0; - F_REF_Offs_khz = 0; - } // This is equation before Table 5.4.2.1-1 in 38101-1-f30 - // F_REF=F_REF_Offs + deltaF_Global(N_REF-NREF_REF_Offs) - nrarfcn = (((dl_CarrierFreq_by_1k - F_REF_Offs_khz) / deltaFglobal) + N_REF_Offs); - //get_delta_arfcn(i, nrarfcn, nr_bandtable[i].N_OFFs_DL); - + uint32_t nrarfcn = (((CarrierFreq_by_1k - F_REF_Offs_khz) / deltaFglobal) + N_REF_Offs); return nrarfcn; } diff --git a/common/utils/nr/nr_common.h b/common/utils/nr/nr_common.h index ca867fa694..3d9f5fbc7e 100644 --- a/common/utils/nr/nr_common.h +++ b/common/utils/nr/nr_common.h @@ -287,7 +287,7 @@ static inline void warn_higher_threequarter_fs(const int n_rb, const int mu) } uint64_t from_nrarfcn(int nr_bandP, uint8_t scs_index, uint32_t dl_nrarfcn); -uint32_t to_nrarfcn(int nr_bandP, uint64_t dl_CarrierFreq, uint8_t scs_index, uint32_t bw); +uint32_t to_nrarfcn(uint64_t dl_CarrierFreq); int cce_to_reg_interleaving(const int R, int k, int n_shift, const int C, int L, const int N_regs); int get_SLIV(uint8_t S, uint8_t L); diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c index c080076b4a..2da33ce205 100644 --- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c +++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c @@ -116,7 +116,7 @@ static uint32_t get_ssb_arfcn(NR_DL_FRAME_PARMS *frame_parms) uint32_t band_size_hz = frame_parms->N_RB_DL * 12 * frame_parms->subcarrier_spacing; int ssb_center_sc = frame_parms->ssb_start_subcarrier + 120; // ssb is 20 PRBs -> 240 sub-carriers uint64_t ssb_freq = frame_parms->dl_CarrierFreq - (band_size_hz / 2) + frame_parms->subcarrier_spacing * ssb_center_sc; - return to_nrarfcn(frame_parms->nr_band, ssb_freq, frame_parms->numerology_index, band_size_hz); + return to_nrarfcn(ssb_freq); } void nr_fill_rx_indication(fapi_nr_rx_indication_t *rx_ind, uint8_t pdu_type, diff --git a/openair1/SIMULATION/NR_PHY/prachsim.c b/openair1/SIMULATION/NR_PHY/prachsim.c index 26bf44da8c..4da1accfe8 100644 --- a/openair1/SIMULATION/NR_PHY/prachsim.c +++ b/openair1/SIMULATION/NR_PHY/prachsim.c @@ -433,11 +433,7 @@ int main(int argc, char **argv){ nr_phy_config_request_sim(gNB, N_RB_UL, N_RB_UL, mu, Nid_cell, SSB_positions); - uint64_t absoluteFrequencyPointA = to_nrarfcn(frame_parms->nr_band, - frame_parms->dl_CarrierFreq, - frame_parms->numerology_index, - frame_parms->N_RB_UL*(180e3)*(1 << frame_parms->numerology_index)); - + uint64_t absoluteFrequencyPointA = to_nrarfcn(frame_parms->dl_CarrierFreq); uint8_t frame = 1; uint8_t subframe = 9; uint8_t slot = 10 * frame_parms->slots_per_subframe - 1; diff --git a/radio/AW2SORI/oaiori.c b/radio/AW2SORI/oaiori.c index b17c7e5dfd..0238595662 100644 --- a/radio/AW2SORI/oaiori.c +++ b/radio/AW2SORI/oaiori.c @@ -417,10 +417,7 @@ int aw2s_startstreaming(openair0_device_t *device) return (0); } -uint32_t to_nrarfcn(int nr_bandP, - uint64_t dl_CarrierFreq, - uint8_t scs_index, - uint32_t bw); +uint32_t to_nrarfcn(uint64_t dl_CarrierFreq); int aw2s_oriinit(openair0_device_t *device) { @@ -543,7 +540,7 @@ int aw2s_oriinit(openair0_device_t *device) txParams.TxNRFDD.axcB = 0; txParams.TxNRFDD.chanBW = openair0_cfg->tx_bw/100e3; - txParams.TxNRFDD.AWS_arfcn = to_nrarfcn(openair0_cfg->nr_band,(long long int)openair0_cfg->tx_freq[0],openair0_cfg->nr_scs_for_raster,(uint32_t)openair0_cfg->tx_bw); + txParams.TxNRFDD.AWS_arfcn = to_nrarfcn((long long int)openair0_cfg->tx_freq[0]); txParams.TxNRFDD.maxTxPwr = 430-((int)openair0_cfg->tx_gain[0]*10); } else if (openair0_cfg->duplex_mode == duplex_mode_TDD && openair0_cfg->nr_flag == 0) { @@ -562,7 +559,7 @@ int aw2s_oriinit(openair0_device_t *device) txParams.TxNRTDD.axcW = 1; txParams.TxNRTDD.axcB = 0; txParams.TxNRTDD.chanBW = openair0_cfg->tx_bw/100e3; - txParams.TxNRTDD.AWS_arfcn = to_nrarfcn(openair0_cfg->nr_band,(long long int)openair0_cfg->tx_freq[0],openair0_cfg->nr_scs_for_raster,(uint32_t)openair0_cfg->tx_bw); + txParams.TxNRTDD.AWS_arfcn = to_nrarfcn((long long int)openair0_cfg->tx_freq[0]); txParams.TxNRTDD.maxTxPwr = 430-((int)openair0_cfg->tx_gain[0]*10); printf("AW2S: Configuring for NR TDD, NRARFCN %u, Power %d, BW %d\n", @@ -678,7 +675,7 @@ int aw2s_oriinit(openair0_device_t *device) rxParams.RxNRFDD.axcW = 1; rxParams.RxNRFDD.axcB = 0; rxParams.RxNRFDD.chanBW = txParams.TxNRFDD.chanBW; - rxParams.RxNRFDD.AWS_arfcn = to_nrarfcn(openair0_cfg->nr_band,(long long int)openair0_cfg->rx_freq[0],openair0_cfg->nr_scs_for_raster,openair0_cfg->rx_bw); + rxParams.RxNRFDD.AWS_arfcn = to_nrarfcn((long long int)openair0_cfg->rx_freq[0]); result = ORI_ObjectCreation(ori, rxTypeRef, rxParams, rxParamList, num_rxparams, rxParamResult, &rx0, &RE_result); } else if (openair0_cfg->duplex_mode == duplex_mode_TDD && openair0_cfg->nr_flag == 0) { diff --git a/radio/fhi_72/mplane/yang/create-yang-config.c b/radio/fhi_72/mplane/yang/create-yang-config.c index 8f35888797..69b180bde2 100644 --- a/radio/fhi_72/mplane/yang/create-yang-config.c +++ b/radio/fhi_72/mplane/yang/create-yang-config.c @@ -248,7 +248,7 @@ static bool create_uplane_conf_v2(const ru_session_t *ru_session, const openair0 VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create \"center-of-channel-bandwidth\" node.\n"); char rx_arfcn[16]; - snprintf(rx_arfcn, sizeof(rx_arfcn), "%d", to_nrarfcn(oai->nr_band, oai->rx_freq[0], oai->nr_scs_for_raster, oai->rx_bw)); + snprintf(rx_arfcn, sizeof(rx_arfcn), "%d", to_nrarfcn(oai->rx_freq[0])); ret = lyd_new_term(rx_carrier_node, NULL, "absolute-frequency-center", rx_arfcn, 0, NULL); VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create \"absolute-frequency-center\" node.\n"); @@ -290,7 +290,7 @@ static bool create_uplane_conf_v2(const ru_session_t *ru_session, const openair0 VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create \"center-of-channel-bandwidth\" node.\n"); char tx_arfcn[16]; - snprintf(tx_arfcn, sizeof(tx_arfcn), "%d", to_nrarfcn(oai->nr_band, oai->tx_freq[0], oai->nr_scs_for_raster, oai->tx_bw)); + snprintf(tx_arfcn, sizeof(tx_arfcn), "%d", to_nrarfcn(oai->tx_freq[0])); ret = lyd_new_term(tx_carrier_node, NULL, "absolute-frequency-center", tx_arfcn, 0, NULL); VERIFY_SUCCESS(ret == LY_SUCCESS, "[MPLANE] Failed to create \"absolute-frequency-center\" node.\n"); From 0219e4d3c738f23509336e4d7d2d1c6350e2e46f Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 12 Feb 2026 10:09:01 +0100 Subject: [PATCH 28/83] Remove band number from openair0_config_t --- executables/nr-ru.c | 5 ++--- radio/COMMON/common_lib.h | 2 -- radio/fhi_72/oran-config.c | 1 - 3 files changed, 2 insertions(+), 6 deletions(-) diff --git a/executables/nr-ru.c b/executables/nr-ru.c index 397f940745..b2c3c98741 100644 --- a/executables/nr-ru.c +++ b/executables/nr-ru.c @@ -1747,13 +1747,12 @@ static void NRRCconfig_RU(configmodule_interface_t *cfg) for (int i = 0; i < ru->num_bands; i++) ru->band[i] = param[RU_BAND_LIST_IDX].iptr[i]; ru->openair0_cfg.nr_flag = *param[RU_NR_FLAG].iptr; - ru->openair0_cfg.nr_band = ru->band[0]; + // TODO remove band from RU? ru->openair0_cfg.nr_scs_for_raster = *param[RU_NR_SCS_FOR_RASTER].iptr; LOG_D(PHY, - "[RU %d] Setting nr_flag %d, nr_band %d, nr_scs_for_raster %d\n", + "[RU %d] Setting nr_flag %d, nr_scs_for_raster %d\n", j, ru->openair0_cfg.nr_flag, - ru->openair0_cfg.nr_band, ru->openair0_cfg.nr_scs_for_raster); ru->openair0_cfg.rxfh_cores[0] = *param[RU_RXFH_CORE_ID].iptr; ru->openair0_cfg.txfh_cores[0] = *param[RU_TXFH_CORE_ID].iptr; diff --git a/radio/COMMON/common_lib.h b/radio/COMMON/common_lib.h index f21a1ffff4..db15a3967d 100644 --- a/radio/COMMON/common_lib.h +++ b/radio/COMMON/common_lib.h @@ -275,8 +275,6 @@ typedef struct openair0_config { recplay_conf_t *recplay_conf; //! Flag to indicate this configuration is for NR int nr_flag; - //! NR band number - int nr_band; //! NR scs for raster int nr_scs_for_raster; //! Core IDs for RX FH diff --git a/radio/fhi_72/oran-config.c b/radio/fhi_72/oran-config.c index 6f8afc092f..0fac6452e6 100644 --- a/radio/fhi_72/oran-config.c +++ b/radio/fhi_72/oran-config.c @@ -902,7 +902,6 @@ static bool set_fh_config(void *mplane_api, int ru_idx, int num_rus, enum xran_c DevAssert(oai0->rx_freq[0] > 0); for (int i = 1; i < oai0->rx_num_channels; ++i) DevAssert(oai0->rx_freq[0] == oai0->rx_freq[i]); - DevAssert(oai0->nr_band > 0); paramdef_t FHconfigs[] = ORAN_FH_DESC; paramlist_def_t FH_ConfigList = {CONFIG_STRING_ORAN_FH}; char aprefix[MAX_OPTNAME_SIZE] = {0}; From f66a7b2108ebabd89aad6c99367e53e6cffea005 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=BAben=20Soares=20Silva?= Date: Thu, 19 Feb 2026 11:27:12 +0000 Subject: [PATCH 29/83] Add SSB Case V3 vendor extension TLV to CONFIG.request pack/unpack and to utility functions --- nfapi/open-nFAPI/fapi/src/nr_fapi_p5.c | 19 +++++++++++++++---- nfapi/open-nFAPI/fapi/src/nr_fapi_p5_utils.c | 8 ++++++++ .../nfapi/public_inc/nfapi_nr_interface.h | 1 + .../nfapi/public_inc/nfapi_nr_interface_scf.h | 12 ++++++------ nfapi/tests/p5/nr_fapi_config_request_test.c | 3 +++ 5 files changed, 33 insertions(+), 10 deletions(-) diff --git a/nfapi/open-nFAPI/fapi/src/nr_fapi_p5.c b/nfapi/open-nFAPI/fapi/src/nr_fapi_p5.c index 9bbda9d519..cfdce8df2d 100644 --- a/nfapi/open-nFAPI/fapi/src/nr_fapi_p5.c +++ b/nfapi/open-nFAPI/fapi/src/nr_fapi_p5.c @@ -1229,6 +1229,14 @@ uint8_t pack_nr_config_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *e // only increase if it was set numTLVs += pNfapiMsg->analog_beamforming_ve.analog_bf_vendor_ext.tl.tag == NFAPI_NR_FAPI_ANALOG_BF_VENDOR_EXTENSION_TAG; + retval &= pack_nr_tlv(NFAPI_NR_FAPI_SSB_CASE_VENDOR_EXTENSION_TAG, + &(pNfapiMsg->ssb_table.case_v3), + ppWritePackedMsg, + end, + &pack_uint8_tlv_value); + + numTLVs += pNfapiMsg->ssb_table.case_v3.tl.tag == NFAPI_NR_FAPI_SSB_CASE_VENDOR_EXTENSION_TAG; + pNfapiMsg->num_tlv = numTLVs; retval &= push8(pNfapiMsg->num_tlv, &pNumTLVFields, end); return retval; @@ -1391,10 +1399,13 @@ uint8_t unpack_nr_config_request(uint8_t **ppReadPackedMsg, uint8_t *end, void * #endif {NFAPI_NR_FAPI_NUM_BEAMS_PERIOD_VENDOR_EXTENSION_TAG, &(pNfapiMsg->analog_beamforming_ve.num_beams_period_vendor_ext), - &unpack_uint8_tlv_value}, - {NFAPI_NR_FAPI_ANALOG_BF_VENDOR_EXTENSION_TAG, - &(pNfapiMsg->analog_beamforming_ve.analog_bf_vendor_ext), - &unpack_uint8_tlv_value}, + &unpack_uint8_tlv_value}, + {NFAPI_NR_FAPI_ANALOG_BF_VENDOR_EXTENSION_TAG, + &(pNfapiMsg->analog_beamforming_ve.analog_bf_vendor_ext), + &unpack_uint8_tlv_value}, + {NFAPI_NR_FAPI_SSB_CASE_VENDOR_EXTENSION_TAG, + &(pNfapiMsg->ssb_table.case_v3), + &unpack_uint8_tlv_value}, {NFAPI_NR_CONFIG_RSSI_MEASUREMENT_TAG, &(pNfapiMsg->measurement_config.rssi_measurement), &unpack_uint8_tlv_value}, {NFAPI_NR_CONFIG_BEAMFORMING_TABLE_TAG, NULL, &unpack_dbt_table_tlv_value}, {NFAPI_NR_CONFIG_PRECODING_TABLE_V6_TAG, NULL, &unpack_pm_table_tlv_value}, diff --git a/nfapi/open-nFAPI/fapi/src/nr_fapi_p5_utils.c b/nfapi/open-nFAPI/fapi/src/nr_fapi_p5_utils.c index 1ef65b664c..953b3bbfc4 100644 --- a/nfapi/open-nFAPI/fapi/src/nr_fapi_p5_utils.c +++ b/nfapi/open-nFAPI/fapi/src/nr_fapi_p5_utils.c @@ -240,6 +240,8 @@ bool eq_config_request(const nfapi_nr_config_request_scf_t *unpacked_req, const EQ_TLV(unpacked_req->ssb_table.ssb_beam_id_list[i].beam_id, req->ssb_table.ssb_beam_id_list[i].beam_id); } + EQ_TLV(unpacked_req->ssb_table.case_v3, req->ssb_table.case_v3); + if (req->cell_config.frame_duplex_type.value == 1 /* TDD */) { EQ_TLV(unpacked_req->tdd_table.tdd_period, req->tdd_table.tdd_period); @@ -786,6 +788,8 @@ void copy_config_request(const nfapi_nr_config_request_scf_t *src, nfapi_nr_conf COPY_TLV(dst->ssb_table.ssb_beam_id_list[i].beam_id, src->ssb_table.ssb_beam_id_list[i].beam_id); } + COPY_TLV(dst->ssb_table.case_v3, src->ssb_table.case_v3); + if (src->cell_config.frame_duplex_type.value == 1 /* TDD */) { COPY_TLV(dst->tdd_table.tdd_period, src->tdd_table.tdd_period); @@ -1225,6 +1229,10 @@ void dump_config_request(const nfapi_nr_config_request_scf_t *msg) depth--; INDENTED_TLV_PRINT("ssPBCH Multiple Carriers in a Band", ssb_table->ss_pbch_multiple_carriers_in_a_band); INDENTED_TLV_PRINT("Multiple Cells ssPBCH in a Carrier", ssb_table->multiple_cells_ss_pbch_in_a_carrier); + // Only print if it's filled + if (ssb_table->case_v3.tl.tag == NFAPI_NR_FAPI_SSB_CASE_VENDOR_EXTENSION_TAG) { + INDENTED_TLV_PRINT("SSB Case V3", ssb_table->case_v3); + } /* TDD Table */ const nfapi_nr_tdd_table_t *tdd_table = &msg->tdd_table; if (cell_config->frame_duplex_type.value == 1 /* TDD */) { diff --git a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface.h b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface.h index 2e74fdc800..70f3c2d67f 100644 --- a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface.h +++ b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface.h @@ -31,6 +31,7 @@ #define NFAPI_NR_NFAPI_TIMING_INFO_PERIOD_TAG 0x0120 #define NFAPI_NR_FAPI_NUM_BEAMS_PERIOD_VENDOR_EXTENSION_TAG 0xA000 #define NFAPI_NR_FAPI_ANALOG_BF_VENDOR_EXTENSION_TAG 0xA001 +#define NFAPI_NR_FAPI_SSB_CASE_VENDOR_EXTENSION_TAG 0xA002 typedef struct { uint16_t phy_id; diff --git a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h index fcd1968c25..b7e1cdee9b 100644 --- a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h +++ b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h @@ -412,15 +412,15 @@ typedef struct typedef struct { nfapi_uint16_tlv_t ssb_offset_point_a;//Offset of lowest subcarrier of lowest resource block used for SS/PBCH block. Given in PRB [38.211, section 4.4.4.2] Value: 0->2199 - nfapi_uint8_tlv_t beta_pss;//PSS EPRE to SSS EPRE in a SS/PBCH block [38.213, sec 4.1] Values: 0 = 0dB - nfapi_uint8_tlv_t ssb_period;//SSB periodicity in msec Value: 0: ms5 1: ms10 2: ms20 3: ms40 4: ms80 5: ms160 - nfapi_uint8_tlv_t ssb_subcarrier_offset;//ssbSubcarrierOffset or 𝑘𝑆𝑆𝐵 (38.211, section 7.4.3.1) Value: 0->31 + nfapi_uint8_tlv_t beta_pss;//PSS EPRE to SSS EPRE in a SS/PBCH block [38.213, sec 4.1] Values: 0 = 0dB + nfapi_uint8_tlv_t ssb_period;//SSB periodicity in msec Value: 0: ms5 1: ms10 2: ms20 3: ms40 4: ms80 5: ms160 + nfapi_uint8_tlv_t ssb_subcarrier_offset;//ssbSubcarrierOffset or 𝑘𝑆𝑆𝐵 (38.211, section 7.4.3.1) Value: 0->31 nfapi_uint32_tlv_t MIB;//MIB payload, where the 24 MSB are used and represent the MIB in [38.331 MIB IE] and represent 0 1 2 3 1 , , , ,..., A− a a a a a [38.212, sec 7.1.1] nfapi_nr_ssb_mask_list_t ssb_mask_list[2]; nfapi_nr_ssb_beam_id_list_t ssb_beam_id_list[64]; - nfapi_uint8_tlv_t ss_pbch_multiple_carriers_in_a_band;//0 = disabled 1 = enabled - nfapi_uint8_tlv_t multiple_cells_ss_pbch_in_a_carrier;//Indicates that multiple cells will be supported in a single carrier 0 = disabled 1 = enabled - + nfapi_uint8_tlv_t ss_pbch_multiple_carriers_in_a_band;//0 = disabled 1 = enabled + nfapi_uint8_tlv_t multiple_cells_ss_pbch_in_a_carrier;//Indicates that multiple cells will be supported in a single carrier 0 = disabled 1 = enabled + nfapi_uint8_tlv_t case_v3; } nfapi_nr_ssb_table_t; //table 3-26 diff --git a/nfapi/tests/p5/nr_fapi_config_request_test.c b/nfapi/tests/p5/nr_fapi_config_request_test.c index ed57a64d62..0564e9e8a3 100644 --- a/nfapi/tests/p5/nr_fapi_config_request_test.c +++ b/nfapi/tests/p5/nr_fapi_config_request_test.c @@ -176,6 +176,9 @@ static void fill_config_request_tlv_tdd_rand(nfapi_nr_config_request_scf_t *nfap nfapi_resp->num_tlv++; } + FILL_TLV(nfapi_resp->ssb_table.case_v3, NFAPI_NR_FAPI_SSB_CASE_VENDOR_EXTENSION_TAG, rand8()); + nfapi_resp->num_tlv++; + FILL_TLV(nfapi_resp->tdd_table.tdd_period, NFAPI_NR_CONFIG_TDD_PERIOD_TAG, 6 /* ms5 */); nfapi_resp->num_tlv++; From 5ed309166b4e8d71a4f3566b7354fb98fdf2e754 Mon Sep 17 00:00:00 2001 From: francescomani Date: Fri, 13 Feb 2026 17:37:33 +0100 Subject: [PATCH 30/83] use FAPI field to set SSB case from upper layers --- common/utils/nr/nr_common.c | 26 +++++ common/utils/nr/nr_common.h | 2 +- .../nfapi/public_inc/fapi_nr_ue_interface.h | 12 +- openair1/PHY/INIT/nr_parms.c | 106 ++---------------- openair2/LAYER2/NR_MAC_UE/config_ue.c | 2 + openair2/LAYER2/NR_MAC_gNB/config.c | 20 ++-- 6 files changed, 55 insertions(+), 113 deletions(-) diff --git a/common/utils/nr/nr_common.c b/common/utils/nr/nr_common.c index 1f7c25c2f0..aba54a07ef 100644 --- a/common/utils/nr/nr_common.c +++ b/common/utils/nr/nr_common.c @@ -152,6 +152,32 @@ int get_smallest_supported_bandwidth_index(int scs, frequency_range_t frequency_ return -1; // not found } +// Table 5.4.3.3-1 38-101 +uint8_t set_ssb_case(int scs, int nr_band) +{ + uint8_t ssb_case = 0; + switch (scs) { + case 0: + ssb_case = 0; // case A + break; + case 1: + if (nr_band == 5 || nr_band == 24 || nr_band == 66 || nr_band == 255) + ssb_case = 1; // case B + else + ssb_case = 2; // case C + break; + case 3: + ssb_case = 3; // case D + break; + case 4: + ssb_case = 4; // case E + break; + default: + AssertFatal(false, "Invalid sub-carrier spacing for SSB\n"); + } + return ssb_case; +} + // Table 5.2-1 NR operating bands in FR1 & FR2 (3GPP TS 38.101) (Rel.17) // Table 5.4.2.3-1 Applicable NR-ARFCN per operating band in FR1 & FR2 (3GPP TS 38.101) // Notes: diff --git a/common/utils/nr/nr_common.h b/common/utils/nr/nr_common.h index 3d9f5fbc7e..93e3296e67 100644 --- a/common/utils/nr/nr_common.h +++ b/common/utils/nr/nr_common.h @@ -288,7 +288,7 @@ static inline void warn_higher_threequarter_fs(const int n_rb, const int mu) uint64_t from_nrarfcn(int nr_bandP, uint8_t scs_index, uint32_t dl_nrarfcn); uint32_t to_nrarfcn(uint64_t dl_CarrierFreq); - +uint8_t set_ssb_case(int scs, int nr_band); int cce_to_reg_interleaving(const int R, int k, int n_shift, const int C, int L, const int N_regs); int get_SLIV(uint8_t S, uint8_t L); void get_coreset_rballoc(const uint8_t *FreqDomainResource, int *n_rb, int *rb_offset); diff --git a/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h b/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h index 481f704da1..1b1b31d74d 100644 --- a/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h +++ b/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h @@ -675,15 +675,15 @@ typedef struct typedef struct { uint16_t ssb_offset_point_a;//Offset of lowest subcarrier of lowest resource block used for SS/PBCH block. Given in PRB [38.211, section 4.4.4.2] Value: 0->2199 - uint8_t beta_pss;//PSS EPRE to SSS EPRE in a SS/PBCH block [38.213, sec 4.1] Values: 0 = 0dB - uint8_t ssb_period;//SSB periodicity in msec Value: 0: ms5 1: ms10 2: ms20 3: ms40 4: ms80 5: ms160 - uint8_t ssb_subcarrier_offset;//ssbSubcarrierOffset or 𝑘𝑆𝑆𝐵 (38.211, section 7.4.3.1) Value: 0->31 + uint8_t beta_pss;//PSS EPRE to SSS EPRE in a SS/PBCH block [38.213, sec 4.1] Values: 0 = 0dB + uint8_t ssb_period;//SSB periodicity in msec Value: 0: ms5 1: ms10 2: ms20 3: ms40 4: ms80 5: ms160 + uint8_t ssb_subcarrier_offset;//ssbSubcarrierOffset or 𝑘𝑆𝑆𝐵 (38.211, section 7.4.3.1) Value: 0->31 uint32_t MIB;//MIB payload, where the 24 MSB are used and represent the MIB in [38.331 MIB IE] and represent 0 1 2 3 1 , , , ,..., A− a a a a a [38.212, sec 7.1.1] fapi_nr_ssb_mask_size_2_t ssb_mask_list[2]; fapi_nr_ssb_mask_size_64_t* ssb_beam_id_list;//64 - uint8_t ss_pbch_multiple_carriers_in_a_band;//0 = disabled 1 = enabled - uint8_t multiple_cells_ss_pbch_in_a_carrier;//Indicates that multiple cells will be supported in a single carrier 0 = disabled 1 = enabled - + uint8_t ss_pbch_multiple_carriers_in_a_band;//0 = disabled 1 = enabled + uint8_t multiple_cells_ss_pbch_in_a_carrier;//Indicates that multiple cells will be supported in a single carrier 0 = disabled 1 = enabled + uint8_t ssb_case; // 0: case A 1: case B 2: case C 3: case D 4: case E } fapi_nr_ssb_table_t; typedef struct diff --git a/openair1/PHY/INIT/nr_parms.c b/openair1/PHY/INIT/nr_parms.c index d6043775af..f49493cb32 100644 --- a/openair1/PHY/INIT/nr_parms.c +++ b/openair1/PHY/INIT/nr_parms.c @@ -29,73 +29,6 @@ static const uint32_t nr_subcarrier_spacing[MAX_NUM_SUBCARRIER_SPACING] = {15e3, 30e3, 60e3, 120e3, 240e3}; static const uint16_t nr_slots_per_subframe[MAX_NUM_SUBCARRIER_SPACING] = {1, 2, 4, 8, 16}; -// Table 5.4.3.3-1 38-101 -static const int nr_ssb_table[][3] = { - {1, 15, nr_ssb_type_A}, - {2, 15, nr_ssb_type_A}, - {3, 15, nr_ssb_type_A}, - {5, 15, nr_ssb_type_A}, - {5, 30, nr_ssb_type_B}, - {7, 15, nr_ssb_type_A}, - {8, 15, nr_ssb_type_A}, - {12, 15, nr_ssb_type_A}, - {13, 15, nr_ssb_type_A}, - {14, 15, nr_ssb_type_A}, - {18, 15, nr_ssb_type_A}, - {20, 15, nr_ssb_type_A}, - {24, 15, nr_ssb_type_A}, - {24, 30, nr_ssb_type_B}, - {25, 15, nr_ssb_type_A}, - {26, 15, nr_ssb_type_A}, - {28, 15, nr_ssb_type_A}, - {29, 15, nr_ssb_type_A}, - {30, 15, nr_ssb_type_A}, - {34, 15, nr_ssb_type_A}, - {34, 30, nr_ssb_type_C}, - {38, 15, nr_ssb_type_A}, - {38, 30, nr_ssb_type_C}, - {39, 15, nr_ssb_type_A}, - {39, 30, nr_ssb_type_C}, - {40, 30, nr_ssb_type_C}, - {41, 15, nr_ssb_type_A}, - {41, 30, nr_ssb_type_C}, - {46, 30, nr_ssb_type_C}, - {48, 30, nr_ssb_type_C}, - {50, 30, nr_ssb_type_C}, - {51, 15, nr_ssb_type_A}, - {53, 15, nr_ssb_type_A}, - {53, 30, nr_ssb_type_C}, - {65, 15, nr_ssb_type_A}, - {66, 15, nr_ssb_type_A}, - {66, 30, nr_ssb_type_B}, - {67, 15, nr_ssb_type_A}, - {70, 15, nr_ssb_type_A}, - {71, 15, nr_ssb_type_A}, - {74, 15, nr_ssb_type_A}, - {75, 15, nr_ssb_type_A}, - {76, 15, nr_ssb_type_A}, - {77, 30, nr_ssb_type_C}, - {78, 30, nr_ssb_type_C}, - {79, 30, nr_ssb_type_C}, - {85, 15, nr_ssb_type_A}, - {90, 15, nr_ssb_type_A}, - {90, 30, nr_ssb_type_C}, - {91, 15, nr_ssb_type_A}, - {92, 15, nr_ssb_type_A}, - {93, 15, nr_ssb_type_A}, - {94, 15, nr_ssb_type_A}, - {96, 30, nr_ssb_type_C}, - {100, 15, nr_ssb_type_A}, - {101, 15, nr_ssb_type_A}, - {101, 30, nr_ssb_type_C}, - {102, 30, nr_ssb_type_C}, - {104, 30, nr_ssb_type_C}, - {254, 15, nr_ssb_type_A}, - {254, 30, nr_ssb_type_C}, - {255, 15, nr_ssb_type_A}, - {255, 30, nr_ssb_type_B}, - {256, 15, nr_ssb_type_A}}; - void set_Lmax(NR_DL_FRAME_PARMS *fp) { // definition of Lmax according to ts 38.213 section 4.1 if (fp->dl_CarrierFreq < 6e9) { @@ -150,55 +83,34 @@ int nr_get_ssb_start_symbol(const NR_DL_FRAME_PARMS *fp, uint8_t i_ssb) return symbol; } -void set_scs_parameters (NR_DL_FRAME_PARMS *fp, int mu, int N_RB_DL) +static void set_scs_parameters(NR_DL_FRAME_PARMS *fp, int mu, int N_RB_DL, int ssb_case) { - int idx = 0; switch(mu) { case NR_MU_0: //15kHz scs fp->subcarrier_spacing = nr_subcarrier_spacing[NR_MU_0]; fp->slots_per_subframe = nr_slots_per_subframe[NR_MU_0]; - fp->ssb_type = nr_ssb_type_A; - while (nr_ssb_table[idx][0] != fp->nr_band) - idx++; - AssertFatal(nr_ssb_table[idx][1] == 15,"SCS %d not applicable to band %d\n", - fp->subcarrier_spacing,fp->nr_band); break; - case NR_MU_1: //30kHz scs fp->subcarrier_spacing = nr_subcarrier_spacing[NR_MU_1]; fp->slots_per_subframe = nr_slots_per_subframe[NR_MU_1]; - while(nr_ssb_table[idx][0] != fp->nr_band || - nr_ssb_table[idx][1] != 30) { - AssertFatal(nr_ssb_table[idx][0] <= fp->nr_band, - "SCS %d not applicable to band %d\n", - fp->subcarrier_spacing, - fp->nr_band); - idx++; - } - fp->ssb_type = nr_ssb_table[idx][2]; break; - case NR_MU_2: //60kHz scs fp->subcarrier_spacing = nr_subcarrier_spacing[NR_MU_2]; fp->slots_per_subframe = nr_slots_per_subframe[NR_MU_2]; break; - case NR_MU_3: fp->subcarrier_spacing = nr_subcarrier_spacing[NR_MU_3]; fp->slots_per_subframe = nr_slots_per_subframe[NR_MU_3]; - fp->ssb_type = nr_ssb_type_D; break; - case NR_MU_4: fp->subcarrier_spacing = nr_subcarrier_spacing[NR_MU_4]; fp->slots_per_subframe = nr_slots_per_subframe[NR_MU_4]; - fp->ssb_type = nr_ssb_type_E; break; - default: - AssertFatal(1==0,"Invalid numerology index %d", mu); + AssertFatal(false, "Invalid numerology index %d", mu); } + fp->ssb_type = ssb_case; // Start with FFT size 512 fp->ofdm_symbol_size = 512; @@ -231,7 +143,7 @@ void set_scs_parameters (NR_DL_FRAME_PARMS *fp, int mu, int N_RB_DL) fp->ofdm_symbol_size); } -void sl_set_scs_parameters (NR_DL_FRAME_PARMS *fp, int mu, int N_RB_SL) +void sl_set_scs_parameters(NR_DL_FRAME_PARMS *fp, int mu, int N_RB_SL) { AssertFatal(mu >= NR_MU_0 && mu <= NR_MU_4,"Invalid numerology index %d", mu); @@ -402,7 +314,7 @@ void nr_init_frame_parms(nfapi_nr_config_request_scf_t* cfg, NR_DL_FRAME_PARMS * fp->half_frame_bit = 0; // half frame bit initialized to 0 here fp->numerology_index = mu; - set_scs_parameters(fp, mu, fp->N_RB_DL); + set_scs_parameters(fp, mu, fp->N_RB_DL, cfg->ssb_table.case_v3.value); fp->slots_per_frame = 10* fp->slots_per_subframe; @@ -435,9 +347,7 @@ void nr_init_frame_parms(nfapi_nr_config_request_scf_t* cfg, NR_DL_FRAME_PARMS * fp->print_ue_help_cmdline_log = true; } -int nr_init_frame_parms_ue(NR_DL_FRAME_PARMS *fp, - fapi_nr_config_request_t* config, - uint16_t nr_band) +int nr_init_frame_parms_ue(NR_DL_FRAME_PARMS *fp, fapi_nr_config_request_t* config, uint16_t nr_band) { uint8_t nb_ant_ports_gNB = 1; @@ -488,7 +398,7 @@ int nr_init_frame_parms_ue(NR_DL_FRAME_PARMS *fp, fp->Ncp = Ncp; int N_RB = fp->N_RB_DL; - set_scs_parameters(fp, fp->numerology_index, N_RB); + set_scs_parameters(fp, fp->numerology_index, N_RB, config->ssb_table.ssb_case); fp->slots_per_frame = 10* fp->slots_per_subframe; fp->symbols_per_slot = ((Ncp == NORMAL)? 14 : 12); // to redefine for different slot formats @@ -553,7 +463,7 @@ void nr_init_frame_parms_ue_sa(NR_DL_FRAME_PARMS *frame_parms, const nrUE_cell_p frame_parms->frame_type = get_frame_type(frame_parms->nr_band, frame_parms->numerology_index); frame_parms->Ncp = NORMAL; - set_scs_parameters(frame_parms, frame_parms->numerology_index, frame_parms->N_RB_DL); + set_scs_parameters(frame_parms, frame_parms->numerology_index, frame_parms->N_RB_DL, set_ssb_case(mu, nr_band)); set_Lmax(frame_parms); frame_parms->slots_per_frame = 10* frame_parms->slots_per_subframe; diff --git a/openair2/LAYER2/NR_MAC_UE/config_ue.c b/openair2/LAYER2/NR_MAC_UE/config_ue.c index b3195894a4..053908e8de 100644 --- a/openair2/LAYER2/NR_MAC_UE/config_ue.c +++ b/openair2/LAYER2/NR_MAC_UE/config_ue.c @@ -229,6 +229,7 @@ static void config_common_ue_sa(NR_UE_MAC_INST_t *mac, NR_ServingCellConfigCommo cfg->ssb_table.ssb_offset_point_a = frequencyInfoDL->offsetToPointA; cfg->ssb_table.ssb_period = scc->ssb_PeriodicityServingCell; cfg->ssb_table.ssb_subcarrier_offset = mac->ssb_subcarrier_offset; + cfg->ssb_table.ssb_case = set_ssb_case(mac->numerology, mac->nr_band); if (mac->frequency_range == FR1){ cfg->ssb_table.ssb_mask_list[0].ssb_mask = ((uint32_t) scc->ssb_PositionsInBurst.inOneGroup.buf[0]) << 24; @@ -546,6 +547,7 @@ static void config_common_ue(NR_UE_MAC_INST_t *mac, NR_ServingCellConfigCommon_t cfg->ssb_table.ssb_period = *scc->ssb_periodicityServingCell; // NSA -> take ssb offset from SCS cfg->ssb_table.ssb_subcarrier_offset = absolute_diff % (12 * scs_scaling); + cfg->ssb_table.ssb_case = set_ssb_case(*scc->ssbSubcarrierSpacing, mac->nr_band); } switch (scc->ssb_PositionsInBurst->present) { diff --git a/openair2/LAYER2/NR_MAC_gNB/config.c b/openair2/LAYER2/NR_MAC_gNB/config.c index 005ad05720..eea50555c4 100644 --- a/openair2/LAYER2/NR_MAC_gNB/config.c +++ b/openair2/LAYER2/NR_MAC_gNB/config.c @@ -397,8 +397,9 @@ static void config_common(gNB_MAC_INST *nrmac, const nr_mac_config_t *config, NR nrmac->common_channels[0].ServingCellConfigCommon = scc; // Carrier configuration - struct NR_FrequencyInfoDL *frequencyInfoDL = scc->downlinkConfigCommon->frequencyInfoDL; - frequency_range_t frequency_range = get_freq_range_from_band(*frequencyInfoDL->frequencyBandList.list.array[0]); + NR_FrequencyInfoDL_t *frequencyInfoDL = scc->downlinkConfigCommon->frequencyInfoDL; + NR_FreqBandIndicatorNR_t nr_band = *frequencyInfoDL->frequencyBandList.list.array[0]; + frequency_range_t frequency_range = get_freq_range_from_band(nr_band); int bw_index = get_supported_band_index(frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing, frequency_range, frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth); @@ -406,7 +407,7 @@ static void config_common(gNB_MAC_INST *nrmac, const nr_mac_config_t *config, NR cfg->carrier_config.dl_bandwidth.tl.tag = NFAPI_NR_CONFIG_DL_BANDWIDTH_TAG; // temporary cfg->num_tlv++; - cfg->carrier_config.dl_frequency.value = from_nrarfcn(*frequencyInfoDL->frequencyBandList.list.array[0], + cfg->carrier_config.dl_frequency.value = from_nrarfcn(nr_band, *scc->ssbSubcarrierSpacing, frequencyInfoDL->absoluteFrequencyPointA) / 1000; // freq in kHz @@ -462,8 +463,7 @@ static void config_common(gNB_MAC_INST *nrmac, const nr_mac_config_t *config, NR } } - NR_FreqBandIndicatorNR_t band = *frequencyInfoDL->frequencyBandList.list.array[0]; - frame_type_t frame_type = get_frame_type(band, *scc->ssbSubcarrierSpacing); + frame_type_t frame_type = get_frame_type(nr_band, *scc->ssbSubcarrierSpacing); nrmac->common_channels[0].frame_type = frame_type; // Cell configuration @@ -508,7 +508,7 @@ static void config_common(gNB_MAC_INST *nrmac, const nr_mac_config_t *config, NR else { // If absent, use SCS as derived from the prach-ConfigurationIndex (for 839) int config_index = rach_ConfigCommon->rach_ConfigGeneric.prach_ConfigurationIndex; - int frame_type = get_frame_type(band, frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing); + int frame_type = get_frame_type(nr_band, frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing); int format = get_nr_prach_format_from_index(config_index, UL_pointA, frame_type) & 0xff; cfg->prach_config.prach_sub_c_spacing.value = get_delta_f_RA_long(format); } @@ -606,6 +606,10 @@ static void config_common(gNB_MAC_INST *nrmac, const nr_mac_config_t *config, NR cfg->ssb_table.ssb_subcarrier_offset.tl.tag = NFAPI_NR_CONFIG_SSB_SUBCARRIER_OFFSET_TAG; cfg->num_tlv++; + cfg->ssb_table.case_v3.value = set_ssb_case(*scc->ssbSubcarrierSpacing, nr_band); + cfg->ssb_table.case_v3.tl.tag = NFAPI_NR_FAPI_SSB_CASE_VENDOR_EXTENSION_TAG; + cfg->num_tlv++; + uint8_t *mib_payload = nrmac->common_channels[0].MIB_pdu; uint32_t mib = (mib_payload[2] << 16) | (mib_payload[1] << 8) | mib_payload[0]; cfg->ssb_table.MIB.tl.tag = NFAPI_NR_CONFIG_MIB_TAG; @@ -742,7 +746,7 @@ static void config_common(gNB_MAC_INST *nrmac, const nr_mac_config_t *config, NR carr_ul - carr_dl, bw, mu, - band, + nr_band, 12 * prb_offset + sc_offset, get_softmodem_params()->threequarter_fs ? "-E" : ""); } else { @@ -751,7 +755,7 @@ static void config_common(gNB_MAC_INST *nrmac, const nr_mac_config_t *config, NR carr_dl, bw, mu, - band, + nr_band, 12 * prb_offset + sc_offset, get_softmodem_params()->threequarter_fs ? "-E" : ""); } From 8180a5db0357de18b30d16135f0bc931d1fdfc40 Mon Sep 17 00:00:00 2001 From: francescomani Date: Sat, 14 Feb 2026 18:20:35 +0100 Subject: [PATCH 31/83] remove L1 nr_band dependence in frame parameters --- executables/nr-ue-ru.c | 6 +++++ executables/nr-ue-ru.h | 2 +- executables/nr-ue.c | 2 +- executables/nr-uesoftmodem.c | 2 +- .../public_inc/sidelink_nr_ue_interface.h | 2 +- openair1/PHY/INIT/nr_init.c | 9 ++++--- openair1/PHY/INIT/nr_parms.c | 25 +++++++++++-------- openair2/LAYER2/NR_MAC_UE/config_ue_sl.c | 7 +++--- 8 files changed, 32 insertions(+), 23 deletions(-) diff --git a/executables/nr-ue-ru.c b/executables/nr-ue-ru.c index 7235ae5c9f..8706b00938 100644 --- a/executables/nr-ue-ru.c +++ b/executables/nr-ue-ru.c @@ -110,6 +110,12 @@ int nrue_get_cell_count(void) return nrue_cell_count; } +int nrue_get_band(const PHY_VARS_NR_UE *UE) +{ + int cell_id = nrue_rus[UE->rf_map.card].used_by_cell; + return nrue_cells[cell_id].band; +} + const nrUE_cell_params_t *nrue_get_cell(int cell_id) { AssertFatal(cell_id >= 0 && cell_id < nrue_cell_count, "Invalid cell ID %d! Cell count = %d\n", cell_id, nrue_cell_count); diff --git a/executables/nr-ue-ru.h b/executables/nr-ue-ru.h index 9fe3fc3bd9..d5a173936b 100644 --- a/executables/nr-ue-ru.h +++ b/executables/nr-ue-ru.h @@ -30,7 +30,7 @@ const nrUE_cell_params_t *nrue_get_cell(int cell_id); NR_DL_FRAME_PARMS *nrue_get_cell_fp(int cell_id); void nrue_set_cell(int cell_id, const nrUE_cell_params_t *cell); void nrue_set_cell_params(configmodule_interface_t *cfg); - +int nrue_get_band(const PHY_VARS_NR_UE *UE); int nrue_get_ru_count(void); const nrUE_RU_params_t *nrue_get_ru(int ru_id); void nrue_set_ru_cell_id(int ru_id, int cell_id); diff --git a/executables/nr-ue.c b/executables/nr-ue.c index 0d1ae421f0..4060662818 100644 --- a/executables/nr-ue.c +++ b/executables/nr-ue.c @@ -837,7 +837,7 @@ void *UE_thread(void *arg) // Get list of GSCN in this band for UE's bandwidth and center frequency. LOG_W(PHY, "UE set to scan all GSCN in current bandwidth\n"); syncMsg->numGscn = - get_scan_ssb_first_sc(fp->dl_CarrierFreq, fp->N_RB_DL, fp->nr_band, fp->numerology_index, syncMsg->gscnInfo); + get_scan_ssb_first_sc(fp->dl_CarrierFreq, fp->N_RB_DL, nrue_get_band(UE), fp->numerology_index, syncMsg->gscnInfo); } else { LOG_W(PHY, "SSB position provided\n"); syncMsg->gscnInfo[0] = (nr_gscn_info_t){.ssbFirstSC = fp->ssb_start_subcarrier}; diff --git a/executables/nr-uesoftmodem.c b/executables/nr-uesoftmodem.c index a0e06850b7..08e7bce9fe 100644 --- a/executables/nr-uesoftmodem.c +++ b/executables/nr-uesoftmodem.c @@ -385,7 +385,7 @@ int main(int argc, char **argv) fapi_nr_config_request_t *nrUE_config = &UE_CC->nrUE_config; nr_init_frame_parms_ue(fp, nrUE_config, mac->nr_band); - cell.band = fp->nr_band; + cell.band = mac->nr_band; cell.rf_frequency = fp->dl_CarrierFreq; cell.rf_freq_offset = fp->ul_CarrierFreq - fp->dl_CarrierFreq; cell.numerology = fp->numerology_index; diff --git a/nfapi/open-nFAPI/nfapi/public_inc/sidelink_nr_ue_interface.h b/nfapi/open-nFAPI/nfapi/public_inc/sidelink_nr_ue_interface.h index 4110d88ed0..cb44cc115a 100644 --- a/nfapi/open-nFAPI/nfapi/public_inc/sidelink_nr_ue_interface.h +++ b/nfapi/open-nFAPI/nfapi/public_inc/sidelink_nr_ue_interface.h @@ -365,7 +365,7 @@ typedef struct //Indicates presence of +/-5Khz shift wrt FREF for V2X reference frequencies. //Possible values: {-1,0,1} int8_t sl_value_N; - + uint32_t band; } sl_nr_carrier_config_t; diff --git a/openair1/PHY/INIT/nr_init.c b/openair1/PHY/INIT/nr_init.c index 1615fc86f3..ef3fd4c7c7 100644 --- a/openair1/PHY/INIT/nr_init.c +++ b/openair1/PHY/INIT/nr_init.c @@ -313,31 +313,32 @@ void nr_phy_config_request_sim(PHY_VARS_gNB *gNB, gNB_config->carrier_config.num_tx_ant.value = fp->nb_antennas_tx; gNB_config->carrier_config.num_rx_ant.value = fp->nb_antennas_rx; + int nr_band = 78; switch (mu) { case 0: gNB->gNB_config.tdd_table.tdd_period.value = 7; fp->dl_CarrierFreq = 2600000000; fp->ul_CarrierFreq = 2600000000; - fp->nr_band = 38; + nr_band = 38; break; case 1: gNB->gNB_config.tdd_table.tdd_period.value = 6; fp->dl_CarrierFreq = 3600000000; fp->ul_CarrierFreq = 3600000000; - fp->nr_band = 78; + nr_band = 78; break; case 3: gNB->gNB_config.tdd_table.tdd_period.value = 3; fp->dl_CarrierFreq = 27524520000; fp->ul_CarrierFreq = 27524520000; - fp->nr_band = 261; + nr_band = 261; break; default: printf("unsupported numerology %d\n", mu); exit(-1); } - frequency_range_t frequency_range = get_freq_range_from_band(fp->nr_band); + frequency_range_t frequency_range = get_freq_range_from_band(nr_band); int bw_index = get_supported_band_index(mu, frequency_range, N_RB_DL); gNB_config->carrier_config.dl_bandwidth.value = get_supported_bw_mhz(frequency_range, bw_index); diff --git a/openair1/PHY/INIT/nr_parms.c b/openair1/PHY/INIT/nr_parms.c index f49493cb32..95002acbf9 100644 --- a/openair1/PHY/INIT/nr_parms.c +++ b/openair1/PHY/INIT/nr_parms.c @@ -364,7 +364,6 @@ int nr_init_frame_parms_ue(NR_DL_FRAME_PARMS *fp, fapi_nr_config_request_t* conf fp->nb_antenna_ports_gNB = nb_ant_ports_gNB; fp->tdd_config = tdd_cfg; fp->Nid_cell = Nid_cell; - fp->nr_band = nr_band; LOG_I(PHY, "Initializing frame parms: set nb_antenna_ports_gNB %d, tdd_config, %d, Nid_cell %d\n", fp->nb_antenna_ports_gNB, fp->tdd_config, fp->Nid_cell); @@ -382,13 +381,21 @@ int nr_init_frame_parms_ue(NR_DL_FRAME_PARMS *fp, fapi_nr_config_request_t* conf fp->N_RB_DL = config->carrier_config.dl_grid_size[fp->numerology_index]; fp->N_RB_SL = config->carrier_config.sl_grid_size[fp->numerology_index]; - fp->frame_type = get_frame_type(fp->nr_band, fp->numerology_index); + fp->frame_type = get_frame_type(nr_band, fp->numerology_index); int64_t uplink_frequency_offset = fp->ul_CarrierFreq - fp->dl_CarrierFreq; uplink_frequency_offset *= 1000; - LOG_I(PHY, "Initializing frame parms: DL frequency %lu Hz, UL frequency %lu Hz: band %d, uldl offset %ld Hz\n", fp->dl_CarrierFreq, fp->ul_CarrierFreq, fp->nr_band, uplink_frequency_offset); + LOG_I(PHY, + "Initializing frame parms: DL frequency %lu Hz, UL frequency %lu Hz: band %d, uldl offset %ld Hz\n", + fp->dl_CarrierFreq, + fp->ul_CarrierFreq, + nr_band, + uplink_frequency_offset); - AssertFatal(fp->frame_type==config->cell_config.frame_duplex_type, "Invalid duplex type (frame_type %d,cell_config.frame_duplex_type %d) in config request file for band %d\n", fp->frame_type,config->cell_config.frame_duplex_type,fp->nr_band); + AssertFatal(fp->frame_type == config->cell_config.frame_duplex_type, + "Invalid duplex type (frame_type %d,cell_config.frame_duplex_type %d) in config request file for band %d\n", + fp->frame_type,config->cell_config.frame_duplex_type, + nr_band); LOG_I(PHY,"Initializing frame parms for mu %d, N_RB %d, Ncp %d\n",fp->numerology_index, fp->N_RB_DL, Ncp); @@ -459,8 +466,7 @@ void nr_init_frame_parms_ue_sa(NR_DL_FRAME_PARMS *frame_parms, const nrUE_cell_p frame_parms->N_RB_DL = N_RB_DL; frame_parms->N_RB_UL = frame_parms->N_RB_DL; - frame_parms->nr_band = nr_band; - frame_parms->frame_type = get_frame_type(frame_parms->nr_band, frame_parms->numerology_index); + frame_parms->frame_type = get_frame_type(nr_band, frame_parms->numerology_index); frame_parms->Ncp = NORMAL; set_scs_parameters(frame_parms, frame_parms->numerology_index, frame_parms->N_RB_DL, set_ssb_case(mu, nr_band)); @@ -506,7 +512,6 @@ void nr_dump_frame_parms(NR_DL_FRAME_PARMS *fp) LOG_I(PHY, "fp->Ncp=%d\n", fp->Ncp); LOG_I(PHY, "fp->N_RB_DL=%d\n", fp->N_RB_DL); LOG_I(PHY, "fp->numerology_index=%d\n", fp->numerology_index); - LOG_I(PHY, "fp->nr_band=%d\n", fp->nr_band); LOG_I(PHY, "fp->ofdm_offset_divisor=%d\n", fp->ofdm_offset_divisor); LOG_I(PHY, "fp->threequarter_fs=%d\n", fp->threequarter_fs); LOG_I(PHY, "fp->sl_CarrierFreq=%lu\n", fp->sl_CarrierFreq); @@ -522,8 +527,6 @@ int nr_init_frame_parms_ue_sl(NR_DL_FRAME_PARMS *fp, fp->ofdm_offset_divisor = ofdm_offset_divisor; fp->threequarter_fs = threequarter_fs; - fp->nr_band = get_band(config->sl_carrier_config.sl_frequency, 0, 0, 0); - fp->att_rx = 0; fp->att_tx = 0; fp->nb_antennas_rx = config->sl_carrier_config.sl_num_rx_ant; @@ -535,7 +538,7 @@ int nr_init_frame_parms_ue_sl(NR_DL_FRAME_PARMS *fp, fp->N_RB_UL = fp->N_RB_SL; fp->Ncp = config->sl_bwp_config.sl_cyclic_prefix; - fp->frame_type = get_frame_type(fp->nr_band, fp->numerology_index); + fp->frame_type = get_frame_type(config->sl_carrier_config.band, fp->numerology_index); uint64_t bw_khz = (12 * config->sl_carrier_config.sl_grid_size) * (15 << config->sl_bwp_config.sl_scs); // REfer to section 3GPP spec 38.101 5.4E.2.1 @@ -555,7 +558,7 @@ int nr_init_frame_parms_ue_sl(NR_DL_FRAME_PARMS *fp, fp->dl_CarrierFreq, fp->ul_CarrierFreq, fp->sl_CarrierFreq, - fp->nr_band); + config->sl_carrier_config.band); AssertFatal(fp->frame_type == TDD, "Sidelink bands only support TDD"); diff --git a/openair2/LAYER2/NR_MAC_UE/config_ue_sl.c b/openair2/LAYER2/NR_MAC_UE/config_ue_sl.c index 58db78ea83..e6d872da81 100644 --- a/openair2/LAYER2/NR_MAC_UE/config_ue_sl.c +++ b/openair2/LAYER2/NR_MAC_UE/config_ue_sl.c @@ -126,9 +126,9 @@ static void sl_prepare_phy_config(int module_id, AssertFatal(SSB_ARFCN, "sl_AbsoluteFrequencySSB cannot be 0\n"); - LOG_I(NR_MAC, "SIDELINK CONFIGs: AbsFreqSSB:%d, AbsFreqPointA:%d, SL band:%d\n", - SSB_ARFCN,pointA_ARFCN, sl_band); + LOG_I(NR_MAC, "SIDELINK CONFIGs: AbsFreqSSB:%d, AbsFreqPointA:%d, SL band:%d\n", SSB_ARFCN, pointA_ARFCN, sl_band); + phycfg->sl_carrier_config.band = sl_band; //FREQSHIFT_7P5KHZ is DISABLED phycfg->sl_carrier_config.sl_frequency_shift_7p5khz = 0; phycfg->sl_carrier_config.sl_value_N = freqcfg->valueN_r16; @@ -141,8 +141,7 @@ static void sl_prepare_phy_config(int module_id, int bw_index = get_supported_band_index(carriercfg->subcarrierSpacing, FR1, carriercfg->carrierBandwidth); phycfg->sl_carrier_config.sl_bandwidth = get_supported_bw_mhz(FR1, bw_index); - phycfg->sl_carrier_config.sl_frequency = - from_nrarfcn(sl_band,carriercfg->subcarrierSpacing,pointA_ARFCN); // freq in kHz + phycfg->sl_carrier_config.sl_frequency = from_nrarfcn(sl_band, carriercfg->subcarrierSpacing, pointA_ARFCN); // freq in kHz phycfg->sl_carrier_config.sl_grid_size = carriercfg->carrierBandwidth; //For sidelink offset to carrier is 0. hence not used From 3c2853e1c06bf29c881c39ff276b72a34922c37e Mon Sep 17 00:00:00 2001 From: francescomani Date: Sun, 15 Feb 2026 16:38:18 +0100 Subject: [PATCH 32/83] remove RU functios gated by has_ctrl_prt parameter never set in NR code --- executables/nr-ru.c | 298 -------------------------------------------- 1 file changed, 298 deletions(-) diff --git a/executables/nr-ru.c b/executables/nr-ru.c index b2c3c98741..fa397c5bef 100644 --- a/executables/nr-ru.c +++ b/executables/nr-ru.c @@ -69,176 +69,6 @@ static int DEFRUTPCORES[] = {-1,-1,-1,-1}; static void NRRCconfig_RU(configmodule_interface_t *cfg); -/*************************************************************/ -/* Functions to attach and configure RRU */ - -int attach_rru(RU_t *ru) -{ - RRU_CONFIG_msg_t rru_config_msg; - int received_capabilities=0; - wait_gNBs(); - - // Wait for capabilities - while (received_capabilities==0) { - rru_config_msg = (RRU_CONFIG_msg_t){.type = RAU_tick, .len = sizeof(rru_config_msg.msg)}; - LOG_D(PHY, "Sending RAU tick to RRU %d\n", ru->idx); - AssertFatal((ru->ifdevice.trx_ctlsend_func(&ru->ifdevice,&rru_config_msg,rru_config_msg.len)!=-1), - "RU %d cannot access remote radio\n",ru->idx); - ssize_t msg_len = rru_config_msg.len + sizeof(RRU_capabilities_t); - // wait for answer with timeout - ssize_t len = ru->ifdevice.trx_ctlrecv_func(&ru->ifdevice, &rru_config_msg, msg_len); - if (len < 0) { - LOG_D(PHY, "Waiting for RRU %d\n", ru->idx); - } else if (rru_config_msg.type == RRU_capabilities) { - AssertFatal(rru_config_msg.len == msg_len, - "Received capabilities with incorrect length (%ld!=%ld)\n", - rru_config_msg.len, - msg_len); - RRU_capabilities_t *cap = (RRU_capabilities_t *)rru_config_msg.msg; - LOG_I(PHY, - "Received capabilities from RRU %d (len %ld/%ld, num_bands %d,max_pdschReferenceSignalPower %d, max_rxgain %d, nb_tx " - "%d, nb_rx %d)\n", - ru->idx, - rru_config_msg.len, - msg_len, - cap->num_bands, - cap->max_pdschReferenceSignalPower[0], - cap->max_rxgain[0], - cap->nb_tx[0], - cap->nb_rx[0]); - received_capabilities=1; - } else { - LOG_E(PHY,"Received incorrect message %d from RRU %d\n",rru_config_msg.type,ru->idx); - } - } - - configure_ru(ru, (RRU_capabilities_t *)rru_config_msg.msg); - rru_config_msg.type = RRU_config; - rru_config_msg.len = sizeof(RRU_CONFIG_msg_t)-MAX_RRU_CONFIG_SIZE+sizeof(RRU_config_t); - RRU_config_t *conf = (RRU_config_t *)rru_config_msg.msg; - LOG_I(PHY, - "Sending Configuration to RRU %d (num_bands %d,band0 %d,txfreq %u,rxfreq %u,att_tx %d,att_rx %d,N_RB_DL %d,N_RB_UL " - "%d,3/4FS %d, prach_FO %d, prach_CI %d)\n", - ru->idx, - conf->num_bands, - conf->band_list[0], - conf->tx_freq[0], - conf->rx_freq[0], - conf->att_tx[0], - conf->att_rx[0], - conf->N_RB_DL[0], - conf->N_RB_UL[0], - conf->threequarter_fs[0], - conf->prach_FreqOffset[0], - conf->prach_ConfigIndex[0]); - AssertFatal((ru->ifdevice.trx_ctlsend_func(&ru->ifdevice,&rru_config_msg,rru_config_msg.len)!=-1), - "RU %d failed send configuration to remote radio\n",ru->idx); - int len = ru->ifdevice.trx_ctlrecv_func(&ru->ifdevice, &rru_config_msg, sizeof(rru_config_msg.msg)); - if (len < 0) { - LOG_I(PHY,"Waiting for RRU %d\n",ru->idx); - } else if (rru_config_msg.type == RRU_config_ok) { - LOG_I(PHY, "RRU_config_ok received\n"); - } else { - LOG_E(PHY,"Received incorrect message %d from RRU %d\n",rru_config_msg.type,ru->idx); - } - - return 0; -} - -int connect_rau(RU_t *ru) { - RRU_CONFIG_msg_t rru_config_msg; - - // wait for RAU_tick - int tick_received = 0; - while (tick_received == 0) { - ssize_t msg_len = sizeof(rru_config_msg.msg); - int len = ru->ifdevice.trx_ctlrecv_func(&ru->ifdevice, &rru_config_msg, msg_len); - if (len < 0) { - LOG_I(PHY,"Waiting for RAU\n"); - } else { - if (rru_config_msg.type == RAU_tick) { - LOG_I(PHY,"Tick received from RAU\n"); - tick_received = 1; - } else - LOG_E(PHY, "Received erroneous message (%d)from RAU, expected RAU_tick\n", rru_config_msg.type); - } - } - - // send capabilities - rru_config_msg.type = RRU_capabilities; - rru_config_msg.len = sizeof(RRU_CONFIG_msg_t)-MAX_RRU_CONFIG_SIZE+sizeof(RRU_capabilities_t); - RRU_capabilities_t *cap = (RRU_capabilities_t *)rru_config_msg.msg; - LOG_I(PHY, - "Sending Capabilities (len %ld, num_bands %d,max_pdschReferenceSignalPower %d, max_rxgain %d, nb_tx %d, nb_rx %d)\n", - rru_config_msg.len, - ru->num_bands, - ru->max_pdschReferenceSignalPower, - ru->max_rxgain, - ru->nb_tx, - ru->nb_rx); - - switch (ru->function) { - case NGFI_RRU_IF4p5: - cap->FH_fmt = OAI_IF4p5_only; - break; - - case NGFI_RRU_IF5: - cap->FH_fmt = OAI_IF5_only; - break; - - case MBP_RRU_IF5: - cap->FH_fmt = MBP_IF5; - break; - - default: - AssertFatal(false, "RU_function is unknown %d\n", RC.ru[0]->function); - break; - } - - cap->num_bands = ru->num_bands; - for (int i = 0; i < ru->num_bands; i++) { - LOG_I(PHY,"Band %d: nb_rx %d nb_tx %d pdschReferenceSignalPower %d rxgain %d\n", - ru->band[i],ru->nb_rx,ru->nb_tx,ru->max_pdschReferenceSignalPower,ru->max_rxgain); - cap->band_list[i] = ru->band[i]; - cap->nb_rx[i] = ru->nb_rx; - cap->nb_tx[i] = ru->nb_tx; - cap->max_pdschReferenceSignalPower[i] = ru->max_pdschReferenceSignalPower; - cap->max_rxgain[i] = ru->max_rxgain; - } - - AssertFatal((ru->ifdevice.trx_ctlsend_func(&ru->ifdevice,&rru_config_msg,rru_config_msg.len)!=-1), - "RU %d failed send capabilities to RAU\n",ru->idx); - // wait for configuration - rru_config_msg.len = sizeof(RRU_CONFIG_msg_t)-MAX_RRU_CONFIG_SIZE+sizeof(RRU_config_t); - - int configuration_received = 0; - while (configuration_received == 0) { - int len = ru->ifdevice.trx_ctlrecv_func(&ru->ifdevice, &rru_config_msg, rru_config_msg.len); - if (len < 0) { - LOG_I(PHY,"Waiting for configuration from RAU\n"); - } else { - RRU_config_t *conf = (RRU_config_t *)rru_config_msg.msg; - LOG_I(PHY, - "Configuration received from RAU (num_bands %d,band0 %d,txfreq %u,rxfreq %u,att_tx %d,att_rx %d,N_RB_DL %d,N_RB_UL " - "%d,3/4FS %d, prach_FO %d, prach_CI %d)\n", - conf->num_bands, - conf->band_list[0], - conf->tx_freq[0], - conf->rx_freq[0], - conf->att_tx[0], - conf->att_rx[0], - conf->N_RB_DL[0], - conf->N_RB_UL[0], - conf->threequarter_fs[0], - conf->prach_FreqOffset[0], - conf->prach_ConfigIndex[0]); - configure_rru(ru, (void *)rru_config_msg.msg); - configuration_received = 1; - } - } - - return 0; -} /*************************************************************/ /* Southbound Fronthaul functions, RCC/RAU */ @@ -1034,15 +864,6 @@ void *ru_thread(void *param) LOG_I(PHY, "Starting IF interface for RU %d, nb_rx %d\n", ru->idx, ru->nb_rx); AssertFatal(ru->nr_start_if(ru, NULL) == 0, "Could not start the IF device\n"); - if (ru->has_ctrl_prt > 0) { - if (ru->if_south == LOCAL_RF) - ret = connect_rau(ru); - else - ret = attach_rru(ru); - - AssertFatal(ret == 0, "Cannot connect to remote radio\n"); - } - } else if (ru->if_south == LOCAL_RF) { // configure RF parameters only ret = openair0_device_load(&ru->rfdevice,&ru->openair0_cfg); AssertFatal(ret==0,"Cannot connect to local radio\n"); @@ -1257,123 +1078,6 @@ void kill_NR_RU_proc(int inst) { LOG_I(PHY, "RU %d RF device stopped\n",ru->idx); } -int check_capabilities(RU_t *ru,RRU_capabilities_t *cap) { - FH_fmt_options_t fmt = cap->FH_fmt; - int i; - LOG_I(PHY,"RRU %d, num_bands %d, looking for band %d\n",ru->idx,cap->num_bands,ru->nr_frame_parms->nr_band); - - for (i=0; inum_bands; i++) { - LOG_I(PHY,"band %d on RRU %d\n",cap->band_list[i],ru->idx); - if (ru->nr_frame_parms->nr_band == cap->band_list[i]) - break; - } - - if (i == cap->num_bands) { - LOG_I(PHY,"Couldn't find target NR band %d on RRU %d\n",ru->nr_frame_parms->nr_band,ru->idx); - return(-1); - } - - switch (ru->if_south) { - case LOCAL_RF: - AssertFatal(1==0, "This RU should not have a local RF, exiting\n"); - return(0); - break; - - case REMOTE_IF5: - if (fmt == OAI_IF5_only || fmt == OAI_IF5_and_IF4p5) - return (0); - break; - - case REMOTE_IF4p5: - if (fmt == OAI_IF4p5_only || fmt == OAI_IF5_and_IF4p5) - return (0); - break; - - case REMOTE_MBP_IF5: - if (fmt == MBP_IF5) - return (0); - break; - - default: - LOG_I(PHY,"No compatible Fronthaul interface found for RRU %d\n", ru->idx); - return(-1); - } - - return(-1); -} - -const char rru_format_options[4][20] = {"OAI_IF5_only", "OAI_IF4p5_only", "OAI_IF5_and_IF4p5", "MBP_IF5"}; -const char rru_formats[3][20] = {"OAI_IF5", "MBP_IF5", "OAI_IF4p5"}; -const char ru_if_formats[4][20] = {"LOCAL_RF", "REMOTE_OAI_IF5", "REMOTE_MBP_IF5", "REMOTE_OAI_IF4p5"}; - -void configure_ru(void *ruu, void *arg) -{ - RU_t *ru = (RU_t *)ruu; - nfapi_nr_config_request_scf_t *cfg = &ru->config; - int ret; - LOG_I(PHY, "Received capabilities from RRU %d\n", ru->idx); - - RRU_capabilities_t *capabilities = (RRU_capabilities_t *)arg; - if (capabilities->FH_fmt < MAX_FH_FMTs) - LOG_I(PHY, "RU FH options %s\n", rru_format_options[capabilities->FH_fmt]); - - ret = check_capabilities(ru,capabilities); - AssertFatal(ret == 0, "Cannot configure RRU %d, check_capabilities returned %d\n", ru->idx, ret); - // take antenna capabilities of RRU - ru->nb_tx = capabilities->nb_tx[0]; - ru->nb_rx = capabilities->nb_rx[0]; - // Pass configuration to RRU - LOG_I(PHY, "Using %s fronthaul (%d), band %d \n",ru_if_formats[ru->if_south],ru->if_south,ru->nr_frame_parms->nr_band); - - // wait for configuration - RRU_config_t *config = (RRU_config_t *)arg; - *config = (RRU_config_t){.FH_fmt = ru->if_south, - .num_bands = 1, - .band_list[0] = ru->nr_frame_parms->nr_band, - .tx_freq[0] = ru->nr_frame_parms->dl_CarrierFreq, - .rx_freq[0] = ru->nr_frame_parms->ul_CarrierFreq, - .att_tx[0] = ru->att_tx, - .att_rx[0] = ru->att_rx, - .N_RB_DL[0] = cfg->carrier_config.dl_grid_size[cfg->ssb_config.scs_common.value].value, - .N_RB_UL[0] = cfg->carrier_config.dl_grid_size[cfg->ssb_config.scs_common.value].value, - .threequarter_fs[0] = ru->nr_frame_parms->threequarter_fs}; - nr_init_frame_parms(&ru->config, ru->nr_frame_parms); - nr_phy_init_RU(ru); -} - -void configure_rru(void *ruu, void *arg) -{ - RRU_config_t *config = (RRU_config_t *)arg; - RU_t *ru = (RU_t *)ruu; - nfapi_nr_config_request_scf_t *cfg = &ru->config; - NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms; - - fp->nr_band = config->band_list[0]; - fp->dl_CarrierFreq = config->tx_freq[0]; - fp->ul_CarrierFreq = config->rx_freq[0]; - - if (fp->dl_CarrierFreq == fp->ul_CarrierFreq) { - cfg->cell_config.frame_duplex_type.value = TDD; - } else - cfg->cell_config.frame_duplex_type.value = FDD; - - ru->att_tx = config->att_tx[0]; - ru->att_rx = config->att_rx[0]; - int mu = cfg->ssb_config.scs_common.value; - cfg->carrier_config.dl_grid_size[mu].value = config->N_RB_DL[0]; - cfg->carrier_config.dl_grid_size[mu].value = config->N_RB_UL[0]; - fp->threequarter_fs = config->threequarter_fs[0]; - - if (ru->function==NGFI_RRU_IF4p5) { - fp->att_rx = ru->att_rx; - fp->att_tx = ru->att_tx; - } - - fill_rf_config(ru,ru->rf_config_file); - nr_init_frame_parms(&ru->config, fp); - nr_phy_init_RU(ru); -} - void set_function_spec_param(RU_t *ru) { switch (ru->if_south) { @@ -1444,7 +1148,6 @@ void set_function_spec_param(RU_t *ru) ru->nr_start_if = nr_start_if; // need to start if interface for IF5 ru->ifdevice.host_type = RAU_HOST; ru->ifdevice.eth_params = &ru->eth_params; - ru->ifdevice.configure_rru = configure_ru; break; @@ -1464,7 +1167,6 @@ void set_function_spec_param(RU_t *ru) ru->nr_start_if = nr_start_if; // need to start if interface for IF4p5 ru->ifdevice.host_type = RAU_HOST; ru->ifdevice.eth_params = &ru->eth_params; - ru->ifdevice.configure_rru = configure_ru; break; default: From 862f84bb68faa3d47db53bf98b66560c7857608a Mon Sep 17 00:00:00 2001 From: francescomani Date: Sun, 15 Feb 2026 16:50:57 +0100 Subject: [PATCH 33/83] remove band from frame parameters and get_band function not used anymore --- common/utils/nr/nr_common.c | 71 ------------------- common/utils/nr/nr_common.h | 1 - openair1/PHY/INIT/nr_init.c | 3 +- .../PHY/INIT/tests/test_nr_frame_params.cpp | 4 -- openair1/PHY/defs_nr_common.h | 2 - 5 files changed, 1 insertion(+), 80 deletions(-) diff --git a/common/utils/nr/nr_common.c b/common/utils/nr/nr_common.c index aba54a07ef..526adfd107 100644 --- a/common/utils/nr/nr_common.c +++ b/common/utils/nr/nr_common.c @@ -419,77 +419,6 @@ bool compare_relative_ul_channel_bw(int nr_band, int scs, int channel_bandwidth, return rel_bw > limit; } -static bool check_delta_duplex(int index, uint64_t dlfreq_khz, uint64_t ulfreq_khz, int64_t dlbw, int64_t ulbw) -{ - int uldl_min_offset = nr_bandtable[index].dl_min - nr_bandtable[index].ul_min; - int txrx_offset = dlfreq_khz - ulfreq_khz; - LOG_I(NR_PHY, "dlfreq:%ld ulfreq:%ld deltaduplex:%d khz, uldl_min_offset:%d khz\n", - dlfreq_khz, ulfreq_khz, txrx_offset, uldl_min_offset); - if (txrx_offset == uldl_min_offset) - return true; - - int band = nr_bandtable[index].band; - - // Refer to section 5.4.4 in spec 38.101-5 - if (band == 256 && txrx_offset >= 165000 && txrx_offset <= 215000) - return true; - if (band == 255 && txrx_offset >= -130500 && txrx_offset <= -72500) - return true; - if (band == 254 && txrx_offset >= 862000 && txrx_offset <= 885000) - return true; - - // Refer to section 5.4.4 in spec 38.101-1 for these bands 24, 91-94, 109 - if (band == 24 && (txrx_offset == -101500 || txrx_offset == -120500)) - return true; - //Delta duplex is also a range for these bands n91-n94, n109. - if ((band >= 91 && band <= 94) || band == 109) { - dlbw = ((dlbw / 1000) + 1) * 1000; - ulbw = ((ulbw / 1000) + 1) * 1000; - int lower_limit = nr_bandtable[index].dl_min - nr_bandtable[index].ul_max + ((dlbw + ulbw) >> 1); - int upper_limit = nr_bandtable[index].dl_max - nr_bandtable[index].ul_min - ((dlbw + ulbw) >> 1); - LOG_I(NR_PHY, "Band %d dlbw:%ld Khz, ulbw: %ld Khz RXTX lower limit:%d khz, upper limit:%d khz\n", - band, dlbw, ulbw, lower_limit, upper_limit); - - if (txrx_offset >= lower_limit && txrx_offset <= upper_limit) - return true; - } - - return false; -} - -uint16_t get_band(uint64_t downlink_frequency, int32_t delta_duplex, int64_t dlbw, int64_t ulbw) -{ - const int64_t dl_freq_khz = downlink_frequency / 1000; - const int32_t delta_duplex_khz = delta_duplex / 1000; - const int64_t ul_freq_khz = dl_freq_khz + delta_duplex_khz; - - uint16_t current_band = 0; - - for (int ind = 0; ind < sizeofArray(nr_bandtable); ind++) { - - if (dl_freq_khz < nr_bandtable[ind].dl_min || dl_freq_khz > nr_bandtable[ind].dl_max) - continue; - - if (ul_freq_khz < nr_bandtable[ind].ul_min || ul_freq_khz > nr_bandtable[ind].ul_max) - continue; - - if (!check_delta_duplex(ind, dl_freq_khz, ul_freq_khz, dlbw, ulbw)) - continue; - - current_band = nr_bandtable[ind].band; - } - - printf("DL frequency %"PRIu64": band %d, UL frequency %"PRIu64"\n", - downlink_frequency, current_band, downlink_frequency+delta_duplex); - - AssertFatal(current_band != 0, - "Can't find EUTRA band for frequency %" PRIu64 " and duplex_spacing %d\n", - downlink_frequency, - delta_duplex); - - return current_band; -} - int NRRIV2BW(int locationAndBandwidth,int N_RB) { int tmp = locationAndBandwidth/N_RB; int tmp2 = locationAndBandwidth%N_RB; diff --git a/common/utils/nr/nr_common.h b/common/utils/nr/nr_common.h index 93e3296e67..087440d13d 100644 --- a/common/utils/nr/nr_common.h +++ b/common/utils/nr/nr_common.h @@ -296,7 +296,6 @@ int get_coreset_num_cces(const uint8_t *FreqDomainResource, int duration); int get_nr_table_idx(int nr_bandP, uint8_t scs_index); int32_t get_delta_duplex(int nr_bandP, uint8_t scs_index); frame_type_t get_frame_type(uint16_t nr_bandP, uint8_t scs_index); -uint16_t get_band(uint64_t downlink_frequency, int32_t delta_duplex, int64_t dlbw, int64_t ulbw); int NRRIV2BW(int locationAndBandwidth,int N_RB); int NRRIV2PRBOFFSET(int locationAndBandwidth,int N_RB); int PRBalloc_to_locationandbandwidth0(int NPRB,int RBstart,int BWPsize); diff --git a/openair1/PHY/INIT/nr_init.c b/openair1/PHY/INIT/nr_init.c index ef3fd4c7c7..d8b34b2598 100644 --- a/openair1/PHY/INIT/nr_init.c +++ b/openair1/PHY/INIT/nr_init.c @@ -367,9 +367,8 @@ void nr_phy_config_request(NR_PHY_Config_t *phy_config) fp->ul_CarrierFreq = ((ul_bw_khz>>1) + gNB_config->carrier_config.uplink_frequency.value)*1000 ; int32_t dlul_offset = fp->ul_CarrierFreq - fp->dl_CarrierFreq; - fp->nr_band = get_band(fp->dl_CarrierFreq, dlul_offset, dl_bw_khz, ul_bw_khz); - LOG_I(PHY, "DL frequency %lu Hz, UL frequency %lu Hz: band %d, uldl offset %d Hz\n", fp->dl_CarrierFreq, fp->ul_CarrierFreq, fp->nr_band, dlul_offset); + LOG_I(PHY, "DL frequency %lu Hz, UL frequency %lu Hz: uldl offset %d Hz\n", fp->dl_CarrierFreq, fp->ul_CarrierFreq, dlul_offset); fp->threequarter_fs = get_softmodem_params()->threequarter_fs; LOG_D(PHY,"Configuring MIB for instance %d, : (Nid_cell %d,DL freq %llu, UL freq %llu)\n", diff --git a/openair1/PHY/INIT/tests/test_nr_frame_params.cpp b/openair1/PHY/INIT/tests/test_nr_frame_params.cpp index acf43ec0b8..4cd742f9f0 100644 --- a/openair1/PHY/INIT/tests/test_nr_frame_params.cpp +++ b/openair1/PHY/INIT/tests/test_nr_frame_params.cpp @@ -101,7 +101,6 @@ TEST(nr_frame_params, test_mu_3) cfg.cell_config.frame_duplex_type.value = TDD; cfg.ssb_config.scs_common.value = mu; fp.dl_CarrierFreq = 27524520000; - fp.nr_band = 261; nr_init_frame_parms(&cfg, &fp); nr_dump_frame_parms(&fp); test_coherence_symbol_api(&fp); @@ -121,7 +120,6 @@ TEST(nr_frame_params, test_mu_2) cfg.cell_config.frame_duplex_type.value = TDD; cfg.ssb_config.scs_common.value = mu; fp.dl_CarrierFreq = 27524520000; - fp.nr_band = 261; nr_init_frame_parms(&cfg, &fp); nr_dump_frame_parms(&fp); test_coherence_symbol_api(&fp); @@ -141,7 +139,6 @@ TEST(nr_frame_params, test_mu_1) cfg.cell_config.frame_duplex_type.value = TDD; cfg.ssb_config.scs_common.value = mu; fp.dl_CarrierFreq = 3600000000; - fp.nr_band = 78; nr_init_frame_parms(&cfg, &fp); nr_dump_frame_parms(&fp); test_coherence_symbol_api(&fp); @@ -161,7 +158,6 @@ TEST(nr_frame_params, test_mu_0) cfg.cell_config.frame_duplex_type.value = TDD; cfg.ssb_config.scs_common.value = mu; fp.dl_CarrierFreq = 2600000000; - fp.nr_band = 38; nr_init_frame_parms(&cfg, &fp); nr_dump_frame_parms(&fp); test_coherence_symbol_api(&fp); diff --git a/openair1/PHY/defs_nr_common.h b/openair1/PHY/defs_nr_common.h index dc2630348c..ca5cb96a22 100644 --- a/openair1/PHY/defs_nr_common.h +++ b/openair1/PHY/defs_nr_common.h @@ -173,8 +173,6 @@ struct NR_DL_FRAME_PARMS { uint8_t N_RBG; /// Total Number of Resource Block Groups SubSets: this is P uint8_t N_RBGS; - /// NR Band - uint16_t nr_band; /// DL carrier frequency uint64_t dl_CarrierFreq; /// UL carrier frequency From 7f8e0b2cd5ad86e055434d0d7ab0f30550e1fc12 Mon Sep 17 00:00:00 2001 From: Behrad Mahmoudi Date: Tue, 17 Feb 2026 20:25:51 +0100 Subject: [PATCH 34/83] Now, the listening telnet socket is only bound to the dedicated interface IPs in config file, both for V4 and V6 --- common/utils/telnetsrv/telnetsrv.c | 50 +++++++++++++++++++++--------- common/utils/telnetsrv/telnetsrv.h | 2 +- 2 files changed, 37 insertions(+), 15 deletions(-) diff --git a/common/utils/telnetsrv/telnetsrv.c b/common/utils/telnetsrv/telnetsrv.c index 03b67506bc..407a6b73b9 100644 --- a/common/utils/telnetsrv/telnetsrv.c +++ b/common/utils/telnetsrv/telnetsrv.c @@ -57,6 +57,10 @@ #include "common/utils/threadPool/notified_fifo.h" #include #include "common/oai_version.h" +#include +#include +#include +#include #include "telnetsrv_phycmd.h" @@ -79,7 +83,7 @@ paramdef_t telnetoptions[] = { /* configuration parameters for telnet utility */ /* optname helpstr paramflags XXXptr defXXXval type numelt */ /*-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ - {"listenaddr", "\n", 0, .uptr = &telnetparams.listenaddr, .defstrval = "0.0.0.0", TYPE_IPV4ADDR, 0}, + {"listenaddr", "\n", 0, .strptr = &telnetparams.listenaddr, .defstrval = "0.0.0.0", TYPE_STRING, 0}, {"listenport", "\n", 0, .uptr = &telnetparams.listenport, .defuintval = 9090, TYPE_UINT, 0}, {"listenstdin", "enable input from stdin\n", PARAMFLAG_BOOL, .uptr = &telnetparams.listenstdin, .defuintval = 0, TYPE_UINT, 0}, {"priority", " ai_next){ - if(bind(sock, (void *) &name, sizeof(name))) - fprintf(stderr,"[TELNETSRV] Error %s on bind call\n",strerror(errno)); + sock = socket(p->ai_family, p->ai_socktype, p->ai_protocol); + if (sock < 0) continue; + setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof optval); + if (bind(sock, p->ai_addr, p->ai_addrlen) == 0) + break; + close(sock); + sock = -1; + } + + freeaddrinfo(res); + + if (sock < 0) { + fprintf(stderr, "Failed to bind socket\n"); + exit(-1); + } if(listen(sock, 1) == -1) fprintf(stderr,"[TELNETSRV] Error %s on listen call\n",strerror(errno)); diff --git a/common/utils/telnetsrv/telnetsrv.h b/common/utils/telnetsrv/telnetsrv.h index ab866c88fb..b841905cae 100644 --- a/common/utils/telnetsrv/telnetsrv.h +++ b/common/utils/telnetsrv/telnetsrv.h @@ -162,7 +162,7 @@ typedef struct { cmdparser_t CmdParsers[TELNET_MAXCMD]; // array of registered modules. char msgbuff[TELNET_MAX_MSGLENGTH]; // internal buffer of the client_printf function which is used to print to the client terminal */ unsigned int listenport; // ip port the telnet server is listening on - unsigned int listenaddr; // ip address the telnet server is listening on + char *listenaddr; // ip address the telnet server is listening on unsigned int listenstdin; // enable command input from stdin unsigned int loopcount; // loop command param: number of loop iteration unsigned int loopdelay; // loop command param: delay in ms between 2 iterations From 0a79dce24b946c8a72e91164b5452f9306391a76 Mon Sep 17 00:00:00 2001 From: francescomani Date: Thu, 23 Jan 2025 10:23:30 +0100 Subject: [PATCH 35/83] configuration of PUCCH2 PRB number depending on antenna ports --- openair2/LAYER2/NR_MAC_gNB/nr_radio_config.c | 72 ++++++++++++-------- 1 file changed, 44 insertions(+), 28 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_radio_config.c b/openair2/LAYER2/NR_MAC_gNB/nr_radio_config.c index a7376d69ec..8f3944ee44 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_radio_config.c +++ b/openair2/LAYER2/NR_MAC_gNB/nr_radio_config.c @@ -56,7 +56,6 @@ #define DEFAULT_MGTA NR_GapConfig__mgta_ms0dot5 #define DEFAULT_MGL NR_GapConfig__mgl_ms6 -#define PUCCH2_SIZE 8 const uint8_t slotsperframe[5] = {10, 20, 40, 80, 160}; static NR_BWP_t clone_generic_parameters(const NR_BWP_t *gp) @@ -216,7 +215,14 @@ static NR_SetupRelease_PDSCH_ConfigCommon_t *clone_pdsch_configcommon(const NR_S return clone; } -static int get_nb_pucch2_per_slot(const NR_ServingCellConfigCommon_t *scc, int bwp_size) +static int get_pucch2_size(const int num_ant_ports) +{ + // TODO the logic to set the number of PRBs needs to be improved + // it should involve the code rate parameter and the max number of bits to be transmitted + return (num_ant_ports <= 4 ? 8 : 16); +} + +static int get_nb_pucch2_per_slot(const NR_ServingCellConfigCommon_t *scc, int bwp_size, const nr_pdsch_AntennaPorts_t *ap) { const NR_TDD_UL_DL_Pattern_t *tdd = scc->tdd_UL_DL_ConfigurationCommon ? &scc->tdd_UL_DL_ConfigurationCommon->pattern1 : NULL; const int n_slots_frame = slotsperframe[*scc->ssbSubcarrierSpacing]; @@ -226,12 +232,14 @@ static int get_nb_pucch2_per_slot(const NR_ServingCellConfigCommon_t *scc, int b int max_csi_reports = MAX_MOBILES_PER_GNB << 1; // 2 reports per UE (RSRP and RI-PMI-CQI) int available_report_occasions = max_meas_report_period * ul_slots_period / n_slots_period; int nb_pucch2 = (max_csi_reports / (available_report_occasions + 1)) + 1; - // in current implementation we need (nb_pucch2 * PUCCH2_SIZE) prbs for PUCCH2 + int pucch2_size = get_pucch2_size(ap->N1 * ap->N2 * ap->XP); + // in current implementation we need (nb_pucch2 * pucch2_size) prbs for PUCCH2 // and MAX_MOBILES_PER_GNB prbs for PUCCH1 // checked for validity in verify_radio_configuration - AssertFatal((nb_pucch2 * PUCCH2_SIZE) + MAX_MOBILES_PER_GNB <= bwp_size, + AssertFatal((nb_pucch2 * pucch2_size) + MAX_MOBILES_PER_GNB <= bwp_size, "Cannot allocate all required PUCCH resources for max number of %d UEs in BWP with %d PRBs\n", - MAX_MOBILES_PER_GNB, bwp_size); + MAX_MOBILES_PER_GNB, + bwp_size); return nb_pucch2; } @@ -1206,11 +1214,12 @@ static void set_dl_DataToUL_ACK(NR_PUCCH_Config_t *pucch_Config, int min_feedbac } // PUCCH resource set 0 for configuration with O_uci <= 2 bits and/or a positive or negative SR (section 9.2.1 of 38.213) -static void config_pucch_resset0(NR_PUCCH_Config_t *pucch_Config, +static void config_pucch_resset0(const NR_ServingCellConfigCommon_t *scc, + NR_PUCCH_Config_t *pucch_Config, int uid, int curr_bwp, - int num_pucch2, - const NR_UE_NR_Capability_t *uecap) + const NR_UE_NR_Capability_t *uecap, + const nr_pdsch_AntennaPorts_t *ap) { NR_PUCCH_ResourceSet_t *pucchresset = calloc(1,sizeof(*pucchresset)); pucchresset->pucch_ResourceSetId = 0; @@ -1224,9 +1233,11 @@ static void config_pucch_resset0(NR_PUCCH_Config_t *pucch_Config, AssertFatal(pucch_F0_2WithoutFH == NULL,"UE does not support PUCCH F0 without frequency hopping. Current configuration is without FH\n"); } + int pucch2_size = get_pucch2_size(ap->N1 * ap->N2 * ap->XP); NR_PUCCH_Resource_t *pucchres0 = calloc(1,sizeof(*pucchres0)); pucchres0->pucch_ResourceId = *pucchid; - pucchres0->startingPRB = (PUCCH2_SIZE * num_pucch2) + uid; + int num_pucch2 = get_nb_pucch2_per_slot(scc, curr_bwp, ap); + pucchres0->startingPRB = (pucch2_size * num_pucch2) + uid; // checked for validity in verify_radio_configuration AssertFatal(pucchres0->startingPRB < curr_bwp, "Not enough resources in current BWP (size %d) to allocate uid %d\n", curr_bwp, uid); pucchres0->intraSlotFrequencyHopping = NULL; @@ -1243,10 +1254,12 @@ static void config_pucch_resset0(NR_PUCCH_Config_t *pucch_Config, // PUCCH resource set 1 for configuration with O_uci > 2 bits (currently format2) -static void config_pucch_resset1(NR_PUCCH_Config_t *pucch_Config, +static void config_pucch_resset1(const NR_ServingCellConfigCommon_t *scc, + NR_PUCCH_Config_t *pucch_Config, int uid, - int num_pucch2, - const NR_UE_NR_Capability_t *uecap) + int curr_bwp, + const NR_UE_NR_Capability_t *uecap, + const nr_pdsch_AntennaPorts_t *ap) { NR_PUCCH_ResourceSet_t *pucchresset=calloc(1,sizeof(*pucchresset)); pucchresset->pucch_ResourceSetId = 1; @@ -1260,14 +1273,16 @@ static void config_pucch_resset1(NR_PUCCH_Config_t *pucch_Config, AssertFatal(pucch_F0_2WithoutFH == NULL,"UE does not support PUCCH F2 without frequency hopping. Current configuration is without FH\n"); } + int pucch2_size = get_pucch2_size(ap->N1 * ap->N2 * ap->XP); NR_PUCCH_Resource_t *pucchres2 = calloc(1,sizeof(*pucchres2)); pucchres2->pucch_ResourceId = *pucchressetid; - pucchres2->startingPRB = PUCCH2_SIZE * (uid % num_pucch2); + int num_pucch2 = get_nb_pucch2_per_slot(scc, curr_bwp, ap); + pucchres2->startingPRB = pucch2_size * (uid % num_pucch2); pucchres2->intraSlotFrequencyHopping = NULL; pucchres2->secondHopPRB = NULL; pucchres2->format.present = NR_PUCCH_Resource__format_PR_format2; pucchres2->format.choice.format2 = calloc(1,sizeof(*pucchres2->format.choice.format2)); - pucchres2->format.choice.format2->nrofPRBs = PUCCH2_SIZE; + pucchres2->format.choice.format2->nrofPRBs = pucch2_size; pucchres2->format.choice.format2->nrofSymbols = 1; pucchres2->format.choice.format2->startingSymbolIndex = 13; asn1cSeqAdd(&pucch_Config->resourceToAddModList->list,pucchres2); @@ -1898,9 +1913,8 @@ static NR_BWP_Uplink_t *config_uplinkBWP(bool is_SA, pucch_Config->resourceSetToReleaseList = NULL; pucch_Config->resourceToAddModList = calloc(1,sizeof(*pucch_Config->resourceToAddModList)); pucch_Config->resourceToReleaseList = NULL; - int num_pucch2 = get_nb_pucch2_per_slot(scc, curr_bwp); - config_pucch_resset0(pucch_Config, uid, curr_bwp, num_pucch2, uecap); - config_pucch_resset1(pucch_Config, uid, num_pucch2, uecap); + config_pucch_resset0(scc, pucch_Config, uid, curr_bwp, uecap, &configuration->pdsch_AntennaPorts); + config_pucch_resset1(scc, pucch_Config, uid, curr_bwp, uecap, &configuration->pdsch_AntennaPorts); set_pucch_power_config(pucch_Config, configuration->do_CSIRS); scheduling_request_config(scc, pucch_Config, ubwp->bwp_Common->genericParameters.subcarrierSpacing); set_dl_DataToUL_ACK(pucch_Config, configuration->minRXTXTIME, ubwp->bwp_Common->genericParameters.subcarrierSpacing); @@ -1935,10 +1949,11 @@ static void set_csi_meas_periodicity(const NR_ServingCellConfigCommon_t *scc, NR_CSI_ReportConfig_t *csirep, int uid, int curr_bwp, + const nr_pdsch_AntennaPorts_t *antennaports, bool is_rsrp) { const int ideal_period = set_ideal_period(true); - const int num_pucch2 = get_nb_pucch2_per_slot(scc, curr_bwp); + const int num_pucch2 = get_nb_pucch2_per_slot(scc, curr_bwp, antennaports); const int idx = (uid * 2 / num_pucch2) + is_rsrp; frame_structure_t *fs = &RC.nrmac[0]->frame_structure; int offset = get_ul_slot_offset(fs, idx, true); @@ -2121,7 +2136,7 @@ static void config_csi_meas_report(NR_CSI_MeasConfig_t *csi_MeasConfig, csirep->nzp_CSI_RS_ResourcesForInterference = NULL; csirep->reportConfigType.present = NR_CSI_ReportConfig__reportConfigType_PR_periodic; csirep->reportConfigType.choice.periodic = calloc(1, sizeof(*csirep->reportConfigType.choice.periodic)); - set_csi_meas_periodicity(servingcellconfigcommon, csirep, uid, curr_bwp, false); + set_csi_meas_periodicity(servingcellconfigcommon, csirep, uid, curr_bwp, antennaports, false); asn1cSeqAdd(&csirep->reportConfigType.choice.periodic->pucch_CSI_ResourceList.list, pucchcsires); csirep->reportQuantity.present = NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_PMI_CQI; csirep->reportQuantity.choice.cri_RI_PMI_CQI = (NULL_t)0; @@ -2188,10 +2203,11 @@ static void config_rsrp_meas_report(NR_CSI_MeasConfig_t *csi_MeasConfig, int rep_id, int uid, int curr_bwp, - int num_antenna_ports, uint64_t ssb_bitmap) { int resource_id = -1; + const nr_pdsch_AntennaPorts_t *pdschap = &configuration->pdsch_AntennaPorts; + const int num_antenna_ports = pdschap->N1 * pdschap->N2 * pdschap->XP; for (int csi_list = 0; csi_list < csi_MeasConfig->csi_ResourceConfigToAddModList->list.count; csi_list++) { NR_CSI_ResourceConfig_t *csires = csi_MeasConfig->csi_ResourceConfigToAddModList->list.array[csi_list]; if (csires->csi_RS_ResourceSetList.present == NR_CSI_ResourceConfig__csi_RS_ResourceSetList_PR_nzp_CSI_RS_SSB) { @@ -2215,7 +2231,7 @@ static void config_rsrp_meas_report(NR_CSI_MeasConfig_t *csi_MeasConfig, csirep->nzp_CSI_RS_ResourcesForInterference = NULL; csirep->reportConfigType.present = NR_CSI_ReportConfig__reportConfigType_PR_periodic; csirep->reportConfigType.choice.periodic = calloc(1, sizeof(*csirep->reportConfigType.choice.periodic)); - set_csi_meas_periodicity(servingcellconfigcommon, csirep, uid, curr_bwp, true); + set_csi_meas_periodicity(servingcellconfigcommon, csirep, uid, curr_bwp, pdschap, true); asn1cSeqAdd(&csirep->reportConfigType.choice.periodic->pucch_CSI_ResourceList.list, pucchcsires); if (configuration->report_type == SSB_SINR) { csirep->reportQuantity.present = NR_CSI_ReportConfig__reportQuantity_PR_none; @@ -3344,9 +3360,8 @@ static NR_BWP_UplinkDedicated_t *configure_initial_ul_bwp(const NR_ServingCellCo pucch_Config->resourceSetToReleaseList = NULL; pucch_Config->resourceToAddModList = calloc(1, sizeof(*pucch_Config->resourceToAddModList)); pucch_Config->resourceToReleaseList = NULL; - int num_pucch2 = get_nb_pucch2_per_slot(scc, curr_bwp); - config_pucch_resset0(pucch_Config, id, curr_bwp, num_pucch2, uecap); - config_pucch_resset1(pucch_Config, id, num_pucch2, uecap); + config_pucch_resset0(scc, pucch_Config, id, curr_bwp, uecap, &configuration->pdsch_AntennaPorts); + config_pucch_resset1(scc, pucch_Config, id, curr_bwp, uecap, &configuration->pdsch_AntennaPorts); set_pucch_power_config(pucch_Config, configuration->do_CSIRS); initialUplinkBWP->pusch_Config = config_pusch(configuration, scc, uecap); @@ -3520,7 +3535,6 @@ static NR_CSI_MeasConfig_t *get_csiMeasConfig(const NR_ServingCellConfig_t *conf bwp_id + 10, uid, curr_bwp, - pdsch_AntennaPorts, bitmap); return csi_MeasConfig; } @@ -3742,16 +3756,18 @@ static bool verify_radio_configuration(int uid, const NR_ServingCellConfigCommon return false; // cannot allocate resources for CSI-RS } + const nr_pdsch_AntennaPorts_t *ap = &configuration->pdsch_AntennaPorts; + int pucch2_size = get_pucch2_size(ap->N1 * ap->N2 * ap->XP); int curr_bwp = NRRIV2BW(scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); - int num_pucch2 = get_nb_pucch2_per_slot(scc, curr_bwp); - int pucchres0_startingPRB = (PUCCH2_SIZE * num_pucch2) + uid; + int num_pucch2 = get_nb_pucch2_per_slot(scc, curr_bwp, ap); + int pucchres0_startingPRB = (pucch2_size * num_pucch2) + uid; // see config_pucch_resset0 if (pucchres0_startingPRB >= curr_bwp) { LOG_E(NR_RRC, "UID %d, cannot allocate resources for PUCCH0, rejecting UE\n", uid); return false; // cannot allocate resources for PUCCH0 } // see get_nb_pucch2_per_slot - if ((num_pucch2 * PUCCH2_SIZE) + MAX_MOBILES_PER_GNB > curr_bwp) { + if ((num_pucch2 * pucch2_size) + MAX_MOBILES_PER_GNB > curr_bwp) { LOG_E(NR_RRC, "UID %d, cannot allocate resources for PUCCH2, rejecting UE\n", uid); return false; // cannot allocate resources for PUCCH2 } From 448f27324812a31c14df895ca5c8cdf3c5d57881 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Fri, 20 Feb 2026 19:14:28 +0100 Subject: [PATCH 36/83] Write NB_ANTENNAS_RX/TX to header file and use in stack Prior to this commit, constants NB_ANTENNAS_RX/TX are provided on the command line to each compiler invocation. This has the drawback (1) that also files that don't need that get the constants, and (2) it is not easy to find them using ctags or similar, as the only definition is in CMakeLists.txt (where it is not found). In this commit, use cmake configure_file() to write a header file with these constants. The file will be generated during cmake invocation, and written to /common/cmake_defs.h. The relevant files that need this definition will pick it from the header. This has been used previously also in a commit to write git information. See-also: 8bffd1666df6 ("Avoid complete rebuild on cmake run with git info change") --- CMakeLists.txt | 6 +++-- cmake_targets/macros.cmake | 13 ----------- common/CMakeLists.txt | 1 + common/cmake_defs.h.in | 30 +++++++++++++++++++++++++ openair1/PHY/defs_UE.h | 1 + openair1/PHY/defs_nr_UE.h | 1 + openair1/PHY/impl_defs_top_NB_IoT.h | 1 + openair1/SIMULATION/LTE_PHY/dlsim.c | 1 + openair1/SIMULATION/LTE_PHY/syncsim.c | 1 + openair1/SIMULATION/LTE_PHY/ulsim.c | 1 + openair1/SIMULATION/TOOLS/channel_sim.c | 1 + radio/COMMON/common_lib.h | 1 + radio/fhi_72/oran_isolate.h | 1 + 13 files changed, 44 insertions(+), 15 deletions(-) create mode 100644 common/cmake_defs.h.in diff --git a/CMakeLists.txt b/CMakeLists.txt index 46016431aa..d0b9f17a02 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -549,8 +549,10 @@ endif() # Hardware dependant options ################################### -add_list1_option(NB_ANTENNAS_RX "4" "Number of antennas in reception" "1" "2" "4") -add_list1_option(NB_ANTENNAS_TX "4" "Number of antennas in transmission" "1" "2" "4") +set(NB_ANTENNAS_RX "4" CACHE STRING "Number of antennas in reception") +set_property(CACHE NB_ANTENNAS_RX PROPERTY STRINGS "1" "2" "4" "8") +set(NB_ANTENNAS_TX "4" CACHE STRING "Number of antennas in transmission") +set_property(CACHE NB_ANTENNAS_TX PROPERTY STRINGS "1" "2" "4" "8") set (CONFIG_ROOTDIR ${OPENAIR_DIR}/common/config) add_library(config_internals OBJECT diff --git a/cmake_targets/macros.cmake b/cmake_targets/macros.cmake index eafee3a0c1..cc59e12a90 100644 --- a/cmake_targets/macros.cmake +++ b/cmake_targets/macros.cmake @@ -34,19 +34,6 @@ macro(add_integer_option name val helpstr) add_definitions("-D${name}=${value}") endmacro(add_integer_option) -macro(add_list1_option name val helpstr) - if(DEFINED ${name}) - set(value ${${name}}) - else(DEFINED ${name}) - set(value ${val}) - endif() - set(${name} ${value} CACHE STRING "${helpstr}") - set_property(CACHE ${name} PROPERTY STRINGS ${ARGN}) - if(NOT "${value}" STREQUAL "False") - add_definitions("-D${name}=${value}") - endif() -endmacro(add_list1_option) - macro(add_list2_option name val helpstr) if(DEFINED ${name}) set(value ${${name}}) diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index f58880b04a..be079b874d 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -1,6 +1,7 @@ add_subdirectory(utils) add_subdirectory(config/yaml) +configure_file(cmake_defs.h.in cmake_defs.h @ONLY) configure_file(oai_version.h.in oai_version.h @ONLY) add_library(instrumentation INTERFACE) diff --git a/common/cmake_defs.h.in b/common/cmake_defs.h.in new file mode 100644 index 0000000000..c2221bf5e5 --- /dev/null +++ b/common/cmake_defs.h.in @@ -0,0 +1,30 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#ifndef CMAKE_DEFS_H_ +#define CMAKE_DEFS_H_ + +// Note: this file is automatically generated from common/cmake_defs.h.in +// please don't modify and change defines such as NB_ANTENNAS_RX/TX in cmake +#define NB_ANTENNAS_RX @NB_ANTENNAS_RX@ +#define NB_ANTENNAS_TX @NB_ANTENNAS_TX@ + +#endif /* CMAKE_DEFS_H_ */ diff --git a/openair1/PHY/defs_UE.h b/openair1/PHY/defs_UE.h index cd8ce75906..82cc747581 100644 --- a/openair1/PHY/defs_UE.h +++ b/openair1/PHY/defs_UE.h @@ -56,6 +56,7 @@ #include #include "common_lib.h" +#include "common/cmake_defs.h" #include "defs_common.h" #include "impl_defs_top.h" diff --git a/openair1/PHY/defs_nr_UE.h b/openair1/PHY/defs_nr_UE.h index 5511d8ed0d..c14751a050 100644 --- a/openair1/PHY/defs_nr_UE.h +++ b/openair1/PHY/defs_nr_UE.h @@ -39,6 +39,7 @@ #endif #endif +#include "common/cmake_defs.h" #include "defs_nr_common.h" #include "CODING/nrPolar_tools/nr_polar_pbch_defs.h" #include "PHY/defs_nr_sl_UE.h" diff --git a/openair1/PHY/impl_defs_top_NB_IoT.h b/openair1/PHY/impl_defs_top_NB_IoT.h index a6409839a4..8d05e9a05e 100644 --- a/openair1/PHY/impl_defs_top_NB_IoT.h +++ b/openair1/PHY/impl_defs_top_NB_IoT.h @@ -34,6 +34,7 @@ #define __PHY_IMPLEMENTATION_DEFS_NB_IOT_H__ #include "common/openairinterface5g_limits.h" +#include "common/cmake_defs.h" #define NUMBER_OF_SUBBANDS_MAX_NB_IoT 13 typedef enum {no_relay_NB_IoT=1,unicast_relay_type1_NB_IoT,unicast_relay_type2_NB_IoT, multicast_relay_NB_IoT} relaying_type_t_NB_IoT; diff --git a/openair1/SIMULATION/LTE_PHY/dlsim.c b/openair1/SIMULATION/LTE_PHY/dlsim.c index d6e8482919..a09b3558cb 100644 --- a/openair1/SIMULATION/LTE_PHY/dlsim.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim.c @@ -35,6 +35,7 @@ #include #include #include +#include "common/cmake_defs.h" #include "common/config/config_load_configmodule.h" #include "common/utils/LOG/log.h" #include "common/utils/var_array.h" diff --git a/openair1/SIMULATION/LTE_PHY/syncsim.c b/openair1/SIMULATION/LTE_PHY/syncsim.c index 456bc53a2c..c29b16e041 100644 --- a/openair1/SIMULATION/LTE_PHY/syncsim.c +++ b/openair1/SIMULATION/LTE_PHY/syncsim.c @@ -30,6 +30,7 @@ #include #include +#include "common/cmake_defs.h" #include "SIMULATION/TOOLS/defs.h" #include "SIMULATION/RF/defs.h" #include "PHY/types.h" diff --git a/openair1/SIMULATION/LTE_PHY/ulsim.c b/openair1/SIMULATION/LTE_PHY/ulsim.c index 7a442a4082..92b9d58f48 100644 --- a/openair1/SIMULATION/LTE_PHY/ulsim.c +++ b/openair1/SIMULATION/LTE_PHY/ulsim.c @@ -33,6 +33,7 @@ #include #include #include +#include "common/cmake_defs.h" #include "common/utils/var_array.h" #include "PHY/types.h" #include "PHY/defs_common.h" diff --git a/openair1/SIMULATION/TOOLS/channel_sim.c b/openair1/SIMULATION/TOOLS/channel_sim.c index 9f196b02ec..5115587bfc 100644 --- a/openair1/SIMULATION/TOOLS/channel_sim.c +++ b/openair1/SIMULATION/TOOLS/channel_sim.c @@ -24,6 +24,7 @@ #include #include +#include "common/cmake_defs.h" #include "SIMULATION/TOOLS/sim.h" #include "SIMULATION/RF/rf.h" #include "PHY/phy_extern_ue.h" diff --git a/radio/COMMON/common_lib.h b/radio/COMMON/common_lib.h index f21a1ffff4..693ca0e3c7 100644 --- a/radio/COMMON/common_lib.h +++ b/radio/COMMON/common_lib.h @@ -35,6 +35,7 @@ #include #include #include +#include "common/cmake_defs.h" #include #include "record_player.h" #include "common/utils/threadPool/notified_fifo.h" diff --git a/radio/fhi_72/oran_isolate.h b/radio/fhi_72/oran_isolate.h index 4f62ff5340..44c9bee51d 100644 --- a/radio/fhi_72/oran_isolate.h +++ b/radio/fhi_72/oran_isolate.h @@ -27,6 +27,7 @@ #include #include +#include "common/cmake_defs.h" #include "xran_fh_o_du.h" #include "openair1/PHY/impl_defs_nr.h" #include "openair1/PHY/TOOLS/tools_defs.h" From 0ea119ec39a44a61197fa6d60bf6d768bbb6533a Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Fri, 20 Feb 2026 19:14:38 +0100 Subject: [PATCH 37/83] Align t_nrPolar_params allocation to 32 bytes --- openair1/PHY/CODING/nrPolar_tools/nr_polar_init.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openair1/PHY/CODING/nrPolar_tools/nr_polar_init.c b/openair1/PHY/CODING/nrPolar_tools/nr_polar_init.c index 609f4b4a8f..462e2bfe08 100644 --- a/openair1/PHY/CODING/nrPolar_tools/nr_polar_init.c +++ b/openair1/PHY/CODING/nrPolar_tools/nr_polar_init.c @@ -97,7 +97,7 @@ t_nrPolar_params *nr_polar_params(int8_t messageType, uint16_t messageLength, ui // printf("currentPtr %p (polarParams %p)\n",currentPtr,polarParams); // Else, initialize and add node to the end of the linked list. - t_nrPolar_params *newPolarInitNode = malloc(sizeof(t_nrPolar_params)); + t_nrPolar_params *newPolarInitNode = memalign(32, sizeof(t_nrPolar_params)); AssertFatal(newPolarInitNode, "[nr_polar_init] New t_nrPolar_params * could not be created"); *newPolarInitNode = (t_nrPolar_params){.busy = true, .nextPtr = PolarList, .tree_linearization.is_initialized = false}; From 5b9d4550bac5ed61dec0b8f32d36b142ac1dc1ff Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 19 Feb 2026 16:55:34 +0100 Subject: [PATCH 38/83] Remove unused defines --- openair1/PHY/NR_REFSIG/pss_nr.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/openair1/PHY/NR_REFSIG/pss_nr.h b/openair1/PHY/NR_REFSIG/pss_nr.h index 8034d7f362..07ab520e90 100644 --- a/openair1/PHY/NR_REFSIG/pss_nr.h +++ b/openair1/PHY/NR_REFSIG/pss_nr.h @@ -72,9 +72,6 @@ #define SYNCHRO_RATE_CHANGE_FACTOR (1) #endif -#define SYNC_TMP_SIZE (NB_ANTENNAS_RX*SYNCHRO_FFT_SIZE_MAX*IQ_SIZE) /* to be aligned with existing lte synchro */ -#define SYNCF_TMP_SIZE (SYNCHRO_FFT_SIZE_MAX*IQ_SIZE) - void init_context_synchro_nr(NR_DL_FRAME_PARMS *frame_parms_ue); int pss_synchro_nr(const c16_t **rxdata, const NR_DL_FRAME_PARMS *frame_parms, From 1b619bed03cf68d6abf365830360fcf7ede9be29 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 19 Feb 2026 16:56:05 +0100 Subject: [PATCH 39/83] Remove unused sched_response_id --- openair1/SIMULATION/NR_PHY/dlsim.c | 1 - openair1/SIMULATION/NR_PHY/ulsim.c | 1 - openair2/NR_PHY_INTERFACE/NR_IF_Module.h | 2 -- 3 files changed, 4 deletions(-) diff --git a/openair1/SIMULATION/NR_PHY/dlsim.c b/openair1/SIMULATION/NR_PHY/dlsim.c index f1461bc25d..44feb23c40 100644 --- a/openair1/SIMULATION/NR_PHY/dlsim.c +++ b/openair1/SIMULATION/NR_PHY/dlsim.c @@ -1054,7 +1054,6 @@ int main(int argc, char **argv) NR_gNB_DLSCH_t *gNB_dlsch = &gNB->dlsch[0]; memset(Sched_INFO, 0, sizeof(*Sched_INFO)); - Sched_INFO->sched_response_id = -1; nfapi_nr_dl_tti_request_body_t *dl_req = &Sched_INFO->DL_req.dl_tti_request_body; // scheduler will place PDSCH second (after PDCCH), verification below nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdsch_pdu = &dl_req->dl_tti_pdu_list[1]; diff --git a/openair1/SIMULATION/NR_PHY/ulsim.c b/openair1/SIMULATION/NR_PHY/ulsim.c index e545d6cba2..80ea9cf31b 100644 --- a/openair1/SIMULATION/NR_PHY/ulsim.c +++ b/openair1/SIMULATION/NR_PHY/ulsim.c @@ -915,7 +915,6 @@ int main(int argc, char *argv[]) NR_Sched_Rsp_t *Sched_INFO = malloc16_clear(sizeof(*Sched_INFO)); memset((void*)Sched_INFO,0,sizeof(*Sched_INFO)); nfapi_nr_ul_tti_request_t *UL_tti_req = &Sched_INFO->UL_tti_req; - Sched_INFO->sched_response_id = -1; nr_phy_data_tx_t phy_data = {0}; diff --git a/openair2/NR_PHY_INTERFACE/NR_IF_Module.h b/openair2/NR_PHY_INTERFACE/NR_IF_Module.h index e53f04d859..e52f4ad678 100644 --- a/openair2/NR_PHY_INTERFACE/NR_IF_Module.h +++ b/openair2/NR_PHY_INTERFACE/NR_IF_Module.h @@ -85,8 +85,6 @@ typedef struct { typedef struct NR_Sched_Rsp { - /// the ID of this sched_response - used by sched_reponse memory management - int sched_response_id; /// Module ID module_id_t module_id; /// CC ID From bb72c4d057b63df4d823d35c6980d92bc8525391 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 19 Feb 2026 17:50:58 +0100 Subject: [PATCH 40/83] Fix alignment problem in nr_dlsim Fix error openair1/SIMULATION/NR_PHY/dlsim.c:1057:37: runtime error: member access within misaligned address 0x7f8a67e01010 for type 'struct NR_Sched_Rsp_t', which requires 32 byte alignment --- openair1/SIMULATION/NR_PHY/dlsim.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openair1/SIMULATION/NR_PHY/dlsim.c b/openair1/SIMULATION/NR_PHY/dlsim.c index 44feb23c40..5072b7bd9d 100644 --- a/openair1/SIMULATION/NR_PHY/dlsim.c +++ b/openair1/SIMULATION/NR_PHY/dlsim.c @@ -1012,7 +1012,7 @@ int main(int argc, char **argv) } //--------------- - Sched_INFO = malloc(sizeof(*Sched_INFO)); + Sched_INFO = memalign(32, sizeof(*Sched_INFO)); if (Sched_INFO == NULL) { LOG_E(PHY, "out of memory\n"); exit(1); From cdfe069c34258c419bb38eefa558dc92e522aa2f Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 19 Feb 2026 17:55:24 +0100 Subject: [PATCH 41/83] Remove unused cmake macros --- cmake_targets/at_commands/CMakeLists.txt | 10 ---------- cmake_targets/macros.cmake | 23 ----------------------- 2 files changed, 33 deletions(-) diff --git a/cmake_targets/at_commands/CMakeLists.txt b/cmake_targets/at_commands/CMakeLists.txt index c912bf9602..b450c087c2 100755 --- a/cmake_targets/at_commands/CMakeLists.txt +++ b/cmake_targets/at_commands/CMakeLists.txt @@ -51,16 +51,6 @@ set(OPENAIR_NAS_DIR ${OPENAIR_DIR}/openair3/NAS) set(CMAKE_MODULE_PATH "${OPENAIR_DIR}/cmake_targets/tools/MODULES" "${CMAKE_MODULE_PATH}") -macro(add_option name val helpstr) - if(DEFINED ${name}) - set(value ${${name}}) - else(DEFINED ${name}) - set(value ${val}) - endif() - set(${name} ${value} CACHE STRING "${helpstr}") - add_definitions("-D${name}=${value}") -endmacro(add_option) - macro(add_boolean_option name val helpstr) if(DEFINED ${name}) set(value ${${name}}) diff --git a/cmake_targets/macros.cmake b/cmake_targets/macros.cmake index cc59e12a90..4b1797db40 100644 --- a/cmake_targets/macros.cmake +++ b/cmake_targets/macros.cmake @@ -1,16 +1,6 @@ ########################################### # macros to define options as there is numerous options in oai ################################################ -macro(add_option name val helpstr) - if(DEFINED ${name}) - set(value ${${name}}) - else(DEFINED ${name}) - set(value ${val}) - endif() - set(${name} ${value} CACHE STRING "${helpstr}") - add_definitions("-D${name}=${value}") -endmacro(add_option) - macro(add_boolean_option name val helpstr adddef) if(DEFINED ${name}) set(value ${${name}}) @@ -34,19 +24,6 @@ macro(add_integer_option name val helpstr) add_definitions("-D${name}=${value}") endmacro(add_integer_option) -macro(add_list2_option name val helpstr) - if(DEFINED ${name}) - set(value ${${name}}) - else(DEFINED ${name}) - set(value ${val}) - endif() - set(${name} ${value} CACHE STRING "${helpstr}") - set_property(CACHE ${name} PROPERTY STRINGS ${ARGN}) - if(NOT "${value}" STREQUAL "None") - add_definitions("-D${value}=1") - endif() -endmacro(add_list2_option) - macro(add_list_string_option name val helpstr) if(DEFINED ${name}) set(value ${${name}}) From 2bd3685d6bc3c4a8e9295cb0716d600716e3851e Mon Sep 17 00:00:00 2001 From: francescomani Date: Fri, 20 Feb 2026 12:44:03 +0100 Subject: [PATCH 42/83] add check for input number of antennas to be compliant with NB_ANTENNAS_TX and NB_ANTENNAS_RX --- executables/nr-ru.c | 6 ++++++ executables/nr-ue-ru.c | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/executables/nr-ru.c b/executables/nr-ru.c index 397f940745..c6a2d30c07 100644 --- a/executables/nr-ru.c +++ b/executables/nr-ru.c @@ -1737,7 +1737,13 @@ static void NRRCconfig_RU(configmodule_interface_t *cfg) } /* strcmp(local_rf, "yes") != 0 */ ru->nb_tx = *param[RU_NB_TX_IDX].uptr; + AssertFatal(ru->nb_tx <= NB_ANTENNAS_TX, + "Config file has %d TX antennas set, but the compile time max value in NB_ANTENNAS_TX\n", + ru->nb_tx); ru->nb_rx = *param[RU_NB_RX_IDX].uptr; + AssertFatal(ru->nb_rx <= NB_ANTENNAS_RX, + "Config file has %d RX antennas set, but the compile time max value in NB_ANTENNAS_RX\n", + ru->nb_rx); ru->att_tx = *param[RU_ATT_TX_IDX].uptr; ru->att_rx = *param[RU_ATT_RX_IDX].uptr; ru->if_frequency = *param[RU_IF_FREQUENCY].u64ptr; diff --git a/executables/nr-ue-ru.c b/executables/nr-ue-ru.c index 7235ae5c9f..748a4fd731 100644 --- a/executables/nr-ue-ru.c +++ b/executables/nr-ue-ru.c @@ -205,6 +205,12 @@ void nrue_set_ru_params(configmodule_interface_t *cfg) if (RUParamList.numelt <= 0) { nrue_ru_count = 1; nrue_rus = calloc_or_fail(nrue_ru_count, sizeof(nrUE_RU_params_t)); + AssertFatal(get_nrUE_params()->nb_antennas_tx <= NB_ANTENNAS_TX, + "Config file has %d TX antennas set, but the compile time max value in NB_ANTENNAS_TX\n", + get_nrUE_params()->nb_antennas_tx); + AssertFatal(get_nrUE_params()->nb_antennas_rx <= NB_ANTENNAS_RX, + "Config file has %d RX antennas set, but the compile time max value in NB_ANTENNAS_RX\n", + get_nrUE_params()->nb_antennas_tx); nrue_rus[0] = (nrUE_RU_params_t){.nb_tx = get_nrUE_params()->nb_antennas_tx, .nb_rx = get_nrUE_params()->nb_antennas_rx, .att_tx = get_nrUE_params()->tx_gain, From 4447d67650a618119e8e9495f20d720f52def51b Mon Sep 17 00:00:00 2001 From: francescomani Date: Tue, 24 Feb 2026 10:52:18 +0100 Subject: [PATCH 43/83] remove unnecessary gNB header dependence in coding files --- openair1/PHY/CODING/coding_defs.h | 13 +++++++++++++ openair1/PHY/CODING/coding_extern.h | 2 ++ .../nrLDPC_coding_aal/nrLDPC_coding_aal.c | 3 +++ .../CODING/nrLDPC_coding/nrLDPC_coding_interface.h | 4 +++- .../nrLDPC_coding_segment_decoder.c | 6 ------ .../nrLDPC_coding_segment_encoder.c | 5 ----- .../nrLDPC_coding_xdma/nrLDPC_coding_xdma.c | 6 ------ .../PHY/CODING/nrLDPC_decoder/nrLDPCdecoder_defs.h | 3 +++ openair1/PHY/CODING/nrLDPC_extern.h | 2 -- openair1/PHY/CODING/nrPolar_tools/nr_polar_init.c | 2 +- openair1/PHY/defs_gNB.h | 13 ------------- 11 files changed, 25 insertions(+), 34 deletions(-) diff --git a/openair1/PHY/CODING/coding_defs.h b/openair1/PHY/CODING/coding_defs.h index e5eb61e0bd..09f324f342 100644 --- a/openair1/PHY/CODING/coding_defs.h +++ b/openair1/PHY/CODING/coding_defs.h @@ -29,6 +29,7 @@ #include #include +#include "common/utils/nr/nr_common.h" #define CRC24_A 0 #define CRC24_B 1 @@ -38,6 +39,18 @@ #define MAX_TURBO_ITERATIONS_MBSFN 8 #define MAX_TURBO_ITERATIONS max_turbo_iterations +static inline int lenWithCrc(int nbSeg, int len) +{ + if (nbSeg > 1) + return (len + 24 + 24 * nbSeg) / nbSeg; + return len + (len > NR_MAX_PDSCH_TBS ? 24 : 16); +} +static inline int crcType(int nbSeg, int len) +{ + if (nbSeg > 1) + return CRC24_B; + return len > NR_MAX_PDSCH_TBS ? CRC24_A : CRC16; +} #define LTE_NULL 2 typedef struct { diff --git a/openair1/PHY/CODING/coding_extern.h b/openair1/PHY/CODING/coding_extern.h index f910d0b1cf..2249c9370f 100644 --- a/openair1/PHY/CODING/coding_extern.h +++ b/openair1/PHY/CODING/coding_extern.h @@ -19,6 +19,8 @@ * contact@openairinterface.org */ +#include "openair1/PHY/defs_common.h" + extern decoder_if_t *decoder16; extern decoder_if_t *decoder8; extern encoder_if_t *encoder; diff --git a/openair1/PHY/CODING/nrLDPC_coding/nrLDPC_coding_aal/nrLDPC_coding_aal.c b/openair1/PHY/CODING/nrLDPC_coding/nrLDPC_coding_aal/nrLDPC_coding_aal.c index 89f16bb706..0da16183eb 100644 --- a/openair1/PHY/CODING/nrLDPC_coding/nrLDPC_coding_aal/nrLDPC_coding_aal.c +++ b/openair1/PHY/CODING/nrLDPC_coding/nrLDPC_coding_aal/nrLDPC_coding_aal.c @@ -9,6 +9,9 @@ #include #define NR_LDPC_ENABLE_PARITY_CHECK +#include "PHY/CODING/nrLDPC_decoder/nrLDPCdecoder_defs.h" +#include "PHY/CODING/coding_defs.h" + #include #include #include diff --git a/openair1/PHY/CODING/nrLDPC_coding/nrLDPC_coding_interface.h b/openair1/PHY/CODING/nrLDPC_coding/nrLDPC_coding_interface.h index ca57c9bab3..2f46faeb2f 100644 --- a/openair1/PHY/CODING/nrLDPC_coding/nrLDPC_coding_interface.h +++ b/openair1/PHY/CODING/nrLDPC_coding/nrLDPC_coding_interface.h @@ -23,7 +23,9 @@ * \brief interface for libraries implementing coding/decoding algorithms */ -#include "PHY/defs_gNB.h" +#include "common/utils/time_meas.h" +#include "openair1/PHY/defs_common.h" +#include "common/utils/threadPool/thread-pool.h" #ifndef __NRLDPC_CODING_INTERFACE__H__ #define __NRLDPC_CODING_INTERFACE__H__ diff --git a/openair1/PHY/CODING/nrLDPC_coding/nrLDPC_coding_segment/nrLDPC_coding_segment_decoder.c b/openair1/PHY/CODING/nrLDPC_coding/nrLDPC_coding_segment/nrLDPC_coding_segment_decoder.c index 00f1787859..5057ce4798 100644 --- a/openair1/PHY/CODING/nrLDPC_coding/nrLDPC_coding_segment/nrLDPC_coding_segment_decoder.c +++ b/openair1/PHY/CODING/nrLDPC_coding/nrLDPC_coding_segment/nrLDPC_coding_segment_decoder.c @@ -25,17 +25,11 @@ // [from gNB coding] #include "nr_rate_matching.h" -#include "PHY/defs_gNB.h" #include "PHY/CODING/coding_extern.h" #include "PHY/CODING/coding_defs.h" #include "PHY/CODING/lte_interleaver_inline.h" #include "PHY/CODING/nrLDPC_coding/nrLDPC_coding_interface.h" #include "PHY/CODING/nrLDPC_extern.h" -#include "PHY/NR_TRANSPORT/nr_transport_common_proto.h" -#include "PHY/NR_TRANSPORT/nr_transport_proto.h" -#include "PHY/NR_TRANSPORT/nr_ulsch.h" -#include "PHY/NR_TRANSPORT/nr_dlsch.h" -#include "SCHED_NR/sched_nr.h" #include "defs.h" #include "common/utils/LOG/log.h" diff --git a/openair1/PHY/CODING/nrLDPC_coding/nrLDPC_coding_segment/nrLDPC_coding_segment_encoder.c b/openair1/PHY/CODING/nrLDPC_coding/nrLDPC_coding_segment/nrLDPC_coding_segment_encoder.c index c0cb6af49f..38d844c180 100644 --- a/openair1/PHY/CODING/nrLDPC_coding/nrLDPC_coding_segment/nrLDPC_coding_segment_encoder.c +++ b/openair1/PHY/CODING/nrLDPC_coding/nrLDPC_coding_segment/nrLDPC_coding_segment_encoder.c @@ -24,16 +24,11 @@ */ #include "nr_rate_matching.h" -#include "PHY/defs_gNB.h" #include "PHY/CODING/coding_extern.h" #include "PHY/CODING/coding_defs.h" #include "PHY/CODING/lte_interleaver_inline.h" #include "PHY/CODING/nrLDPC_coding/nrLDPC_coding_interface.h" #include "PHY/CODING/nrLDPC_extern.h" -#include "PHY/NR_TRANSPORT/nr_transport_proto.h" -#include "PHY/NR_TRANSPORT/nr_transport_common_proto.h" -#include "PHY/NR_TRANSPORT/nr_dlsch.h" -#include "SCHED_NR/sched_nr.h" #include "common/utils/LOG/log.h" #include "common/utils/nr/nr_common.h" #include diff --git a/openair1/PHY/CODING/nrLDPC_coding/nrLDPC_coding_xdma/nrLDPC_coding_xdma.c b/openair1/PHY/CODING/nrLDPC_coding/nrLDPC_coding_xdma/nrLDPC_coding_xdma.c index 7a13087610..b78d1da8e6 100644 --- a/openair1/PHY/CODING/nrLDPC_coding/nrLDPC_coding_xdma/nrLDPC_coding_xdma.c +++ b/openair1/PHY/CODING/nrLDPC_coding/nrLDPC_coding_xdma/nrLDPC_coding_xdma.c @@ -33,12 +33,6 @@ #include "PHY/CODING/lte_interleaver_inline.h" #include "PHY/CODING/nrLDPC_coding/nrLDPC_coding_xdma/nrLDPC_coding_xdma_offload.h" #include "PHY/CODING/nrLDPC_extern.h" -#include "PHY/NR_TRANSPORT/nr_dlsch.h" -#include "PHY/NR_TRANSPORT/nr_transport_common_proto.h" -#include "PHY/NR_TRANSPORT/nr_transport_proto.h" -#include "PHY/NR_TRANSPORT/nr_ulsch.h" -#include "PHY/defs_gNB.h" -#include "SCHED_NR/sched_nr.h" #include "common/utils/LOG/log.h" #include "defs.h" // #define DEBUG_ULSCH_DECODING diff --git a/openair1/PHY/CODING/nrLDPC_decoder/nrLDPCdecoder_defs.h b/openair1/PHY/CODING/nrLDPC_decoder/nrLDPCdecoder_defs.h index b04b991249..fa74a42c91 100644 --- a/openair1/PHY/CODING/nrLDPC_decoder/nrLDPCdecoder_defs.h +++ b/openair1/PHY/CODING/nrLDPC_decoder/nrLDPCdecoder_defs.h @@ -99,6 +99,9 @@ /** Maximum number of segments per TB = MAX_NUM_NR_DLSCH_SEGMENTS_PER_LAYER*NR_MAX_NB_LAYERS */ #define NR_LDPC_MAX_NUM_CB 144 +/* LDPC maximum code block size - maximum E */ +#define LDPC_MAX_CB_SIZE 32768 + // ============================================================================== // GLOBAL CONSTANT VARIABLES diff --git a/openair1/PHY/CODING/nrLDPC_extern.h b/openair1/PHY/CODING/nrLDPC_extern.h index 7c4287d3f1..6ed940396d 100644 --- a/openair1/PHY/CODING/nrLDPC_extern.h +++ b/openair1/PHY/CODING/nrLDPC_extern.h @@ -21,8 +21,6 @@ #ifndef _NRLDPC_EXTERN_H__ #define _NRLDPC_EXTERN_H__ #include "openair1/PHY/CODING/nrLDPC_defs.h" -/* LDPC maximum code block size - maximum E */ -#define LDPC_MAX_CB_SIZE 32768 /* ldpc coder/decoder API*/ typedef struct ldpc_interface_s { LDPC_initfunc_t *LDPCinit; diff --git a/openair1/PHY/CODING/nrPolar_tools/nr_polar_init.c b/openair1/PHY/CODING/nrPolar_tools/nr_polar_init.c index 609f4b4a8f..85def82ba5 100644 --- a/openair1/PHY/CODING/nrPolar_tools/nr_polar_init.c +++ b/openair1/PHY/CODING/nrPolar_tools/nr_polar_init.c @@ -32,7 +32,7 @@ #include "nr_polar_defs.h" #include "nr_polar_psbch_defs.h" -#include "PHY/NR_TRANSPORT/nr_dci.h" +#include "common/utils/LOG/log.h" #define PolarKey ((messageType << 24) | (messageLength << 8) | aggregation_level) static t_nrPolar_params *PolarList = NULL; diff --git a/openair1/PHY/defs_gNB.h b/openair1/PHY/defs_gNB.h index 62860283d9..c5abe7523d 100644 --- a/openair1/PHY/defs_gNB.h +++ b/openair1/PHY/defs_gNB.h @@ -159,19 +159,6 @@ typedef struct { ////////////////////////////////////////////////////////////// } NR_UL_gNB_HARQ_t; -static inline int lenWithCrc(int nbSeg, int len) -{ - if (nbSeg > 1) - return (len + 24 + 24 * nbSeg) / nbSeg; - return len + (len > NR_MAX_PDSCH_TBS ? 24 : 16); -} -static inline int crcType(int nbSeg, int len) -{ - if (nbSeg > 1) - return CRC24_B; - return len > NR_MAX_PDSCH_TBS ? CRC24_A : CRC16; -} - typedef struct { uint32_t frame; uint32_t slot; From 96bc3a0ee941d76f0704b1e3160813cfc8421c20 Mon Sep 17 00:00:00 2001 From: francescomani Date: Tue, 24 Feb 2026 11:05:48 +0100 Subject: [PATCH 44/83] remove unnecessary defs_gNB from LTE files --- openair1/PHY/INIT/nr_init_ru.c | 3 ++- openair1/PHY/INIT/phy_init.h | 1 - openair2/PHY_INTERFACE/phy_stub_UE.c | 1 - 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/openair1/PHY/INIT/nr_init_ru.c b/openair1/PHY/INIT/nr_init_ru.c index 787d05697c..48621afee4 100644 --- a/openair1/PHY/INIT/nr_init_ru.c +++ b/openair1/PHY/INIT/nr_init_ru.c @@ -19,12 +19,13 @@ * contact@openairinterface.org */ -#include "phy_init.h" #include "PHY/phy_extern.h" #include "SCHED/sched_common.h" #include "assertions.h" #include #include "openair1/PHY/defs_RU.h" +#include "openair1/PHY/defs_nr_common.h" +#include "openair1/PHY/defs_gNB.h" void nr_phy_init_RU(RU_t *ru) { diff --git a/openair1/PHY/INIT/phy_init.h b/openair1/PHY/INIT/phy_init.h index 6b278f899f..0f2705d735 100644 --- a/openair1/PHY/INIT/phy_init.h +++ b/openair1/PHY/INIT/phy_init.h @@ -24,7 +24,6 @@ #include "PHY/defs_eNB.h" #include "PHY/defs_UE.h" -#include "PHY/defs_gNB.h" #include "LTE_SystemInformationBlockType2.h" //#include "RadioResourceConfigCommonSIB.h" diff --git a/openair2/PHY_INTERFACE/phy_stub_UE.c b/openair2/PHY_INTERFACE/phy_stub_UE.c index 3c0640cd5e..8f7ff98f79 100644 --- a/openair2/PHY_INTERFACE/phy_stub_UE.c +++ b/openair2/PHY_INTERFACE/phy_stub_UE.c @@ -34,7 +34,6 @@ #include #include #include "openair2/NR_PHY_INTERFACE/NR_IF_Module.h" -#include "openair1/PHY/defs_gNB.h" #include "nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h" #include "openair1/PHY/LTE_TRANSPORT/transport_common.h" #include "softmodem-common.h" From d6759b35d22da1b7c829286a1602167d5a91d6fc Mon Sep 17 00:00:00 2001 From: francescomani Date: Tue, 24 Feb 2026 11:12:07 +0100 Subject: [PATCH 45/83] remove unnecessary gNB DLSCH header in UE dlsch demodulation --- openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c index 980a625978..73bcbfab46 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c @@ -32,12 +32,10 @@ #include "common/platform_constants.h" #include "nr_phy_common.h" #include "PHY/defs_nr_UE.h" -#include "PHY/phy_extern.h" #include "nr_transport_proto_ue.h" #include "PHY/sse_intrin.h" #include "T.h" #include "openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h" -#include "openair1/PHY/NR_TRANSPORT/nr_dlsch.h" #include "PHY/NR_REFSIG/nr_refsig.h" #include "PHY/NR_REFSIG/dmrs_nr.h" #include "common/utils/nr/nr_common.h" From 8c4fe047d00c8845dc45d8a4afcb1097fe4849b7 Mon Sep 17 00:00:00 2001 From: francescomani Date: Tue, 24 Feb 2026 12:39:11 +0100 Subject: [PATCH 46/83] remove some LTE dependence in NR files --- executables/nr-gnb.c | 3 +-- .../nrLDPC_coding_segment_decoder.c | 1 - .../nrLDPC_coding_segment_encoder.c | 1 - .../nrLDPC_coding_xdma/nrLDPC_coding_xdma.c | 1 - openair1/PHY/INIT/nr_parms.c | 14 +++++++------- .../NR_ESTIMATION/nr_ul_channel_estimation.c | 17 ++++++++--------- openair1/PHY/NR_REFSIG/nr_dmrs_rx.c | 14 ++++++-------- openair1/PHY/NR_REFSIG/nr_refsig.h | 5 ++--- openair1/PHY/NR_REFSIG/nr_refsig_common.h | 2 ++ openair1/PHY/NR_REFSIG/refsig_defs_ue.h | 2 +- openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c | 1 - openair1/PHY/NR_TRANSPORT/nr_prs.c | 1 - .../PHY/NR_TRANSPORT/nr_ulsch_demodulation.c | 2 +- .../NR_UE_ESTIMATION/nr_dl_channel_estimation.c | 2 +- openair1/PHY/NR_UE_TRANSPORT/nr_psbch_tx.c | 1 - openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c | 1 - openair1/PHY/defs_nr_common.h | 7 ++++++- openair1/SCHED_NR/phy_procedures_nr_gNB.c | 2 +- openair1/SIMULATION/NR_PHY/dlschsim.c | 2 +- openair1/SIMULATION/NR_PHY/srssim.c | 2 +- openair1/SIMULATION/NR_PHY/ulschsim.c | 2 +- openair1/SIMULATION/NR_PHY/ulsim.c | 2 +- 22 files changed, 40 insertions(+), 45 deletions(-) diff --git a/executables/nr-gnb.c b/executables/nr-gnb.c index 226bf2775b..c5c1dee427 100644 --- a/executables/nr-gnb.c +++ b/executables/nr-gnb.c @@ -51,7 +51,6 @@ #include "PHY/NR_TRANSPORT/nr_transport_proto.h" #include "PHY/TOOLS/tools_defs.h" #include "PHY/defs_RU.h" -#include "PHY/defs_common.h" #include "PHY/defs_gNB.h" #include "PHY/defs_nr_common.h" #include "PHY/impl_defs_nr.h" @@ -200,7 +199,7 @@ static void rx_func(processingData_L1_t *info) int soffset = (slot_rx % RU_RX_SLOT_DEPTH) * gNB->frame_parms.symbols_per_slot * gNB->frame_parms.ofdm_symbol_size; for (int bb = 0; bb < gNB->common_vars.num_beams_period; bb++) { for (int aa = 0; aa < gNB->frame_parms.nb_antennas_rx; aa++) { - const uint max_symb = (gNB->frame_parms.Ncp == EXTENDED) ? 12 : 14; + const uint max_symb = (gNB->frame_parms.Ncp == NR_EXTENDED) ? 12 : 14; for (int sym = 0; sym < max_symb; sym++) apply_nr_rotation_symbol_RX(&gNB->frame_parms, gNB->common_vars.rxdataF[bb][aa] + soffset + sym * gNB->frame_parms.ofdm_symbol_size, diff --git a/openair1/PHY/CODING/nrLDPC_coding/nrLDPC_coding_segment/nrLDPC_coding_segment_decoder.c b/openair1/PHY/CODING/nrLDPC_coding/nrLDPC_coding_segment/nrLDPC_coding_segment_decoder.c index 5057ce4798..e6e56b1654 100644 --- a/openair1/PHY/CODING/nrLDPC_coding/nrLDPC_coding_segment/nrLDPC_coding_segment_decoder.c +++ b/openair1/PHY/CODING/nrLDPC_coding/nrLDPC_coding_segment/nrLDPC_coding_segment_decoder.c @@ -27,7 +27,6 @@ #include "nr_rate_matching.h" #include "PHY/CODING/coding_extern.h" #include "PHY/CODING/coding_defs.h" -#include "PHY/CODING/lte_interleaver_inline.h" #include "PHY/CODING/nrLDPC_coding/nrLDPC_coding_interface.h" #include "PHY/CODING/nrLDPC_extern.h" #include "defs.h" diff --git a/openair1/PHY/CODING/nrLDPC_coding/nrLDPC_coding_segment/nrLDPC_coding_segment_encoder.c b/openair1/PHY/CODING/nrLDPC_coding/nrLDPC_coding_segment/nrLDPC_coding_segment_encoder.c index 38d844c180..037ce6690f 100644 --- a/openair1/PHY/CODING/nrLDPC_coding/nrLDPC_coding_segment/nrLDPC_coding_segment_encoder.c +++ b/openair1/PHY/CODING/nrLDPC_coding/nrLDPC_coding_segment/nrLDPC_coding_segment_encoder.c @@ -26,7 +26,6 @@ #include "nr_rate_matching.h" #include "PHY/CODING/coding_extern.h" #include "PHY/CODING/coding_defs.h" -#include "PHY/CODING/lte_interleaver_inline.h" #include "PHY/CODING/nrLDPC_coding/nrLDPC_coding_interface.h" #include "PHY/CODING/nrLDPC_extern.h" #include "common/utils/LOG/log.h" diff --git a/openair1/PHY/CODING/nrLDPC_coding/nrLDPC_coding_xdma/nrLDPC_coding_xdma.c b/openair1/PHY/CODING/nrLDPC_coding/nrLDPC_coding_xdma/nrLDPC_coding_xdma.c index b78d1da8e6..cd478d59a8 100644 --- a/openair1/PHY/CODING/nrLDPC_coding/nrLDPC_coding_xdma/nrLDPC_coding_xdma.c +++ b/openair1/PHY/CODING/nrLDPC_coding/nrLDPC_coding_xdma/nrLDPC_coding_xdma.c @@ -30,7 +30,6 @@ #include #include "PHY/CODING/coding_defs.h" #include "PHY/CODING/coding_extern.h" -#include "PHY/CODING/lte_interleaver_inline.h" #include "PHY/CODING/nrLDPC_coding/nrLDPC_coding_xdma/nrLDPC_coding_xdma_offload.h" #include "PHY/CODING/nrLDPC_extern.h" #include "common/utils/LOG/log.h" diff --git a/openair1/PHY/INIT/nr_parms.c b/openair1/PHY/INIT/nr_parms.c index d6043775af..21b2980288 100644 --- a/openair1/PHY/INIT/nr_parms.c +++ b/openair1/PHY/INIT/nr_parms.c @@ -409,7 +409,7 @@ void nr_init_frame_parms(nfapi_nr_config_request_scf_t* cfg, NR_DL_FRAME_PARMS * fp->nb_antennas_rx = cfg->carrier_config.num_rx_ant.value; // It denotes the number of rx antennas at gNB fp->nb_antennas_tx = cfg->carrier_config.num_tx_ant.value; // It corresponds to pdsch_AntennaPorts (logical antenna ports) - fp->symbols_per_slot = ((Ncp == NORMAL)? 14 : 12); // to redefine for different slot formats + fp->symbols_per_slot = ((Ncp == NR_NORMAL)? 14 : 12); // to redefine for different slot formats fp->samples_per_subframe_wCP = fp->ofdm_symbol_size * fp->symbols_per_slot * fp->slots_per_subframe; fp->samples_per_frame_wCP = 10 * fp->samples_per_subframe_wCP; fp->samples_per_slot_wCP = fp->symbols_per_slot*fp->ofdm_symbol_size; @@ -443,7 +443,7 @@ int nr_init_frame_parms_ue(NR_DL_FRAME_PARMS *fp, uint8_t nb_ant_ports_gNB = 1; uint8_t tdd_cfg = 3; uint8_t Nid_cell = 0; - int Ncp = NORMAL; + int Ncp = NR_NORMAL; if(fp->nb_antennas_rx == 0) fp->nb_antennas_rx = 1; @@ -491,7 +491,7 @@ int nr_init_frame_parms_ue(NR_DL_FRAME_PARMS *fp, set_scs_parameters(fp, fp->numerology_index, N_RB); fp->slots_per_frame = 10* fp->slots_per_subframe; - fp->symbols_per_slot = ((Ncp == NORMAL)? 14 : 12); // to redefine for different slot formats + fp->symbols_per_slot = ((Ncp == NR_NORMAL)? 14 : 12); // to redefine for different slot formats fp->samples_per_subframe_wCP = fp->ofdm_symbol_size * fp->symbols_per_slot * fp->slots_per_subframe; fp->samples_per_frame_wCP = 10 * fp->samples_per_subframe_wCP; fp->samples_per_slot_wCP = fp->symbols_per_slot*fp->ofdm_symbol_size; @@ -552,12 +552,12 @@ void nr_init_frame_parms_ue_sa(NR_DL_FRAME_PARMS *frame_parms, const nrUE_cell_p frame_parms->nr_band = nr_band; frame_parms->frame_type = get_frame_type(frame_parms->nr_band, frame_parms->numerology_index); - frame_parms->Ncp = NORMAL; + frame_parms->Ncp = NR_NORMAL; set_scs_parameters(frame_parms, frame_parms->numerology_index, frame_parms->N_RB_DL); set_Lmax(frame_parms); frame_parms->slots_per_frame = 10* frame_parms->slots_per_subframe; - frame_parms->symbols_per_slot = ((frame_parms->Ncp == NORMAL)? 14 : 12); // to redefine for different slot formats + frame_parms->symbols_per_slot = ((frame_parms->Ncp == NR_NORMAL)? 14 : 12); // to redefine for different slot formats frame_parms->samples_per_subframe_wCP = frame_parms->ofdm_symbol_size * frame_parms->symbols_per_slot * frame_parms->slots_per_subframe; frame_parms->samples_per_frame_wCP = 10 * frame_parms->samples_per_subframe_wCP; frame_parms->samples_per_slot_wCP = frame_parms->symbols_per_slot*frame_parms->ofdm_symbol_size; @@ -652,7 +652,7 @@ int nr_init_frame_parms_ue_sl(NR_DL_FRAME_PARMS *fp, LOG_I(PHY, "Initializing frame parms for mu %d, N_RB %d, Ncp %d\n", fp->numerology_index, fp->N_RB_DL, fp->Ncp); - if (fp->Ncp == EXTENDED) + if (fp->Ncp == NR_EXTENDED) AssertFatal(fp->numerology_index == NR_MU_2, "Invalid cyclic prefix %d for numerology index %d\n", fp->Ncp, @@ -661,7 +661,7 @@ int nr_init_frame_parms_ue_sl(NR_DL_FRAME_PARMS *fp, sl_set_scs_parameters(fp, fp->numerology_index, fp->N_RB_SL); fp->slots_per_frame = 10 * fp->slots_per_subframe; - fp->symbols_per_slot = ((fp->Ncp == NORMAL) ? 14 : 12); // to redefine for different slot formats + fp->symbols_per_slot = ((fp->Ncp == NR_NORMAL) ? 14 : 12); // to redefine for different slot formats fp->samples_per_subframe_wCP = fp->ofdm_symbol_size * fp->symbols_per_slot * fp->slots_per_subframe; fp->samples_per_frame_wCP = 10 * fp->samples_per_subframe_wCP; fp->samples_per_slot_wCP = fp->symbols_per_slot * fp->ofdm_symbol_size; diff --git a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c index d4432ef308..b078d2be1c 100644 --- a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c +++ b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c @@ -488,10 +488,9 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, const int nb_rb_pusch = pusch_pdu->rb_size; //------------------generate DMRS------------------// - + NR_DL_FRAME_PARMS *fp = &gNB->frame_parms; if (pusch_pdu->transform_precoding == transformPrecoder_disabled) { // Note: pilot returned by the following function is already the complex conjugate of the transmitted DMRS - NR_DL_FRAME_PARMS *fp = &gNB->frame_parms; const uint32_t *gold = nr_gold_pusch(fp->N_RB_UL, fp->symbols_per_slot, gNB->gNB_config.cell_config.phy_cell_id.value, @@ -500,7 +499,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, symbol); float beta_dmrs_pusch = get_beta_dmrs(pusch_pdu->num_dmrs_cdm_grps_no_data, pusch_pdu->dmrs_config_type == pusch_dmrs_type2); int16_t dmrs_scaling = (1 / beta_dmrs_pusch) * (1 << 14); - nr_pusch_dmrs_rx(gNB, + nr_pusch_dmrs_rx(fp->Ncp, Ns, gold, pilot, @@ -521,7 +520,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, "Num RBs not configured according to 3GPP 38.211 section 6.3.1.4. For PUSCH with transform precoding, num RBs " "cannot be multiple of any other primenumber other than 2,3,5\n"); AssertFatal(dmrs_seq != NULL, "DMRS low PAPR seq not found, check if DMRS sequences are generated"); - nr_pusch_lowpaprtype1_dmrs_rx(gNB, Ns, dmrs_seq, pilot, 1000, 0, nb_rb_pusch, 0, pusch_pdu->dmrs_config_type); + nr_pusch_lowpaprtype1_dmrs_rx(fp->Ncp, Ns, dmrs_seq, pilot, 1000, 0, nb_rb_pusch, 0, pusch_pdu->dmrs_config_type); #ifdef DEBUG_PUSCH printf("NR_UL_CHANNEL_EST: index %d, u %d,v %d\n", index, u, v); LOG_M("gNb_DMRS_SEQ.m", "gNb_DMRS_SEQ", dmrs_seq, 6 * nb_rb_pusch, 1, 1); @@ -556,7 +555,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, delay_t *delay = &gNB->ulsch[ul_id].delay; memset(delay, 0, sizeof(*delay)); - int nb_antennas_rx = gNB->frame_parms.nb_antennas_rx; + int nb_antennas_rx = fp->nb_antennas_rx; delay_t delay_arr[nb_antennas_rx]; uint64_t noise_amp2_arr[nb_antennas_rx]; int max_ch_arr[nb_antennas_rx]; @@ -573,7 +572,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, initNotifiedFIFO(&respPuschAarx); start_meas(&gNB->pusch_channel_estimation_antenna_processing_stats); int numAntennas = gNB->dmrs_num_antennas_per_thread; - int num_jobs = CEILIDIV(gNB->frame_parms.nb_antennas_rx, numAntennas); + int num_jobs = CEILIDIV(fp->nb_antennas_rx, numAntennas); puschAntennaProc_t rdatas[num_jobs]; memset(rdatas, 0, sizeof(rdatas)); task_ans_t ans; @@ -597,7 +596,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, rdata->noise_amp2 = &noise_amp2_arr[rdata->aarx]; rdata->delay = &delay_arr[rdata->aarx]; rdata->beam_nb = beam_nb; - rdata->frame_parms = &gNB->frame_parms; + rdata->frame_parms = fp; rdata->pusch_vars = &gNB->pusch_vars[ul_id]; rdata->chest_freq = gNB->chest_freq; rdata->rxdataF = gNB->common_vars.rxdataF; @@ -617,14 +616,14 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, join_task_ans(&ans); stop_meas(&gNB->pusch_channel_estimation_antenna_processing_stats); - for (int aarx = 0; aarx < gNB->frame_parms.nb_antennas_rx; aarx++) { + for (int aarx = 0; aarx < fp->nb_antennas_rx; aarx++) { *max_ch = max(*max_ch, max_ch_arr[aarx]); noise_amp2 += noise_amp2_arr[aarx]; nest_count += nest_count_arr[aarx]; } // get the maximum delay *delay = delay_arr[0]; - for (int aarx = 1; aarx < gNB->frame_parms.nb_antennas_rx; aarx++) { + for (int aarx = 1; aarx < fp->nb_antennas_rx; aarx++) { if (delay_arr[aarx].est_delay >= delay->est_delay) { *delay = delay_arr[aarx]; } diff --git a/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c b/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c index 3624d754e9..70fd564065 100644 --- a/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c +++ b/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c @@ -36,9 +36,7 @@ #include "PHY/TOOLS/tools_defs.h" #include "refsig_defs_ue.h" -#include "PHY/defs_nr_UE.h" #include "nr_refsig.h" -#include "PHY/defs_gNB.h" #include "nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface.h" // Table 6.4.1.1.3-1/2 from TS 38.211 @@ -66,7 +64,7 @@ static inline c16_t get_modulated(const uint32_t *gold_sequence, const int idx_g return (c16_t){-val.r, -val.i}; } -int nr_pusch_dmrs_rx(PHY_VARS_gNB *gNB, +int nr_pusch_dmrs_rx(nr_prefix_type_t Ncp, unsigned int Ns, const uint32_t *nr_gold_pusch, c16_t *output, @@ -88,7 +86,7 @@ int nr_pusch_dmrs_rx(PHY_VARS_gNB *gNB, const int nb_dmrs = dmrs_type == pusch_dmrs_type1 ? 6 : 4; if ((p>=1000) && (p<((dmrs_type==pusch_dmrs_type1) ? 1008 : 1012))) { - if (gNB->frame_parms.Ncp == NORMAL) { + if (Ncp == NR_NORMAL) { for (int k = 0; k < nb_pusch_rb * nb_dmrs; k++) { int i = k + dmrs_offset; int w = (wf[p - 1000][i & 1]) * (wt[p - 1000][lp]); @@ -110,7 +108,7 @@ int nr_pusch_dmrs_rx(PHY_VARS_gNB *gNB, return(0); } -int nr_pdsch_dmrs_rx(const PHY_VARS_NR_UE *ue, +int nr_pdsch_dmrs_rx(nr_prefix_type_t Ncp, unsigned int Ns, const unsigned int *nr_gold_pdsch, c16_t *output, @@ -128,7 +126,7 @@ int nr_pdsch_dmrs_rx(const PHY_VARS_NR_UE *ue, LOG_E(PHY,"Bad PDSCH DMRS config type %d\n", config_type); if ((p >= 1000) && (p < ((config_type == NFAPI_NR_DMRS_TYPE1) ? 1008 : 1012))) { - if (ue->frame_parms.Ncp == NORMAL) { + if (Ncp == NR_NORMAL) { for (int i = 0; i < nb_pdsch_rb * ((config_type == NFAPI_NR_DMRS_TYPE1) ? 6 : 4); i++) { int w = (wf[p - 1000][i & 1]) * (wt[p - 1000][lp]); output[i] = get_modulated(nr_gold_pdsch, i, w == 1); @@ -215,7 +213,7 @@ void nr_gen_ref_conj_symbols(const uint32_t *in, uint32_t length, c16_t *output, } } -int nr_pusch_lowpaprtype1_dmrs_rx(PHY_VARS_gNB *gNB, +int nr_pusch_lowpaprtype1_dmrs_rx(nr_prefix_type_t Ncp, unsigned int Ns, c16_t *dmrs_seq, c16_t *output, @@ -234,7 +232,7 @@ int nr_pusch_lowpaprtype1_dmrs_rx(PHY_VARS_gNB *gNB, LOG_E(PHY,"PUSCH DMRS config type %d not valid\n", dmrs_type); if ((p>=1000) && (p<1008)) { - if (gNB->frame_parms.Ncp == NORMAL) { + if (Ncp == NR_NORMAL) { nb_dmrs = NR_NB_SC_PER_RB/2; // for DMRS TYPE 1 - 6 DMRS REs present per RB for (int i=dmrs_offset; i + uint32_t *gold_cache(uint32_t key, int length); uint32_t *nr_gold_pbch(int Lmax, int Nid, int n_hf, int ssb); uint32_t *nr_gold_pdcch(int N_RB_DL, int symbols_per_slot, unsigned short n_idDMRS, int ns, int l); diff --git a/openair1/PHY/NR_REFSIG/refsig_defs_ue.h b/openair1/PHY/NR_REFSIG/refsig_defs_ue.h index fb7dce4489..8a20823d5d 100644 --- a/openair1/PHY/NR_REFSIG/refsig_defs_ue.h +++ b/openair1/PHY/NR_REFSIG/refsig_defs_ue.h @@ -37,7 +37,7 @@ void nr_pbch_dmrs_rx(int dmrss, const unsigned int *nr_gold_pbch, c16_t *output, */ void nr_pdcch_dmrs_ref(const unsigned int *nr_gold_pdcch, c16_t *output, unsigned short nb_rb_corset); -int nr_pdsch_dmrs_rx(const PHY_VARS_NR_UE *ue, +int nr_pdsch_dmrs_rx(nr_prefix_type_t Ncp, unsigned int Ns, const unsigned int *nr_gold_pdsch, c16_t *output, diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c b/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c index 71f5759396..8a73d7754a 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c +++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c @@ -26,7 +26,6 @@ #include "PHY/defs_gNB.h" #include "PHY/CODING/coding_extern.h" #include "PHY/CODING/coding_defs.h" -#include "PHY/CODING/lte_interleaver_inline.h" #include "PHY/CODING/nrLDPC_coding/nrLDPC_coding_interface.h" #include "PHY/CODING/nrLDPC_extern.h" #include "PHY/NR_TRANSPORT/nr_transport_proto.h" diff --git a/openair1/PHY/NR_TRANSPORT/nr_prs.c b/openair1/PHY/NR_TRANSPORT/nr_prs.c index 799912713d..5ac37037fc 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_prs.c +++ b/openair1/PHY/NR_TRANSPORT/nr_prs.c @@ -1,6 +1,5 @@ #include "PHY/defs_gNB.h" #include "PHY/NR_TRANSPORT/nr_transport_proto.h" -#include "PHY/LTE_REFSIG/lte_refsig.h" #include "PHY/NR_REFSIG/nr_refsig.h" #include "PHY/sse_intrin.h" #include "openair1/PHY/NR_REFSIG/refsig_defs_ue.h" diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c index ba4d192629..e76cc3a3fd 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c +++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c @@ -32,7 +32,7 @@ void nr_idft(int32_t *z, uint32_t Msc_PUSCH) int i, ip; - LOG_T(PHY,"Doing lte_idft for Msc_PUSCH %d\n",Msc_PUSCH); + LOG_T(PHY,"Doing nr_idft for Msc_PUSCH %d\n", Msc_PUSCH); if ((Msc_PUSCH % 1536) > 0) { // conjugate input diff --git a/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c b/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c index a6ff270840..34fad79800 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c +++ b/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c @@ -1296,7 +1296,7 @@ void nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, float beta_dmrs_pdsch = get_beta_dmrs(dlsch->n_dmrs_cdm_groups, config_type == NFAPI_NR_DMRS_TYPE2); int16_t dmrs_scaling = (int16_t)((1 / beta_dmrs_pdsch) * (1 << 14)); const uint32_t *gold = nr_gold_pdsch(fp->N_RB_DL, fp->symbols_per_slot, dlsch->dlDmrsScramblingId, dlsch->nscid, slot, symbol); - nr_pdsch_dmrs_rx(ue, slot, gold, pilot, 1000 + p, 0, nb_rb_pdsch + rb_offset, config_type, dmrs_scaling); + nr_pdsch_dmrs_rx(fp->Ncp, slot, gold, pilot, 1000 + p, 0, nb_rb_pdsch + rb_offset, config_type, dmrs_scaling); delay_t delay = {0}; diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_psbch_tx.c b/openair1/PHY/NR_UE_TRANSPORT/nr_psbch_tx.c index 5a80ca272b..65b6a587ea 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_psbch_tx.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_psbch_tx.c @@ -20,7 +20,6 @@ */ #include "PHY/defs_nr_UE.h" -#include "PHY/LTE_REFSIG/lte_refsig.h" #include "PHY/NR_REFSIG/nr_mod_table.h" #include "PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h" #include "PHY/CODING/nrPolar_tools/nr_polar_psbch_defs.h" diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c index 029c1c5d38..852e87c071 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c @@ -26,7 +26,6 @@ #include "PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h" #include "PHY/CODING/coding_defs.h" #include "PHY/CODING/coding_extern.h" -#include "PHY/CODING/lte_interleaver_inline.h" #include "PHY/CODING/nrLDPC_extern.h" #include "PHY/CODING/nrLDPC_coding/nrLDPC_coding_interface.h" #include "PHY/NR_UE_TRANSPORT/nr_transport_ue.h" diff --git a/openair1/PHY/defs_nr_common.h b/openair1/PHY/defs_nr_common.h index dc2630348c..100cb70e4c 100644 --- a/openair1/PHY/defs_nr_common.h +++ b/openair1/PHY/defs_nr_common.h @@ -86,6 +86,11 @@ #define NR_PUCCH_DMRS_RB 4 +typedef enum { + NR_NORMAL = 0, + NR_EXTENDED = 1 +} nr_prefix_type_t; + typedef enum { NR_MU_0=0, NR_MU_1, @@ -232,7 +237,7 @@ struct NR_DL_FRAME_PARMS { /// Number of common transmit antenna ports in eNodeB (1 or 2) uint8_t nb_antenna_ports_gNB; /// Cyclic Prefix for DL (0=Normal CP, 1=Extended CP) - lte_prefix_type_t Ncp; + nr_prefix_type_t Ncp; /// sequence which is computed based on carrier frequency and numerology to rotate/derotate each OFDM symbol according to Section 5.3 in 38.211 /// First dimension is for the direction of the link (0 DL, 1 UL, 2 SL) c16_t symbol_rotation[3][224]; diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c index ead0b624f7..e304fe3dc9 100644 --- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c +++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c @@ -338,7 +338,7 @@ void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB, slot, fp->N_RB_DL, 0, - fp->Ncp == EXTENDED ? 12 : 14); + fp->Ncp == NR_EXTENDED ? 12 : 14); } T(T_GNB_PHY_DL_OUTPUT_SIGNAL, T_INT(0), diff --git a/openair1/SIMULATION/NR_PHY/dlschsim.c b/openair1/SIMULATION/NR_PHY/dlschsim.c index fa1ee27db1..155c5a6017 100644 --- a/openair1/SIMULATION/NR_PHY/dlschsim.c +++ b/openair1/SIMULATION/NR_PHY/dlschsim.c @@ -374,7 +374,7 @@ int main(int argc, char **argv) frame_parms->nb_antennas_tx = n_tx; frame_parms->nb_antennas_rx = n_rx; frame_parms->N_RB_DL = N_RB_DL; - frame_parms->Ncp = extended_prefix_flag ? EXTENDED : NORMAL; + frame_parms->Ncp = extended_prefix_flag ? NR_EXTENDED : NR_NORMAL; crcTableInit(); nr_phy_config_request_sim(gNB, N_RB_DL, N_RB_DL, mu, Nid_cell,SSB_positions); // TDD configuration diff --git a/openair1/SIMULATION/NR_PHY/srssim.c b/openair1/SIMULATION/NR_PHY/srssim.c index f791173e39..d68f925374 100644 --- a/openair1/SIMULATION/NR_PHY/srssim.c +++ b/openair1/SIMULATION/NR_PHY/srssim.c @@ -338,7 +338,7 @@ int main(int argc, char *argv[]) NR_DL_FRAME_PARMS *fp = &gNB->frame_parms; fp->N_RB_DL = N_RB_DL; fp->N_RB_UL = N_RB_UL; - fp->Ncp = extended_prefix_flag ? EXTENDED : NORMAL; + fp->Ncp = extended_prefix_flag ? NR_EXTENDED : NR_NORMAL; fp->nb_antennas_tx = n_tx; fp->nb_antennas_rx = n_rx; fp->threequarter_fs = threequarter_fs; diff --git a/openair1/SIMULATION/NR_PHY/ulschsim.c b/openair1/SIMULATION/NR_PHY/ulschsim.c index bbe69b2cba..a3bf9b5959 100644 --- a/openair1/SIMULATION/NR_PHY/ulschsim.c +++ b/openair1/SIMULATION/NR_PHY/ulschsim.c @@ -393,7 +393,7 @@ int main(int argc, char **argv) frame_parms = &gNB->frame_parms; //to be initialized I suppose (maybe not necessary for PBCH) frame_parms->N_RB_DL = N_RB_DL; frame_parms->N_RB_UL = N_RB_UL; - frame_parms->Ncp = extended_prefix_flag ? EXTENDED : NORMAL; + frame_parms->Ncp = extended_prefix_flag ? NR_EXTENDED : NR_NORMAL; gNB->max_ldpc_iterations = max_ldpc_iterations; crcTableInit(); diff --git a/openair1/SIMULATION/NR_PHY/ulsim.c b/openair1/SIMULATION/NR_PHY/ulsim.c index e545d6cba2..04a35bc14f 100644 --- a/openair1/SIMULATION/NR_PHY/ulsim.c +++ b/openair1/SIMULATION/NR_PHY/ulsim.c @@ -741,7 +741,7 @@ int main(int argc, char *argv[]) gNB->pusch_thres = -20; gNB->frame_parms.N_RB_DL = N_RB_DL; gNB->frame_parms.N_RB_UL = N_RB_UL; - gNB->frame_parms.Ncp = extended_prefix_flag ? EXTENDED : NORMAL; + gNB->frame_parms.Ncp = extended_prefix_flag ? NR_EXTENDED : NR_NORMAL; AssertFatal((gNB->if_inst = NR_IF_Module_init(0)) != NULL, "Cannot register interface"); gNB->if_inst->NR_PHY_config_req = nr_phy_config_request; From a35c272e04f0a2a0d01ff2aec12040d37aedb31f Mon Sep 17 00:00:00 2001 From: francescomani Date: Tue, 24 Feb 2026 12:56:11 +0100 Subject: [PATCH 47/83] improvements in NR_REFSIG headers --- doc/Doxyfile | 1 - openair1/PHY/INIT/nr_init_ue.c | 2 +- openair1/PHY/NR_REFSIG/nr_dmrs_rx.c | 1 - openair1/PHY/NR_REFSIG/nr_gold_ue.c | 2 +- openair1/PHY/NR_REFSIG/nr_refsig.h | 30 ++++++++++- openair1/PHY/NR_REFSIG/refsig_defs_ue.h | 54 ------------------- .../{nr_refsig_common.h => sl_refsig_defs.h} | 22 ++++---- openair1/PHY/NR_TRANSPORT/nr_pbch.c | 2 +- openair1/PHY/NR_TRANSPORT/nr_prs.c | 1 - .../nr_dl_channel_estimation.c | 1 - openair1/PHY/NR_UE_TRANSPORT/dci_nr.c | 1 - .../PHY/NR_UE_TRANSPORT/nr_initial_sync.c | 2 +- openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c | 2 +- openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c | 2 +- .../PHY/nr_phy_common/inc/nr_phy_common.h | 2 +- openair1/SIMULATION/NR_PHY/dlschsim.c | 1 - openair1/SIMULATION/NR_PHY/pbchsim.c | 1 - openair1/SIMULATION/NR_PHY/pucchsim.c | 1 - openair1/SIMULATION/NR_PHY/ulschsim.c | 1 - 19 files changed, 45 insertions(+), 84 deletions(-) delete mode 100644 openair1/PHY/NR_REFSIG/refsig_defs_ue.h rename openair1/PHY/NR_REFSIG/{nr_refsig_common.h => sl_refsig_defs.h} (60%) diff --git a/doc/Doxyfile b/doc/Doxyfile index 961ab2fcf9..f89d2fd26f 100644 --- a/doc/Doxyfile +++ b/doc/Doxyfile @@ -2046,7 +2046,6 @@ INPUT = \ @CMAKE_CURRENT_SOURCE_DIR@/../openair1/PHY/NR_REFSIG/ul_ref_seq_nr.c \ @CMAKE_CURRENT_SOURCE_DIR@/../openair1/PHY/NR_REFSIG/sss_nr.h \ @CMAKE_CURRENT_SOURCE_DIR@/../openair1/PHY/NR_REFSIG/dmrs_nr.c \ -@CMAKE_CURRENT_SOURCE_DIR@/../openair1/PHY/NR_REFSIG/refsig_defs_ue.h \ @CMAKE_CURRENT_SOURCE_DIR@/../openair1/PHY/NR_REFSIG/ptrs_nr.h \ @CMAKE_CURRENT_SOURCE_DIR@/../openair1/PHY/NR_REFSIG/nr_refsig.h \ @CMAKE_CURRENT_SOURCE_DIR@/../openair1/PHY/NR_REFSIG/dmrs_nr.h \ diff --git a/openair1/PHY/INIT/nr_init_ue.c b/openair1/PHY/INIT/nr_init_ue.c index 7b21102bbf..38a992e8da 100644 --- a/openair1/PHY/INIT/nr_init_ue.c +++ b/openair1/PHY/INIT/nr_init_ue.c @@ -28,7 +28,7 @@ #include "PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h" #include "PHY/NR_REFSIG/pss_nr.h" #include "PHY/NR_REFSIG/ul_ref_seq_nr.h" -#include "PHY/NR_REFSIG/refsig_defs_ue.h" +#include "PHY/NR_REFSIG/sl_refsig_defs.h" #include "PHY/NR_REFSIG/nr_refsig.h" #include "PHY/NR_REFSIG/nr_mod_table.h" #include "openair2/COMMON/prs_nr_paramdef.h" diff --git a/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c b/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c index 70fd564065..d06ce6d917 100644 --- a/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c +++ b/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c @@ -35,7 +35,6 @@ //#define DEBUG_PUSCH #include "PHY/TOOLS/tools_defs.h" -#include "refsig_defs_ue.h" #include "nr_refsig.h" #include "nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface.h" diff --git a/openair1/PHY/NR_REFSIG/nr_gold_ue.c b/openair1/PHY/NR_REFSIG/nr_gold_ue.c index 4cb75e0f78..cc48ada3e2 100644 --- a/openair1/PHY/NR_REFSIG/nr_gold_ue.c +++ b/openair1/PHY/NR_REFSIG/nr_gold_ue.c @@ -19,7 +19,7 @@ * contact@openairinterface.org */ -#include "refsig_defs_ue.h" +#include "sl_refsig_defs.h" #include "openair1/PHY/LTE_TRANSPORT/transport_proto.h" // for lte_gold_generic() void sl_init_psbch_dmrs_gold_sequences(PHY_VARS_NR_UE *UE) diff --git a/openair1/PHY/NR_REFSIG/nr_refsig.h b/openair1/PHY/NR_REFSIG/nr_refsig.h index 764eff2ed4..e5a5e73229 100644 --- a/openair1/PHY/NR_REFSIG/nr_refsig.h +++ b/openair1/PHY/NR_REFSIG/nr_refsig.h @@ -24,8 +24,36 @@ #ifndef __NR_REFSIG__H__ #define __NR_REFSIG__H__ -#include "openair1/PHY/NR_REFSIG/nr_refsig_common.h" #include "PHY/nr_phy_common/inc/nr_phy_common.h" +#include "PHY/defs_nr_common.h" + +uint32_t *gold_cache(uint32_t key, int length); +uint32_t *nr_gold_pbch(int Lmax, int Nid, int n_hf, int ssb); +uint32_t *nr_gold_pdcch(int N_RB_DL, int symbols_per_slot, unsigned short n_idDMRS, int ns, int l); +uint32_t *nr_gold_pdsch(int N_RB_DL, int symbols_per_slot, int nid, int nscid, int slot, int symbol); +uint32_t *nr_gold_pusch(int N_RB_UL, int symbols_per_slot, int Nid, int nscid, int slot, int symbol); +uint32_t *nr_gold_csi_rs(int N_RB_DL, int symbols_per_slot, int slot, int symb, uint32_t Nid); +uint32_t *nr_gold_prs(int nid, int slot, int symbol); + +int nr_pdsch_dmrs_rx(nr_prefix_type_t Ncp, + unsigned int Ns, + const unsigned int *nr_gold_pdsch, + c16_t *output, + unsigned short p, + unsigned char lp, + unsigned short nb_pdsch_rb, + uint8_t config_type, + int16_t dmrs_scaling); + +/*!\brief This function generates the NR Gold sequence (38-211, Sec 5.2.1) for the PBCH DMRS. +@param PHY_VARS_NR_UE* ue structure provides configuration, frame parameters and the pointers to the 32 bits sequence storage tables + */ +void nr_pbch_dmrs_rx(int dmrss, const unsigned int *nr_gold_pbch, c16_t *output, bool sidelink); + +/*!\brief This function generates the NR Gold sequence (38-211, Sec 5.2.1) for the PDCCH DMRS. +@param PHY_VARS_NR_UE* ue structure provides configuration, frame parameters and the pointers to the 32 bits sequence storage tables + */ +void nr_pdcch_dmrs_ref(const unsigned int *nr_gold_pdcch, c16_t *output, unsigned short nb_rb_corset); int nr_pusch_dmrs_rx(nr_prefix_type_t Ncp, unsigned int Ns, diff --git a/openair1/PHY/NR_REFSIG/refsig_defs_ue.h b/openair1/PHY/NR_REFSIG/refsig_defs_ue.h deleted file mode 100644 index 8a20823d5d..0000000000 --- a/openair1/PHY/NR_REFSIG/refsig_defs_ue.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.openairinterface.org/?page_id=698 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *------------------------------------------------------------------------------- - * For more information about the OpenAirInterface (OAI) Software Alliance: - * contact@openairinterface.org - */ - -/* Definitions for LTE Reference signals */ -/* Author R. Knopp / EURECOM / OpenAirInterface.org */ -#ifndef __NR_REFSIG_DEFS__H__ -#define __NR_REFSIG_DEFS__H__ - -#include "PHY/defs_nr_UE.h" -#include "nr_refsig_common.h" - -/*!\brief This function generates the NR Gold sequence (38-211, Sec 5.2.1) for the PBCH DMRS. -@param PHY_VARS_NR_UE* ue structure provides configuration, frame parameters and the pointers to the 32 bits sequence storage tables - */ -void nr_pbch_dmrs_rx(int dmrss, const unsigned int *nr_gold_pbch, c16_t *output, bool sidelink); - -/*!\brief This function generates the NR Gold sequence (38-211, Sec 5.2.1) for the PDCCH DMRS. -@param PHY_VARS_NR_UE* ue structure provides configuration, frame parameters and the pointers to the 32 bits sequence storage tables - */ -void nr_pdcch_dmrs_ref(const unsigned int *nr_gold_pdcch, c16_t *output, unsigned short nb_rb_corset); - -int nr_pdsch_dmrs_rx(nr_prefix_type_t Ncp, - unsigned int Ns, - const unsigned int *nr_gold_pdsch, - c16_t *output, - unsigned short p, - unsigned char lp, - unsigned short nb_pdsch_rb, - uint8_t config_type, - int16_t dmrs_scaling); - -void sl_generate_pss(SL_NR_UE_INIT_PARAMS_t *sl_init_params, uint8_t n_sl_id2, uint16_t scaling); -void sl_generate_pss_ifft_samples(sl_nr_ue_phy_params_t *sl_ue_params, SL_NR_UE_INIT_PARAMS_t *sl_init_params); -void sl_generate_sss(SL_NR_UE_INIT_PARAMS_t *sl_init_params, uint16_t slss_id, uint16_t scaling); -void sl_init_psbch_dmrs_gold_sequences(PHY_VARS_NR_UE *UE); -#endif diff --git a/openair1/PHY/NR_REFSIG/nr_refsig_common.h b/openair1/PHY/NR_REFSIG/sl_refsig_defs.h similarity index 60% rename from openair1/PHY/NR_REFSIG/nr_refsig_common.h rename to openair1/PHY/NR_REFSIG/sl_refsig_defs.h index f10582118f..9fa57c81b0 100644 --- a/openair1/PHY/NR_REFSIG/nr_refsig_common.h +++ b/openair1/PHY/NR_REFSIG/sl_refsig_defs.h @@ -19,19 +19,15 @@ * contact@openairinterface.org */ -/* Definitions for NR Reference signals */ +/* Definitions for LTE Reference signals */ +/* Author R. Knopp / EURECOM / OpenAirInterface.org */ +#ifndef __NR_REFSIG_DEFS__H__ +#define __NR_REFSIG_DEFS__H__ -#ifndef __NR_REFSIG_COMMON_H__ -#define __NR_REFSIG_COMMON_H__ - -#include - -uint32_t *gold_cache(uint32_t key, int length); -uint32_t *nr_gold_pbch(int Lmax, int Nid, int n_hf, int ssb); -uint32_t *nr_gold_pdcch(int N_RB_DL, int symbols_per_slot, unsigned short n_idDMRS, int ns, int l); -uint32_t *nr_gold_pdsch(int N_RB_DL, int symbols_per_slot, int nid, int nscid, int slot, int symbol); -uint32_t *nr_gold_pusch(int N_RB_UL, int symbols_per_slot, int Nid, int nscid, int slot, int symbol); -uint32_t *nr_gold_csi_rs(int N_RB_DL, int symbols_per_slot, int slot, int symb, uint32_t Nid); -uint32_t *nr_gold_prs(int nid, int slot, int symbol); +#include "PHY/defs_nr_UE.h" +void sl_generate_pss(SL_NR_UE_INIT_PARAMS_t *sl_init_params, uint8_t n_sl_id2, uint16_t scaling); +void sl_generate_pss_ifft_samples(sl_nr_ue_phy_params_t *sl_ue_params, SL_NR_UE_INIT_PARAMS_t *sl_init_params); +void sl_generate_sss(SL_NR_UE_INIT_PARAMS_t *sl_init_params, uint16_t slss_id, uint16_t scaling); +void sl_init_psbch_dmrs_gold_sequences(PHY_VARS_NR_UE *UE); #endif diff --git a/openair1/PHY/NR_TRANSPORT/nr_pbch.c b/openair1/PHY/NR_TRANSPORT/nr_pbch.c index 2aa2a113ad..159e040d11 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_pbch.c +++ b/openair1/PHY/NR_TRANSPORT/nr_pbch.c @@ -36,7 +36,7 @@ #include "PHY/sse_intrin.h" #include "executables/softmodem-common.h" #include "reverse_bits.h" -#include "openair1/PHY/NR_REFSIG/nr_refsig_common.h" +#include "openair1/PHY/NR_REFSIG/nr_refsig.h" #include "openair1/PHY/NR_REFSIG/nr_mod_table.h" #include "openair1/PHY/TOOLS/tools_defs.h" diff --git a/openair1/PHY/NR_TRANSPORT/nr_prs.c b/openair1/PHY/NR_TRANSPORT/nr_prs.c index 5ac37037fc..17336074db 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_prs.c +++ b/openair1/PHY/NR_TRANSPORT/nr_prs.c @@ -2,7 +2,6 @@ #include "PHY/NR_TRANSPORT/nr_transport_proto.h" #include "PHY/NR_REFSIG/nr_refsig.h" #include "PHY/sse_intrin.h" -#include "openair1/PHY/NR_REFSIG/refsig_defs_ue.h" #include "openair1/PHY/NR_REFSIG/nr_mod_table.h" //#define DEBUG_PRS_MOD //#define DEBUG_PRS_MAP diff --git a/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c b/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c index 34fad79800..8978527095 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c +++ b/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c @@ -23,7 +23,6 @@ #include #include "SCHED_NR_UE/defs.h" #include "nr_estimation.h" -#include "PHY/NR_REFSIG/refsig_defs_ue.h" #include "PHY/NR_REFSIG/nr_refsig.h" #include "PHY/NR_REFSIG/dmrs_nr.h" #include "PHY/NR_REFSIG/ptrs_nr.h" diff --git a/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c b/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c index cd233bca26..b5f26266e5 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c +++ b/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c @@ -40,7 +40,6 @@ #include "PHY/sse_intrin.h" #include "common/utils/nr/nr_common.h" #include -#include "openair1/PHY/NR_REFSIG/refsig_defs_ue.h" #include "PHY/NR_UE_ESTIMATION/nr_estimation.h" #include "assertions.h" diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c b/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c index 4b4b4b7be8..9d2db73e66 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c @@ -42,7 +42,7 @@ #include "PHY/NR_REFSIG/pss_nr.h" #include "PHY/NR_REFSIG/sss_nr.h" -#include "PHY/NR_REFSIG/refsig_defs_ue.h" +#include "PHY/NR_REFSIG/nr_refsig.h" #include "PHY/TOOLS/tools_defs.h" #include "nr-uesoftmodem.h" diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c b/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c index 613e70be0d..0c78cb3cb1 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c @@ -36,8 +36,8 @@ #include "openair1/SCHED_NR_UE/defs.h" #include #include -#include "openair1/PHY/NR_REFSIG/nr_refsig_common.h" #include "PHY/nr_phy_common/inc/nr_phy_common.h" +#include "openair1/PHY/NR_REFSIG/nr_refsig.h" #include "reverse_bits.h" #include "instrumentation.h" //#define DEBUG_PBCH diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c index 804529ffbf..94ee8022a8 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c @@ -32,7 +32,7 @@ #include #include "PHY/NR_REFSIG/dmrs_nr.h" #include "PHY/NR_REFSIG/ptrs_nr.h" -#include "PHY/NR_REFSIG/refsig_defs_ue.h" +#include "PHY/NR_REFSIG/nr_refsig.h" #include "PHY/NR_UE_TRANSPORT/nr_transport_ue.h" #include "PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h" #include "PHY/MODULATION/nr_modulation.h" diff --git a/openair1/PHY/nr_phy_common/inc/nr_phy_common.h b/openair1/PHY/nr_phy_common/inc/nr_phy_common.h index 5b60f3bdf6..b4c0e1239c 100644 --- a/openair1/PHY/nr_phy_common/inc/nr_phy_common.h +++ b/openair1/PHY/nr_phy_common/inc/nr_phy_common.h @@ -23,7 +23,7 @@ #define __NR_PHY_COMMON__H__ #include "PHY/impl_defs_top.h" #include "PHY/TOOLS/tools_defs.h" -#include "PHY/NR_REFSIG/nr_refsig_common.h" +#include "PHY/NR_REFSIG/nr_refsig.h" #include "PHY/MODULATION/nr_modulation.h" void init_byte2m128i(void); diff --git a/openair1/SIMULATION/NR_PHY/dlschsim.c b/openair1/SIMULATION/NR_PHY/dlschsim.c index 155c5a6017..076f05db48 100644 --- a/openair1/SIMULATION/NR_PHY/dlschsim.c +++ b/openair1/SIMULATION/NR_PHY/dlschsim.c @@ -38,7 +38,6 @@ #include "PHY/INIT/nr_phy_init.h" #include "PHY/MODULATION/modulation_eNB.h" #include "PHY/MODULATION/modulation_UE.h" -#include "PHY/NR_REFSIG/refsig_defs_ue.h" #include "PHY/NR_TRANSPORT/nr_dlsch.h" #include "PHY/NR_TRANSPORT/nr_transport_proto.h" #include "PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h" diff --git a/openair1/SIMULATION/NR_PHY/pbchsim.c b/openair1/SIMULATION/NR_PHY/pbchsim.c index abf3fd83fe..087b17ab06 100644 --- a/openair1/SIMULATION/NR_PHY/pbchsim.c +++ b/openair1/SIMULATION/NR_PHY/pbchsim.c @@ -34,7 +34,6 @@ #include "PHY/defs_nr_common.h" #include "PHY/defs_nr_UE.h" #include "PHY/defs_gNB.h" -#include "PHY/NR_REFSIG/refsig_defs_ue.h" #include "PHY/MODULATION/modulation_eNB.h" #include "PHY/MODULATION/modulation_UE.h" #include "PHY/MODULATION/nr_modulation.h" diff --git a/openair1/SIMULATION/NR_PHY/pucchsim.c b/openair1/SIMULATION/NR_PHY/pucchsim.c index 67aa99e417..980beac6b3 100644 --- a/openair1/SIMULATION/NR_PHY/pucchsim.c +++ b/openair1/SIMULATION/NR_PHY/pucchsim.c @@ -34,7 +34,6 @@ #include "PHY/defs_nr_common.h" #include "PHY/defs_nr_UE.h" #include "PHY/defs_gNB.h" -#include "PHY/NR_REFSIG/refsig_defs_ue.h" #include "PHY/MODULATION/modulation_eNB.h" #include "PHY/MODULATION/modulation_UE.h" #include "PHY/NR_ESTIMATION/nr_ul_estimation.h" diff --git a/openair1/SIMULATION/NR_PHY/ulschsim.c b/openair1/SIMULATION/NR_PHY/ulschsim.c index a3bf9b5959..df7db31c2e 100644 --- a/openair1/SIMULATION/NR_PHY/ulschsim.c +++ b/openair1/SIMULATION/NR_PHY/ulschsim.c @@ -35,7 +35,6 @@ #include "PHY/defs_gNB.h" #include "PHY/CODING/nrLDPC_coding/nrLDPC_coding_interface.h" #include "PHY/INIT/nr_phy_init.h" -#include "PHY/NR_REFSIG/refsig_defs_ue.h" #include "PHY/MODULATION/modulation_eNB.h" #include "PHY/MODULATION/modulation_UE.h" #include "PHY/NR_TRANSPORT/nr_transport_proto.h" From fd69dc08231a6930699c5632b5a7431d91f52a37 Mon Sep 17 00:00:00 2001 From: francescomani Date: Tue, 24 Feb 2026 13:00:03 +0100 Subject: [PATCH 48/83] include license header in nr_prs.c --- openair1/PHY/NR_TRANSPORT/nr_prs.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/openair1/PHY/NR_TRANSPORT/nr_prs.c b/openair1/PHY/NR_TRANSPORT/nr_prs.c index 17336074db..be1bd8adb8 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_prs.c +++ b/openair1/PHY/NR_TRANSPORT/nr_prs.c @@ -1,3 +1,24 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + #include "PHY/defs_gNB.h" #include "PHY/NR_TRANSPORT/nr_transport_proto.h" #include "PHY/NR_REFSIG/nr_refsig.h" From e9cef104918b8cc18539fd3edd70d0347444d498 Mon Sep 17 00:00:00 2001 From: francescomani Date: Wed, 25 Feb 2026 09:25:28 +0100 Subject: [PATCH 49/83] other small minor cleanup --- openair1/PHY/NR_TRANSPORT/nr_dci_tools.c | 2 -- openair1/PHY/NR_TRANSPORT/nr_prach_common.c | 1 - openair1/PHY/NR_UE_TRANSPORT/README | 1 - openair1/PHY/defs_gNB.h | 1 - openair1/PHY/defs_nr_common.h | 1 - openair1/PHY/impl_defs_top.h | 14 -------------- 6 files changed, 20 deletions(-) delete mode 100644 openair1/PHY/NR_UE_TRANSPORT/README diff --git a/openair1/PHY/NR_TRANSPORT/nr_dci_tools.c b/openair1/PHY/NR_TRANSPORT/nr_dci_tools.c index c2d2ab7a24..742d3bb43e 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dci_tools.c +++ b/openair1/PHY/NR_TRANSPORT/nr_dci_tools.c @@ -35,8 +35,6 @@ //#define DEBUG_FILL_DCI -#include "nr_dlsch.h" - int compfunc(const void *a, const void *b) { return (*(int *)a - *(int *)b); diff --git a/openair1/PHY/NR_TRANSPORT/nr_prach_common.c b/openair1/PHY/NR_TRANSPORT/nr_prach_common.c index 7a7c64a048..8c6fe7152a 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_prach_common.c +++ b/openair1/PHY/NR_TRANSPORT/nr_prach_common.c @@ -31,7 +31,6 @@ */ #include "PHY/sse_intrin.h" #include "PHY/impl_defs_nr.h" -#include "PHY/defs_nr_UE.h" #include "PHY/NR_TRANSPORT/nr_prach.h" #include "PHY/NR_TRANSPORT/nr_transport_common_proto.h" #include "common/utils/LOG/log.h" diff --git a/openair1/PHY/NR_UE_TRANSPORT/README b/openair1/PHY/NR_UE_TRANSPORT/README deleted file mode 100644 index 62393afe93..0000000000 --- a/openair1/PHY/NR_UE_TRANSPORT/README +++ /dev/null @@ -1 +0,0 @@ -UE NR transport/physical channel procedures are here diff --git a/openair1/PHY/defs_gNB.h b/openair1/PHY/defs_gNB.h index c5abe7523d..b1113517c6 100644 --- a/openair1/PHY/defs_gNB.h +++ b/openair1/PHY/defs_gNB.h @@ -37,7 +37,6 @@ #include "defs_nr_common.h" #include "CODING/nrPolar_tools/nr_polar_pbch_defs.h" #include "openair2/NR_PHY_INTERFACE/NR_IF_Module.h" -#include "PHY/NR_TRANSPORT/nr_transport_common_proto.h" #include "PHY/impl_defs_top.h" #include "PHY/CODING/nrLDPC_coding/nrLDPC_coding_interface.h" #include "PHY/CODING/nrLDPC_extern.h" diff --git a/openair1/PHY/defs_nr_common.h b/openair1/PHY/defs_nr_common.h index 100cb70e4c..746740b7fa 100644 --- a/openair1/PHY/defs_nr_common.h +++ b/openair1/PHY/defs_nr_common.h @@ -34,7 +34,6 @@ #define __PHY_DEFS_NR_COMMON__H__ #include "PHY/impl_defs_top.h" -#include "nfapi_nr_interface_scf.h" #include "impl_defs_nr.h" #include "PHY/CODING/nrPolar_tools/nr_polar_defs.h" diff --git a/openair1/PHY/impl_defs_top.h b/openair1/PHY/impl_defs_top.h index a59244a14b..2ae4ebb119 100644 --- a/openair1/PHY/impl_defs_top.h +++ b/openair1/PHY/impl_defs_top.h @@ -240,20 +240,6 @@ #define NR_MAX_ULSCH_HARQ_PROCESSES (NR_MAX_HARQ_PROCESSES) /* cf 38.214 6.1 UE procedure for receiving the physical uplink shared channel */ #define NR_MAX_DLSCH_HARQ_PROCESSES (NR_MAX_HARQ_PROCESSES) /* cf 38.214 5.1 UE procedure for receiving the physical downlink shared channel */ -/// Data structure for transmission. -typedef struct { - /// RAW TX sample buffer - char *TX_DMA_BUFFER[2]; -} TX_VARS ; - -/// Data structure for reception. -typedef struct { - /// RAW TX sample buffer - char *TX_DMA_BUFFER[2]; - /// RAW RX sample buffer - int *RX_DMA_BUFFER[2]; -} TX_RX_VARS; - /// Measurement Variables //#define NUMBER_OF_SUBBANDS_MAX 13 From 10c26a79a5e4b63fb8a20fbec30af6d992b6e17f Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 26 Feb 2026 09:32:12 +0100 Subject: [PATCH 50/83] Link log_headers to ldpc_aal to also force build of T headers --- .../PHY/CODING/nrLDPC_coding/nrLDPC_coding_aal/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openair1/PHY/CODING/nrLDPC_coding/nrLDPC_coding_aal/CMakeLists.txt b/openair1/PHY/CODING/nrLDPC_coding/nrLDPC_coding_aal/CMakeLists.txt index 1bad804fba..383a9c8108 100644 --- a/openair1/PHY/CODING/nrLDPC_coding/nrLDPC_coding_aal/CMakeLists.txt +++ b/openair1/PHY/CODING/nrLDPC_coding/nrLDPC_coding_aal/CMakeLists.txt @@ -21,7 +21,7 @@ if (ENABLE_LDPC_AAL) set_target_properties(ldpc_aal PROPERTIES COMPILE_FLAGS "-DALLOW_EXPERIMENTAL_API") set_target_properties(ldpc_aal PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}) target_include_directories(ldpc_aal PRIVATE ${LIBDPDK_AAL_INCLUDE_DIRS}) - target_link_libraries(ldpc_aal PRIVATE ldpc_gen_HEADERS ${LIBDPDK_AAL_LDFLAGS}) + target_link_libraries(ldpc_aal PRIVATE log_headers ldpc_gen_HEADERS ${LIBDPDK_AAL_LDFLAGS}) if (PMD_T2) target_link_libraries(ldpc_aal PRIVATE ${PMD_T2}) endif() From de3dfee0c2b1ef3cf59d294a6f1e38186170c5b9 Mon Sep 17 00:00:00 2001 From: Jaroslava Fiedlerova Date: Sat, 21 Feb 2026 12:56:00 +0000 Subject: [PATCH 51/83] nr_dlsim: add -f feature flag support and remove unused SCG handling - Replace previous handling of -f with a generic feature flag option. - Add support for the "cuda" flag to enable CUDA channel simulation when compiled with ENABLE_CUDA. - Remove unused SCGroupConfig file handling (scg_fd) and related code. - Clean up deprecated code and variables associated with SCG reading - not required anymore after b232be94edc8a98d16128c3275654e156f350b78 --- openair1/SIMULATION/NR_PHY/dlsim.c | 83 +++++------------------------- 1 file changed, 14 insertions(+), 69 deletions(-) diff --git a/openair1/SIMULATION/NR_PHY/dlsim.c b/openair1/SIMULATION/NR_PHY/dlsim.c index 75cebba300..d0afbba0d1 100644 --- a/openair1/SIMULATION/NR_PHY/dlsim.c +++ b/openair1/SIMULATION/NR_PHY/dlsim.c @@ -407,8 +407,6 @@ int main(int argc, char **argv) int print_perf = 0; - FILE *scg_fd=NULL; - int use_cuda = 0; void *h_tx_sig_pinned = NULL; @@ -420,15 +418,7 @@ int main(int argc, char **argv) void *d_channel_coeffs_gpu = NULL; #endif - static struct option long_options[] = {{"cuda", no_argument, 0, 0}, {0, 0, 0, 0}}; - int option_index = 0; - - while ((c = getopt_long(argc, - argv, - "O:f:hA:p:g:i:n:s:S:t:v:x:y:z:o:H:M:N:F:GR:d:PI:L:a:b:e:m:w:T:U:q:X:Y:Z:", - long_options, - &option_index)) - != -1) { + while ((c = getopt(argc, argv, "--:O:f:hA:p:f:g:i:n:s:S:t:v:x:y:z:o:H:M:N:F:GR:d:PI:L:a:b:e:m:w:T:U:q:X:Y:Z:")) != -1) { /* ignore long options starting with '--', option '-O' and their arguments that are handled by configmodule */ /* with this opstring getopt returns 1 for non-option arguments, refer to 'man 3 getopt' */ if (c == 1 || c == '-' || c == 'O') @@ -436,19 +426,14 @@ int main(int argc, char **argv) printf("handling optarg %c\n",c); switch (c) { - #ifdef ENABLE_CUDA - case 0: - if (strcmp(long_options[option_index].name, "cuda") == 0) { - use_cuda = 1; - } - #endif - break; - case 'f': - scg_fd = fopen(optarg,"r"); - - if (scg_fd==NULL) { - printf("Error opening %s\n",optarg); +#ifdef ENABLE_CUDA + if (strcmp(optarg, "cuda") == 0) { + use_cuda = 1; + } else +#endif + { + printf("Unsupported flag '%s' for -f. Run '-h' to see the list of available options.\n", optarg); exit(-1); } break; @@ -658,7 +643,12 @@ int main(int argc, char **argv) printf("-b Number of PRB for PDSCH\n"); printf("-d number of dlsch threads, 0: no dlsch parallelization\n"); printf("-e MSC index\n"); - printf("-f raw file containing RRC configuration (generated by gNB)\n"); + printf("-f Enable optional feature flag. Available flags:\n"); +#ifdef ENABLE_CUDA + printf(" cuda Enable CUDA channel simulation\n"); +#else + printf(" (none) No optional features were compiled into this executable\n"); +#endif printf("-g Channel model: [A] TDLA30, [B] TDLB100, [C] TDLC300, e.g. -g A\n"); printf("-h This message\n"); printf("-H Slot number\n"); @@ -818,48 +808,6 @@ int main(int argc, char **argv) gNB_mac->dl_bler.harq_round_max = num_rounds; - /* - // read in SCGroupConfig - AssertFatal(scg_fd != NULL,"no reconfig.raw file\n"); - char buffer[1024]; - int msg_len=fread(buffer,1,1024,scg_fd); - NR_RRCReconfiguration_t *NR_RRCReconfiguration = NULL; - - printf("Decoding NR_RRCReconfiguration (%d bytes)\n",msg_len); - asn_dec_rval_t dec_rval = uper_decode_complete( NULL, - &asn_DEF_NR_RRCReconfiguration, - (void **)&NR_RRCReconfiguration, - (uint8_t *)buffer, - msg_len); - - if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) { - AssertFatal(1==0,"NR_RRCReConfiguration decode error\n"); - // free the memory - SEQUENCE_free( &asn_DEF_NR_RRCReconfiguration, NR_RRCReconfiguration, 1 ); - exit(-1); - } - fclose(scg_fd); - - AssertFatal(NR_RRCReconfiguration->criticalExtensions.present == NR_RRCReconfiguration__criticalExtensions_PR_rrcReconfiguration,"wrong NR_RRCReconfiguration->criticalExstions.present type\n"); - - NR_RRCReconfiguration_IEs_t *reconfig_ies = NR_RRCReconfiguration->criticalExtensions.choice.rrcReconfiguration; - NR_CellGroupConfig_t *secondaryCellGroup = NULL; - dec_rval = uper_decode_complete( NULL, - &asn_DEF_NR_CellGroupConfig, - (void **)&secondaryCellGroup, - (uint8_t *)reconfig_ies->secondaryCellGroup->buf, - reconfig_ies->secondaryCellGroup->size); - - if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) { - AssertFatal(1==0,"NR_CellGroupConfig decode error\n"); - // free the memory - SEQUENCE_free( &asn_DEF_NR_CellGroupConfig, secondaryCellGroup, 1 ); - exit(-1); - } - - NR_ServingCellConfigCommon_t *scc = secondaryCellGroup->spCellConfig->reconfigurationWithSync->spCellConfigCommon; - */ - gNB->ap_N1 = pdsch_AntennaPorts.N1; gNB->ap_N2 = pdsch_AntennaPorts.N2; gNB->ap_XP = pdsch_AntennaPorts.XP; @@ -1595,9 +1543,6 @@ int main(int argc, char **argv) if (input_fd) fclose(input_fd); - if (scg_fd) - fclose(scg_fd); - // closing csv file if (filename_csv != NULL) { // means we are asked to print stats to CSV fclose(csv_file); From afc52abb8a423350e6384f7ffa223c0e3d410305 Mon Sep 17 00:00:00 2001 From: Nika Ghaderi Date: Tue, 23 Sep 2025 10:59:10 +0000 Subject: [PATCH 52/83] Integrate CUDA Channel Pipeline into UL Simulator This commit integrates the GPU-based channel simulation pipeline into the ulsim. A `--cuda` command-line flag is added to enable the GPU path at runtime. When activated, the simulator will: - Allocate all necessary GPU and pinned host memory via the `init_cuda_chsim_buffers` helper function. - In the main simulation loop, call the `run_channel_pipeline_cuda` function to perform the channel simulation on the GPU, bypassing the CPU-based functions. - Clean up all CUDA resources on exit using the `free_cuda_chsim_buffers` helper. The cpu path is also updated to use multipath_channel_float and add_noise_float. --- openair1/SIMULATION/NR_PHY/ulsim.c | 220 ++++++++++++++++++++++++----- 1 file changed, 188 insertions(+), 32 deletions(-) diff --git a/openair1/SIMULATION/NR_PHY/ulsim.c b/openair1/SIMULATION/NR_PHY/ulsim.c index e545d6cba2..b49dbeca82 100644 --- a/openair1/SIMULATION/NR_PHY/ulsim.c +++ b/openair1/SIMULATION/NR_PHY/ulsim.c @@ -90,6 +90,11 @@ #include "time_meas.h" #include "utils.h" +#ifdef ENABLE_CUDA +#include +#include "SIMULATION/TOOLS/oai_cuda.h" +#endif + //#define DEBUG_ULSIM const char *__asan_default_options() @@ -286,7 +291,7 @@ int main(int argc, char *argv[]) int slot = 8, frame = 1; int do_SRS = 0; FILE *output_fd = NULL; - double **s_re,**s_im,**r_re,**r_im; + float **s_interleaved, **r_re, **r_im; //uint8_t write_output_file = 0; int trial, n_trials = 1, n_false_positive = 0, delay = 0; double maxDoppler = 0.0; @@ -364,7 +369,25 @@ int main(int argc, char *argv[]) int c; bool setAffinity=false; char gNBthreads[128]="n"; - while ((c = getopt(argc, argv, "--:O:a:b:c:d:ef:g:h:i:jk:m:n:o::p:q:r:s:t:u:v:w:y:z:A:C:F:G:H:I:M:N:PR:S:T:U:L:ZW:E:X:Y:")) + static struct option long_options[] = {{"cuda", no_argument, 0, 0}, {0, 0, 0, 0}}; + int option_index = 0; + int use_cuda = 0; + + void *h_tx_sig_pinned = NULL; + +#ifdef ENABLE_CUDA + void *d_tx_sig = NULL, *d_intermediate_sig = NULL, *d_final_output = NULL; + void *d_curand_states = NULL; + void *h_final_output_pinned = NULL; + float *h_channel_coeffs = NULL; + void *d_channel_coeffs_gpu = NULL; +#endif + + while ((c = getopt_long(argc, + argv, + "--:O:a:b:c:d:ef:g:h:i:jk:m:n:o::p:q:r:s:t:u:v:w:y:z:A:C:F:G:H:I:M:N:PR:S:T:U:L:ZW:E:X:Y:", + long_options, + &option_index)) != -1) { /* ignore long options starting with '--', option '-O' and their arguments that are handled by configmodule */ /* with this opstring getopt returns 1 for non-option arguments, refer to 'man 3 getopt' */ @@ -373,7 +396,14 @@ int main(int argc, char *argv[]) printf("handling optarg %c\n",c); switch (c) { - +#ifdef ENABLE_CUDA + case 0: + if (strcmp(long_options[option_index].name, "cuda") == 0) { + use_cuda = 1; + printf("CUDA acceleration enabled.\n"); + } + break; +#endif case 'a': start_symbol = atoi(optarg); AssertFatal(start_symbol >= 0 && start_symbol < 13,"start_symbol %d is not in 0..12\n",start_symbol); @@ -746,10 +776,9 @@ int main(int argc, char *argv[]) AssertFatal((gNB->if_inst = NR_IF_Module_init(0)) != NULL, "Cannot register interface"); gNB->if_inst->NR_PHY_config_req = nr_phy_config_request; - s_re = malloc(n_tx*sizeof(double*)); - s_im = malloc(n_tx*sizeof(double*)); - r_re = malloc(n_rx*sizeof(double*)); - r_im = malloc(n_rx*sizeof(double*)); + s_interleaved = malloc(n_tx * sizeof(float *)); + r_re = malloc(n_rx * sizeof(float *)); + r_im = malloc(n_rx * sizeof(float *)); NR_ServingCellConfigCommon_t *scc = calloc(1,sizeof(*scc));; prepare_scc(scc); @@ -873,6 +902,35 @@ int main(int argc, char *argv[]) exit(-1); } + const int num_samples_alloc = 153600; +#ifdef ENABLE_CUDA + init_cuda_chsim_buffers(use_cuda, + n_tx, + n_rx, + &d_tx_sig, + &d_intermediate_sig, + &d_final_output, + &d_curand_states, + &h_tx_sig_pinned, + &h_final_output_pinned, + &d_channel_coeffs_gpu); + if (use_cuda) { + int num_links = n_tx * n_rx; + h_channel_coeffs = (float *)malloc(num_links * UE2gNB->channel_length * sizeof(float2)); + } +#endif + +#if !defined(ENABLE_CUDA) || !use_cuda + printf("Pre-allocating padded host memory for the CPU channel pipeline...\n"); + const int max_padding_alloc = 256 - 1; + size_t padded_tx_alloc_bytes = n_tx * (num_samples_alloc + max_padding_alloc) * 2 * sizeof(float); + h_tx_sig_pinned = malloc(padded_tx_alloc_bytes); + if (h_tx_sig_pinned == NULL) { + printf("Error: Failed to allocate host buffer for CPU path\n"); + exit(-1); + } +#endif + // Configure UE UE = calloc(1, sizeof(PHY_VARS_NR_UE)); PHY_vars_UE_g = malloc(sizeof(PHY_VARS_NR_UE**)); @@ -917,6 +975,10 @@ int main(int argc, char *argv[]) nfapi_nr_ul_tti_request_t *UL_tti_req = &Sched_INFO->UL_tti_req; Sched_INFO->sched_response_id = -1; + time_stats_t channel_stats = {0}; + time_stats_t noise_stats = {0}; + time_stats_t pipeline_stats = {0}; + nr_phy_data_tx_t phy_data = {0}; uint32_t errors_decoding = 0; @@ -1045,14 +1107,13 @@ int main(int argc, char *argv[]) printf("[ULSIM]: VALUE OF G: %u, TBS: %u\n", available_bits, TBS); int frame_length_complex_samples = gNB->frame_parms.samples_per_subframe * NR_NUMBER_OF_SUBFRAMES_PER_FRAME; - for (int aatx=0; aatxframe_parms.ofdm_symbol_size, nb_rb, precod_nbr_layers, SNR, n_trials); - for (i = 0; i < slot_length; i++) { - for (int aa = 0; aa < UE->frame_parms.nb_antennas_tx; aa++) { - s_re[aa][i] = (double)UE->common_vars.txData[aa][slot_offset + i].r; - s_im[aa][i] = (double)UE->common_vars.txData[aa][slot_offset + i].i; + for (int aa = 0; aa < UE->frame_parms.nb_antennas_tx; aa++) { + for (i = 0; i < slot_length; i++) { + s_interleaved[aa][2 * i] = (float)UE->common_vars.txData[aa][slot_offset + i].r; + s_interleaved[aa][2 * i + 1] = (float)UE->common_vars.txData[aa][slot_offset + i].i; } } - multipath_channel(UE2gNB, s_re, s_im, r_re, r_im, slot_length, 0, (n_trials == 1) ? 1 : 0); - add_noise(rxdata, - (const double **)r_re, - (const double **)r_im, - sigma, - slot_length, - slot_offset, - ts, - delay, - pdu_bit_map, - PUSCH_PDU_BITMAP_PUSCH_PTRS, - gNB->frame_parms.nb_antennas_rx); + const int padding_len = UE2gNB->channel_length - 1; + const int padded_slot_length = slot_length + padding_len; + float *h_tx_ptr = (float *)h_tx_sig_pinned; + size_t total_padded_bytes_for_slot = n_tx * padded_slot_length * 2 * sizeof(float); + memset(h_tx_ptr, 0, total_padded_bytes_for_slot); - } /*End input_fd */ + for (int j = 0; j < n_tx; j++) { + float *data_start_ptr = h_tx_ptr + (j * padded_slot_length + padding_len) * 2; + memcpy(data_start_ptr, s_interleaved[j], slot_length * 2 * sizeof(float)); + } + +#ifdef ENABLE_CUDA + if (use_cuda) { +#if defined(USE_UNIFIED_MEMORY) + int deviceId; + cudaGetDevice(&deviceId); + const int padding_len = UE2gNB->channel_length - 1; + const int padded_slot_length = slot_length + padding_len; + cudaMemPrefetchAsync(d_tx_sig, n_tx * padded_slot_length * 2 * sizeof(float), deviceId, 0); +#endif + + start_meas(&pipeline_stats); + random_channel(UE2gNB, 0); + int num_links = UE2gNB->nb_tx * UE2gNB->nb_rx; + if (h_channel_coeffs == NULL) { + h_channel_coeffs = (float *)malloc(num_links * 256 * sizeof(float2)); + } + + for (int link = 0; link < num_links; link++) { + for (int l = 0; l < UE2gNB->channel_length; l++) { + int idx = link * UE2gNB->channel_length + l; + ((float2 *)h_channel_coeffs)[idx].x = (float)UE2gNB->ch[link][l].r; + ((float2 *)h_channel_coeffs)[idx].y = (float)UE2gNB->ch[link][l].i; + } + } + + run_channel_pipeline_cuda(rxdata, + n_tx, + n_rx, + UE2gNB->channel_length, + slot_length, + h_channel_coeffs, + (float)sigma, + ts, + pdu_bit_map, + PUSCH_PDU_BITMAP_PUSCH_PTRS, + slot_offset, + delay, + d_tx_sig, + d_intermediate_sig, + d_final_output, + d_curand_states, + h_tx_sig_pinned, + h_final_output_pinned, + d_channel_coeffs_gpu); + cudaDeviceSynchronize(); + stop_meas(&pipeline_stats); + + } else +#endif + { + float **tx_sig_for_cpu = malloc(n_tx * sizeof(float *)); + float *h_tx_ptr = (float *)h_tx_sig_pinned; + const int padding_len = UE2gNB->channel_length - 1; + const int padded_slot_length = slot_length + padding_len; + + for (int j = 0; j < n_tx; j++) { + tx_sig_for_cpu[j] = h_tx_ptr + (j * padded_slot_length + padding_len) * 2; + } + + start_meas(&channel_stats); + multipath_channel_float(UE2gNB, tx_sig_for_cpu, r_re, r_im, slot_length, 0, (n_trials == 1) ? 1 : 0); + stop_meas(&channel_stats); + + free(tx_sig_for_cpu); + + bool apply_phase_noise = (pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_PTRS); + start_meas(&noise_stats); + add_noise_float(rxdata, + (const float **)r_re, + (const float **)r_im, + (float)sigma, + slot_length, + slot_offset, + ts, + delay, + apply_phase_noise, + gNB->frame_parms.nb_antennas_rx); + stop_meas(&noise_stats); + } + } + /*End input_fd */ //---------------------------------------------------------- //------------------- gNB phy procedures ------------------- @@ -1728,6 +1866,13 @@ int main(int argc, char *argv[]) printStatIndent2(&gNB->srs_report_tlv_stats,"SRS report TLV build time"); printStatIndent3(&gNB->srs_beam_report_stats,"SRS beam report build time"); printStatIndent3(&gNB->srs_iq_matrix_stats,"SRS IQ matrix build time"); + + if (use_cuda) { + printStatIndent(&pipeline_stats, "GPU Channel Pipeline"); + } else { + printStatIndent(&channel_stats, "Multipath Channel (CPU)"); + printStatIndent(&noise_stats, "Add Noise (CPU)"); + } printf("\n"); } @@ -1783,6 +1928,17 @@ int main(int argc, char *argv[]) fclose(uci_ulsch_matlab_vec); free_and_zero(UE->phy_sim_test_buf); +#ifdef ENABLE_CUDA + free_cuda_chsim_buffers(use_cuda, + &d_tx_sig, + &d_intermediate_sig, + &d_final_output, + &d_curand_states, + &h_tx_sig_pinned, + &h_final_output_pinned, + &h_channel_coeffs, + &d_channel_coeffs_gpu); +#endif return ret; } From 864d378a258075152a79cd0b8fbe770efebb414c Mon Sep 17 00:00:00 2001 From: Jaroslava Fiedlerova Date: Sat, 21 Feb 2026 12:53:20 +0000 Subject: [PATCH 53/83] nr_ulsim: add -f option to support feature flags (e.g. CUDA) - Introduce usage of the -f option in ulsim to allow enabling specific feature flags at runtime. - Add support for the "cuda" flag to enable CUDA channel simulation when compiled with CUDA support. If an unsupported flag is provided, nr_ulsim reports an error. --- openair1/SIMULATION/NR_PHY/ulsim.c | 41 +++++++++++------------------- 1 file changed, 15 insertions(+), 26 deletions(-) diff --git a/openair1/SIMULATION/NR_PHY/ulsim.c b/openair1/SIMULATION/NR_PHY/ulsim.c index b49dbeca82..98a0af3cce 100644 --- a/openair1/SIMULATION/NR_PHY/ulsim.c +++ b/openair1/SIMULATION/NR_PHY/ulsim.c @@ -342,7 +342,6 @@ int main(int argc, char *argv[]) int ilbrm = 0; UE_nr_rxtx_proc_t UE_proc; - FILE *scg_fd=NULL; FILE *uci_ulsch_matlab_vec = NULL; int file_offset = 0; @@ -369,8 +368,6 @@ int main(int argc, char *argv[]) int c; bool setAffinity=false; char gNBthreads[128]="n"; - static struct option long_options[] = {{"cuda", no_argument, 0, 0}, {0, 0, 0, 0}}; - int option_index = 0; int use_cuda = 0; void *h_tx_sig_pinned = NULL; @@ -383,11 +380,7 @@ int main(int argc, char *argv[]) void *d_channel_coeffs_gpu = NULL; #endif - while ((c = getopt_long(argc, - argv, - "--:O:a:b:c:d:ef:g:h:i:jk:m:n:o::p:q:r:s:t:u:v:w:y:z:A:C:F:G:H:I:M:N:PR:S:T:U:L:ZW:E:X:Y:", - long_options, - &option_index)) + while ((c = getopt(argc, argv, "--:O:a:b:c:d:ef:g:h:i:jk:m:n:o::p:q:r:s:t:u:v:w:y:z:A:C:F:G:H:I:M:N:PR:S:T:U:L:ZW:E:X:Y:")) != -1) { /* ignore long options starting with '--', option '-O' and their arguments that are handled by configmodule */ /* with this opstring getopt returns 1 for non-option arguments, refer to 'man 3 getopt' */ @@ -396,14 +389,6 @@ int main(int argc, char *argv[]) printf("handling optarg %c\n",c); switch (c) { -#ifdef ENABLE_CUDA - case 0: - if (strcmp(long_options[option_index].name, "cuda") == 0) { - use_cuda = 1; - printf("CUDA acceleration enabled.\n"); - } - break; -#endif case 'a': start_symbol = atoi(optarg); AssertFatal(start_symbol >= 0 && start_symbol < 13,"start_symbol %d is not in 0..12\n",start_symbol); @@ -428,15 +413,17 @@ int main(int argc, char *argv[]) break; case 'f': - scg_fd = fopen(optarg, "r"); - - if (scg_fd == NULL) { - printf("Error opening %s\n", optarg); +#ifdef ENABLE_CUDA + if (strcmp(optarg, "cuda") == 0) { + use_cuda = 1; + } else +#endif + { + printf("Unsupported flag '%s' for -f. Run '-h' to see the list of available options.\n", optarg); exit(-1); } - break; - + case 'g': switch ((char) *optarg) { @@ -688,7 +675,12 @@ int main(int argc, char *argv[]) printf("-c RNTI\n"); printf("-d Introduce delay in terms of number of samples\n"); printf("-e To simulate MSG3 configuration\n"); - printf("-f Input file to read from\n");// file not used in the code + printf("-f Enable optional feature flag. Available flags:\n"); +#ifdef ENABLE_CUDA + printf(" cuda Enable CUDA channel simulation\n"); +#else + printf(" (none) No optional features were compiled into this executable\n"); +#endif printf("-g Channel model configuration. Arguments list: Number of arguments = 3, {Channel model: [A] TDLA30, [B] TDLB100, [C] TDLC300}, {Correlation: [l] Low, [m] Medium, [h] High}, {Maximum Doppler shift} e.g. -g A,l,10\n"); printf("-h This message\n"); printf("-i Change channel estimation technique. Arguments list: Number of arguments=2, Frequency domain {0:Linear interpolation, 1:PRB based averaging}, Time domain {0:Estimates of last DMRS symbol, 1:Average of DMRS symbols}. e.g. -i 1,0\n"); @@ -1915,9 +1907,6 @@ int main(int argc, char *argv[]) if (input_fd) fclose(input_fd); - if (scg_fd) - fclose(scg_fd); - // closing csv file if (filename_csv != NULL) { // means we are asked to print stats to CSV fclose(csv_file); From c32d881be8c06d77b208af67f4eb7ab11dbc5099 Mon Sep 17 00:00:00 2001 From: Jaroslava Fiedlerova Date: Mon, 9 Feb 2026 14:02:37 +0000 Subject: [PATCH 54/83] doc: Add instructions about dlsim/ulsim with cuda channel simulation --- openair1/SIMULATION/TOOLS/DOC/gpu_acceleration.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/openair1/SIMULATION/TOOLS/DOC/gpu_acceleration.md b/openair1/SIMULATION/TOOLS/DOC/gpu_acceleration.md index a34d289bb0..d4a6acfda2 100644 --- a/openair1/SIMULATION/TOOLS/DOC/gpu_acceleration.md +++ b/openair1/SIMULATION/TOOLS/DOC/gpu_acceleration.md @@ -132,6 +132,12 @@ This is the traditional CUDA programming model. The host and device have separat To ensure the feature is modular, the integration into the OAI project was handled at both the build system and source code levels. All of the new CUDA source files (`channel_pipeline.cu`, `multipath_channel.cu`, `phase_noise.cu`) are compiled into a single static library named `oai_cuda_lib`. This is defined in the main `CMakeLists.txt` file and is controlled by the `CUDA_ENABLE` CMake option, which is disabled by default. When this option is activated (`-DCUDA_ENABLE=ON`), the build system compiles the CUDA library and also defines a global `ENABLE_CUDA` preprocessor macro that is visible to the rest of the project. +This `ENABLE_CUDA` macro is then used within the simulator files, such as `dlsim.c` and `ulsim.c`, to conditionally compile all CUDA-related code. This approach allows for the inclusion of the `oai_cuda.h` header, and the pre-allocation of GPU memory at startup, all without affecting the standard CPU-only build. + +Inside the main processing loop, an `if (use_cuda)` statement acts as the primary runtime switch. To enable a direct comparison, timing measurement calls have been added to both the GPU and CPU execution paths. Also, both paths now source their data from the same common, pre-padded host buffer. The GPU path receives a pointer to the entire padded buffer and leverages its optimized kernel, while the CPU path uses a temporary array of offset pointers to work on the same data without being aware of the padding. This ensures both computations operate on the exact same source data, isolating the performance measurement to the channel processing itself. To execute the simulation on the GPU, the `-f cuda` flag must be provided at runtime; otherwise, the program defaults to this refined CPU implementation. + +Finally, the build system links the `nr_dlsim` and `nr_ulsim` executables against the `oai_cuda_lib` only when the feature is enabled, creating a clean separation between the two codebases. + --- ## Benchmark and Analysis Suite From a6bf72e895732c7ee5a04ed49248306695d18933 Mon Sep 17 00:00:00 2001 From: Jaroslava Fiedlerova Date: Mon, 16 Feb 2026 08:59:26 +0000 Subject: [PATCH 55/83] Fix compilation Fix compilation error: /oai-ran/openair1/SIMULATION/NR_PHY/dlsim.c:932:42: error: variable 'h_channel_coeffs' set but not used [-Werror,-Wunused-but-set-variable] 932 | float *h_channel_coeffs = NULL; | ^ --- openair1/SIMULATION/NR_PHY/dlsim.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/openair1/SIMULATION/NR_PHY/dlsim.c b/openair1/SIMULATION/NR_PHY/dlsim.c index d0afbba0d1..9203e73749 100644 --- a/openair1/SIMULATION/NR_PHY/dlsim.c +++ b/openair1/SIMULATION/NR_PHY/dlsim.c @@ -877,11 +877,13 @@ int main(int argc, char **argv) 0, 0); - float *h_channel_coeffs = NULL; +#ifdef ENABLE_CUDA + float *h_channel_coeffs = NULL; if (use_cuda) { int num_links = n_tx * n_rx; h_channel_coeffs = (float *)malloc(num_links * gNB2UE->channel_length * sizeof(float) * 2); } +#endif if (gNB2UE==NULL) { printf("Problem generating channel model. Exiting.\n"); exit(-1); From e1b7e91f8a37eebaa9a43a3a49999946eb69857f Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 26 Feb 2026 10:26:56 +0100 Subject: [PATCH 56/83] Use nocolor in various CI pipelines --- ci-scripts/yaml_files/5g_sa_n310_4x4_60MHz/docker-compose.yml | 4 ++-- ci-scripts/yaml_files/lte_n3xx_tdd_2x2_tm1/docker-compose.yml | 2 +- ci-scripts/yaml_files/lte_n3xx_tdd_2x2_tm2/docker-compose.yml | 2 +- ci-scripts/yaml_files/sa_aw2s_gnb/docker-compose.yml | 1 + 4 files changed, 5 insertions(+), 4 deletions(-) diff --git a/ci-scripts/yaml_files/5g_sa_n310_4x4_60MHz/docker-compose.yml b/ci-scripts/yaml_files/5g_sa_n310_4x4_60MHz/docker-compose.yml index 487672ae1f..91597197ca 100644 --- a/ci-scripts/yaml_files/5g_sa_n310_4x4_60MHz/docker-compose.yml +++ b/ci-scripts/yaml_files/5g_sa_n310_4x4_60MHz/docker-compose.yml @@ -10,7 +10,7 @@ services: - IPC_LOCK environment: TZ: Europe/Paris - USE_ADDITIONAL_OPTIONS: --nfapi VNF + USE_ADDITIONAL_OPTIONS: --nfapi VNF --log_config.global_log_options level,nocolor,utc_time NFAPI_TRACE_LEVEL: info volumes: - ../../conf_files/gnb-vnf.sa.band77.162prb.nfapi.4x4.conf:/opt/oai-gnb/etc/gnb.conf @@ -30,7 +30,7 @@ services: - IPC_LOCK environment: TZ: Europe/Paris - USE_ADDITIONAL_OPTIONS: --nfapi PNF + USE_ADDITIONAL_OPTIONS: --nfapi PNF --log_config.global_log_options level,nocolor,utc_time NFAPI_TRACE_LEVEL: info volumes: - ../../conf_files/gnb-pnf.band77.usrpn310.4x4.conf:/opt/oai-gnb/etc/gnb.conf diff --git a/ci-scripts/yaml_files/lte_n3xx_tdd_2x2_tm1/docker-compose.yml b/ci-scripts/yaml_files/lte_n3xx_tdd_2x2_tm1/docker-compose.yml index 0aefaf5ef0..0cc07d308e 100644 --- a/ci-scripts/yaml_files/lte_n3xx_tdd_2x2_tm1/docker-compose.yml +++ b/ci-scripts/yaml_files/lte_n3xx_tdd_2x2_tm1/docker-compose.yml @@ -5,7 +5,7 @@ services: container_name: oai-enb environment: TZ: Europe/Paris - USE_ADDITIONAL_OPTIONS: --usrp-tx-thread-config 1 --thread-pool 0,2,4,6 + USE_ADDITIONAL_OPTIONS: --usrp-tx-thread-config 1 --thread-pool 0,2,4,6 --log_config.global_log_options level,nocolor,utc_time volumes: - ../../conf_files/enb.band38.lte_2x2.100prb.usrpn310.conf:/opt/oai-enb/etc/enb.conf network_mode: "host" diff --git a/ci-scripts/yaml_files/lte_n3xx_tdd_2x2_tm2/docker-compose.yml b/ci-scripts/yaml_files/lte_n3xx_tdd_2x2_tm2/docker-compose.yml index db6215a148..94ceec5723 100644 --- a/ci-scripts/yaml_files/lte_n3xx_tdd_2x2_tm2/docker-compose.yml +++ b/ci-scripts/yaml_files/lte_n3xx_tdd_2x2_tm2/docker-compose.yml @@ -5,7 +5,7 @@ services: container_name: oai-enb environment: TZ: Europe/Paris - USE_ADDITIONAL_OPTIONS: --usrp-tx-thread-config 1 --thread-pool 0,2,4,6 + USE_ADDITIONAL_OPTIONS: --usrp-tx-thread-config 1 --thread-pool 0,2,4,6 --log_config.global_log_options level,nocolor,utc_time volumes: - ../../conf_files/enb.band38.lte_2x2_tm2.100prb.usrpn310.conf:/opt/oai-enb/etc/enb.conf network_mode: "host" diff --git a/ci-scripts/yaml_files/sa_aw2s_gnb/docker-compose.yml b/ci-scripts/yaml_files/sa_aw2s_gnb/docker-compose.yml index 54bf6cec00..bc1d20a984 100644 --- a/ci-scripts/yaml_files/sa_aw2s_gnb/docker-compose.yml +++ b/ci-scripts/yaml_files/sa_aw2s_gnb/docker-compose.yml @@ -12,6 +12,7 @@ services: core: -1 # for core dumps environment: TZ: Europe/Paris + USE_ADDITIONAL_OPTIONS: --log_config.global_log_options level,nocolor,utc_time volumes: - ../../conf_files/gnb.sa.band78.51prb.aw2s.ddsuu.conf:/opt/oai-gnb-aw2s/etc/gnb.conf healthcheck: From 3a9fdb674ae9c01d0a0c8e34002664ad38156b3f Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Wed, 18 Feb 2026 18:12:00 +0100 Subject: [PATCH 57/83] Shorten logging output to time I am not sure we ever need the millisecond output. The date is typically also clear from the output (we could print the date at the beginning, once, instead, but this is not done here. Finally, in Jenkins, we typically get time stamps. Thus, it's not necessary to print this by default. On the other hand, since it might be useful when running locally, make time stamps in logs configurable. --- ci-scripts/args_parse.py | 6 +++++- ci-scripts/main.py | 14 ++++++-------- ci-scripts/run_locally.sh | 6 +++--- 3 files changed, 14 insertions(+), 12 deletions(-) diff --git a/ci-scripts/args_parse.py b/ci-scripts/args_parse.py index 3a3ea52fa0..48bca5644f 100644 --- a/ci-scripts/args_parse.py +++ b/ci-scripts/args_parse.py @@ -44,6 +44,7 @@ import constants as CONST def ArgsParse(argvs,CiTestObj,RAN,HTML,CONTAINERS,HELP,SCA,CLUSTER): force_local = False + date_fmt = None while len(argvs) > 1: myArgv = argvs.pop(1) # 0th is this file's name @@ -56,6 +57,9 @@ def ArgsParse(argvs,CiTestObj,RAN,HTML,CONTAINERS,HELP,SCA,CLUSTER): #consider inline parameters + elif re.match(r'^\-\-datefmt=(.+)$', myArgv, re.IGNORECASE): + matchReg = re.match(r'^\-\-datefmt=(.+)$', myArgv, re.IGNORECASE) + date_fmt = matchReg.group(1) elif re.match(r'^\-\-mode=(.+)$', myArgv, re.IGNORECASE): matchReg = re.match(r'^\-\-mode=(.+)$', myArgv, re.IGNORECASE) mode = matchReg.group(1) @@ -168,4 +172,4 @@ def ArgsParse(argvs,CiTestObj,RAN,HTML,CONTAINERS,HELP,SCA,CLUSTER): HELP.GenericHelp(CONST.Version) sys.exit('Invalid Parameter: ' + myArgv) - return mode, force_local + return mode, force_local, date_fmt diff --git a/ci-scripts/main.py b/ci-scripts/main.py index d86af05871..1abdda36ed 100644 --- a/ci-scripts/main.py +++ b/ci-scripts/main.py @@ -62,13 +62,6 @@ import lxml.etree as ET import logging import signal import traceback -logging.basicConfig( - level=logging.DEBUG, - stream=sys.stdout, - format="[%(asctime)s] %(levelname)8s: %(message)s" -) - - #----------------------------------------------------------- @@ -349,7 +342,12 @@ CLUSTER = cls_cluster.Cluster() import args_parse # Force local execution, move all execution targets to localhost force_local = False -mode, force_local = args_parse.ArgsParse(sys.argv,CiTestObj,RAN,HTML,CONTAINERS,HELP,SCA,CLUSTER) +mode, force_local, date_fmt = args_parse.ArgsParse(sys.argv,CiTestObj,RAN,HTML,CONTAINERS,HELP,SCA,CLUSTER) +fmt = "%(levelname)8s: %(message)s" +if date_fmt: + fmt = "[%(asctime)s] %(levelname)s %(message)s" +logging.basicConfig(level=logging.DEBUG, stream=sys.stdout, format=fmt, datefmt=date_fmt,) + #----------------------------------------------------------- # mode amd XML class (action) analysis diff --git a/ci-scripts/run_locally.sh b/ci-scripts/run_locally.sh index 6423378e9c..645ac1a9fe 100755 --- a/ci-scripts/run_locally.sh +++ b/ci-scripts/run_locally.sh @@ -31,15 +31,15 @@ docker tag oai-nr-cuup oai-ci/oai-nr-cuup:develop-${SHORT_COMMIT_SHA} python3 main.py --mode=InitiateHtml --ranRepository=NONE --ranBranch=${CURRENT_BRANCH} \ --ranCommitID=${COMMIT_SHA} --ranAllowMerge=false \ --ranTargetBranch=NONE \ - --XMLTestFile=xml_files/${TESTCASE} --local + --XMLTestFile=xml_files/${TESTCASE} --local --datefmt="%H:%M:%S" python3 main.py --mode=TesteNB --ranRepository=NONE --ranBranch=${CURRENT_BRANCH} \ --ranCommitID=${COMMIT_SHA} --ranAllowMerge=false \ --ranTargetBranch=NONE \ --eNBSourceCodePath=${REPO_PATH} \ - --XMLTestFile=${TESTCASE} --local + --XMLTestFile=${TESTCASE} --local --datefmt="%H:%M:%S" RET=$? -python3 main.py --mode=FinalizeHtml --local +python3 main.py --mode=FinalizeHtml --local --datefmt="%H:%M:%S" exit ${RET} From 0b219bf443c0c89c161f3626b7583b16c8605f8c Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Fri, 22 Aug 2025 08:02:51 +0200 Subject: [PATCH 58/83] Fix invalid escape sequences Use a raw string as suggested: ci-scripts/cls_static_code_analysis.py:93: SyntaxWarning: invalid escape sequence '\:' result = re.search('([a-zA-Z0-9\:\-\.\/])+\.git', self.ranRepository) ci-scripts/cls_static_code_analysis.py:125: SyntaxWarning: invalid escape sequence '\.' ret = re.search('cppcheck version="(?P[0-9\.]+)"', str(line)) ci-scripts/cls_oai_html.py:221: SyntaxWarning: invalid escape sequence '\/' cmd = "sed -i -e 's/__STATE_" + self.htmlTabNames[0] + "__/<\/span>/' test_results.html" ci-scripts/ran.py:428: SyntaxWarning: "\[" is an invalid escape sequence. Such sequences will not work in the future. Did you mean "\\["? A raw string is also an option. result = re.search('\[gNB [0-9]+\]\[RAPROC\] PUSCH with TC_RNTI 0x[0-9a-fA-F]+ received correctly, adding UE MAC Context RNTI 0x[0-9a-fA-F]+', str(line)) ci-scripts/ran.py:457: SyntaxWarning: "\[" is an invalid escape sequence. Such sequences will not work in the future. Did you mean "\\["? A raw string is also an option. result = re.search('\[PHY\]\s+problem receiving samples', str(line)) ci-scripts/ran.py:461: SyntaxWarning: "\[" is an invalid escape sequence. Such sequences will not work in the future. Did you mean "\\["? A raw string is also an option. result = re.search('\[MAC\]\s+Removing UE', str(line)) --- ci-scripts/cls_oai_html.py | 2 +- ci-scripts/cls_static_code_analysis.py | 4 ++-- ci-scripts/ran.py | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/ci-scripts/cls_oai_html.py b/ci-scripts/cls_oai_html.py index 6e29063192..444fc68b5c 100644 --- a/ci-scripts/cls_oai_html.py +++ b/ci-scripts/cls_oai_html.py @@ -218,7 +218,7 @@ class HTMLManagement(): cmd = "sed -i -e 's/__STATE_" + self.htmlTabNames[0] + "__//' test_results.html" subprocess.run(cmd, shell=True) else: - cmd = "sed -i -e 's/__STATE_" + self.htmlTabNames[0] + "__/<\/span>/' test_results.html" + cmd = "sed -i -e 's/__STATE_" + self.htmlTabNames[0] + r"__/<\/span>/' test_results.html" subprocess.run(cmd, shell=True) self.htmlFooterCreated = False diff --git a/ci-scripts/cls_static_code_analysis.py b/ci-scripts/cls_static_code_analysis.py index 5ed52e4027..cc9abedf23 100644 --- a/ci-scripts/cls_static_code_analysis.py +++ b/ci-scripts/cls_static_code_analysis.py @@ -89,7 +89,7 @@ class StaticCodeAnalysis(): logging.debug('Building on server: ' + node) cmd = cls_cmd.getConnection(node) # on RedHat/CentOS .git extension is mandatory - result = re.search('([a-zA-Z0-9\:\-\.\/])+\.git', self.ranRepository) + result = re.search(r'([a-zA-Z0-9\:\-\.\/])+\.git', self.ranRepository) if result is not None: full_ran_repo_name = self.ranRepository.replace('git/', 'git') else: @@ -121,7 +121,7 @@ class StaticCodeAnalysis(): xmlStart = False with open(filename, 'r') as logfile: for line in logfile: - ret = re.search('cppcheck version="(?P[0-9\.]+)"', str(line)) + ret = re.search(r'cppcheck version="(?P[0-9\.]+)"', str(line)) if ret is not None: CCR.versions[vId] = ret.group('version') if re.search('RUN cat cmake_targets/log/cppcheck.xml', str(line)) is not None: diff --git a/ci-scripts/ran.py b/ci-scripts/ran.py index 04384ad4f4..9a69f2d747 100644 --- a/ci-scripts/ran.py +++ b/ci-scripts/ran.py @@ -420,7 +420,7 @@ class RANManagement(): if result is not None: mbmsRequestMsg += 1 #FR1 NSA test : add new markers to make sure gNB is used - result = re.search('\[gNB [0-9]+\]\[RAPROC\] PUSCH with TC_RNTI 0x[0-9a-fA-F]+ received correctly, adding UE MAC Context RNTI 0x[0-9a-fA-F]+', str(line)) + result = re.search(r'\[gNB [0-9]+\]\[RAPROC\] PUSCH with TC_RNTI 0x[0-9a-fA-F]+ received correctly, adding UE MAC Context RNTI 0x[0-9a-fA-F]+', str(line)) if result is not None: NSA_RAPROC_PUSCH_check = 1 @@ -449,11 +449,11 @@ class RANManagement(): #count "problem receiving samples" msg - result = re.search('\[PHY\]\s+problem receiving samples', str(line)) + result = re.search(r'\[PHY\]\s+problem receiving samples', str(line)) if result is not None: pb_receiving_samples_cnt += 1 #count "Removing UE" msg - result = re.search('\[MAC\]\s+Removing UE', str(line)) + result = re.search(r'\[MAC\]\s+Removing UE', str(line)) if result is not None: removing_ue += 1 #count "X2AP-PDU" From 7fe3183d1e1dc9b93261eda2d7520774a5909f2e Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Tue, 17 Feb 2026 19:03:26 +0100 Subject: [PATCH 59/83] Remove dead code --- ci-scripts/main.py | 22 +--------------------- 1 file changed, 1 insertion(+), 21 deletions(-) diff --git a/ci-scripts/main.py b/ci-scripts/main.py index 1abdda36ed..7dd0ef28ef 100644 --- a/ci-scripts/main.py +++ b/ci-scripts/main.py @@ -279,15 +279,6 @@ def ExecuteActionWithParam(action, ctx, node): return success -#check if given test is in list -#it is in list if one of the strings in 'list' is at the beginning of 'test' -def test_in_list(test, list): - for check in list: - check=check.replace('+','') - if (test.startswith(check)): - return True - return False - test_runner_abort = False def receive_signal(signum, frame): global test_runner_abort @@ -365,18 +356,7 @@ elif re.match('^TerminateSPGW$', mode, re.IGNORECASE): elif re.match('^LogCollectBuild$', mode, re.IGNORECASE): logging.warning("Option LogCollectBuild ignored") elif re.match('^LogCollecteNB$', mode, re.IGNORECASE): - if RAN.eNBSourceCodePath == '': - HELP.GenericHelp(CONST.Version) - sys.exit('Insufficient Parameter') - if os.path.isdir('cmake_targets/log'): - cmd = 'zip -r enb.log.' + RAN.BuildId + '.zip cmake_targets/log' - logging.info(cmd) - try: - zipStatus = subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT, universal_newlines=True, timeout=60) - except subprocess.CalledProcessError as e: - logging.error("Command '{}' returned non-zero exit status {}.".format(e.cmd, e.returncode)) - logging.error("Error output:\n{}".format(e.output)) - sys.exit(0) + logging.warning("Option LogCollecteNB ignored") elif re.match('^LogCollectHSS$', mode, re.IGNORECASE): logging.warning("Option LogCollectHSS ignored") elif re.match('^LogCollectMME$', mode, re.IGNORECASE): From cc1d66319020c55987cde9d1584d3e1f50c54ec0 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 19 Feb 2026 09:44:34 +0100 Subject: [PATCH 60/83] Remove unused code in args_parse.py --- ci-scripts/args_parse.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/ci-scripts/args_parse.py b/ci-scripts/args_parse.py index 48bca5644f..9f181ae68e 100644 --- a/ci-scripts/args_parse.py +++ b/ci-scripts/args_parse.py @@ -33,7 +33,6 @@ #----------------------------------------------------------- import sys # arg import re # reg -import yaml import constants as CONST #----------------------------------------------------------- @@ -162,9 +161,6 @@ def ArgsParse(argvs,CiTestObj,RAN,HTML,CONTAINERS,HELP,SCA,CLUSTER): elif re.match(r'^\-\-OCRegistry=(.+)$', myArgv, re.IGNORECASE): matchReg = re.match(r'^\-\-OCRegistry=(.+)$', myArgv, re.IGNORECASE) CLUSTER.OCRegistry = matchReg.group(1) - elif re.match(r'^\-\-BuildId=(.+)$', myArgv, re.IGNORECASE): - matchReg = re.match(r'^\-\-BuildId=(.+)$', myArgv, re.IGNORECASE) - RAN.BuildId = matchReg.group(1) elif re.match(r'^\-\-FlexRicTag=(.+)$', myArgv, re.IGNORECASE): matchReg = re.match(r'^\-\-FlexRicTag=(.+)$', myArgv, re.IGNORECASE) CONTAINERS.flexricTag = matchReg.group(1) From 84a49886d80f584cd9bab99ef2018962aa249f8d Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Wed, 30 Oct 2024 19:41:37 +0100 Subject: [PATCH 61/83] Move unused configs to untested --- .../{ => untested}/enb.band38.nsa_2x2.100prb.usrpn310.conf | 0 .../conf_files/{ => untested}/enb.band7.tm1.50prb.usrpb210.conf | 0 .../{ => untested}/gnb.nsa.band78.106prb.usrpn310.2x2.conf | 0 .../{ => untested}/gnb.sa.band78.106prb.usrp310.2x2.conf | 0 .../{ => untested}/gnb.sa.band78.106prb.usrpn310.ddsuu-2x2.conf | 0 .../{ => untested}/gnb.sa.band78.162prb.usrpn310.2x2.conf | 0 6 files changed, 0 insertions(+), 0 deletions(-) rename ci-scripts/conf_files/{ => untested}/enb.band38.nsa_2x2.100prb.usrpn310.conf (100%) rename ci-scripts/conf_files/{ => untested}/enb.band7.tm1.50prb.usrpb210.conf (100%) rename ci-scripts/conf_files/{ => untested}/gnb.nsa.band78.106prb.usrpn310.2x2.conf (100%) rename ci-scripts/conf_files/{ => untested}/gnb.sa.band78.106prb.usrp310.2x2.conf (100%) rename ci-scripts/conf_files/{ => untested}/gnb.sa.band78.106prb.usrpn310.ddsuu-2x2.conf (100%) rename ci-scripts/conf_files/{ => untested}/gnb.sa.band78.162prb.usrpn310.2x2.conf (100%) diff --git a/ci-scripts/conf_files/enb.band38.nsa_2x2.100prb.usrpn310.conf b/ci-scripts/conf_files/untested/enb.band38.nsa_2x2.100prb.usrpn310.conf similarity index 100% rename from ci-scripts/conf_files/enb.band38.nsa_2x2.100prb.usrpn310.conf rename to ci-scripts/conf_files/untested/enb.band38.nsa_2x2.100prb.usrpn310.conf diff --git a/ci-scripts/conf_files/enb.band7.tm1.50prb.usrpb210.conf b/ci-scripts/conf_files/untested/enb.band7.tm1.50prb.usrpb210.conf similarity index 100% rename from ci-scripts/conf_files/enb.band7.tm1.50prb.usrpb210.conf rename to ci-scripts/conf_files/untested/enb.band7.tm1.50prb.usrpb210.conf diff --git a/ci-scripts/conf_files/gnb.nsa.band78.106prb.usrpn310.2x2.conf b/ci-scripts/conf_files/untested/gnb.nsa.band78.106prb.usrpn310.2x2.conf similarity index 100% rename from ci-scripts/conf_files/gnb.nsa.band78.106prb.usrpn310.2x2.conf rename to ci-scripts/conf_files/untested/gnb.nsa.band78.106prb.usrpn310.2x2.conf diff --git a/ci-scripts/conf_files/gnb.sa.band78.106prb.usrp310.2x2.conf b/ci-scripts/conf_files/untested/gnb.sa.band78.106prb.usrp310.2x2.conf similarity index 100% rename from ci-scripts/conf_files/gnb.sa.band78.106prb.usrp310.2x2.conf rename to ci-scripts/conf_files/untested/gnb.sa.band78.106prb.usrp310.2x2.conf diff --git a/ci-scripts/conf_files/gnb.sa.band78.106prb.usrpn310.ddsuu-2x2.conf b/ci-scripts/conf_files/untested/gnb.sa.band78.106prb.usrpn310.ddsuu-2x2.conf similarity index 100% rename from ci-scripts/conf_files/gnb.sa.band78.106prb.usrpn310.ddsuu-2x2.conf rename to ci-scripts/conf_files/untested/gnb.sa.band78.106prb.usrpn310.ddsuu-2x2.conf diff --git a/ci-scripts/conf_files/gnb.sa.band78.162prb.usrpn310.2x2.conf b/ci-scripts/conf_files/untested/gnb.sa.band78.162prb.usrpn310.2x2.conf similarity index 100% rename from ci-scripts/conf_files/gnb.sa.band78.162prb.usrpn310.2x2.conf rename to ci-scripts/conf_files/untested/gnb.sa.band78.162prb.usrpn310.2x2.conf From 4a2f6cd823823188b022bd604040a7b4a0d1bf2a Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Wed, 30 Oct 2024 19:48:01 +0100 Subject: [PATCH 62/83] Remove unused docker file --- .../fr1_enb_mono_fdd_tim/docker-compose.yml | 27 ------------------- 1 file changed, 27 deletions(-) delete mode 100644 ci-scripts/yaml_files/fr1_enb_mono_fdd_tim/docker-compose.yml diff --git a/ci-scripts/yaml_files/fr1_enb_mono_fdd_tim/docker-compose.yml b/ci-scripts/yaml_files/fr1_enb_mono_fdd_tim/docker-compose.yml deleted file mode 100644 index 7963f823b1..0000000000 --- a/ci-scripts/yaml_files/fr1_enb_mono_fdd_tim/docker-compose.yml +++ /dev/null @@ -1,27 +0,0 @@ -services: - enb_mono_fdd: - image: ${REGISTRY-oaisoftwarealliance/}oai-enb:${TAG:-develop} - privileged: true - container_name: prod-enb-mono-fdd - environment: - USE_B2XX: 'yes' - USE_ADDITIONAL_OPTIONS: --RUs.[0].max_rxgain 115 --RUs.[0].max_pdschReferenceSignalPower -27 --eNBs.[0].component_carriers.[0].pucch_p0_Nominal -96 --log_config.global_log_options level,nocolor,time - volumes: - - ../../conf_files/enb.band7.25prb.usrpb200.conf:/opt/oai-enb/etc/enb.conf - networks: - public_net: - ipv4_address: 192.168.61.30 - healthcheck: - # pgrep does NOT work - test: /bin/bash -c "ps aux | grep -v grep | grep -c softmodem" - interval: 10s - timeout: 5s - retries: 5 - -networks: - public_net: - name: prod-oai-public-net - ipam: - config: - - subnet: 192.168.61.0/26 - From 92997fba2bbeea215477bf5a6726a2665083f441 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Tue, 28 Jan 2025 18:54:59 +0100 Subject: [PATCH 63/83] Update tests/README.md --- ci-scripts/tests/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/ci-scripts/tests/README.md b/ci-scripts/tests/README.md index f583c51c08..355d046efd 100644 --- a/ci-scripts/tests/README.md +++ b/ci-scripts/tests/README.md @@ -16,6 +16,7 @@ To run individual unit tests, start them like so: python tests/deployment.py -v python tests/iperf-analysis.py -v python tests/ping-iperf.py -v + python tests/pull-clean-int-registry.py -v The logs will indicate if all tests passed. `tests/deployment.py` requires these images to be present: From 44ad255195c89c070997086db3fcbaec9f265d30 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 31 Oct 2024 17:23:06 +0100 Subject: [PATCH 64/83] Remove unused USRP_IPAddress --- ci-scripts/main.py | 2 -- ci-scripts/ran.py | 1 - ci-scripts/xml_files/gnb_phytest_usrp_run.xml | 1 - ci-scripts/xml_files/gnb_phytest_usrp_run_100_2x2.xml | 1 - ci-scripts/xml_files/gnb_phytest_usrp_run_60.xml | 1 - ci-scripts/xml_files/gnb_phytest_usrp_run_60_2x2.xml | 1 - 6 files changed, 7 deletions(-) diff --git a/ci-scripts/main.py b/ci-scripts/main.py index 7dd0ef28ef..a67405728d 100644 --- a/ci-scripts/main.py +++ b/ci-scripts/main.py @@ -108,8 +108,6 @@ def ExecuteActionWithParam(action, ctx, node): else: RAN.datalog_rt_stats_file=datalog_rt_stats_file RAN.Initialize_eNB_args=test.findtext('Initialize_eNB_args') - USRPIPAddress = test.findtext('USRP_IPAddress') or '' - #local variable air_interface air_interface = test.findtext('air_interface') if (air_interface is None) or (air_interface.lower() not in ['nr','lte']): diff --git a/ci-scripts/ran.py b/ci-scripts/ran.py index 9a69f2d747..850b44318c 100644 --- a/ci-scripts/ran.py +++ b/ci-scripts/ran.py @@ -70,7 +70,6 @@ class RANManagement(): self.runtime_stats= '' self.datalog_rt_stats={} self.datalog_rt_stats_file='datalog_rt_stats.default.yaml' - self.USRPIPAddress = '' #checkers from xml self.ran_checkers={} self.cmd_prefix = '' # prefix before {lte,nr}-softmodem diff --git a/ci-scripts/xml_files/gnb_phytest_usrp_run.xml b/ci-scripts/xml_files/gnb_phytest_usrp_run.xml index f6af5ee485..e2bd3204aa 100644 --- a/ci-scripts/xml_files/gnb_phytest_usrp_run.xml +++ b/ci-scripts/xml_files/gnb_phytest_usrp_run.xml @@ -39,7 +39,6 @@ -O ci-scripts/conf_files/gnb.band79.106prb.usrpn300.phytest-dora.conf --phy-test -q -U 768 -T 106 -t 23 -D 127 -m 28 -M 106 --usrp-tx-thread-config 1 --log_config.global_log_options level,nocolor,time datalog_rt_stats.default.yaml NR - 192.168.20.2 numactl --cpunodebind=netdev:enp94s0f0np0 --membind=netdev:enp94s0f0np0 diff --git a/ci-scripts/xml_files/gnb_phytest_usrp_run_100_2x2.xml b/ci-scripts/xml_files/gnb_phytest_usrp_run_100_2x2.xml index 93053dee90..c33908a92d 100644 --- a/ci-scripts/xml_files/gnb_phytest_usrp_run_100_2x2.xml +++ b/ci-scripts/xml_files/gnb_phytest_usrp_run_100_2x2.xml @@ -39,7 +39,6 @@ -O ci-scripts/conf_files/gnb.band79.273prb.usrpn300.phytest-dora.conf --phy-test -q -U 768 -T 273 -t 23 -D 127 -m 23 -M 273 -l 2 --usrp-tx-thread-config 1 --log_config.global_log_options level,nocolor,time datalog_rt_stats.100.2x2.yaml NR - 192.168.20.2 numactl --cpunodebind=netdev:enp94s0f0np0 --membind=netdev:enp94s0f0np0 diff --git a/ci-scripts/xml_files/gnb_phytest_usrp_run_60.xml b/ci-scripts/xml_files/gnb_phytest_usrp_run_60.xml index 2cd040a47a..0348c63b35 100644 --- a/ci-scripts/xml_files/gnb_phytest_usrp_run_60.xml +++ b/ci-scripts/xml_files/gnb_phytest_usrp_run_60.xml @@ -39,7 +39,6 @@ -O ci-scripts/conf_files/gnb.band79.162prb.usrpn300.phytest-dora.conf --phy-test -q -U 768 -T 162 -t 23 -D 127 -m 23 -M 162 --usrp-tx-thread-config 1 --log_config.global_log_options level,nocolor,time datalog_rt_stats.1x1.60.yaml NR - 192.168.20.2 numactl --cpunodebind=netdev:enp94s0f0np0 --membind=netdev:enp94s0f0np0 diff --git a/ci-scripts/xml_files/gnb_phytest_usrp_run_60_2x2.xml b/ci-scripts/xml_files/gnb_phytest_usrp_run_60_2x2.xml index 7e5592fb6e..075ba3e92f 100644 --- a/ci-scripts/xml_files/gnb_phytest_usrp_run_60_2x2.xml +++ b/ci-scripts/xml_files/gnb_phytest_usrp_run_60_2x2.xml @@ -39,7 +39,6 @@ -O ci-scripts/conf_files/gnb.band79.162prb.usrpn300.phytest-dora.conf --phy-test --gNBs.[0].pdsch_AntennaPorts_XP 2 --RUs.[0].nb_tx 2 --RUs.[0].nb_rx 2 -q -U 768 -T 162 -t 23 -D 127 -m 23 -M 162 -l 2 --usrp-tx-thread-config 1 --log_config.global_log_options level,nocolor,time datalog_rt_stats.60.2x2.yaml NR - 192.168.20.2 numactl --cpunodebind=netdev:enp94s0f0np0 --membind=netdev:enp94s0f0np0 From 41a6188c0422bef4ad09db2f38ef04484c0f293b Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Wed, 21 Jan 2026 19:00:15 +0100 Subject: [PATCH 65/83] Change bash set options to improve run_locally.sh set -e makes the script exit on error. However, there is code to handle a non-zero return code of the script, and -e prevents from writing the footer. add set -x to see all the commands that are being executed. --- ci-scripts/run_locally.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ci-scripts/run_locally.sh b/ci-scripts/run_locally.sh index 645ac1a9fe..f01d263433 100755 --- a/ci-scripts/run_locally.sh +++ b/ci-scripts/run_locally.sh @@ -1,6 +1,5 @@ #!/bin/bash -set -e SHORT_COMMIT_SHA=$(git rev-parse --short=8 HEAD) COMMIT_SHA=$(git rev-parse HEAD) CURRENT_BRANCH=$(git rev-parse --abbrev-ref HEAD) @@ -13,6 +12,8 @@ if [ $# -eq 0 ] exit 1 fi +set -x + # The script assumes you've build the following images: # # docker build . -f docker/Dockerfile.gNB.ubuntu -t oai-gnb From e809841aeaaa1fe972c9f5db203a573cc9a7e3c7 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Wed, 21 Jan 2026 15:40:21 +0100 Subject: [PATCH 66/83] Move Real-Time Stats Analysis to separate step Factor out to make existing log analysis simpler. It will also allow to more easily port this functionality to docker-based setups. --- ci-scripts/cls_analysis.py | 38 +++++++ ci-scripts/main.py | 9 +- ci-scripts/ran.py | 98 +++---------------- ci-scripts/xml_class_list.yml | 1 + .../gnb_phytest_rfemulator_run_100_2x2.xml | 8 +- ci-scripts/xml_files/gnb_phytest_usrp_run.xml | 8 +- .../gnb_phytest_usrp_run_100_2x2.xml | 8 +- .../xml_files/gnb_phytest_usrp_run_60.xml | 8 +- .../xml_files/gnb_phytest_usrp_run_60_2x2.xml | 8 +- 9 files changed, 93 insertions(+), 93 deletions(-) diff --git a/ci-scripts/cls_analysis.py b/ci-scripts/cls_analysis.py index 588490da62..3d9eb9c499 100644 --- a/ci-scripts/cls_analysis.py +++ b/ci-scripts/cls_analysis.py @@ -22,6 +22,8 @@ import re import os +import logging +import yaml import xml.etree.ElementTree as ET import json @@ -109,3 +111,39 @@ class Analysis(): test_summary['Nbpass'] = nb_tests - nb_failed test_summary['Nbfail'] = nb_failed return nb_failed == 0, test_summary, test_result + + def analyze_rt_stats(thresholds, L1_stats, MAC_stats): + with open(thresholds, 'r') as f: + datalog_rt_stats = yaml.load(f, Loader=yaml.FullLoader) + + rt_keys = datalog_rt_stats['Ref'] + real_time_stats = {} + for sf in [L1_stats, MAC_stats]: + with open(sf, 'r') as f: + for line in f.readlines(): + for k in rt_keys: + result = re.search(k, line) + if result is not None: + tmp = re.match(rf'^.*?(\b{k}\b.*)', line.rstrip()) + if tmp is not None: + real_time_stats[k] = tmp.group(1) + + # datalog_rt_stats format must align with HTML.CreateHtmlDataLogTable() + datalog_rt_stats['Data']={} + for k in real_time_stats: + tmp = re.match(r'^(?P.*):\s+(?P\d+\.\d+) us;\s+(?P\d+);\s+(?P\d+\.\d+) us;', real_time_stats[k]) + if tmp is not None: + metric = tmp.group('metric') + avg = float(tmp.group('avg')) + max = float(tmp.group('max')) + count = int(tmp.group('count')) + datalog_rt_stats['Data'][metric] = ["{:.0f}".format(avg),"{:.0f}".format(max),"{:d}".format(count),"{:.2f}".format(avg / datalog_rt_stats['Ref'][metric])] + + success = True + for k in datalog_rt_stats['Data']: + valnorm = float(datalog_rt_stats['Data'][k][3]) + dev = datalog_rt_stats['DeviationThreshold'][k] + if valnorm > 1.0 + dev or valnorm < 1.0 - dev: # condition for fail: avg/ref deviates by more than "deviation threshold" + logging.debug(f'\u001B[1;30;43m normalized metric {k}={valnorm} deviates by more than {dev}\u001B[0m') + success = False + return success, datalog_rt_stats diff --git a/ci-scripts/main.py b/ci-scripts/main.py index a67405728d..4628b1fcba 100644 --- a/ci-scripts/main.py +++ b/ci-scripts/main.py @@ -102,11 +102,6 @@ def ExecuteActionWithParam(action, ctx, node): success = CONTAINERS.BuildRunTests(ctx, node, HTML) elif action == 'Initialize_eNB': - datalog_rt_stats_file=test.findtext('rt_stats_cfg') - if datalog_rt_stats_file is None: - RAN.datalog_rt_stats_file='datalog_rt_stats.default.yaml' - else: - RAN.datalog_rt_stats_file=datalog_rt_stats_file RAN.Initialize_eNB_args=test.findtext('Initialize_eNB_args') #local variable air_interface air_interface = test.findtext('air_interface') @@ -271,6 +266,10 @@ def ExecuteActionWithParam(action, ctx, node): images = test.findtext('images').split() success = CLUSTER.PullClusterImage(HTML, node, images, tag_prefix=tag_prefix) + elif action == 'AnalyzeRTStats': + yaml = test.findtext('stats_cfg') + success = RAN.AnalyzeRTStats(HTML, node, ctx, yaml) + else: logging.warning(f"unknown action {action}, skip step") success = True # by default, we skip the step and print a warning diff --git a/ci-scripts/ran.py b/ci-scripts/ran.py index 850b44318c..a4cd624975 100644 --- a/ci-scripts/ran.py +++ b/ci-scripts/ran.py @@ -46,6 +46,7 @@ import cls_cmd import cls_cmd import helpreadme as HELP import constants as CONST +import cls_analysis from cls_ci_helper import archiveArtifact #----------------------------------------------------------- @@ -68,8 +69,6 @@ class RANManagement(): self.eNBmbmsEnables = [False, False, False] self.eNBstatuses = [-1, -1, -1] self.runtime_stats= '' - self.datalog_rt_stats={} - self.datalog_rt_stats_file='datalog_rt_stats.default.yaml' #checkers from xml self.ran_checkers={} self.cmd_prefix = '' # prefix before {lte,nr}-softmodem @@ -151,8 +150,6 @@ class RANManagement(): logdir = os.path.dirname(logfile) file = archiveArtifact(cmd, ctx, logfile) - archiveArtifact(cmd, ctx, f"{logdir}/nrL1_stats.log") - archiveArtifact(cmd, ctx, f"{logdir}/nrMAC_stats.log") cmd.close() if file is None: logging.debug('\u001B[1;37;41m Could not copy xNB logfile to analyze it! \u001B[0m') @@ -167,12 +164,22 @@ class RANManagement(): else: HTML.CreateHtmlTestRow(self.runtime_stats, 'OK', CONST.ALL_PROCESSES_OK) - #display rt stats for gNB only - if len(self.datalog_rt_stats) != 0: - HTML.CreateHtmlDataLogTable(self.datalog_rt_stats) - return logStatus >= 0 + def AnalyzeRTStats(self, HTML, node, ctx, thresholds): + logging.info(f'Analyzing realtime stats from server: {node}') + lSourcePath = self.eNBSourceCodePath + + logdir = f'{lSourcePath}/cmake_targets' + with cls_cmd.getConnection(node) as cmd: + l1_file = archiveArtifact(cmd, ctx, f"{logdir}/nrL1_stats.log") + mac_file = archiveArtifact(cmd, ctx, f"{logdir}/nrMAC_stats.log") + + logging.info(f"check against thresholds from {thresholds}") + success, datalog_rt_stats = cls_analysis.Analysis.analyze_rt_stats(thresholds, l1_file, mac_file) + HTML.CreateHtmlDataLogTable(datalog_rt_stats) + return success + def _analyzeUeRetx(self, rounds, checkers, regex): if len(rounds) == 0 or len(checkers) == 0: logging.warning(f'warning: rounds={rounds} checkers={checkers}') @@ -241,8 +248,6 @@ class RANManagement(): NSA_RAPROC_PUSCH_check = 0 #dlsch and ulsch statistics (dictionary) dlsch_ulsch_stats = {} - #real time statistics (dictionary) - real_time_stats = {} #count "problem receiving samples" msg pb_receiving_samples_cnt = 0 #count "removing UE" msg @@ -470,54 +475,6 @@ class RANManagement(): enb_log_file.close() - - #the following part takes the *_stats.log files as source (not the stdout log file) - - #the datalog config file has to be loaded - datalog_rt_stats_file=self.datalog_rt_stats_file - if (os.path.isfile(datalog_rt_stats_file)): - yaml_file=datalog_rt_stats_file - elif (os.path.isfile('ci-scripts/'+datalog_rt_stats_file)): - yaml_file='ci-scripts/'+datalog_rt_stats_file - else: - logging.error("Datalog RT stats yaml file cannot be found") - sys.exit("Datalog RT stats yaml file cannot be found") - - with open(yaml_file,'r') as f: - datalog_rt_stats = yaml.load(f,Loader=yaml.FullLoader) - rt_keys = datalog_rt_stats['Ref'] #we use the keys from the Ref field - - # nrL1_stats.log/nrMAC_stats.log should be in the same directory as main log file - # currently the link is only implicit as below based on pattern matching - # I will rework this to give the file explicitly - l1_stats_fn = re.sub(r'-enb.log$', '-nrL1_stats.log', eNBlogFile) - mac_stats_fn = re.sub(r'-enb.log$', '-nrMAC_stats.log', eNBlogFile) - if os.path.isfile(l1_stats_fn) and os.path.isfile(mac_stats_fn): - # don't use CI-nrL1_stats.log, as this will increase the processing time for - # no reason, we just need the last occurence - nrL1_stats = open(l1_stats_fn, 'r') - nrMAC_stats = open(mac_stats_fn, 'r') - for line in nrL1_stats.readlines(): - for k in rt_keys: - result = re.search(k, line) - if result is not None: - #remove 1- all useless char before relevant info 2- trailing char - tmp=re.match(rf'^.*?(\b{k}\b.*)',line.rstrip()) #from python 3.6 we can use literal string interpolation for the variable k, using rf' in the regex - if tmp!=None: - real_time_stats[k]=tmp.group(1) - for line in nrMAC_stats.readlines(): - for k in rt_keys: - result = re.search(k, line) - if result is not None: - #remove 1- all useless char before relevant info 2- trailing char - tmp=re.match(rf'^.*?(\b{k}\b.*)',line.rstrip()) #from python 3.6 we can use literal string interpolation for the variable k, using rf' in the regex - if tmp!=None: - real_time_stats[k]=tmp.group(1) - nrL1_stats.close() - nrMAC_stats.close() - else: - logging.debug(f"NR Stats files for RT analysis not found: {l1_stats_fn}, {mac_stats_fn}") - #stdout log file and stat log files analysis completed logging.debug(' File analysis (stdout, stats) completed') @@ -601,31 +558,6 @@ class RANManagement(): retx_status[ue]['ul'] = self._analyzeUeRetx(dlulstat['ulsch_rounds'], ulcheckers, r'^.*ulsch_rounds\s+(\d+)\/(\d+)\/(\d+)\/(\d+),\s+ulsch_errors\s+(\d+)') - #real time statistics - datalog_rt_stats['Data']={} - if len(real_time_stats)!=0: #check if dictionary is not empty - for k in real_time_stats: - tmp=re.match(r'^(?P.*):\s+(?P\d+\.\d+) us;\s+(?P\d+);\s+(?P\d+\.\d+) us;',real_time_stats[k]) - if tmp is not None: - metric=tmp.group('metric') - avg=float(tmp.group('avg')) - max=float(tmp.group('max')) - count=int(tmp.group('count')) - datalog_rt_stats['Data'][metric]=["{:.0f}".format(avg),"{:.0f}".format(max),"{:d}".format(count),"{:.2f}".format(avg/datalog_rt_stats['Ref'][metric])] - #once all metrics are collected, store the data as a class attribute to build a dedicated HTML table afterward - self.datalog_rt_stats=datalog_rt_stats - #check if there is a fail => will render the test as failed - for k in datalog_rt_stats['Data']: - valnorm = float(datalog_rt_stats['Data'][k][3]) - dev = datalog_rt_stats['DeviationThreshold'][k] - if valnorm > 1.0 + dev or valnorm < 1.0 - dev: # condition for fail : avg/ref deviates by more than "deviation threshold" - logging.debug(f'\u001B[1;30;43m normalized datalog_rt_stats metric {k}={valnorm} deviates by more than {dev}\u001B[0m') - RealTimeProcessingIssue = True - else: - statMsg = 'No real time stats found in the log file\n' - logging.debug('No real time stats found in the log file') - htmleNBFailureMsg += statMsg - if not showedByeMsg: logging.debug('\u001B[1;37;41m ' + nodeB_prefix + 'NB did not show "Bye." message at end, it likely did not stop properly! \u001B[0m') htmleNBFailureMsg += 'No Bye. message found, did not stop properly\n' diff --git a/ci-scripts/xml_class_list.yml b/ci-scripts/xml_class_list.yml index e8fa42dcd3..7dba0d247a 100755 --- a/ci-scripts/xml_class_list.yml +++ b/ci-scripts/xml_class_list.yml @@ -32,3 +32,4 @@ - Custom_Command - Custom_Script - Create_Workspace + - AnalyzeRTStats diff --git a/ci-scripts/xml_files/gnb_phytest_rfemulator_run_100_2x2.xml b/ci-scripts/xml_files/gnb_phytest_rfemulator_run_100_2x2.xml index 30f307612c..620d275d37 100644 --- a/ci-scripts/xml_files/gnb_phytest_rfemulator_run_100_2x2.xml +++ b/ci-scripts/xml_files/gnb_phytest_rfemulator_run_100_2x2.xml @@ -37,7 +37,6 @@ Initialize gNB USRP caracal -O ci-scripts/conf_files/gnb.band79.273prb.usrpn300.phytest-dora.conf --phy-test -q -U 768 -T 273 -t 23 -D 127 -m 23 -M 273 -l 2 --device.name rf_emulator --rf_emulator.noise_level_dBFS -36 --log_config.global_log_options level,nocolor,time - datalog_rt_stats.100.2x2.yaml NR numactl --cpunodebind=netdev:enp94s0f0np0 --membind=netdev:enp94s0f0np0 @@ -48,6 +47,13 @@ 60 + + AnalyzeRTStats + Analyze Real-Time Stats + datalog_rt_stats.100.2x2.yaml + caracal + + Terminate_eNB caracal diff --git a/ci-scripts/xml_files/gnb_phytest_usrp_run.xml b/ci-scripts/xml_files/gnb_phytest_usrp_run.xml index e2bd3204aa..f2c140faac 100644 --- a/ci-scripts/xml_files/gnb_phytest_usrp_run.xml +++ b/ci-scripts/xml_files/gnb_phytest_usrp_run.xml @@ -37,7 +37,6 @@ Initialize gNB USRP caracal -O ci-scripts/conf_files/gnb.band79.106prb.usrpn300.phytest-dora.conf --phy-test -q -U 768 -T 106 -t 23 -D 127 -m 28 -M 106 --usrp-tx-thread-config 1 --log_config.global_log_options level,nocolor,time - datalog_rt_stats.default.yaml NR numactl --cpunodebind=netdev:enp94s0f0np0 --membind=netdev:enp94s0f0np0 @@ -48,6 +47,13 @@ 60 + + AnalyzeRTStats + Analyze Real-Time Stats + datalog_rt_stats.default.yaml + caracal + + Terminate_eNB true diff --git a/ci-scripts/xml_files/gnb_phytest_usrp_run_100_2x2.xml b/ci-scripts/xml_files/gnb_phytest_usrp_run_100_2x2.xml index c33908a92d..5204653223 100644 --- a/ci-scripts/xml_files/gnb_phytest_usrp_run_100_2x2.xml +++ b/ci-scripts/xml_files/gnb_phytest_usrp_run_100_2x2.xml @@ -37,7 +37,6 @@ Initialize gNB USRP caracal -O ci-scripts/conf_files/gnb.band79.273prb.usrpn300.phytest-dora.conf --phy-test -q -U 768 -T 273 -t 23 -D 127 -m 23 -M 273 -l 2 --usrp-tx-thread-config 1 --log_config.global_log_options level,nocolor,time - datalog_rt_stats.100.2x2.yaml NR numactl --cpunodebind=netdev:enp94s0f0np0 --membind=netdev:enp94s0f0np0 @@ -48,6 +47,13 @@ 60 + + AnalyzeRTStats + Analyze Real-Time Stats + datalog_rt_stats.100.2x2.yaml + caracal + + Terminate_eNB true diff --git a/ci-scripts/xml_files/gnb_phytest_usrp_run_60.xml b/ci-scripts/xml_files/gnb_phytest_usrp_run_60.xml index 0348c63b35..e939cb1e07 100644 --- a/ci-scripts/xml_files/gnb_phytest_usrp_run_60.xml +++ b/ci-scripts/xml_files/gnb_phytest_usrp_run_60.xml @@ -37,7 +37,6 @@ Initialize gNB USRP caracal -O ci-scripts/conf_files/gnb.band79.162prb.usrpn300.phytest-dora.conf --phy-test -q -U 768 -T 162 -t 23 -D 127 -m 23 -M 162 --usrp-tx-thread-config 1 --log_config.global_log_options level,nocolor,time - datalog_rt_stats.1x1.60.yaml NR numactl --cpunodebind=netdev:enp94s0f0np0 --membind=netdev:enp94s0f0np0 @@ -48,6 +47,13 @@ 60 + + AnalyzeRTStats + Analyze Real-Time Stats + datalog_rt_stats.1x1.60.yaml + caracal + + Terminate_eNB true diff --git a/ci-scripts/xml_files/gnb_phytest_usrp_run_60_2x2.xml b/ci-scripts/xml_files/gnb_phytest_usrp_run_60_2x2.xml index 075ba3e92f..1adcd042ac 100644 --- a/ci-scripts/xml_files/gnb_phytest_usrp_run_60_2x2.xml +++ b/ci-scripts/xml_files/gnb_phytest_usrp_run_60_2x2.xml @@ -37,7 +37,6 @@ Initialize gNB USRP caracal -O ci-scripts/conf_files/gnb.band79.162prb.usrpn300.phytest-dora.conf --phy-test --gNBs.[0].pdsch_AntennaPorts_XP 2 --RUs.[0].nb_tx 2 --RUs.[0].nb_rx 2 -q -U 768 -T 162 -t 23 -D 127 -m 23 -M 162 -l 2 --usrp-tx-thread-config 1 --log_config.global_log_options level,nocolor,time - datalog_rt_stats.60.2x2.yaml NR numactl --cpunodebind=netdev:enp94s0f0np0 --membind=netdev:enp94s0f0np0 @@ -48,6 +47,13 @@ 60 + + AnalyzeRTStats + Analyze Real-Time Stats + datalog_rt_stats.60.2x2.yaml + caracal + + Terminate_eNB true From 65dab3e027d80f40521666986a4742607450d995 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Wed, 29 Jan 2025 09:47:34 +0100 Subject: [PATCH 67/83] Add unit test phytest analysis --- ci-scripts/tests/README.md | 1 + ci-scripts/tests/analysis.py | 57 +++++++++++++++++++ .../analysis/gnb_phytest.success.nrL1.log | 37 ++++++++++++ .../analysis/gnb_phytest.success.nrMAC.log | 0 4 files changed, 95 insertions(+) create mode 100644 ci-scripts/tests/analysis.py create mode 100644 ci-scripts/tests/analysis/gnb_phytest.success.nrL1.log create mode 100644 ci-scripts/tests/analysis/gnb_phytest.success.nrMAC.log diff --git a/ci-scripts/tests/README.md b/ci-scripts/tests/README.md index 355d046efd..48a48b8a31 100644 --- a/ci-scripts/tests/README.md +++ b/ci-scripts/tests/README.md @@ -10,6 +10,7 @@ directory, i.e., `ci-scripts/`, and run To run individual unit tests, start them like so: + python tests/analysis.py -v python tests/build.py -v python tests/cmd.py -v python tests/corenetwork.py -v diff --git a/ci-scripts/tests/analysis.py b/ci-scripts/tests/analysis.py new file mode 100644 index 0000000000..37e4d3499e --- /dev/null +++ b/ci-scripts/tests/analysis.py @@ -0,0 +1,57 @@ +import sys +import logging +logging.basicConfig( + level=logging.DEBUG, + stream=sys.stdout, + format="[%(asctime)s] %(levelname)8s: %(message)s" +) +import os +import unittest +import yaml + +sys.path.append('./') # to find OAI imports below +import cls_analysis +import cls_oai_html +import constants + +class TestAnalysis(unittest.TestCase): + def setUp(self): + self.html = cls_oai_html.HTMLManagement() + self.html.testCaseId = "000000" + self.maxDiff = 10000 # to compare long files below + + def test_gnb_phytest(self): + rtsf = "datalog_rt_stats.100.2x2.yaml" + l1f = "tests/analysis/gnb_phytest.success.nrL1.log" + macf = "tests/analysis/gnb_phytest.success.nrMAC.log" + status, s = cls_analysis.Analysis.analyze_rt_stats(rtsf, l1f, macf) + self.assertTrue(status) + self.assertEqual(s['Title'], "Processing Time (us) from datalog_rt_stats.100.2x2.yaml") + self.assertEqual(s['ColNames'], ["Metric", "Average; Max; Count", "Average vs Reference Deviation (Reference Value; Acceptability Deviation Threshold)"]) + with open(rtsf, 'r') as f: + rt_stats = yaml.load(f, Loader=yaml.FullLoader) + # check that analyze_rt_stats() picked up all Ref/DeviationThreshold values from yaml file, e.g. + # s['Ref']['L1 Tx processing'] == corresponding value in yaml + # s['DeviationThreshold']['L1 Tx processing'] == corresponding value in yaml + for k, v in rt_stats['Ref'].items(): + self.assertEqual(s['Ref'][k], v) + for k, v in rt_stats['DeviationThreshold'].items(): + self.assertEqual(s['DeviationThreshold'][k], v) + for k, v in s['Ref'].items(): + self.assertEqual(v, rt_stats['Ref'][k]) + for k, v in s['DeviationThreshold'].items(): + self.assertEqual(v, rt_stats['DeviationThreshold'][k]) + self.assertEqual(s['Data']['L1 Tx processing'], ['476', '872', '102933', '1.00']) + self.assertEqual(s['Data']['DLSCH encoding'], ['216', '544', '77201', '1.08']) + self.assertEqual(s['Data']['L1 Rx processing'], ['488', '868', '38598', '0.92']) + self.assertEqual(s['Data']['UL Indication'], ['1', '10', '38598', '0.76']) + self.assertEqual(s['Data']['Slot Indication'], ['18', '94', '128667', '1.38']) + self.assertEqual(s['Data']['PUSCH inner-receiver'], ['307', '530', '25730', '0.85']) + self.assertEqual(s['Data']['feprx'], ['169', '310', '38600', '1.12']) + self.assertEqual(s['Data']['feptx_ofdm (per port, half_slot)'], ['56', '88', '102933', '0.98']) + self.assertEqual(s['Data']['feptx_total'], ['148', '299', '102933', '1.00']) + # TODO this one is not found, the CI does not recover this?? + #self.assertEqual(s['Data']['DL & UL scheduling timing'], ['17', '97', '159371', '1.14']) + +if __name__ == '__main__': + unittest.main() diff --git a/ci-scripts/tests/analysis/gnb_phytest.success.nrL1.log b/ci-scripts/tests/analysis/gnb_phytest.success.nrL1.log new file mode 100644 index 0000000000..066a71978b --- /dev/null +++ b/ci-scripts/tests/analysis/gnb_phytest.success.nrL1.log @@ -0,0 +1,37 @@ +Blacklisted PRBs 0/273 +-5.-6.-4.-4.-4.-6.-6.-6.-8.-6.-6.-4.-4.-4.-3.-6.-6.-11.-8.-8.-5.-4.-5.-4.-5. +-6.-11.-11.-8.-8.-5.-5.-4.-4.-6.-8.-11.-11.-8.-8.-6.-5.-6.-6.-8.-11.-11.-11.-8.-6. +-6.-6.-6.-11.-11.-11.-11.-11.-11.-6.-6.-6.-8.-3.-11.-11.-11.-8.-8.-6.-6.-6.-11.-11.-11. +-11.-8.-6.-5.-6.-6.-8.-11.-11.-11.-6.-6.-5.-4.-4.-5.-8.-8.-8.-6.-5.-4.-3.-3.-4. +-4.-6.-6.-5.-3.-3.-2.-2.-2.-3.-3.-4.-5.-5.-3.-2.-1.-1.-2.-5.-4.-4.-4.-3.-2. + 0.-1.-1.-1.-2.-2.-3.-2.-1. 0. 2.-11.13. 8. 7. 6. 5. 0. 0.-1. 0. 0. 0.-1.-3. +-3.-3.-3.-1.-1.-1.-1.-1.-1.-2.-3.-1.-1.-1.-1.-2.-1.-3.-4.-5.-8.-6.-3.-3.-3. +-3.-3.-5.-8.-8.-8.-6.-4.-4.-3.-4.-6.-6.-8.-8.-8.-6.-5.-6.-5.-6.-8.-11.-11.-11. +-8.-5.-5.-8.-6.-6.-8.-11.-11.-11.-8.-6.-6.-6.-8.-11.-11.-11.-8.-8.-6.-6.-5.-5.-8. +-11.-11.-8.-11.-6.-5.-5.-5.-5.-6.-11.-11.-8.-6.-3.-4.-5.-5.-6.-8.-6.-6.-5.-4.-4. +-4.-5.-6.-6.-11.-8.-6.-4.-3.-4.-3.-4.-5.-6.-8.-6.-5.-4.-3.-4.-3.-6.-5. +max_IO = 24 (137), min_I0 = 0 (17), avg_I0 = 11 dB(8.8.) +PRACH I0 = 0.0 dB +DLSCH RNTI 1234: current_Qm 6, current_RI 2, total_bytes TX -1130807110 +ULSCH RNTI 1234, 389: ulsch_power[0] 41,5 ulsch_noise_power[0] 7.8, sync_pos 0 + ulsch_power[1] 26.7, ulsch_noise_power[1] 7.8 + round_trials 6434(1.0e+00):6432(1.0e+00):6432(1.0e+00):6432, DTX 0, current_Qm 6, current_RI 1, total_bytes RX/SCHED 0/385630560 + L1 Tx job: 401.013 us; 128667; 895.809 us; + L1 Rx job: 183.883 us; 128667; 980.814 us; + L1 Tx processing: 476.247 us; 102933; 872.099 us; + DLSCH encoding: 216.371 us; 77201; 544.272 us; + DLSCH scrambling: 5.524 us; 77201; 19.192 us; + DLSCH modulation: 21.137 us; 77201; 36.428 us; + DLSCH resource mapping: 1.127 us; 1003613; 12.027 us; + DLSCH precoding: 3.667 us; 1003613; 17.411 us; + L1 Rx processing: 488.478 us; 38598; 867.672 us; +UL segment deinterleaving: 5.063 us; 488870; 27.005 us; + UL segment rate recovery: 11.554 us; 488870; 517.998 us; + UL segments decoding: 134.035 us; 488870; 759.164 us; + UL Indication: 0.763 us; 38598; 9.588 us; + Slot Indication: 17.891 us; 128667; 94.446 us; + PUSCH inner-receiver: 307.193 us; 25730; 529.580 us; + feprx: 169.305 us; 38600; 310.489 us; +feptx_ofdm (per port, half_slot): 56.093 us; 102933; 88.125 us; + feptx_total: 147.889 us; 102933; 299.307 us; + diff --git a/ci-scripts/tests/analysis/gnb_phytest.success.nrMAC.log b/ci-scripts/tests/analysis/gnb_phytest.success.nrMAC.log new file mode 100644 index 0000000000..e69de29bb2 From 9e35799ca6b28c7e58bbe31e2237c8f56e27b914 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 31 Oct 2024 15:27:14 +0100 Subject: [PATCH 68/83] Remove X2HO eNBmbmsEnables variables - it is spaghetti code: difficult to understand which code paths are taken - the only effect seems to be in the UE log analysis function: it might make the log fail. However, we test that iperf is successful (Iperf2_Unidir()), and would detect before the log analysis if MBMS traffic does not work - the rest is only messages that likely nobody reads The real reason for this change is to reduce the number of class members in the ran.py class, to simplify the functioning of the eNB analysis function (no self) to reduce dependencies on the ran.py class. --- ci-scripts/cls_oaicitest.py | 14 ----------- ci-scripts/ran.py | 46 ------------------------------------- 2 files changed, 60 deletions(-) diff --git a/ci-scripts/cls_oaicitest.py b/ci-scripts/cls_oaicitest.py index 237e795937..67dc5c5e4d 100644 --- a/ci-scripts/cls_oaicitest.py +++ b/ci-scripts/cls_oaicitest.py @@ -604,7 +604,6 @@ class OaiCiTest(): nrDecodeMib = 0 nrFoundDCI = 0 nrCRCOK = 0 - mbms_messages = 0 nbPduSessAccept = 0 nbPduDiscard = 0 HTML.htmlUEFailureMsg='' @@ -678,10 +677,6 @@ class OaiCiTest(): result = re.search('No cell synchronization found, abandoning', str(line)) if result is not None: no_cell_sync_found = True - if RAN.eNBmbmsEnables[0]: - result = re.search('TRIED TO PUSH MBMS DATA', str(line)) - if result is not None: - mbms_messages += 1 result = re.search(r"MIB Information => ([a-zA-Z]{1,10}), ([a-zA-Z]{1,10}), NidCell (?P\d{1,3}), N_RB_DL (?P\d{1,3}), PHICH DURATION (?P\d), PHICH RESOURCE (?P.{1,4}), TX_ANT (?P\d)", str(line)) if result is not None and (not mib_found): try: @@ -812,15 +807,6 @@ class OaiCiTest(): statMsg = f'UE showed {fatalErrorCount} "MAC BSR Triggered ReTxBSR Timer expiry" message(s)' logging.debug(f'\u001B[1;30;43m{statMsg}\u001B[0m') HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + statMsg + '\n' - if RAN.eNBmbmsEnables[0]: - if mbms_messages > 0: - statMsg = f'UE showed {mbms_messages} "TRIED TO PUSH MBMS DATA" message(s)' - logging.debug(f'\u001B[1;30;43m{statMsg}\u001B[0m') - else: - statMsg = 'UE did NOT SHOW "TRIED TO PUSH MBMS DATA" message(s)' - logging.debug(f'\u001B[1;30;41m{statMsg}\u001B[0m') - global_status = CONST.OAI_UE_PROCESS_NO_MBMS_MSGS - HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + statMsg + '\n' if foundSegFault: logging.debug('\u001B[1;37;41m UE ended with a Segmentation Fault! \u001B[0m') if not nrUEFlag: diff --git a/ci-scripts/ran.py b/ci-scripts/ran.py index a4cd624975..ef790b45c8 100644 --- a/ci-scripts/ran.py +++ b/ci-scripts/ran.py @@ -66,7 +66,6 @@ class RANManagement(): self.imageKind = '' self.air_interface = '' self.eNBOptions = ['', '', ''] - self.eNBmbmsEnables = [False, False, False] self.eNBstatuses = [-1, -1, -1] self.runtime_stats= '' #checkers from xml @@ -234,9 +233,6 @@ class RANManagement(): isRRU = False isSlave = False slaveReceivesFrameResyncCmd = False - X2HO_state = CONST.X2_HO_REQ_STATE__IDLE - X2HO_inNbProcedures = 0 - X2HO_outNbProcedures = 0 global_status = CONST.ALL_PROCESSES_OK # Runtime statistics runTime = '' @@ -297,31 +293,6 @@ class RANManagement(): if result is not None: fields=line.split(':') nbContextSwitches = 'nbContextSwitches : ' + fields[1].replace('\n','') - if X2HO_state == CONST.X2_HO_REQ_STATE__IDLE: - result = re.search('target eNB Receives X2 HO Req X2AP_HANDOVER_REQ', str(line)) - if result is not None: - X2HO_state = CONST.X2_HO_REQ_STATE__TARGET_RECEIVES_REQ - result = re.search('source eNB receives the X2 HO ACK X2AP_HANDOVER_REQ_ACK', str(line)) - if result is not None: - X2HO_state = CONST.X2_HO_REQ_STATE__SOURCE_RECEIVES_REQ_ACK - if X2HO_state == CONST.X2_HO_REQ_STATE__TARGET_RECEIVES_REQ: - result = re.search('Received LTE_RRCConnectionReconfigurationComplete from UE', str(line)) - if result is not None: - X2HO_state = CONST.X2_HO_REQ_STATE__TARGET_RRC_RECFG_COMPLETE - if X2HO_state == CONST.X2_HO_REQ_STATE__TARGET_RRC_RECFG_COMPLETE: - result = re.search('issue rrc_eNB_send_PATH_SWITCH_REQ', str(line)) - if result is not None: - X2HO_state = CONST.X2_HO_REQ_STATE__TARGET_SENDS_SWITCH_REQ - if X2HO_state == CONST.X2_HO_REQ_STATE__TARGET_SENDS_SWITCH_REQ: - result = re.search('received path switch ack S1AP_PATH_SWITCH_REQ_ACK', str(line)) - if result is not None: - X2HO_state = CONST.X2_HO_REQ_STATE__IDLE - X2HO_inNbProcedures += 1 - if X2HO_state == CONST.X2_HO_REQ_STATE__SOURCE_RECEIVES_REQ_ACK: - result = re.search('source eNB receives the X2 UE CONTEXT RELEASE X2AP_UE_CONTEXT_RELEASE', str(line)) - if result is not None: - X2HO_state = CONST.X2_HO_REQ_STATE__IDLE - X2HO_outNbProcedures += 1 if self.eNBOptions[0] != '': res1 = re.search('max_rxgain (?P[0-9]+)', self.eNBOptions[0]) @@ -419,10 +390,6 @@ class RANManagement(): result = re.search('dropping, not enough RBs', str(line)) if result is not None: dropNotEnoughRBs += 1 - if self.eNBmbmsEnables[0]: - result = re.search('MBMS USER-PLANE.*Requesting.*bytes from RLC', str(line)) - if result is not None: - mbmsRequestMsg += 1 #FR1 NSA test : add new markers to make sure gNB is used result = re.search(r'\[gNB [0-9]+\]\[RAPROC\] PUSCH with TC_RNTI 0x[0-9a-fA-F]+ received correctly, adding UE MAC Context RNTI 0x[0-9a-fA-F]+', str(line)) if result is not None: @@ -659,19 +626,6 @@ class RANManagement(): rrcMsg = ' -- ' + str(rrcReestablishReject) + ' were rejected' logging.debug('\u001B[1;30;43m ' + rrcMsg + ' \u001B[0m') htmleNBFailureMsg += rrcMsg + '\n' - if self.eNBmbmsEnables[0]: - if mbmsRequestMsg > 0: - rrcMsg = 'eNB requested ' + str(mbmsRequestMsg) + ' times the RLC for MBMS USER-PLANE' - logging.debug('\u001B[1;30;43m ' + rrcMsg + ' \u001B[0m') - htmleNBFailureMsg += rrcMsg + '\n' - if X2HO_inNbProcedures > 0: - rrcMsg = 'eNB completed ' + str(X2HO_inNbProcedures) + ' X2 Handover Connection procedure(s)' - logging.debug('\u001B[1;30;43m ' + rrcMsg + ' \u001B[0m') - htmleNBFailureMsg += rrcMsg + '\n' - if X2HO_outNbProcedures > 0: - rrcMsg = 'eNB completed ' + str(X2HO_outNbProcedures) + ' X2 Handover Release procedure(s)' - logging.debug('\u001B[1;30;43m ' + rrcMsg + ' \u001B[0m') - htmleNBFailureMsg += rrcMsg + '\n' if self.eNBOptions[0] != '': res1 = re.search('drx_Config_present prSetup', self.eNBOptions[0]) if res1 is not None: From 2e85f676461c6786b2e6945282742f258499d6a9 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Tue, 17 Feb 2026 18:58:02 +0100 Subject: [PATCH 69/83] Remove air_interface: it's not used --- ci-scripts/cls_oaicitest.py | 1 - ci-scripts/main.py | 14 -------------- ci-scripts/ran.py | 7 +++---- .../gnb_phytest_rfemulator_run_100_2x2.xml | 1 - ci-scripts/xml_files/gnb_phytest_usrp_run.xml | 2 -- .../xml_files/gnb_phytest_usrp_run_100_2x2.xml | 2 -- ci-scripts/xml_files/gnb_phytest_usrp_run_60.xml | 2 -- .../xml_files/gnb_phytest_usrp_run_60_2x2.xml | 2 -- 8 files changed, 3 insertions(+), 28 deletions(-) diff --git a/ci-scripts/cls_oaicitest.py b/ci-scripts/cls_oaicitest.py index 67dc5c5e4d..850961c00b 100644 --- a/ci-scripts/cls_oaicitest.py +++ b/ci-scripts/cls_oaicitest.py @@ -301,7 +301,6 @@ class OaiCiTest(): self.iperf_profile = '' self.iperf_tcp_rate_target = '' self.finalStatus = False - self.air_interface='' self.ue_ids = [] self.svr_node = None self.svr_id = None diff --git a/ci-scripts/main.py b/ci-scripts/main.py index 4628b1fcba..75f92bba3b 100644 --- a/ci-scripts/main.py +++ b/ci-scripts/main.py @@ -103,13 +103,6 @@ def ExecuteActionWithParam(action, ctx, node): elif action == 'Initialize_eNB': RAN.Initialize_eNB_args=test.findtext('Initialize_eNB_args') - #local variable air_interface - air_interface = test.findtext('air_interface') - if (air_interface is None) or (air_interface.lower() not in ['nr','lte']): - RAN.air_interface = 'lte-softmodem' - else: - RAN.air_interface = air_interface.lower() +'-softmodem' - cmd_prefix = test.findtext('cmd_prefix') if cmd_prefix is not None: RAN.cmd_prefix = cmd_prefix success = RAN.InitializeeNB(ctx, node, HTML) @@ -122,13 +115,6 @@ def ExecuteActionWithParam(action, ctx, node): string_field=test.findtext('u_retx_th') if (string_field is not None): RAN.ran_checkers['u_retx_th'] = [float(x) for x in string_field.split(',')] - - #local variable air_interface - air_interface = test.findtext('air_interface') - if (air_interface is None) or (air_interface.lower() not in ['nr','lte']): - RAN.air_interface = 'lte-softmodem' - else: - RAN.air_interface = air_interface.lower() +'-softmodem' success = RAN.TerminateeNB(ctx, node, HTML) elif action == 'Initialize_UE' or action == 'Attach_UE' or action == 'Detach_UE' or action == 'Terminate_UE' or action == 'CheckStatusUE' or action == 'DataEnable_UE' or action == 'DataDisable_UE': diff --git a/ci-scripts/ran.py b/ci-scripts/ran.py index ef790b45c8..020ec5949f 100644 --- a/ci-scripts/ran.py +++ b/ci-scripts/ran.py @@ -64,7 +64,6 @@ class RANManagement(): self.eNBSourceCodePath = '' self.Initialize_eNB_args = '' self.imageKind = '' - self.air_interface = '' self.eNBOptions = ['', '', ''] self.eNBstatuses = [-1, -1, -1] self.runtime_stats= '' @@ -99,7 +98,7 @@ class RANManagement(): logfile = f'{lSourcePath}/cmake_targets/enb.log' cmd.cd(f"{lSourcePath}/cmake_targets/") # important: set wd so nrL1_stats.log etc are logged here - cmd.run(f'sudo -E stdbuf -o0 {self.cmd_prefix} {lSourcePath}/cmake_targets/ran_build/build/{self.air_interface} -O {lSourcePath}/{full_config_file} {extra_options} > {logfile} 2>&1 &') + cmd.run(f'sudo -E stdbuf -o0 {self.cmd_prefix} {lSourcePath}/cmake_targets/ran_build/build/nr-softmodem -O {lSourcePath}/{full_config_file} {extra_options} > {logfile} 2>&1 &') if extra_options != '': self.eNBOptions = extra_options @@ -113,12 +112,12 @@ class RANManagement(): enbDidSync = True break if not enbDidSync: - cmd.run(f'sudo killall -9 {self.air_interface}') # in case it did not stop automatically + cmd.run(f'sudo killall -9 nr-softmodem') # in case it did not stop automatically archiveArtifact(cmd, ctx, logfile) cmd.close() - msg = f'{self.cmd_prefix} {self.air_interface} -O {config_file} {extra_options}' + msg = f'{self.cmd_prefix} nr-softmodem -O {config_file} {extra_options}' if enbDidSync: logging.debug('\u001B[1m Initialize eNB/gNB Completed\u001B[0m') HTML.CreateHtmlTestRowQueue(msg, 'OK', []) diff --git a/ci-scripts/xml_files/gnb_phytest_rfemulator_run_100_2x2.xml b/ci-scripts/xml_files/gnb_phytest_rfemulator_run_100_2x2.xml index 620d275d37..c91b9c8fc5 100644 --- a/ci-scripts/xml_files/gnb_phytest_rfemulator_run_100_2x2.xml +++ b/ci-scripts/xml_files/gnb_phytest_rfemulator_run_100_2x2.xml @@ -59,7 +59,6 @@ caracal true Terminate gNB - NR diff --git a/ci-scripts/xml_files/gnb_phytest_usrp_run.xml b/ci-scripts/xml_files/gnb_phytest_usrp_run.xml index f2c140faac..f2ad827d29 100644 --- a/ci-scripts/xml_files/gnb_phytest_usrp_run.xml +++ b/ci-scripts/xml_files/gnb_phytest_usrp_run.xml @@ -37,7 +37,6 @@ Initialize gNB USRP caracal -O ci-scripts/conf_files/gnb.band79.106prb.usrpn300.phytest-dora.conf --phy-test -q -U 768 -T 106 -t 23 -D 127 -m 28 -M 106 --usrp-tx-thread-config 1 --log_config.global_log_options level,nocolor,time - NR numactl --cpunodebind=netdev:enp94s0f0np0 --membind=netdev:enp94s0f0np0 @@ -59,7 +58,6 @@ true Terminate gNB caracal - NR diff --git a/ci-scripts/xml_files/gnb_phytest_usrp_run_100_2x2.xml b/ci-scripts/xml_files/gnb_phytest_usrp_run_100_2x2.xml index 5204653223..d298873582 100644 --- a/ci-scripts/xml_files/gnb_phytest_usrp_run_100_2x2.xml +++ b/ci-scripts/xml_files/gnb_phytest_usrp_run_100_2x2.xml @@ -37,7 +37,6 @@ Initialize gNB USRP caracal -O ci-scripts/conf_files/gnb.band79.273prb.usrpn300.phytest-dora.conf --phy-test -q -U 768 -T 273 -t 23 -D 127 -m 23 -M 273 -l 2 --usrp-tx-thread-config 1 --log_config.global_log_options level,nocolor,time - NR numactl --cpunodebind=netdev:enp94s0f0np0 --membind=netdev:enp94s0f0np0 @@ -59,7 +58,6 @@ true Terminate gNB caracal - NR diff --git a/ci-scripts/xml_files/gnb_phytest_usrp_run_60.xml b/ci-scripts/xml_files/gnb_phytest_usrp_run_60.xml index e939cb1e07..7354fa3596 100644 --- a/ci-scripts/xml_files/gnb_phytest_usrp_run_60.xml +++ b/ci-scripts/xml_files/gnb_phytest_usrp_run_60.xml @@ -37,7 +37,6 @@ Initialize gNB USRP caracal -O ci-scripts/conf_files/gnb.band79.162prb.usrpn300.phytest-dora.conf --phy-test -q -U 768 -T 162 -t 23 -D 127 -m 23 -M 162 --usrp-tx-thread-config 1 --log_config.global_log_options level,nocolor,time - NR numactl --cpunodebind=netdev:enp94s0f0np0 --membind=netdev:enp94s0f0np0 @@ -59,7 +58,6 @@ true Terminate gNB caracal - NR diff --git a/ci-scripts/xml_files/gnb_phytest_usrp_run_60_2x2.xml b/ci-scripts/xml_files/gnb_phytest_usrp_run_60_2x2.xml index 1adcd042ac..7dd50ca83f 100644 --- a/ci-scripts/xml_files/gnb_phytest_usrp_run_60_2x2.xml +++ b/ci-scripts/xml_files/gnb_phytest_usrp_run_60_2x2.xml @@ -37,7 +37,6 @@ Initialize gNB USRP caracal -O ci-scripts/conf_files/gnb.band79.162prb.usrpn300.phytest-dora.conf --phy-test --gNBs.[0].pdsch_AntennaPorts_XP 2 --RUs.[0].nb_tx 2 --RUs.[0].nb_rx 2 -q -U 768 -T 162 -t 23 -D 127 -m 23 -M 162 -l 2 --usrp-tx-thread-config 1 --log_config.global_log_options level,nocolor,time - NR numactl --cpunodebind=netdev:enp94s0f0np0 --membind=netdev:enp94s0f0np0 @@ -59,7 +58,6 @@ true Terminate gNB caracal - NR From 03f56c10e7759bab5239819e2c2f5609bd9032c8 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Mon, 16 Feb 2026 23:48:31 +0100 Subject: [PATCH 70/83] GetDeployedServices(): return container ID will be relevant to get the return code in the next commit. --- ci-scripts/cls_containerize.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ci-scripts/cls_containerize.py b/ci-scripts/cls_containerize.py index 7826a32a61..c56bdb33d2 100644 --- a/ci-scripts/cls_containerize.py +++ b/ci-scripts/cls_containerize.py @@ -186,7 +186,7 @@ def GetDeployedServices(ssh, file): else: c = ret.stdout logging.info(f'service {s} with container id {c}') - deployed_services.append(s) + deployed_services.append((s, c)) return deployed_services def CheckLogs(self, filename, HTML, RAN): @@ -790,7 +790,7 @@ class Containerize(): wd_yaml = f'{wd}/docker-compose.y*ml' with cls_cmd.getConnection(node) as ssh: ExistEnvFilePrint(ssh, wd) - services = GetDeployedServices(ssh, wd_yaml) + services = [s for s, _ in GetDeployedServices(ssh, wd_yaml)] success = [] fail = [] for s in reqServices: @@ -820,7 +820,7 @@ class Containerize(): copyin_res = None ssh.run(f'docker compose -f {wd_yaml} stop') if services is not None: - copyin_res = [CopyinServiceLog(ssh, lSourcePath, s, wd_yaml, ctx) for s in services] + copyin_res = [CopyinServiceLog(ssh, lSourcePath, s, wd_yaml, ctx) for s, _ in services] else: logging.warning('could not identify services to stop => no log file') ssh.run(f'docker compose -f {wd_yaml} down -v') From fe464ec6d00002304fc7bf8180355d5e533c4188 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Tue, 17 Feb 2026 01:04:00 +0100 Subject: [PATCH 71/83] Initial code for log analysis - we agreed to basically throw away the old log checker (as it is unmaintainable) - now: provide list of analysis to do * all checkers in cls_log_analysis, can be unit tested (see also next commit) * looked up dynamically to simplify adding of new tests + config * configured with DESCRIPTION [DESCRIPTION...] DESCRIPTION ... where DESCRIPTION follows service=func[=options]: - service is name of service to check - func is function to call, which receives filename - option are arbitary options to pass to func is whitespace delimited (so can take multiple service analysis definitions) exists to allow service definitions with whitespace changes that would not work in - I initially planned to check return code, but most softmodems actually exit with non-zero return code, so this is still TODO - Default analyzer (checking for assertions, ...) is always run if a service is listed - checks for file size - add unit tests --- ci-scripts/cls_analysis.py | 98 +++++++++++++++++++ ci-scripts/cls_containerize.py | 21 ++-- ci-scripts/cls_loganalysis.py | 40 ++++++++ ci-scripts/main.py | 24 +++-- ci-scripts/ran.py | 14 ++- ci-scripts/tests/README.md | 1 + ci-scripts/tests/analysis.py | 14 +++ ci-scripts/tests/deployment.py | 48 +++++++-- ci-scripts/tests/log-analysis.py | 26 +++++ ci-scripts/tests/log-analysis/empty.log | 0 .../gnb_phytest_rfemulator_run_100_2x2.xml | 3 + 11 files changed, 257 insertions(+), 32 deletions(-) create mode 100644 ci-scripts/cls_loganalysis.py create mode 100644 ci-scripts/tests/log-analysis.py create mode 100644 ci-scripts/tests/log-analysis/empty.log diff --git a/ci-scripts/cls_analysis.py b/ci-scripts/cls_analysis.py index 3d9eb9c499..866a261352 100644 --- a/ci-scripts/cls_analysis.py +++ b/ci-scripts/cls_analysis.py @@ -24,10 +24,13 @@ import re import os import logging import yaml +import signal import xml.etree.ElementTree as ET import json +import importlib, inspect + class Analysis(): def _get_test_description(properties): @@ -147,3 +150,98 @@ class Analysis(): logging.debug(f'\u001B[1;30;43m normalized metric {k}={valnorm} deviates by more than {dev}\u001B[0m') success = False return success, datalog_rt_stats + + +# returns tuple of (service, analyzer, option string) +def _lookupServiceAnalyzerOpt(s, analyzers): + res = s.split("=", 2) + name = res[0] + if len(res) == 1: + return res[0], analyzers["Default"], None + opt = res[2] if len(res) > 2 else None + func = res[1] + a = analyzers[func] if func in analyzers else None + return name, a, opt + +# groups requested service analysis (service=func[=option]) on per service +# basis and looks up analyzer func. If log analysis is requested, will always +# run Default log analysis +def _groupServices(to_analyze): + req_analysis = {} + # get content of cls_loganalysis module, then get all analyzers (classes) in this module + mod = importlib.import_module("cls_loganalysis") + analyzers = {name:cl for name, cl in inspect.getmembers(mod, inspect.isclass)} + for req in to_analyze: + s, func, opt = _lookupServiceAnalyzerOpt(req, analyzers) + logging.debug(f"requested check '{req}' => service {s}, function {func.__name__}, options '{opt}'") + # always put default analyzer first + l = req_analysis[s] if s in req_analysis else [(analyzers["Default"], None, "default")] + if func is not analyzers["Default"]: + l.append((func, opt, req)) + req_analysis[s] = l + return req_analysis + +def _describe_exit_code(code): + if code > 128: + sig = code - 128 + try: + return f"terminated by signal {sig} ({signal.Signals(sig).name})" + except ValueError: + return f"terminated by unknown signal {sig}" + else: + return f"custom exit code" + +def AnalyzeServices(HTML, service_desc, to_analyze): + success = True + # hack: we want to give as a description "log analysis", but the description + # is set outside, so retain what was set before + orig_html_desc = HTML.desc + # group analysis on a per-service basis, then iterate + for serv, list_analysis in _groupServices(to_analyze).items(): + HTML.desc = f"Log analysis for service {serv}" + if serv not in service_desc: + success = False + logging.error(f"requested service {serv} not in list of services") + HTML.CreateHtmlTestRowQueue("N/A", 'KO', ["service not detected"]) + continue + # pre-initialize with return code + rc = service_desc[serv]["returncode"] + logging.info(f"analyze service {serv}: return code {rc}") + service_success = True # TODO rc == 0: too many functions (eNB, lteUE, RIC, nrUE) fail non-zero + logs = [] + if rc != 0: + logs.append(f"=> return code {rc}, likely " + _describe_exit_code(rc) + " [ignored by CI]") + # skip if the file is too big + logfile = service_desc[serv]["logfile"] + filename = os.path.basename(logfile) + b = os.path.getsize(logfile) + logging.debug(f"using logfile {logfile} of size {b} bytes") + if b > 10 * 1024 * 1024: + success = False + logs.append(f"logfile too big (>10MB)") + logging.error(logs) + HTML.CreateHtmlTestRowQueue(filename, 'KO', ["\n".join(logs)]) + continue + # run each analyzer with its options on the logfile + for (func, opt, desc) in list_analysis: + if func is None: + service_success = False + logging.error(f"request analysis function for desc {desc} not found") + HTML.CreateHtmlTestRowQueue(serv, 'KO', [f"no analysis function for {desc}"]) + continue + result, l = func.run(logfile, opt) + logging.info(f"service {serv}: analysis with func {func}, result {result}, logs '{l}'") + service_success = service_success and result + if not result: + logs.append(f"=> {func.__name__} check (options '{opt}') FAILED") + logs.append(l) + logs = '\n'.join(logs) + if not service_success: + logging.error(l) + else: + logging.info(l) + all_funcs = ", ".join([f.__name__ for (f, _, _) in list_analysis]) + HTML.CreateHtmlTestRowQueue(f"Check {all_funcs} on {filename}", 'OK' if service_success else 'KO', [logs]) + success = success and service_success + HTML.desc = orig_html_desc + return success diff --git a/ci-scripts/cls_containerize.py b/ci-scripts/cls_containerize.py index c56bdb33d2..16fc89613d 100644 --- a/ci-scripts/cls_containerize.py +++ b/ci-scripts/cls_containerize.py @@ -46,6 +46,7 @@ import cls_cmd import helpreadme as HELP import constants as CONST import cls_oaicitest +import cls_analysis from cls_ci_helper import archiveArtifact from collections import deque @@ -808,7 +809,7 @@ class Containerize(): HTML.CreateHtmlTestRowQueue(self.services, 'KO', [f'Failed stopping {" ".join(fail)}, succeeded {" ".join(success)}']) return success - def UndeployObject(self, ctx, node, HTML, RAN): + def UndeployObject(self, ctx, node, HTML, to_analyze): lSourcePath = self.eNBSourceCodePath logging.info(f'\u001B[1m Undeploying all objects from server {node}\u001B[0m') yaml = self.yamlPath.strip('/') @@ -817,21 +818,27 @@ class Containerize(): with cls_cmd.getConnection(node) as ssh: ExistEnvFilePrint(ssh, wd) services = GetDeployedServices(ssh, wd_yaml) - copyin_res = None + all_logs = True ssh.run(f'docker compose -f {wd_yaml} stop') if services is not None: - copyin_res = [CopyinServiceLog(ssh, lSourcePath, s, wd_yaml, ctx) for s, _ in services] + service_desc = {} + for s, c in services: + ret = ssh.run(f'docker inspect {c} --format="{{{{.State.ExitCode}}}}"') + rc = int(ret.stdout.strip()) + f = CopyinServiceLog(ssh, lSourcePath, s, wd_yaml, ctx) + all_logs = all_logs and f is not None + service_desc[s] = {'returncode': rc, 'logfile': f} else: logging.warning('could not identify services to stop => no log file') ssh.run(f'docker compose -f {wd_yaml} down -v') + HTML.CreateHtmlTestRowQueue(node, 'OK', ['Undeployment successful']) ssh.run(f'rm {wd}/.env') - if not copyin_res: + if not all_logs: HTML.CreateHtmlTestRowQueue('N/A', 'KO', ['Could not copy logfile(s)']) - logging.error(f"could not copy all files: {copyin_res=} {services=}") + logging.error(f"could not copy all files: {all_logs=} {services=}") success = False else: - log_results = [CheckLogs(self, f, HTML, RAN) for f in copyin_res] - success = all(log_results) + success = cls_analysis.AnalyzeServices(HTML, service_desc, to_analyze) if success: logging.info('\u001B[1m Undeploying objects Pass\u001B[0m') else: diff --git a/ci-scripts/cls_loganalysis.py b/ci-scripts/cls_loganalysis.py new file mode 100644 index 0000000000..0003b8be69 --- /dev/null +++ b/ci-scripts/cls_loganalysis.py @@ -0,0 +1,40 @@ +#/* +# * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more +# * contributor license agreements. See the NOTICE file distributed with +# * this work for additional information regarding copyright ownership. +# * The OpenAirInterface Software Alliance licenses this file to You under +# * the OAI Public License, Version 1.1 (the "License"); you may not use this file +# * except in compliance with the License. +# * You may obtain a copy of the License at +# * +# * http://www.openairinterface.org/?page_id=698 +# * +# * Unless required by applicable law or agreed to in writing, software +# * distributed under the License is distributed on an "AS IS" BASIS, +# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# * See the License for the specific language governing permissions and +# * limitations under the License. +# *------------------------------------------------------------------------------- +# * For more information about the OpenAirInterface (OAI) Software Alliance: +# * contact@openairinterface.org +# */ +#--------------------------------------------------------------------- + +import re +import os +import logging + +class Default: + def run(file, opt=None): + # TODO add check on assertions, etc + if not os.path.exists(file): + return False, f"cannot find file {file}" + return True, "" + +class ContainsString: + def run(file, needle): + with open(file, "r") as f: + for line in f.readlines(): + if re.search(needle, line): + return True, "" + return False, f"could not find '{needle}' in logs" diff --git a/ci-scripts/main.py b/ci-scripts/main.py index 75f92bba3b..bbce96f304 100644 --- a/ci-scripts/main.py +++ b/ci-scripts/main.py @@ -115,7 +115,14 @@ def ExecuteActionWithParam(action, ctx, node): string_field=test.findtext('u_retx_th') if (string_field is not None): RAN.ran_checkers['u_retx_th'] = [float(x) for x in string_field.split(',')] - success = RAN.TerminateeNB(ctx, node, HTML) + services = [] + analysis = test.find("analysis") + if analysis is not None: + # services: multiple services to analyse, separated by whitespace + services = analysis.findtext("services", default="").split() + # service: individual services to analyze, in case they have whitespace + services = services + [s.text for s in analysis.findall("service")] + success = RAN.TerminateeNB(ctx, node, HTML, services) elif action == 'Initialize_UE' or action == 'Attach_UE' or action == 'Detach_UE' or action == 'Terminate_UE' or action == 'CheckStatusUE' or action == 'DataEnable_UE' or action == 'DataDisable_UE': CiTestObj.ue_ids = test.findtext('id').split(' ') @@ -188,12 +195,6 @@ def ExecuteActionWithParam(action, ctx, node): elif action == 'Deploy_Object' or action == 'Undeploy_Object' or action == "Create_Workspace" or action == "Stop_Object": CONTAINERS.yamlPath = test.findtext('yaml_path') - string_field=test.findtext('d_retx_th') - if (string_field is not None): - CONTAINERS.ran_checkers['d_retx_th'] = [float(x) for x in string_field.split(',')] - string_field=test.findtext('u_retx_th') - if (string_field is not None): - CONTAINERS.ran_checkers['u_retx_th'] = [float(x) for x in string_field.split(',')] CONTAINERS.services = test.findtext('services') CONTAINERS.num_attempts = int(test.findtext('num_attempts') or 1) CONTAINERS.deploymentTag = cls_containerize.CreateTag(CONTAINERS.ranCommitID, CONTAINERS.ranBranch, CONTAINERS.ranAllowMerge) @@ -202,7 +203,14 @@ def ExecuteActionWithParam(action, ctx, node): elif action == 'Stop_Object': success = CONTAINERS.StopObject(ctx, node, HTML) elif action == 'Undeploy_Object': - success = CONTAINERS.UndeployObject(ctx, node, HTML, RAN) + analysis = test.find("analysis") + services = [] + if analysis is not None: + # services: multiple services to analyse, separated by whitespace + services = analysis.findtext("services", default="").split() + # service: individual services to analyze, in case they have whitespace + services = services + [s.text for s in analysis.findall("service")] + success = CONTAINERS.UndeployObject(ctx, node, HTML, services) elif action == 'Create_Workspace': if force_local: # Do not create a working directory when running locally. Current repo directory will be used diff --git a/ci-scripts/ran.py b/ci-scripts/ran.py index 020ec5949f..27b309cafd 100644 --- a/ci-scripts/ran.py +++ b/ci-scripts/ran.py @@ -127,7 +127,7 @@ class RANManagement(): return enbDidSync - def TerminateeNB(self, ctx, node, HTML): + def TerminateeNB(self, ctx, node, HTML, to_analyze): logging.debug('Stopping eNB/gNB on server: ' + node) lSourcePath = self.eNBSourceCodePath cmd = cls_cmd.getConnection(node) @@ -142,6 +142,7 @@ class RANManagement(): if result is not None: cmd.run('sudo -S killall --signal SIGKILL -r .*-softmodem') time.sleep(5) + HTML.CreateHtmlTestRowQueue(node, 'OK', ['Undeployment successful']) # see InitializeeNB() logfile = f'{lSourcePath}/cmake_targets/enb.log' @@ -156,13 +157,10 @@ class RANManagement(): return False logging.debug('\u001B[1m Analyzing xNB logfile \u001B[0m ' + file) - logStatus = self.AnalyzeLogFile_eNB(file, HTML, self.ran_checkers) - if logStatus < 0: - HTML.CreateHtmlTestRow('N/A', 'KO', logStatus) - else: - HTML.CreateHtmlTestRow(self.runtime_stats, 'OK', CONST.ALL_PROCESSES_OK) - - return logStatus >= 0 + service_desc = {} + service_desc["nr-softmodem"] = {'returncode': 0, 'logfile': file} + success = cls_analysis.AnalyzeServices(HTML, service_desc, to_analyze) + return success def AnalyzeRTStats(self, HTML, node, ctx, thresholds): logging.info(f'Analyzing realtime stats from server: {node}') diff --git a/ci-scripts/tests/README.md b/ci-scripts/tests/README.md index 48a48b8a31..ac3aa2115f 100644 --- a/ci-scripts/tests/README.md +++ b/ci-scripts/tests/README.md @@ -16,6 +16,7 @@ To run individual unit tests, start them like so: python tests/corenetwork.py -v python tests/deployment.py -v python tests/iperf-analysis.py -v + python tests/log-analysis.py -v python tests/ping-iperf.py -v python tests/pull-clean-int-registry.py -v diff --git a/ci-scripts/tests/analysis.py b/ci-scripts/tests/analysis.py index 37e4d3499e..e77bf14603 100644 --- a/ci-scripts/tests/analysis.py +++ b/ci-scripts/tests/analysis.py @@ -53,5 +53,19 @@ class TestAnalysis(unittest.TestCase): # TODO this one is not found, the CI does not recover this?? #self.assertEqual(s['Data']['DL & UL scheduling timing'], ['17', '97', '159371', '1.14']) + def test_analze_services_no_service(self): + service_desc = {} # nothing to analyze + to_analyze = ["testserv"] # some service requested to be analyze that does not exist + status = cls_analysis.AnalyzeServices(self.html, service_desc, to_analyze) + self.assertFalse(status) + + # TODO this does not work: we don't evaluate return codes yet + #def test_analze_service_exit_nonnull(self): + # service_desc = {} + # service_desc["testserv"] = {'returncode': 129, 'logfile': 'tests/log-analysis/empty.log'} + # to_analyze = ["testserv"] # some service requested to be analyze that does not exist + # status = cls_analysis.AnalyzeServices(self.html, service_desc, to_analyze) + # self.assertFalse(status) + if __name__ == '__main__': unittest.main() diff --git a/ci-scripts/tests/deployment.py b/ci-scripts/tests/deployment.py index 10bd2c843f..4fb466acc2 100644 --- a/ci-scripts/tests/deployment.py +++ b/ci-scripts/tests/deployment.py @@ -16,7 +16,6 @@ import cls_oai_html import cls_oaicitest import cls_containerize from cls_ci_helper import TestCaseCtx -import ran import cls_cmd class TestDeploymentMethods(unittest.TestCase): @@ -39,7 +38,6 @@ class TestDeploymentMethods(unittest.TestCase): self.html.testCaseId = "000000" self.ci = cls_oaicitest.OaiCiTest() self.cont = cls_containerize.Containerize() - self.ran = ran.RANManagement() self.cont.yamlPath = '' self.cont.ranAllowMerge = True self.cont.ranBranch = '' @@ -56,7 +54,7 @@ class TestDeploymentMethods(unittest.TestCase): self.cont.yamlPath = 'tests/simple-dep/' self.cont.deploymentTag = "noble" deploy = self.cont.DeployObject(self.ctx, self.node, self.html) - undeploy = self.cont.UndeployObject(self.ctx, self.node, self.html, self.ran) + undeploy = self.cont.UndeployObject(self.ctx, self.node, self.html, []) self.assertTrue(deploy) self.assertTrue(undeploy) @@ -79,7 +77,7 @@ class TestDeploymentMethods(unittest.TestCase): stopB = self.cont.StopObject(self.ctx, self.node, self.html) # should not undeploy anything (everything already stopped) self.cont.services = None - undeployAll = self.cont.UndeployObject(self.ctx, self.node, self.html, self.ran) + undeployAll = self.cont.UndeployObject(self.ctx, self.node, self.html, []) self.assertTrue(deploy) self.assertFalse(stopC) self.assertTrue(stopA) @@ -92,7 +90,7 @@ class TestDeploymentMethods(unittest.TestCase): old = self.cont.yamlPath self.cont.yamlPath = 'tests/simple-fail/' deploy = self.cont.DeployObject(self.ctx, self.node, self.html) - self.cont.UndeployObject(self.ctx, self.node, self.html, self.ran) + self.cont.UndeployObject(self.ctx, self.node, self.html, []) self.assertFalse(deploy) self.cont.yamlPath = old @@ -101,7 +99,7 @@ class TestDeploymentMethods(unittest.TestCase): old = self.cont.yamlPath self.cont.yamlPath = 'tests/simple-fail-2svc/' deploy = self.cont.DeployObject(self.ctx, self.node, self.html) - self.cont.UndeployObject(self.ctx, self.node, self.html, self.ran) + self.cont.UndeployObject(self.ctx, self.node, self.html, []) self.assertFalse(deploy) self.cont.yamlPath = old @@ -110,7 +108,7 @@ class TestDeploymentMethods(unittest.TestCase): self.cont.services = "oai-gnb" self.cont.deploymentTag = 'develop-12345678' deploy = self.cont.DeployObject(self.ctx, self.node, self.html) - undeploy = self.cont.UndeployObject(self.ctx, self.node, self.html, self.ran) + undeploy = self.cont.UndeployObject(self.ctx, self.node, self.html, []) self.assertTrue(deploy) self.assertTrue(undeploy) @@ -119,7 +117,7 @@ class TestDeploymentMethods(unittest.TestCase): self.cont.services = "oai-gnb oai-nr-ue" self.cont.deploymentTag = 'develop-12345678' deploy = self.cont.DeployObject(self.ctx, self.node, self.html) - undeploy = self.cont.UndeployObject(self.ctx, self.node, self.html, self.ran) + undeploy = self.cont.UndeployObject(self.ctx, self.node, self.html, []) self.assertTrue(deploy) self.assertTrue(undeploy) @@ -130,7 +128,7 @@ class TestDeploymentMethods(unittest.TestCase): deploy1 = self.cont.DeployObject(self.ctx, self.node, self.html) self.cont.services = "oai-nr-ue" deploy2 = self.cont.DeployObject(self.ctx, self.node, self.html) - undeploy = self.cont.UndeployObject(self.ctx, self.node, self.html, self.ran) + undeploy = self.cont.UndeployObject(self.ctx, self.node, self.html, []) self.assertTrue(deploy1) self.assertTrue(deploy2) self.assertTrue(undeploy) @@ -145,5 +143,37 @@ class TestDeploymentMethods(unittest.TestCase): cmd.run(f"rm -rf {self.cont.eNBSourceCodePath}") self.assertTrue(ws) + def test_undeploy_loganalysis(self): + self.cont.yamlPath = 'yaml_files/5g_rfsimulator_tdd_dora' + self.cont.services = "oai-gnb" + self.cont.deploymentTag = 'develop-12345678' + deploy = self.cont.DeployObject(self.ctx, self.node, self.html) + analyze = ["oai-gnb"] + undeploy = self.cont.UndeployObject(self.ctx, self.node, self.html, analyze) + self.assertTrue(deploy) + self.assertTrue(undeploy) + + def test_undeploy_multi_loganalysis(self): + self.cont.yamlPath = 'yaml_files/5g_rfsimulator_tdd_dora' + self.cont.services = "oai-gnb" + self.cont.deploymentTag = 'develop-12345678' + deploy = self.cont.DeployObject(self.ctx, self.node, self.html) + analyze = ["oai-gnb", "oai-gnb=ContainsString=NOTFOUND"] + undeploy = self.cont.UndeployObject(self.ctx, self.node, self.html, analyze) + self.assertTrue(deploy) + self.assertFalse(undeploy) + + # TODO this does not work: we don't evaluate return codes yet + #def test_undeploy_rc_nonnull(self): + # # fails reliably + # old = self.cont.yamlPath + # self.cont.yamlPath = 'tests/simple-fail/' + # deploy = self.cont.DeployObject(self.ctx, self.node, self.html) + # # should be false because wrong exit code + # undeploy = self.cont.UndeployObject(self.ctx, self.node, self.html, ["test"]) + # self.assertFalse(deploy) + # self.assertFalse(undeploy) + # self.cont.yamlPath = old + if __name__ == '__main__': unittest.main() diff --git a/ci-scripts/tests/log-analysis.py b/ci-scripts/tests/log-analysis.py new file mode 100644 index 0000000000..dba7e9caf4 --- /dev/null +++ b/ci-scripts/tests/log-analysis.py @@ -0,0 +1,26 @@ +import sys +import logging +logging.basicConfig( + level=logging.DEBUG, + stream=sys.stdout, + format="[%(asctime)s] %(levelname)8s: %(message)s" +) +import os +import unittest + +sys.path.append('./') # to find OAI imports below +import cls_loganalysis + +class TestLogAnalysis(unittest.TestCase): + def test_no_file(self): + f = "/total/fantasy/path/file.log" + result, _ = cls_loganalysis.Default.run(f, None) + self.assertFalse(result) + + def test_no_error(self): + f = "tests/log-analysis/empty.log" + result, _ = cls_loganalysis.Default.run(f, None) + self.assertTrue(result) + +if __name__ == '__main__': + unittest.main() diff --git a/ci-scripts/tests/log-analysis/empty.log b/ci-scripts/tests/log-analysis/empty.log new file mode 100644 index 0000000000..e69de29bb2 diff --git a/ci-scripts/xml_files/gnb_phytest_rfemulator_run_100_2x2.xml b/ci-scripts/xml_files/gnb_phytest_rfemulator_run_100_2x2.xml index c91b9c8fc5..8429baa1ba 100644 --- a/ci-scripts/xml_files/gnb_phytest_rfemulator_run_100_2x2.xml +++ b/ci-scripts/xml_files/gnb_phytest_rfemulator_run_100_2x2.xml @@ -59,6 +59,9 @@ caracal true Terminate gNB + + nr-softmodem=ContainsString=Bye. + From 707cb560d56511724ea8d2abd3a7208cb26e6ca9 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Wed, 18 Feb 2026 17:17:10 +0100 Subject: [PATCH 72/83] Implement retransmission checker, include unit test --- ci-scripts/cls_containerize.py | 2 - ci-scripts/cls_loganalysis.py | 94 +++++++++++++++++++ ci-scripts/main.py | 7 -- ci-scripts/ran.py | 66 ------------- ci-scripts/tests/log-analysis.py | 72 ++++++++++++++ .../tests/log-analysis/retx-check-bad.log | 54 +++++++++++ .../tests/log-analysis/retx-check-good.log | 8 ++ .../xml_files/container_5g_fdd_rfsim.xml | 2 - 8 files changed, 228 insertions(+), 77 deletions(-) create mode 100644 ci-scripts/tests/log-analysis/retx-check-bad.log create mode 100644 ci-scripts/tests/log-analysis/retx-check-good.log diff --git a/ci-scripts/cls_containerize.py b/ci-scripts/cls_containerize.py index 16fc89613d..235b5cdce9 100644 --- a/ci-scripts/cls_containerize.py +++ b/ci-scripts/cls_containerize.py @@ -267,8 +267,6 @@ class Containerize(): self.dockerfileprefix = '' self.host = '' - #checkers from xml - self.ran_checkers={} self.num_attempts = 1 self.flexricTag = '' diff --git a/ci-scripts/cls_loganalysis.py b/ci-scripts/cls_loganalysis.py index 0003b8be69..2369f1115f 100644 --- a/ci-scripts/cls_loganalysis.py +++ b/ci-scripts/cls_loganalysis.py @@ -38,3 +38,97 @@ class ContainsString: if re.search(needle, line): return True, "" return False, f"could not find '{needle}' in logs" + +class RetxCheck(): + def _parseList(s): + if not s: + return [] + return [int(n) for n in s.split(",")] + + def _get_ul_dl(s): + dl, ul = (None, None) + for o in s.split(";", 1): + if o.startswith("dl="): + dl = o[3:] + elif o.startswith("ul="): + ul = o[3:] + else: + raise ValueError(f"unrecognized option {s}: needs format '[ul=,dl=]X,Y,...[;ul=Z,V,...]'") + return dl, ul + + def _parseRetxCheckers(options): + if not "=" in options: + dlul = RetxCheck._parseList(options) + return dlul, dlul + dl, ul = RetxCheck._get_ul_dl(options) + return RetxCheck._parseList(dl), RetxCheck._parseList(ul) + + def _analyzeUeRetx(rounds, checkers, regex): + perc = list(0 for i in checkers) # results in % + stats = list(False for i in checkers) # status if succeeded + tmp = re.match(regex, rounds) + if tmp is None: + logging.error('_analyzeUeRetx: did not match regex for DL retx analysis') + return stats + retx_data = [float(x) for x in tmp.groups()] + for i in range(0, len(perc)): + #case where numerator > denumerator with denum ==0 is disregarded, cannot hapen in principle, will lead to 0% + perc[i] = 0 if (retx_data[i] == 0) else 100 * retx_data[i + 1] / retx_data[i] + #treating % > 100 , % > requirement + stats[i] = perc[i] <= 100 and perc[i] <= checkers[i] + return stats + + def _filter_retx_rounds(l): + # map to round number if False, else None + l = [i+1 if x is False else None for i, x in enumerate(l)] + # filter out None + return [x for x in l if x is not None] + + def run(file, options): + # aggregate statistics per UE + dlsch_ulsch_stats = {} + status = True + with open(file, "r") as f: + for line in f.readlines(): + keys = {'dlsch_rounds','ulsch_rounds'} + for k in keys: + result = re.search(k, line) + if result is None: + continue + result = re.search('UE (?:RNTI )?([0-9a-f]{4})', line) + if result is None: + logging.error(f'did not find RNTI while matching key {k}') + status = False + continue + rnti = result.group(1) + if not rnti in dlsch_ulsch_stats: + dlsch_ulsch_stats[rnti] = {} + dlsch_ulsch_stats[rnti][k]=re.sub(r'^.*\]\s+', r'' , line.rstrip()) + + dl, ul = RetxCheck._parseRetxCheckers(options) + msgs = [] + for ue in dlsch_ulsch_stats: + dlulstat = dlsch_ulsch_stats[ue] + + for key in dlulstat: + msgs.append(dlulstat[key]) + + retx_dl = RetxCheck._analyzeUeRetx(dlulstat['dlsch_rounds'], dl, r'^.*dlsch_rounds\s+(\d+)\/(\d+)\/(\d+)\/(\d+),\s+dlsch_errors\s+(\d+)') + retx_ul = RetxCheck._analyzeUeRetx(dlulstat['ulsch_rounds'], ul, r'^.*ulsch_rounds\s+(\d+)\/(\d+)\/(\d+)\/(\d+),\s+ulsch_errors\s+(\d+)') + + if False in retx_dl or False in retx_ul: + dlstr = RetxCheck._filter_retx_rounds(retx_dl) + ulstr = RetxCheck._filter_retx_rounds(retx_ul) + msg = f"UE {ue}: retx rounds" + if dlstr: + msg = f"{msg} DL {dlstr}" + if ulstr: + msg = f"{msg} UL {ulstr}" + msg = f"{msg} exceeded threshold" + msgs.append('!!! Failure: ' + msg) + logging.error(f'\u001B[1;37;41m {msg}\u001B[0m') + status = False + else: + msg = f"UE {ue} retransmissions within bounds" + logging.debug(msg) + return status, "\n".join(msgs) diff --git a/ci-scripts/main.py b/ci-scripts/main.py index bbce96f304..3b40941b91 100644 --- a/ci-scripts/main.py +++ b/ci-scripts/main.py @@ -108,13 +108,6 @@ def ExecuteActionWithParam(action, ctx, node): success = RAN.InitializeeNB(ctx, node, HTML) elif action == 'Terminate_eNB': - #retx checkers - string_field = test.findtext('d_retx_th') - if (string_field is not None): - RAN.ran_checkers['d_retx_th'] = [float(x) for x in string_field.split(',')] - string_field=test.findtext('u_retx_th') - if (string_field is not None): - RAN.ran_checkers['u_retx_th'] = [float(x) for x in string_field.split(',')] services = [] analysis = test.find("analysis") if analysis is not None: diff --git a/ci-scripts/ran.py b/ci-scripts/ran.py index 27b309cafd..864c2463a5 100644 --- a/ci-scripts/ran.py +++ b/ci-scripts/ran.py @@ -67,8 +67,6 @@ class RANManagement(): self.eNBOptions = ['', '', ''] self.eNBstatuses = [-1, -1, -1] self.runtime_stats= '' - #checkers from xml - self.ran_checkers={} self.cmd_prefix = '' # prefix before {lte,nr}-softmodem self.node = '' self.command = '' @@ -176,25 +174,6 @@ class RANManagement(): HTML.CreateHtmlDataLogTable(datalog_rt_stats) return success - def _analyzeUeRetx(self, rounds, checkers, regex): - if len(rounds) == 0 or len(checkers) == 0: - logging.warning(f'warning: rounds={rounds} checkers={checkers}') - return [] - - perc = list(0 for i in checkers) # results in % - stats = list(False for i in checkers) # status if succeeded - tmp = re.match(regex, rounds) - if tmp is None: - logging.error('_analyzeUeRetx: did not match regex for DL retx analysis') - return stats - retx_data = [float(x) for x in tmp.groups()] - for i in range(0, len(perc)): - #case where numerator > denumerator with denum ==0 is disregarded, cannot hapen in principle, will lead to 0% - perc[i] = 0 if (retx_data[i] == 0) else 100 * retx_data[i + 1] / retx_data[i] - #treating % > 100 , % > requirement - stats[i] = perc[i] <= 100 and perc[i] <= checkers[i] - return stats - def AnalyzeLogFile_eNB(self, eNBlogFile, HTML, checkers={}): if (not os.path.isfile(eNBlogFile)): return -1 @@ -239,8 +218,6 @@ class RANManagement(): nbContextSwitches = '' #NSA FR1 check NSA_RAPROC_PUSCH_check = 0 - #dlsch and ulsch statistics (dictionary) - dlsch_ulsch_stats = {} #count "problem receiving samples" msg pb_receiving_samples_cnt = 0 #count "removing UE" msg @@ -392,22 +369,6 @@ class RANManagement(): if result is not None: NSA_RAPROC_PUSCH_check = 1 - # Collect information on UE DLSCH and ULSCH statistics - keys = {'dlsch_rounds','ulsch_rounds'} - for k in keys: - result = re.search(k, line) - if result is None: - continue - result = re.search('UE (?:RNTI )?([0-9a-f]{4})', line) - if result is None: - logging.error(f'did not find RNTI while matching key {k}') - continue - rnti = result.group(1) - - #remove 1- all useless char before relevant info (ulsch or dlsch) 2- trailing char - if not rnti in dlsch_ulsch_stats: dlsch_ulsch_stats[rnti] = {} - dlsch_ulsch_stats[rnti][k]=re.sub(r'^.*\]\s+', r'' , line.rstrip()) - result = re.search('Received NR_RRCReconfigurationComplete from UE', str(line)) if result is not None: nrRrcRcfgComplete += 1 @@ -505,23 +466,6 @@ class RANManagement(): logging.debug(statMsg) htmleNBFailureMsg += htmlMsg - #ulsch and dlsch statistics and checkers - for ue in dlsch_ulsch_stats: - dlulstat = dlsch_ulsch_stats[ue] - #print statistics into html - statMsg='' - for key in dlulstat: - statMsg += dlulstat[key] + '\n' - logging.debug(dlulstat[key]) - htmleNBFailureMsg += statMsg - - retx_status[ue] = {} - dlcheckers = [] if 'd_retx_th' not in checkers else checkers['d_retx_th'] - retx_status[ue]['dl'] = self._analyzeUeRetx(dlulstat['dlsch_rounds'], dlcheckers, r'^.*dlsch_rounds\s+(\d+)\/(\d+)\/(\d+)\/(\d+),\s+dlsch_errors\s+(\d+)') - ulcheckers = [] if 'u_retx_th' not in checkers else checkers['u_retx_th'] - retx_status[ue]['ul'] = self._analyzeUeRetx(dlulstat['ulsch_rounds'], ulcheckers, r'^.*ulsch_rounds\s+(\d+)\/(\d+)\/(\d+)\/(\d+),\s+ulsch_errors\s+(\d+)') - - if not showedByeMsg: logging.debug('\u001B[1;37;41m ' + nodeB_prefix + 'NB did not show "Bye." message at end, it likely did not stop properly! \u001B[0m') htmleNBFailureMsg += 'No Bye. message found, did not stop properly\n' @@ -557,16 +501,6 @@ class RANManagement(): logging.debug(statMsg) htmleNBFailureMsg += htmlMsg - for ue in retx_status: - msg = f"retransmissions for UE {ue}: DL {retx_status[ue]['dl']} UL {retx_status[ue]['ul']}" - if False in retx_status[ue]['dl'] or False in retx_status[ue]['ul']: - msg = 'Failure: ' + msg - logging.error(f'\u001B[1;37;41m {msg}\u001B[0m') - htmleNBFailureMsg += f'{msg}\n' - global_status = CONST.ENB_RETX_ISSUE - else: - logging.debug(msg) - if RealTimeProcessingIssue: logging.debug('\u001B[1;37;41m ' + nodeB_prefix + 'NB ended with real time processing issue! \u001B[0m') htmleNBFailureMsg += 'Fail due to real time processing issue\n' diff --git a/ci-scripts/tests/log-analysis.py b/ci-scripts/tests/log-analysis.py index dba7e9caf4..d7e754a054 100644 --- a/ci-scripts/tests/log-analysis.py +++ b/ci-scripts/tests/log-analysis.py @@ -12,6 +12,9 @@ sys.path.append('./') # to find OAI imports below import cls_loganalysis class TestLogAnalysis(unittest.TestCase): + def setUp(self): + self.maxDiff = None + def test_no_file(self): f = "/total/fantasy/path/file.log" result, _ = cls_loganalysis.Default.run(f, None) @@ -22,5 +25,74 @@ class TestLogAnalysis(unittest.TestCase): result, _ = cls_loganalysis.Default.run(f, None) self.assertTrue(result) + def test_retx_check_good(self): + f = "tests/log-analysis/retx-check-good.log" + opt = "dl=1,0,0,0;ul=1,0,0,0" + result, log = cls_loganalysis.RetxCheck.run(f, opt) + expected = """UE f40a: dlsch_rounds 86/0/0/0, dlsch_errors 0, pucch0_DTX 0, BLER 0.00052 MCS (0) 0 CCE fail 3 +UE f40a: ulsch_rounds 518/0/0/0, ulsch_errors 0, ulsch_DTX 0, BLER 0.00000 MCS (0) 0 (Qm 2 deltaMCS 0 dB) NPRB 5 SNR 51.0 dB CCE fail 0""" + self.assertTrue(result) + self.assertEqual(log, expected) + + def test_retx_check_good_single_val(self): + f = "tests/log-analysis/retx-check-good.log" + opt = "1,0,0,0" + result, log = cls_loganalysis.RetxCheck.run(f, opt) + expected = """UE f40a: dlsch_rounds 86/0/0/0, dlsch_errors 0, pucch0_DTX 0, BLER 0.00052 MCS (0) 0 CCE fail 3 +UE f40a: ulsch_rounds 518/0/0/0, ulsch_errors 0, ulsch_DTX 0, BLER 0.00000 MCS (0) 0 (Qm 2 deltaMCS 0 dB) NPRB 5 SNR 51.0 dB CCE fail 0""" + self.assertTrue(result) + self.assertEqual(log, expected) + + def test_retx_check_good_ul_only(self): + f = "tests/log-analysis/retx-check-good.log" + opt = "ul=1,0,0,0" + result, log = cls_loganalysis.RetxCheck.run(f, opt) + expected = """UE f40a: dlsch_rounds 86/0/0/0, dlsch_errors 0, pucch0_DTX 0, BLER 0.00052 MCS (0) 0 CCE fail 3 +UE f40a: ulsch_rounds 518/0/0/0, ulsch_errors 0, ulsch_DTX 0, BLER 0.00000 MCS (0) 0 (Qm 2 deltaMCS 0 dB) NPRB 5 SNR 51.0 dB CCE fail 0""" + self.assertTrue(result) + self.assertEqual(log, expected) + + def test_retx_check_bad(self): + f = "tests/log-analysis/retx-check-bad.log" + opt = "dl=10,100,100,100;ul=10,100,100,100" + result, log = cls_loganalysis.RetxCheck.run(f, opt) + expected = """UE a491: dlsch_rounds 13/1/0/0, dlsch_errors 0, pucch0_DTX 0, BLER 0.11000 MCS (0) 0 CCE fail 0 +UE a491: ulsch_rounds 23/1/0/0, ulsch_errors 0, ulsch_DTX 1, BLER 0.08447 MCS (0) 0 (Qm 2 deltaMCS 0 dB) NPRB 5 SNR 34.0 dB CCE fail 0 +UE bf9b: dlsch_rounds 370/368/368/368, dlsch_errors 368, pucch0_DTX 1377, BLER 1.00000 MCS (0) 0 CCE fail 64 +UE bf9b: ulsch_rounds 150/148/147/147, ulsch_errors 147, ulsch_DTX 589, BLER 1.00000 MCS (0) 0 (Qm 2 deltaMCS 0 dB) NPRB 104 SNR 38.0 dB CCE fail 0 +!!! Failure: UE bf9b: retx rounds DL [1] UL [1] exceeded threshold +UE 257a: dlsch_rounds 68071/142/14/0, dlsch_errors 0, pucch0_DTX 10, BLER 0.00427 MCS (1) 25 CCE fail 0 +UE 257a: ulsch_rounds 41777/2863/10/0, ulsch_errors 0, ulsch_DTX 17, BLER 0.11456 MCS (1) 10 (Qm 4 deltaMCS 0 dB) NPRB 5 SNR 29.0 dB CCE fail 0""" + self.assertFalse(result) + self.assertEqual(log, expected) + + def test_retx_check_dl_only_bad(self): + f = "tests/log-analysis/retx-check-bad.log" + opt = "dl=10,80,100,100" + result, log = cls_loganalysis.RetxCheck.run(f, opt) + expected = """UE a491: dlsch_rounds 13/1/0/0, dlsch_errors 0, pucch0_DTX 0, BLER 0.11000 MCS (0) 0 CCE fail 0 +UE a491: ulsch_rounds 23/1/0/0, ulsch_errors 0, ulsch_DTX 1, BLER 0.08447 MCS (0) 0 (Qm 2 deltaMCS 0 dB) NPRB 5 SNR 34.0 dB CCE fail 0 +UE bf9b: dlsch_rounds 370/368/368/368, dlsch_errors 368, pucch0_DTX 1377, BLER 1.00000 MCS (0) 0 CCE fail 64 +UE bf9b: ulsch_rounds 150/148/147/147, ulsch_errors 147, ulsch_DTX 589, BLER 1.00000 MCS (0) 0 (Qm 2 deltaMCS 0 dB) NPRB 104 SNR 38.0 dB CCE fail 0 +!!! Failure: UE bf9b: retx rounds DL [1, 2] exceeded threshold +UE 257a: dlsch_rounds 68071/142/14/0, dlsch_errors 0, pucch0_DTX 10, BLER 0.00427 MCS (1) 25 CCE fail 0 +UE 257a: ulsch_rounds 41777/2863/10/0, ulsch_errors 0, ulsch_DTX 17, BLER 0.11456 MCS (1) 10 (Qm 4 deltaMCS 0 dB) NPRB 5 SNR 29.0 dB CCE fail 0""" + self.assertFalse(result) + self.assertEqual(log, expected) + + def test_retx_check_ul_bad(self): + f = "tests/log-analysis/retx-check-bad.log" + opt = "dl=100,100,100,100;ul=10,100,100,100" + result, log = cls_loganalysis.RetxCheck.run(f, opt) + expected = """UE a491: dlsch_rounds 13/1/0/0, dlsch_errors 0, pucch0_DTX 0, BLER 0.11000 MCS (0) 0 CCE fail 0 +UE a491: ulsch_rounds 23/1/0/0, ulsch_errors 0, ulsch_DTX 1, BLER 0.08447 MCS (0) 0 (Qm 2 deltaMCS 0 dB) NPRB 5 SNR 34.0 dB CCE fail 0 +UE bf9b: dlsch_rounds 370/368/368/368, dlsch_errors 368, pucch0_DTX 1377, BLER 1.00000 MCS (0) 0 CCE fail 64 +UE bf9b: ulsch_rounds 150/148/147/147, ulsch_errors 147, ulsch_DTX 589, BLER 1.00000 MCS (0) 0 (Qm 2 deltaMCS 0 dB) NPRB 104 SNR 38.0 dB CCE fail 0 +!!! Failure: UE bf9b: retx rounds UL [1] exceeded threshold +UE 257a: dlsch_rounds 68071/142/14/0, dlsch_errors 0, pucch0_DTX 10, BLER 0.00427 MCS (1) 25 CCE fail 0 +UE 257a: ulsch_rounds 41777/2863/10/0, ulsch_errors 0, ulsch_DTX 17, BLER 0.11456 MCS (1) 10 (Qm 4 deltaMCS 0 dB) NPRB 5 SNR 29.0 dB CCE fail 0""" + self.assertFalse(result) + self.assertEqual(log, expected) + if __name__ == '__main__': unittest.main() diff --git a/ci-scripts/tests/log-analysis/retx-check-bad.log b/ci-scripts/tests/log-analysis/retx-check-bad.log new file mode 100644 index 0000000000..7651da78cf --- /dev/null +++ b/ci-scripts/tests/log-analysis/retx-check-bad.log @@ -0,0 +1,54 @@ +9185541.336575 [NR_RRC] I UE 1 Logical Channel DL-DCCH, Generate SecurityModeCommand (bytes 3) +9185541.356794 [NR_RRC] A [UL] (cellID bc614e, UE ID 1 RNTI a491) Received Security Mode Complete +9185541.357264 [NR_RRC] I UE 1: Logical Channel DL-DCCH, Generate NR UECapabilityEnquiry (bytes 8, xid 2) +9185541.373199 [NR_RRC] A [UL] (cellID bc614e, UE ID 1 RNTI a491) Received UE capabilities +9185541.373330 [NR_RRC] I Send message to ngap: NGAP_UE_CAPABILITIES_IND +9185541.373356 [NR_RRC] A [DL] (cellID bc614e, UE ID 1 RNTI a491) Send DL Information Transfer [53 bytes] +9185541.373368 [NR_RRC] I Send message to sctp: NGAP_InitialContextSetupResponse +9185541.390034 [NR_MAC] I Frame.Slot 384.0 +UE RNTI a491 CU-UE-ID 1 in-sync PH 59 dB PCMAX 21 dBm, average RSRP -101 (4 meas) +UE a491: CQI 2, RI 2, PMI (0,0) +UE a491: dlsch_rounds 13/1/0/0, dlsch_errors 0, pucch0_DTX 0, BLER 0.11000 MCS (0) 0 CCE fail 0 +UE a491: ulsch_rounds 23/1/0/0, ulsch_errors 0, ulsch_DTX 1, BLER 0.08447 MCS (0) 0 (Qm 2 deltaMCS 0 dB) NPRB 5 SNR 34.0 dB CCE fail 0 +UE a491: MAC: TX 367 RX 3664 bytes +UE a491: LCID 1: TX 213 RX 1649 bytes + +9185559.310044 [NR_MAC] I Frame.Slot 128.0 +UE RNTI bf9b CU-UE-ID 1 in-sync PH 48 dB PCMAX 21 dBm +UE bf9b: dlsch_rounds 370/368/368/368, dlsch_errors 368, pucch0_DTX 1377, BLER 1.00000 MCS (0) 0 CCE fail 64 +UE bf9b: ulsch_rounds 150/148/147/147, ulsch_errors 147, ulsch_DTX 589, BLER 1.00000 MCS (0) 0 (Qm 2 deltaMCS 0 dB) NPRB 104 SNR 38.0 dB CCE fail 0 +UE bf9b: MAC: TX 10145 RX 82 bytes +UE bf9b: LCID 1: TX 5283 RX 53 bytes + +9185582.350069 [NR_MAC] I Frame.Slot 384.0 +UE RNTI 257a CU-UE-ID 2 in-sync PH 48 dB PCMAX 21 dBm, average RSRP -83 (16 meas) +UE 257a: CQI 15, RI 2, PMI (0,1) +UE 257a: UL-RI 2, TPMI 0 +UE 257a: dlsch_rounds 153/1/0/0, dlsch_errors 0, pucch0_DTX 0, BLER 0.00000 MCS (1) 0 CCE fail 0 +UE 257a: ulsch_rounds 562/2/1/0, ulsch_errors 0, ulsch_DTX 3, BLER 0.00000 MCS (1) 0 (Qm 2 deltaMCS 0 dB) NPRB 5 SNR 29.5 dB CCE fail 0 +UE 257a: MAC: TX 13416 RX 26519 bytes +UE 257a: LCID 1: TX 523 RX 2046 bytes +UE 257a: LCID 2: TX 0 RX 0 bytes +UE 257a: LCID 4: TX 9800 RX 9945 bytes + +9185687.310202 [NR_MAC] I Frame.Slot 640.0 +UE RNTI 257a CU-UE-ID 2 in-sync PH 61 dB PCMAX 21 dBm, average RSRP -83 (16 meas) +UE 257a: CQI 15, RI 2, PMI (0,1) +UE 257a: UL-RI 2, TPMI 0 +UE 257a: dlsch_rounds 64992/129/13/0, dlsch_errors 0, pucch0_DTX 10, BLER 0.00242 MCS (1) 27 CCE fail 0 +UE 257a: ulsch_rounds 39328/2610/8/0, ulsch_errors 0, ulsch_DTX 14, BLER 0.11139 MCS (1) 9 (Qm 4 deltaMCS 0 dB) NPRB 273 SNR 25.5 dB CCE fail 0 +UE 257a: MAC: TX 3344707955 RX 818603547 bytes +UE 257a: LCID 1: TX 832 RX 4312 bytes +UE 257a: LCID 2: TX 0 RX 0 bytes +UE 257a: LCID 4: TX 3322610250 RX 815642955 bytes + +9185692.430254 [NR_MAC] I Frame.Slot 128.0 +UE RNTI 257a CU-UE-ID 2 in-sync PH 48 dB PCMAX 21 dBm, average RSRP -84 (16 meas) +UE 257a: CQI 15, RI 2, PMI (0,1) +UE 257a: UL-RI 2, TPMI 0 +UE 257a: dlsch_rounds 68071/142/14/0, dlsch_errors 0, pucch0_DTX 10, BLER 0.00427 MCS (1) 25 CCE fail 0 +UE 257a: ulsch_rounds 41777/2863/10/0, ulsch_errors 0, ulsch_DTX 17, BLER 0.11456 MCS (1) 10 (Qm 4 deltaMCS 0 dB) NPRB 5 SNR 29.0 dB CCE fail 0 +UE 257a: MAC: TX 3424886787 RX 879242724 bytes +UE 257a: LCID 1: TX 847 RX 4422 bytes +UE 257a: LCID 2: TX 0 RX 0 bytes +UE 257a: LCID 4: TX 3401067134 RX 875911216 bytes diff --git a/ci-scripts/tests/log-analysis/retx-check-good.log b/ci-scripts/tests/log-analysis/retx-check-good.log new file mode 100644 index 0000000000..c586c615f3 --- /dev/null +++ b/ci-scripts/tests/log-analysis/retx-check-good.log @@ -0,0 +1,8 @@ +7799905.793901 [NR_MAC] I Frame.Slot 256.0 +UE RNTI f40a CU-UE-ID 2 in-sync PH 48 dB PCMAX 20 dBm, average RSRP -44 (16 meas) +UE f40a: dlsch_rounds 86/0/0/0, dlsch_errors 0, pucch0_DTX 0, BLER 0.00052 MCS (0) 0 CCE fail 3 +UE f40a: ulsch_rounds 518/0/0/0, ulsch_errors 0, ulsch_DTX 0, BLER 0.00000 MCS (0) 0 (Qm 2 deltaMCS 0 dB) NPRB 5 SNR 51.0 dB CCE fail 0 +UE f40a: MAC: TX 3836 RX 13684 bytes +UE f40a: LCID 1: TX 530 RX 281 bytes +UE f40a: LCID 2: TX 3 RX 35 bytes +UE f40a: LCID 4: TX 1886 RX 2100 bytes diff --git a/ci-scripts/xml_files/container_5g_fdd_rfsim.xml b/ci-scripts/xml_files/container_5g_fdd_rfsim.xml index b4383feeaf..eb616d9e35 100644 --- a/ci-scripts/xml_files/container_5g_fdd_rfsim.xml +++ b/ci-scripts/xml_files/container_5g_fdd_rfsim.xml @@ -113,8 +113,6 @@ Undeploy all OAI 5G stack localhost ci-scripts/yaml_files/5g_fdd_rfsimulator - 1,0,0,0 - 1,0,0,0 From 30a27432f0eea0c7da5a2bffeed1042b5c5d92bf Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Tue, 17 Feb 2026 18:56:28 +0100 Subject: [PATCH 73/83] Remove unused logging and unused imports --- ci-scripts/cls_containerize.py | 60 ----- ci-scripts/cls_oaicitest.py | 259 ------------------- ci-scripts/ran.py | 441 --------------------------------- 3 files changed, 760 deletions(-) diff --git a/ci-scripts/cls_containerize.py b/ci-scripts/cls_containerize.py index 235b5cdce9..e21cb3771b 100644 --- a/ci-scripts/cls_containerize.py +++ b/ci-scripts/cls_containerize.py @@ -31,24 +31,17 @@ #----------------------------------------------------------- # Import #----------------------------------------------------------- -import sys # arg import re # reg import logging import os -import shutil -import time -from zipfile import ZipFile #----------------------------------------------------------- # OAI Testing modules #----------------------------------------------------------- import cls_cmd -import helpreadme as HELP import constants as CONST -import cls_oaicitest import cls_analysis from cls_ci_helper import archiveArtifact -from collections import deque #----------------------------------------------------------- # Helper functions used here and in other classes @@ -190,59 +183,6 @@ def GetDeployedServices(ssh, file): deployed_services.append((s, c)) return deployed_services -def CheckLogs(self, filename, HTML, RAN): - success = True - name = os.path.basename(filename) - if (any(sub in name for sub in ['oai_ue','oai-nr-ue','lte_ue'])): - logging.debug(f'\u001B[1m Analyzing UE logfile {filename} \u001B[0m') - logStatus = cls_oaicitest.OaiCiTest().AnalyzeLogFile_UE(filename, HTML, RAN) - opt = f"UE log analysis ({name})" - # usage of htmlUEFailureMsg/htmleNBFailureMsg is because Analyze log files - # abuse HTML to store their reports, and we here want to put custom options, - # which is not possible with CreateHtmlTestRow - # solution: use HTML templates, where we don't need different HTML write funcs - if (logStatus < 0): - HTML.CreateHtmlTestRowQueue(opt, 'KO', [HTML.htmlUEFailureMsg]) - success = False - else: - HTML.CreateHtmlTestRowQueue(opt, 'OK', [HTML.htmlUEFailureMsg]) - HTML.htmlUEFailureMsg = "" - elif 'nv-cubb' in name: - msg = 'Undeploy PNF/Nvidia CUBB' - HTML.CreateHtmlTestRow(msg, 'OK', CONST.ALL_PROCESSES_OK) - elif (any(sub in name for sub in ['enb','rru','rcc','cu','du','gnb','vnf'])): - logging.debug(f'\u001B[1m Analyzing XnB logfile {filename}\u001B[0m') - logStatus = RAN.AnalyzeLogFile_eNB(filename, HTML, self.ran_checkers) - opt = f"xNB log analysis ({name})" - if (logStatus < 0): - HTML.CreateHtmlTestRowQueue(opt, 'KO', [HTML.htmleNBFailureMsg]) - success = False - else: - HTML.CreateHtmlTestRowQueue(opt, 'OK', [HTML.htmleNBFailureMsg]) - HTML.htmleNBFailureMsg = "" - elif 'xapp' in name: - opt = f"Undeploy {name}" - with open(f'{filename}', "r") as f: - last_line = deque(f, maxlen=1).pop() - if ('Test xApp run SUCCESSFULLY' in last_line): - HTML.CreateHtmlTestRowQueue(opt, 'OK', ["xApp run successfully"]) - else: - HTML.CreateHtmlTestRowQueue(opt, 'KO', ["xApp didn't run successfully"]) - success = False - elif 'RIC' in name: - opt = f"Undeploy {name}" - with open(f'{filename}', 'r') as f: - last_line = deque(f, maxlen=1).pop() - if ('Removing E2 Node' in last_line): - HTML.CreateHtmlTestRowQueue(opt, 'OK', ["nearRT-RIC run successfully"]) - else: - HTML.CreateHtmlTestRowQueue(opt, 'KO', ["nearRT-RIC didn't run successfully"]) - success = False - else: - logging.info(f"Skipping analysis of log '{filename}': no submatch for xNB/UE") - logging.debug(f"log check: file {filename} passed analysis {success}") - return success - #----------------------------------------------------------- # Class Declaration #----------------------------------------------------------- diff --git a/ci-scripts/cls_oaicitest.py b/ci-scripts/cls_oaicitest.py index 850961c00b..26ac91e668 100644 --- a/ci-scripts/cls_oaicitest.py +++ b/ci-scripts/cls_oaicitest.py @@ -32,7 +32,6 @@ #----------------------------------------------------------- # Import Libs #----------------------------------------------------------- -import sys # arg import re # reg import time # sleep import os @@ -41,7 +40,6 @@ import concurrent.futures import json #import our libs -import helpreadme as HELP import constants as CONST import cls_module @@ -578,263 +576,6 @@ class OaiCiTest(): HTML.CreateHtmlTestRowQueue(self.iperf_args, 'KO', [f'{ue_header}\n{msg}']) return success - def AnalyzeLogFile_UE(self, UElogFile,HTML,RAN): - if (not os.path.isfile(f'{UElogFile}')): - return -1 - ue_log_file = open(f'{UElogFile}', 'r') - exitSignalReceived = False - foundAssertion = False - msgAssertion = '' - msgLine = 0 - foundSegFault = False - foundRealTimeIssue = False - uciStatMsgCount = 0 - pdcpDataReqFailedCount = 0 - badDciCount = 0 - f1aRetransmissionCount = 0 - fatalErrorCount = 0 - macBsrTimerExpiredCount = 0 - rrcConnectionRecfgComplete = 0 - no_cell_sync_found = False - mib_found = False - frequency_found = False - plmn_found = False - nrUEFlag = False - nrDecodeMib = 0 - nrFoundDCI = 0 - nrCRCOK = 0 - nbPduSessAccept = 0 - nbPduDiscard = 0 - HTML.htmlUEFailureMsg='' - global_status = CONST.ALL_PROCESSES_OK - for line in ue_log_file.readlines(): - result = re.search('nr_synchro_time|Starting NR UE soft modem', str(line)) - sidelink = re.search('sl-mode', str(line)) - if result is not None: - nrUEFlag = True - if sidelink is not None: - nrUEFlag = False - if nrUEFlag: - result = re.search('decode mib', str(line)) - if result is not None: - nrDecodeMib += 1 - result = re.search('found 1 DCIs', str(line)) - if result is not None: - nrFoundDCI += 1 - result = re.search('CRC OK', str(line)) - if result is not None: - nrCRCOK += 1 - result = re.search('Received PDU Session Establishment Accept', str(line)) - if result is not None: - nbPduSessAccept += 1 - result = re.search('warning: discard PDU, sn out of window', str(line)) - if result is not None: - nbPduDiscard += 1 - result = re.search('--nfapi STANDALONE_PNF --node-number 2', str(line)) - if result is not None: - frequency_found = True - result = re.search('Exiting OAI softmodem', str(line)) - if result is not None: - exitSignalReceived = True - result = re.search('System error|[Ss]egmentation [Ff]ault|======= Backtrace: =========|======= Memory map: ========', str(line)) - if result is not None and not exitSignalReceived: - foundSegFault = True - result = re.search('[Cc]ore [dD]ump', str(line)) - if result is not None and not exitSignalReceived: - foundSegFault = True - result = re.search('[Aa]ssertion', str(line)) - if result is not None and not exitSignalReceived: - foundAssertion = True - result = re.search('LLL', str(line)) - if result is not None and not exitSignalReceived: - foundRealTimeIssue = True - if foundAssertion and (msgLine < 3): - msgLine += 1 - msgAssertion += str(line) - result = re.search('uci->stat', str(line)) - if result is not None and not exitSignalReceived: - uciStatMsgCount += 1 - result = re.search('PDCP data request failed', str(line)) - if result is not None and not exitSignalReceived: - pdcpDataReqFailedCount += 1 - result = re.search('bad DCI 1', str(line)) - if result is not None and not exitSignalReceived: - badDciCount += 1 - result = re.search('Format1A Retransmission but TBS are different', str(line)) - if result is not None and not exitSignalReceived: - f1aRetransmissionCount += 1 - result = re.search('FATAL ERROR', str(line)) - if result is not None and not exitSignalReceived: - fatalErrorCount += 1 - result = re.search('MAC BSR Triggered ReTxBSR Timer expiry', str(line)) - if result is not None and not exitSignalReceived: - macBsrTimerExpiredCount += 1 - result = re.search('Generating RRCConnectionReconfigurationComplete', str(line)) - if result is not None: - rrcConnectionRecfgComplete += 1 - # No cell synchronization found, abandoning - result = re.search('No cell synchronization found, abandoning', str(line)) - if result is not None: - no_cell_sync_found = True - result = re.search(r"MIB Information => ([a-zA-Z]{1,10}), ([a-zA-Z]{1,10}), NidCell (?P\d{1,3}), N_RB_DL (?P\d{1,3}), PHICH DURATION (?P\d), PHICH RESOURCE (?P.{1,4}), TX_ANT (?P\d)", str(line)) - if result is not None and (not mib_found): - try: - mibMsg = "MIB Information: " + result.group(1) + ', ' + result.group(2) - HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + mibMsg + '\n' - logging.debug(f'\033[94m{mibMsg}\033[0m') - mibMsg = " nidcell = " + result.group('nidcell') - HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + mibMsg - logging.debug(f'\033[94m{mibMsg}\033[0m') - mibMsg = " n_rb_dl = " + result.group('n_rb_dl') - HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + mibMsg + '\n' - logging.debug(f'\033[94m{mibMsg}\033[0m') - mibMsg = " phich_duration = " + result.group('phich_duration') - HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + mibMsg - logging.debug(f'\033[94m{mibMsg}\033[0m') - mibMsg = " phich_resource = " + result.group('phich_resource') - HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + mibMsg + '\n' - logging.debug(f'\033[94m{mibMsg}\033[0m') - mibMsg = " tx_ant = " + result.group('tx_ant') - HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + mibMsg + '\n' - logging.debug(f'\033[94m{mibMsg}\033[0m') - mib_found = True - except Exception as e: - logging.error(f'\033[91m MIB marker was not found \033[0m') - result = re.search("Initial sync: pbch decoded sucessfully", str(line)) - if result is not None and (not frequency_found): - try: - mibMsg = f"UE decoded PBCH successfully" - HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + mibMsg + '\n' - logging.debug(f'\033[94m{mibMsg}\033[0m') - frequency_found = True - except Exception as e: - logging.error(f'\033[91m UE did not find PBCH\033[0m') - result = re.search(r"PLMN MCC (?P\d{1,3}), MNC (?P\d{1,3}), TAC", str(line)) - if result is not None and (not plmn_found): - try: - mibMsg = f"PLMN MCC = {result.group('mcc')} MNC = {result.group('mnc')}" - HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + mibMsg + '\n' - logging.debug(f'\033[94m{mibMsg}\033[0m') - plmn_found = True - except Exception as e: - logging.error(f'\033[91m PLMN not found \033[0m') - result = re.search(r"Found (?P[\w,\s]{1,15}) \(name from internal table\)", str(line)) - if result is not None: - try: - mibMsg = f"The operator is: {result.group('operator')}" - HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + mibMsg + '\n' - logging.debug(f'\033[94m{mibMsg}\033[0m') - except Exception as e: - logging.error(f'\033[91m Operator name not found \033[0m') - result = re.search("SIB5 InterFreqCarrierFreq element (.{1,4})/(.{1,4})", str(line)) - if result is not None: - try: - mibMsg = f'SIB5 InterFreqCarrierFreq element {result.group(1)}/{result.group(2)}' - HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + mibMsg + ' -> ' - logging.debug(f'\033[94m{mibMsg}\033[0m') - except Exception as e: - logging.error(f'\033[91m SIB5 InterFreqCarrierFreq element not found \033[0m') - result = re.search(r"DL Carrier Frequency/ARFCN : \-*(?P\d{1,15}/\d{1,4})", str(line)) - if result is not None: - try: - freq = result.group('carrier_frequency') - new_freq = re.sub('/[0-9]+','',freq) - float_freq = float(new_freq) / 1000000 - HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + 'DL Freq: ' + ('%.1f' % float_freq) + ' MHz' - logging.debug(f'\033[94m DL Carrier Frequency is: {freq}\033[0m') - except Exception as e: - logging.error(f'\033[91m DL Carrier Frequency not found \033[0m') - result = re.search(r"AllowedMeasBandwidth : (?P\d{1,7})", str(line)) - if result is not None: - try: - prb = result.group('allowed_bandwidth') - HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + ' -- PRB: ' + prb + '\n' - logging.debug(f'\033[94m AllowedMeasBandwidth: {prb}\033[0m') - except Exception as e: - logging.error(f'\033[91m AllowedMeasBandwidth not found \033[0m') - ue_log_file.close() - if rrcConnectionRecfgComplete > 0: - statMsg = f'UE connected to eNB ({rrcConnectionRecfgComplete}) RRCConnectionReconfigurationComplete message(s) generated)' - logging.debug(f'\033[94m{statMsg}\033[0m') - HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + statMsg + '\n' - if nrUEFlag: - if nrDecodeMib > 0: - statMsg = f'UE showed {nrDecodeMib} "MIB decode" message(s)' - logging.debug(f'\u001B[1;30;43m{statMsg}\u001B[0m') - HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + statMsg + '\n' - if nrFoundDCI > 0: - statMsg = f'UE showed {nrFoundDCI} "DCI found" message(s)' - logging.debug(f'\u001B[1;30;43m{statMsg}\u001B[0m') - HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + statMsg + '\n' - if nrCRCOK > 0: - statMsg = f'UE showed {nrCRCOK} "PDSCH decoding" message(s)' - logging.debug(f'\u001B[1;30;43m{statMsg}\u001B[0m') - HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + statMsg + '\n' - if not frequency_found: - statMsg = 'NR-UE could NOT synch!' - logging.error(f'\u001B[1;30;43m{statMsg}\u001B[0m') - HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + statMsg + '\n' - if nbPduSessAccept > 0: - statMsg = f'UE showed {nbPduSessAccept} "Received PDU Session Establishment Accept" message(s)' - logging.debug(f'\u001B[1;30;43m{statMsg}\u001B[0m') - HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + statMsg + '\n' - if nbPduDiscard > 0: - statMsg = f'UE showed {nbPduDiscard} "warning: discard PDU, sn out of window" message(s)' - logging.debug(f'\u001B[1;30;43m{statMsg}\u001B[0m') - HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + statMsg + '\n' - if uciStatMsgCount > 0: - statMsg = f'UE showed {uciStatMsgCount} "uci->stat" message(s)' - logging.debug(f'\u001B[1;30;43m{statMsg}\u001B[0m') - HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + statMsg + '\n' - if pdcpDataReqFailedCount > 0: - statMsg = f'UE showed {pdcpDataReqFailedCount} "PDCP data request failed" message(s)' - logging.debug(f'\u001B[1;30;43m{statMsg}\u001B[0m') - HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + statMsg + '\n' - if badDciCount > 0: - statMsg = f'UE showed {badDciCount} "bad DCI 1(A)" message(s)' - logging.debug(f'\u001B[1;30;43m{statMsg}\u001B[0m') - HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + statMsg + '\n' - if f1aRetransmissionCount > 0: - statMsg = f'UE showed {f1aRetransmissionCount} "Format1A Retransmission but TBS are different" message(s)' - logging.debug(f'\u001B[1;30;43m{statMsg}\u001B[0m') - HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + statMsg + '\n' - if fatalErrorCount > 0: - statMsg = f'UE showed {fatalErrorCount} "FATAL ERROR:" message(s)' - logging.debug(f'\u001B[1;30;43m{statMsg}\u001B[0m') - HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + statMsg + '\n' - if macBsrTimerExpiredCount > 0: - statMsg = f'UE showed {fatalErrorCount} "MAC BSR Triggered ReTxBSR Timer expiry" message(s)' - logging.debug(f'\u001B[1;30;43m{statMsg}\u001B[0m') - HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + statMsg + '\n' - if foundSegFault: - logging.debug('\u001B[1;37;41m UE ended with a Segmentation Fault! \u001B[0m') - if not nrUEFlag: - global_status = CONST.OAI_UE_PROCESS_SEG_FAULT - else: - if not frequency_found: - global_status = CONST.OAI_UE_PROCESS_SEG_FAULT - if foundAssertion: - logging.debug('\u001B[1;30;43m UE showed an assertion! \u001B[0m') - HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + 'UE showed an assertion!\n' - if not nrUEFlag: - if not mib_found or not frequency_found: - global_status = CONST.OAI_UE_PROCESS_ASSERTION - else: - if not frequency_found: - global_status = CONST.OAI_UE_PROCESS_ASSERTION - if foundRealTimeIssue: - logging.debug('\u001B[1;37;41m UE faced real time issues! \u001B[0m') - HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + 'UE faced real time issues!\n' - if nrUEFlag: - if not frequency_found: - global_status = CONST.OAI_UE_PROCESS_COULD_NOT_SYNC - else: - if no_cell_sync_found and not mib_found: - logging.debug('\u001B[1;37;41m UE could not synchronize ! \u001B[0m') - HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + 'UE could not synchronize!\n' - global_status = CONST.OAI_UE_PROCESS_COULD_NOT_SYNC - return global_status - def TerminateUE(self, ctx, node, HTML): ues = [cls_module.Module_UE(n.strip(), node) for n in self.ue_ids] with concurrent.futures.ThreadPoolExecutor(max_workers=64) as executor: diff --git a/ci-scripts/ran.py b/ci-scripts/ran.py index 864c2463a5..950b868ad3 100644 --- a/ci-scripts/ran.py +++ b/ci-scripts/ran.py @@ -31,21 +31,15 @@ #----------------------------------------------------------- # Import #----------------------------------------------------------- -import sys # arg import re # reg import logging import os import time -import yaml -import cls_cmd - #----------------------------------------------------------- # OAI Testing modules #----------------------------------------------------------- import cls_cmd -import helpreadme as HELP -import constants as CONST import cls_analysis from cls_ci_helper import archiveArtifact @@ -173,438 +167,3 @@ class RANManagement(): success, datalog_rt_stats = cls_analysis.Analysis.analyze_rt_stats(thresholds, l1_file, mac_file) HTML.CreateHtmlDataLogTable(datalog_rt_stats) return success - - def AnalyzeLogFile_eNB(self, eNBlogFile, HTML, checkers={}): - if (not os.path.isfile(eNBlogFile)): - return -1 - enb_log_file = open(eNBlogFile, 'r') - exitSignalReceived = False - foundAssertion = False - msgAssertion = '' - msgLine = 0 - foundSegFault = False - foundRealTimeIssue = False - foundRealTimeIssue_cnt = 0 - rrcSetupComplete = 0 - rrcReleaseRequest = 0 - rrcReconfigRequest = 0 - rrcReconfigComplete = 0 - rrcReestablishRequest = 0 - rrcReestablishComplete = 0 - rrcReestablishReject = 0 - rlcDiscardBuffer = 0 - rachCanceledProcedure = 0 - uciStatMsgCount = 0 - pdcpFailure = 0 - ulschFailure = 0 - ulschAllocateCCEerror = 0 - uplinkSegmentsAborted = 0 - ulschReceiveOK = 0 - gnbRxTxWakeUpFailure = 0 - gnbTxWriteThreadEnabled = False - cdrxActivationMessageCount = 0 - dropNotEnoughRBs = 0 - mbmsRequestMsg = 0 - htmleNBFailureMsg = '' - isRRU = False - isSlave = False - slaveReceivesFrameResyncCmd = False - global_status = CONST.ALL_PROCESSES_OK - # Runtime statistics - runTime = '' - userTime = '' - systemTime = '' - maxPhyMemUsage = '' - nbContextSwitches = '' - #NSA FR1 check - NSA_RAPROC_PUSCH_check = 0 - #count "problem receiving samples" msg - pb_receiving_samples_cnt = 0 - #count "removing UE" msg - removing_ue = 0 - #count"X2AP-PDU" - x2ap_pdu = 0 - #gnb specific log markers - gnb_markers ={'SgNBReleaseRequestAcknowledge': [],'FAILURE': [], 'scgFailureInformationNR-r15': [], 'SgNBReleaseRequest': [], 'Detected UL Failure on PUSCH':[]} - nodeB_prefix_found = False - RealTimeProcessingIssue = False - retx_status = {} - nrRrcRcfgComplete = 0 - harqFeedbackPast = 0 - showedByeMsg = False # last line is Bye. -> stopped properly - - line_cnt=0 #log file line counter - for line in enb_log_file.readlines(): - line_cnt+=1 - # Detection of eNB/gNB from a container log - result = re.search('Starting eNB soft modem', str(line)) - if result is not None: - nodeB_prefix_found = True - nodeB_prefix = 'e' - result = re.search('Starting gNB soft modem', str(line)) - if result is not None: - nodeB_prefix_found = True - nodeB_prefix = 'g' - result = re.search('Run time:' ,str(line)) - # Runtime statistics - result = re.search('Run time:' ,str(line)) - if result is not None: - runTime = str(line).strip() - if runTime != '': - result = re.search('Time executing user inst', str(line)) - if result is not None: - fields=line.split(':') - userTime = 'userTime : ' + fields[1].replace('\n','') - result = re.search('Time executing system inst', str(line)) - if result is not None: - fields=line.split(':') - systemTime = 'systemTime : ' + fields[1].replace('\n','') - result = re.search('Max. Phy. memory usage:', str(line)) - if result is not None: - fields=line.split(':') - maxPhyMemUsage = 'maxPhyMemUsage : ' + fields[1].replace('\n','') - result = re.search('Number of context switch.*process origin', str(line)) - if result is not None: - fields=line.split(':') - nbContextSwitches = 'nbContextSwitches : ' + fields[1].replace('\n','') - - if self.eNBOptions[0] != '': - res1 = re.search('max_rxgain (?P[0-9]+)', self.eNBOptions[0]) - res2 = re.search('max_rxgain (?P[0-9]+)', str(line)) - if res1 is not None and res2 is not None: - requested_option = int(res1.group('requested_option')) - applied_option = int(res2.group('applied_option')) - if requested_option == applied_option: - htmleNBFailureMsg += ' Command line option(s) correctly applied ' + self.eNBOptions[0] + '\n\n' - else: - htmleNBFailureMsg += ' Command line option(s) NOT applied ' + self.eNBOptions[0] + '\n\n' - result = re.search('Exiting OAI softmodem|Caught SIGTERM, shutting down', str(line)) - if result is not None: - exitSignalReceived = True - result = re.search('[Ss]egmentation [Ff]ault', str(line)) - if result is not None and not exitSignalReceived: - foundSegFault = True - result = re.search('[Cc]ore [dD]ump', str(line)) - if result is not None and not exitSignalReceived: - foundSegFault = True - result = re.search('[Aa]ssertion', str(line)) - if result is not None and not exitSignalReceived: - foundAssertion = True - result = re.search('LLL', str(line)) - if result is not None and not exitSignalReceived: - foundRealTimeIssue = True - foundRealTimeIssue_cnt += 1 - if foundAssertion and (msgLine < 3): - msgLine += 1 - msgAssertion += str(line) - result = re.search('Setting function for RU', str(line)) - if result is not None: - isRRU = True - if isRRU: - result = re.search('RU 0 is_slave=yes', str(line)) - if result is not None: - isSlave = True - if isSlave: - result = re.search('Received RRU_frame_resynch command', str(line)) - if result is not None: - slaveReceivesFrameResyncCmd = True - result = re.search('LTE_RRCConnectionSetupComplete from UE', str(line)) - if result is not None: - rrcSetupComplete += 1 - result = re.search('Generate LTE_RRCConnectionRelease|Generate RRCConnectionRelease', str(line)) - if result is not None: rrcReleaseRequest += 1 - result = re.search('Generate LTE_RRCConnectionReconfiguration', str(line)) - if result is not None: - rrcReconfigRequest += 1 - result = re.search('LTE_RRCConnectionReconfigurationComplete from UE rnti', str(line)) - if result is not None: - rrcReconfigComplete += 1 - result = re.search('LTE_RRCConnectionReestablishmentRequest', str(line)) - if result is not None: - rrcReestablishRequest += 1 - result = re.search('LTE_RRCConnectionReestablishmentComplete', str(line)) - if result is not None: - rrcReestablishComplete += 1 - result = re.search('LTE_RRCConnectionReestablishmentReject', str(line)) - if result is not None: - rrcReestablishReject += 1 - result = re.search('CDRX configuration activated after RRC Connection', str(line)) - if result is not None: - cdrxActivationMessageCount += 1 - result = re.search('uci->stat', str(line)) - if result is not None: - uciStatMsgCount += 1 - result = re.search('PDCP.*Out of Resources.*reason', str(line)) - if result is not None: - pdcpFailure += 1 - result = re.search('could not wakeup gNB rxtx process', str(line)) - if result is not None: - gnbRxTxWakeUpFailure += 1 - result = re.search('tx write thread ready', str(line)) - if result is not None: - gnbTxWriteThreadEnabled = True - result = re.search('ULSCH in error in round|ULSCH 0 in error', str(line)) - if result is not None: - ulschFailure += 1 - result = re.search('ERROR ALLOCATING CCEs', str(line)) - if result is not None: - ulschAllocateCCEerror += 1 - result = re.search('uplink segment error.*aborted [1-9] segments', str(line)) - if result is not None: - uplinkSegmentsAborted += 1 - result = re.search('ULSCH received ok', str(line)) - if result is not None: - ulschReceiveOK += 1 - result = re.search('BAD all_segments_received', str(line)) - if result is not None: - rlcDiscardBuffer += 1 - result = re.search('Canceled RA procedure for UE rnti', str(line)) - if result is not None: - rachCanceledProcedure += 1 - result = re.search('dropping, not enough RBs', str(line)) - if result is not None: - dropNotEnoughRBs += 1 - #FR1 NSA test : add new markers to make sure gNB is used - result = re.search(r'\[gNB [0-9]+\]\[RAPROC\] PUSCH with TC_RNTI 0x[0-9a-fA-F]+ received correctly, adding UE MAC Context RNTI 0x[0-9a-fA-F]+', str(line)) - if result is not None: - NSA_RAPROC_PUSCH_check = 1 - - result = re.search('Received NR_RRCReconfigurationComplete from UE', str(line)) - if result is not None: - nrRrcRcfgComplete += 1 - result = re.search('HARQ feedback is in the past', str(line)) - if result is not None: - harqFeedbackPast += 1 - - - #count "problem receiving samples" msg - result = re.search(r'\[PHY\]\s+problem receiving samples', str(line)) - if result is not None: - pb_receiving_samples_cnt += 1 - #count "Removing UE" msg - result = re.search(r'\[MAC\]\s+Removing UE', str(line)) - if result is not None: - removing_ue += 1 - #count "X2AP-PDU" - result = re.search('X2AP-PDU', str(line)) - if result is not None: - x2ap_pdu += 1 - #gnb markers logging - for k in gnb_markers: - result = re.search(k, line) - if result is not None: - gnb_markers[k].append(line_cnt) - - # check whether e/gNB log finishes with "Bye." message - showedByeMsg |= re.search(r'^Bye.\n', str(line), re.MULTILINE) is not None - - enb_log_file.close() - - #stdout log file and stat log files analysis completed - logging.debug(' File analysis (stdout, stats) completed') - - #post processing depending on the node type - if not nodeB_prefix_found: - if self.air_interface == 'lte-softmodem': - nodeB_prefix = 'e' - else: - nodeB_prefix = 'g' - - if nodeB_prefix == 'g': - if ulschReceiveOK > 0: - statMsg = nodeB_prefix + 'NB showed ' + str(ulschReceiveOK) + ' "ULSCH received ok" message(s)' - logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m') - htmleNBFailureMsg += statMsg + '\n' - if gnbRxTxWakeUpFailure > 0: - statMsg = nodeB_prefix + 'NB showed ' + str(gnbRxTxWakeUpFailure) + ' "could not wakeup gNB rxtx process" message(s)' - logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m') - htmleNBFailureMsg += statMsg + '\n' - if gnbTxWriteThreadEnabled: - statMsg = nodeB_prefix + 'NB ran with TX Write thread enabled' - logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m') - htmleNBFailureMsg += statMsg + '\n' - if nrRrcRcfgComplete > 0: - statMsg = nodeB_prefix + 'NB showed ' + str(nrRrcRcfgComplete) + ' "Received NR_RRCReconfigurationComplete from UE" message(s)' - logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m') - htmleNBFailureMsg += statMsg + '\n' - if harqFeedbackPast > 0: - statMsg = nodeB_prefix + 'NB showed ' + str(harqFeedbackPast) + ' "HARQ feedback is in the past" message(s)' - logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m') - htmleNBFailureMsg += statMsg + '\n' - #FR1 NSA test : add new markers to make sure gNB is used - if NSA_RAPROC_PUSCH_check: - statMsg = '[RAPROC] PUSCH with TC_RNTI message check for ' + nodeB_prefix + 'NB : PASS ' - htmlMsg = statMsg+'\n' - else: - statMsg = '[RAPROC] PUSCH with TC_RNTI message check for ' + nodeB_prefix + 'NB : FAIL or not relevant' - htmlMsg = statMsg+'\n' - logging.debug(statMsg) - htmleNBFailureMsg += htmlMsg - #problem receiving samples log - statMsg = '[PHY] problem receiving samples msg count = '+str(pb_receiving_samples_cnt) - htmlMsg = statMsg+'\n' - logging.debug(statMsg) - htmleNBFailureMsg += htmlMsg - #gnb markers - statMsg = 'logfile line count = ' + str(line_cnt) - htmlMsg = statMsg+'\n' - logging.debug(statMsg) - htmleNBFailureMsg += htmlMsg - if len(gnb_markers['SgNBReleaseRequestAcknowledge'])!=0: - statMsg = 'SgNBReleaseRequestAcknowledge = ' + str(len(gnb_markers['SgNBReleaseRequestAcknowledge'])) + ' occurences , starting line ' + str(gnb_markers['SgNBReleaseRequestAcknowledge'][0]) - else: - statMsg = 'SgNBReleaseRequestAcknowledge = ' + str(len(gnb_markers['SgNBReleaseRequestAcknowledge'])) + ' occurences' - htmlMsg = statMsg+'\n' - logging.debug(statMsg) - htmleNBFailureMsg += htmlMsg - statMsg = 'FAILURE = ' + str(len(gnb_markers['FAILURE'])) + ' occurences' - htmlMsg = statMsg+'\n' - logging.debug(statMsg) - htmleNBFailureMsg += htmlMsg - statMsg = 'Detected UL Failure on PUSCH = ' + str(len(gnb_markers['Detected UL Failure on PUSCH'])) + ' occurences' - htmlMsg = statMsg+'\n' - logging.debug(statMsg) - htmleNBFailureMsg += htmlMsg - - if not showedByeMsg: - logging.debug('\u001B[1;37;41m ' + nodeB_prefix + 'NB did not show "Bye." message at end, it likely did not stop properly! \u001B[0m') - htmleNBFailureMsg += 'No Bye. message found, did not stop properly\n' - global_status = CONST.ENB_SHUTDOWN_NO_BYE - else: - logging.debug('"Bye." message found at end.') - - else: - #Removing UE log - statMsg = '[MAC] Removing UE msg count = '+str(removing_ue) - htmlMsg = statMsg+'\n' - logging.debug(statMsg) - htmleNBFailureMsg += htmlMsg - #X2AP-PDU log - statMsg = 'X2AP-PDU msg count = '+str(x2ap_pdu) - htmlMsg = statMsg+'\n' - logging.debug(statMsg) - htmleNBFailureMsg += htmlMsg - #nsa markers - statMsg = 'logfile line count = ' + str(line_cnt) - htmlMsg = statMsg+'\n' - logging.debug(statMsg) - htmleNBFailureMsg += htmlMsg - if len(gnb_markers['SgNBReleaseRequest'])!=0: - statMsg = 'SgNBReleaseRequest = ' + str(len(gnb_markers['SgNBReleaseRequest'])) + ' occurences , starting line ' + str(gnb_markers['SgNBReleaseRequest'][0]) - else: - statMsg = 'SgNBReleaseRequest = ' + str(len(gnb_markers['SgNBReleaseRequest'])) + ' occurences' - htmlMsg = statMsg+'\n' - logging.debug(statMsg) - htmleNBFailureMsg += htmlMsg - statMsg = 'scgFailureInformationNR-r15 = ' + str(len(gnb_markers['scgFailureInformationNR-r15'])) + ' occurences' - htmlMsg = statMsg+'\n' - logging.debug(statMsg) - htmleNBFailureMsg += htmlMsg - - if RealTimeProcessingIssue: - logging.debug('\u001B[1;37;41m ' + nodeB_prefix + 'NB ended with real time processing issue! \u001B[0m') - htmleNBFailureMsg += 'Fail due to real time processing issue\n' - global_status = CONST.ENB_REAL_TIME_PROCESSING_ISSUE - if uciStatMsgCount > 0: - statMsg = nodeB_prefix + 'NB showed ' + str(uciStatMsgCount) + ' "uci->stat" message(s)' - logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m') - htmleNBFailureMsg += statMsg + '\n' - if pdcpFailure > 0: - statMsg = nodeB_prefix + 'NB showed ' + str(pdcpFailure) + ' "PDCP Out of Resources" message(s)' - logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m') - htmleNBFailureMsg += statMsg + '\n' - if ulschFailure > 0: - statMsg = nodeB_prefix + 'NB showed ' + str(ulschFailure) + ' "ULSCH in error in round" message(s)' - logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m') - htmleNBFailureMsg += statMsg + '\n' - if ulschAllocateCCEerror > 0: - statMsg = nodeB_prefix + 'NB showed ' + str(ulschAllocateCCEerror) + ' "eNB_dlsch_ulsch_scheduler(); ERROR ALLOCATING CCEs" message(s)' - logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m') - htmleNBFailureMsg += statMsg + '\n' - if uplinkSegmentsAborted > 0: - statMsg = nodeB_prefix + 'NB showed ' + str(uplinkSegmentsAborted) + ' "uplink segment error 0/2, aborted * segments" message(s)' - logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m') - htmleNBFailureMsg += statMsg + '\n' - if dropNotEnoughRBs > 0: - statMsg = 'eNB showed ' + str(dropNotEnoughRBs) + ' "dropping, not enough RBs" message(s)' - logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m') - htmleNBFailureMsg += statMsg + '\n' - if rrcSetupComplete > 0: - rrcMsg = nodeB_prefix + 'NB completed ' + str(rrcSetupComplete) + ' RRC Connection Setup(s)' - logging.debug('\u001B[1;30;43m ' + rrcMsg + ' \u001B[0m') - htmleNBFailureMsg += rrcMsg + '\n' - rrcMsg = ' -- ' + str(rrcSetupComplete) + ' were completed' - logging.debug('\u001B[1;30;43m ' + rrcMsg + ' \u001B[0m') - htmleNBFailureMsg += rrcMsg + '\n' - if rrcReleaseRequest > 0: - rrcMsg = nodeB_prefix + 'NB requested ' + str(rrcReleaseRequest) + ' RRC Connection Release(s)' - logging.debug('\u001B[1;30;43m ' + rrcMsg + ' \u001B[0m') - htmleNBFailureMsg += rrcMsg + '\n' - if rrcReconfigRequest > 0 or rrcReconfigComplete > 0: - rrcMsg = nodeB_prefix + 'NB requested ' + str(rrcReconfigRequest) + ' RRC Connection Reconfiguration(s)' - logging.debug('\u001B[1;30;43m ' + rrcMsg + ' \u001B[0m') - htmleNBFailureMsg += rrcMsg + '\n' - rrcMsg = ' -- ' + str(rrcReconfigComplete) + ' were completed' - logging.debug('\u001B[1;30;43m ' + rrcMsg + ' \u001B[0m') - htmleNBFailureMsg += rrcMsg + '\n' - if rrcReestablishRequest > 0 or rrcReestablishComplete > 0 or rrcReestablishReject > 0: - rrcMsg = nodeB_prefix + 'NB requested ' + str(rrcReestablishRequest) + ' RRC Connection Reestablishment(s)' - logging.debug('\u001B[1;30;43m ' + rrcMsg + ' \u001B[0m') - htmleNBFailureMsg += rrcMsg + '\n' - rrcMsg = ' -- ' + str(rrcReestablishComplete) + ' were completed' - logging.debug('\u001B[1;30;43m ' + rrcMsg + ' \u001B[0m') - htmleNBFailureMsg += rrcMsg + '\n' - rrcMsg = ' -- ' + str(rrcReestablishReject) + ' were rejected' - logging.debug('\u001B[1;30;43m ' + rrcMsg + ' \u001B[0m') - htmleNBFailureMsg += rrcMsg + '\n' - if self.eNBOptions[0] != '': - res1 = re.search('drx_Config_present prSetup', self.eNBOptions[0]) - if res1 is not None: - if cdrxActivationMessageCount > 0: - rrcMsg = 'eNB activated the CDRX Configuration for ' + str(cdrxActivationMessageCount) + ' time(s)' - logging.debug('\u001B[1;30;43m ' + rrcMsg + ' \u001B[0m') - htmleNBFailureMsg += rrcMsg + '\n' - else: - rrcMsg = 'eNB did NOT ACTIVATE the CDRX Configuration' - logging.debug('\u001B[1;37;43m ' + rrcMsg + ' \u001B[0m') - htmleNBFailureMsg += rrcMsg + '\n' - if rachCanceledProcedure > 0: - rachMsg = nodeB_prefix + 'NB cancelled ' + str(rachCanceledProcedure) + ' RA procedure(s)' - logging.debug('\u001B[1;30;43m ' + rachMsg + ' \u001B[0m') - htmleNBFailureMsg += rachMsg + '\n' - if isRRU: - if isSlave: - if slaveReceivesFrameResyncCmd: - rruMsg = 'Slave RRU received the RRU_frame_resynch command from RAU' - logging.debug('\u001B[1;30;43m ' + rruMsg + ' \u001B[0m') - htmleNBFailureMsg += rruMsg + '\n' - else: - rruMsg = 'Slave RRU DID NOT receive the RRU_frame_resynch command from RAU' - logging.debug('\u001B[1;37;41m ' + rruMsg + ' \u001B[0m') - htmleNBFailureMsg += rruMsg + '\n' - global_status = CONST.ENB_PROCESS_SLAVE_RRU_NOT_SYNCED - if foundSegFault: - logging.debug('\u001B[1;37;41m ' + nodeB_prefix + 'NB ended with a Segmentation Fault! \u001B[0m') - global_status = CONST.ENB_PROCESS_SEG_FAULT - if foundAssertion: - logging.debug('\u001B[1;37;41m ' + nodeB_prefix + 'NB ended with an assertion! \u001B[0m') - htmleNBFailureMsg += msgAssertion - global_status = CONST.ENB_PROCESS_ASSERTION - if foundRealTimeIssue: - logging.debug('\u001B[1;37;41m ' + nodeB_prefix + 'NB faced real time issues! \u001B[0m') - htmleNBFailureMsg += nodeB_prefix + 'NB faced real time issues! COUNT = '+ str(foundRealTimeIssue_cnt) +' lines\n' - if rlcDiscardBuffer > 0: - rlcMsg = nodeB_prefix + 'NB RLC discarded ' + str(rlcDiscardBuffer) + ' buffer(s)' - logging.debug('\u001B[1;37;41m ' + rlcMsg + ' \u001B[0m') - htmleNBFailureMsg += rlcMsg + '\n' - global_status = CONST.ENB_PROCESS_REALTIME_ISSUE - HTML.htmleNBFailureMsg=htmleNBFailureMsg - # Runtime statistics for console output and HTML - if runTime != '': - logging.debug(runTime) - logging.debug(userTime) - logging.debug(systemTime) - logging.debug(maxPhyMemUsage) - logging.debug(nbContextSwitches) - self.runtime_stats='
'+runTime + '\n'+ userTime + '\n' + systemTime + '\n' + maxPhyMemUsage + '\n' + nbContextSwitches+'
' - return global_status From 366df408a1073908f816fbde36555e5a1bf70d4a Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Mon, 23 Feb 2026 14:26:41 +0100 Subject: [PATCH 74/83] Default checker: check for assertions --- ci-scripts/cls_loganalysis.py | 13 +++++++++---- ci-scripts/tests/log-analysis.py | 8 ++++---- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/ci-scripts/cls_loganalysis.py b/ci-scripts/cls_loganalysis.py index 2369f1115f..f4de1258b8 100644 --- a/ci-scripts/cls_loganalysis.py +++ b/ci-scripts/cls_loganalysis.py @@ -26,10 +26,15 @@ import logging class Default: def run(file, opt=None): - # TODO add check on assertions, etc - if not os.path.exists(file): - return False, f"cannot find file {file}" - return True, "" + success = True + logs = [] + with open(file, "r") as f: + for line in f.readlines(): + result = re.search('[Aa]ssertion', line) + if result: + logs.append(line) + success = False + return success, "\n".join(logs) class ContainsString: def run(file, needle): diff --git a/ci-scripts/tests/log-analysis.py b/ci-scripts/tests/log-analysis.py index d7e754a054..6d5f6c5bd7 100644 --- a/ci-scripts/tests/log-analysis.py +++ b/ci-scripts/tests/log-analysis.py @@ -15,10 +15,10 @@ class TestLogAnalysis(unittest.TestCase): def setUp(self): self.maxDiff = None - def test_no_file(self): - f = "/total/fantasy/path/file.log" - result, _ = cls_loganalysis.Default.run(f, None) - self.assertFalse(result) + #def test_no_file(self): + # f = "/total/fantasy/path/file.log" + # result, _ = cls_loganalysis.Default.run(f, None) + # self.assertFalse(result) def test_no_error(self): f = "tests/log-analysis/empty.log" From 735058f5c4b0f8af7883de77e010c081bd57c181 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 19 Feb 2026 11:28:54 +0100 Subject: [PATCH 75/83] New log-analysis checker LastLineContains --- ci-scripts/cls_loganalysis.py | 9 +++++++++ ci-scripts/tests/log-analysis.py | 16 ++++++++++++++++ ci-scripts/tests/log-analysis/arbitrary.log | 9 +++++++++ 3 files changed, 34 insertions(+) create mode 100644 ci-scripts/tests/log-analysis/arbitrary.log diff --git a/ci-scripts/cls_loganalysis.py b/ci-scripts/cls_loganalysis.py index f4de1258b8..38c36202bd 100644 --- a/ci-scripts/cls_loganalysis.py +++ b/ci-scripts/cls_loganalysis.py @@ -23,6 +23,7 @@ import re import os import logging +from collections import deque class Default: def run(file, opt=None): @@ -44,6 +45,14 @@ class ContainsString: return True, "" return False, f"could not find '{needle}' in logs" +class LastLineContains: + def run(file, string): + with open(file, "r") as f: + last_line = deque(f, maxlen=1).pop() + success = string in last_line + log = "" if success else f"could not find '{string}' in last line" + return success, log + class RetxCheck(): def _parseList(s): if not s: diff --git a/ci-scripts/tests/log-analysis.py b/ci-scripts/tests/log-analysis.py index 6d5f6c5bd7..a4416305a8 100644 --- a/ci-scripts/tests/log-analysis.py +++ b/ci-scripts/tests/log-analysis.py @@ -94,5 +94,21 @@ UE 257a: ulsch_rounds 41777/2863/10/0, ulsch_errors 0, ulsch_DTX 17, BLER 0.1145 self.assertFalse(result) self.assertEqual(log, expected) + def test_last_line_contains_false(self): + f = "tests/log-analysis/arbitrary.log" + opt = "Bye." + result, log = cls_loganalysis.LastLineContains.run(f, opt) + expected = f"could not find '{opt}' in last line" + self.assertFalse(result) + self.assertEqual(log, expected) + + def test_last_line_contains_false(self): + f = "tests/log-analysis/arbitrary.log" + opt = "got sync" + result, log = cls_loganalysis.LastLineContains.run(f, opt) + expected = "" + self.assertTrue(result) + self.assertEqual(log, expected) + if __name__ == '__main__': unittest.main() diff --git a/ci-scripts/tests/log-analysis/arbitrary.log b/ci-scripts/tests/log-analysis/arbitrary.log new file mode 100644 index 0000000000..095690aeb3 --- /dev/null +++ b/ci-scripts/tests/log-analysis/arbitrary.log @@ -0,0 +1,9 @@ +[UTIL] threadCreate() for L1_rx_thread: creating thread (no affinity, default priority) +[UTIL] threadCreate() for L1_tx_thread: creating thread (no affinity, default priority) +[UTIL] threadCreate() for L1_stats: creating thread (no affinity, default priority) +TYPE TO TERMINATE +[PHY] got sync (ru_thread) +[PHY] RU 0 rf device ready +[PHY] RU 0 RF started cpu_meas_enabled 0 +[HW] No connected device, generating void samples... +[PHY] got sync (L1_stats_thread) From 516583405176d5a73543f1bd273a94362d64fa8c Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 26 Feb 2026 13:36:17 +0100 Subject: [PATCH 76/83] Introduce EndsWithBye log analysis check It was initially foreseen to just check the program exit code, but most executables don't return with 0 (so the CI would always fail). Add a separate check that will check for the Bye., only going through the last X lines instead of the entire file. --- ci-scripts/cls_loganalysis.py | 13 +++++++++++++ ci-scripts/tests/log-analysis.py | 17 +++++++++++++++++ ci-scripts/tests/log-analysis/with-bye.log | 3 +++ 3 files changed, 33 insertions(+) create mode 100644 ci-scripts/tests/log-analysis/with-bye.log diff --git a/ci-scripts/cls_loganalysis.py b/ci-scripts/cls_loganalysis.py index 38c36202bd..b28e217707 100644 --- a/ci-scripts/cls_loganalysis.py +++ b/ci-scripts/cls_loganalysis.py @@ -53,6 +53,19 @@ class LastLineContains: log = "" if success else f"could not find '{string}' in last line" return success, log +class EndsWithBye: + def run(file, option): + # no option: we ignore any + with open(file, "r") as f: + n = 0 + for line in reversed(f.readlines()): + if re.search(r'^Bye.\n', line, re.MULTILINE) is not None: + return True, "" + n = n + 1 + if n > 50: # if not found in last 50 lines, assume it does not exist + break + return False, "No Bye. message found, did not stop properly" + class RetxCheck(): def _parseList(s): if not s: diff --git a/ci-scripts/tests/log-analysis.py b/ci-scripts/tests/log-analysis.py index a4416305a8..2df23483d3 100644 --- a/ci-scripts/tests/log-analysis.py +++ b/ci-scripts/tests/log-analysis.py @@ -110,5 +110,22 @@ UE 257a: ulsch_rounds 41777/2863/10/0, ulsch_errors 0, ulsch_DTX 17, BLER 0.1145 self.assertTrue(result) self.assertEqual(log, expected) + def test_ends_no_bye(self): + f = "tests/log-analysis/arbitrary.log" + opt = None + result, log = cls_loganalysis.EndsWithBye.run(f, opt) + expected = "No Bye. message found, did not stop properly" + self.assertFalse(result) + self.assertEqual(log, expected) + + def test_ends_with_bye(self): + f = "tests/log-analysis/with-bye.log" + opt = None + result, log = cls_loganalysis.EndsWithBye.run(f, opt) + expected = "" + self.assertTrue(result) + self.assertEqual(log, expected) + + if __name__ == '__main__': unittest.main() diff --git a/ci-scripts/tests/log-analysis/with-bye.log b/ci-scripts/tests/log-analysis/with-bye.log new file mode 100644 index 0000000000..22abbfab05 --- /dev/null +++ b/ci-scripts/tests/log-analysis/with-bye.log @@ -0,0 +1,3 @@ +Some other logs +Bye. +process exited. From c6bb50edb11d6a9af1830767872d3f57fc101d20 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Tue, 24 Feb 2026 08:16:21 +0100 Subject: [PATCH 77/83] Add LogAnalysis in all XML files I try to retain/match the previous log checks, without adding new checks. --- ci-scripts/xml_files/container_4g_l2sim_tdd.xml | 3 +++ .../xml_files/container_4g_rfsim_fdd_05MHz.xml | 3 +++ .../xml_files/container_4g_rfsim_fdd_05MHz_noS1.xml | 3 +++ .../xml_files/container_4g_rfsim_fdd_10MHz.xml | 3 +++ .../xml_files/container_4g_rfsim_fdd_20MHz.xml | 3 +++ ci-scripts/xml_files/container_4g_rfsim_fembms.xml | 3 +++ ci-scripts/xml_files/container_4g_rfsim_mbms.xml | 3 +++ .../xml_files/container_4g_rfsim_tdd_05MHz.xml | 3 +++ ci-scripts/xml_files/container_5g_e1_rfsim.xml | 5 +++-- ci-scripts/xml_files/container_5g_f1_rfsim.xml | 5 +++-- ci-scripts/xml_files/container_5g_fdd_rfsim.xml | 3 +++ ci-scripts/xml_files/container_5g_flexric_rfsim.xml | 8 ++++++++ ci-scripts/xml_files/container_5g_rfsim.xml | 5 +++-- ci-scripts/xml_files/container_5g_rfsim_24prb.xml | 3 +++ ci-scripts/xml_files/container_5g_rfsim_2x2.xml | 5 +++-- .../xml_files/container_5g_rfsim_fdd_phytest.xml | 5 +++-- .../xml_files/container_5g_rfsim_fr2_66prb.xml | 5 +++-- ci-scripts/xml_files/container_5g_rfsim_multiue.xml | 7 ++++--- ci-scripts/xml_files/container_5g_rfsim_n2_ho.xml | 5 +++-- ci-scripts/xml_files/container_5g_rfsim_ntn_geo.xml | 3 +++ ci-scripts/xml_files/container_5g_rfsim_ntn_leo.xml | 3 +++ ci-scripts/xml_files/container_5g_rfsim_prs.xml | 5 +++-- .../xml_files/container_5g_rfsim_sidelink.xml | 13 ++++--------- ci-scripts/xml_files/container_5g_rfsim_simple.xml | 5 +++-- .../xml_files/container_5g_rfsim_tdd_dora.xml | 5 +++-- .../xml_files/container_5g_rfsim_u0_25prb.xml | 5 +++-- .../xml_files/container_5g_vrtsim_chanmod.xml | 5 +++-- .../xml_files/container_5g_vrtsim_chanmod_gh.xml | 5 +++-- ci-scripts/xml_files/container_5g_vrtsim_cirdb.xml | 5 +++-- .../xml_files/container_lte_b200_fdd_05Mhz_tm1.xml | 3 +++ .../container_lte_b200_fdd_05Mhz_tm1_if4_5.xml | 3 +++ ...ainer_lte_b200_fdd_05Mhz_tm1_no_rrc_activity.xml | 3 +++ .../xml_files/container_lte_b200_fdd_10Mhz_tm1.xml | 3 +++ .../container_lte_b200_fdd_10Mhz_tm1_cdrx.xml | 3 +++ .../container_lte_b200_fdd_10Mhz_tm1_oaiue.xml | 6 ++++++ .../xml_files/container_lte_b200_fdd_20Mhz_tm1.xml | 3 +++ .../xml_files/container_lte_b200_tdd_05Mhz_tm1.xml | 3 +++ .../container_lte_b200_tdd_05Mhz_tm1_if4_5.xml | 3 +++ .../xml_files/container_lte_b200_tdd_10Mhz_tm1.xml | 3 +++ .../xml_files/container_lte_b200_tdd_20Mhz_tm1.xml | 3 +++ ...ner_lte_b200_tdd_20Mhz_tm1_default_scheduler.xml | 3 +++ .../xml_files/container_lte_n3xx_tdd_2x2_tm1.xml | 3 +++ .../xml_files/container_lte_n3xx_tdd_2x2_tm2.xml | 3 +++ ci-scripts/xml_files/container_nsa_b200_quectel.xml | 8 ++++++-- .../xml_files/container_sa_aerial_quectel.xml | 5 +++-- .../container_sa_aerial_quectel_ul_heavy.xml | 5 +++-- ci-scripts/xml_files/container_sa_aw2s_asue.xml | 3 +++ ci-scripts/xml_files/container_sa_aw2s_asue_2x2.xml | 3 +++ ci-scripts/xml_files/container_sa_b200_quectel.xml | 5 +++-- .../xml_files/container_sa_e1_b200_quectel.xml | 5 +++-- .../xml_files/container_sa_f1_b200_quectel.xml | 5 +++-- .../xml_files/container_sa_f1_ho_b210_quectel.xml | 6 ++++++ .../container_sa_fhi72_metanoia_up2_2x2.xml | 3 +++ .../xml_files/container_sa_fhi72_vvdn_up2.xml | 3 +++ .../xml_files/container_sa_n2_ho_b210_quectel.xml | 6 ++++++ .../container_sa_n310_2X2_100MHz_quectel.xml | 5 +++-- .../container_sa_n310_2X2_60MHz_quectel.xml | 5 +++-- .../container_sa_n310_4X4_60MHz_quectel.xml | 5 +++-- ci-scripts/xml_files/container_sa_n310_nrue.xml | 8 ++++++-- .../xml_files/container_sa_n310_nrue_longrun.xml | 8 ++++++-- .../xml_files/container_sa_sc_b200_quectel.xml | 5 +++-- .../gnb_phytest_rfemulator_run_100_2x2.xml | 2 +- ci-scripts/xml_files/gnb_phytest_usrp_run.xml | 3 +++ .../xml_files/gnb_phytest_usrp_run_100_2x2.xml | 3 +++ ci-scripts/xml_files/gnb_phytest_usrp_run_60.xml | 3 +++ .../xml_files/gnb_phytest_usrp_run_60_2x2.xml | 3 +++ 66 files changed, 221 insertions(+), 65 deletions(-) diff --git a/ci-scripts/xml_files/container_4g_l2sim_tdd.xml b/ci-scripts/xml_files/container_4g_l2sim_tdd.xml index 1b3ec37b81..5483a9e4c7 100644 --- a/ci-scripts/xml_files/container_4g_l2sim_tdd.xml +++ b/ci-scripts/xml_files/container_4g_l2sim_tdd.xml @@ -129,6 +129,9 @@ localhost Undeploy all OAI 4G stack ci-scripts/yaml_files/4g_l2sim_fdd + + oai_enb=EndsWithBye oai_ue1 +
diff --git a/ci-scripts/xml_files/container_4g_rfsim_fdd_05MHz.xml b/ci-scripts/xml_files/container_4g_rfsim_fdd_05MHz.xml index adad131ef7..57295697e4 100644 --- a/ci-scripts/xml_files/container_4g_rfsim_fdd_05MHz.xml +++ b/ci-scripts/xml_files/container_4g_rfsim_fdd_05MHz.xml @@ -147,6 +147,9 @@ Undeploy all OAI 4G stack localhost ci-scripts/yaml_files/4g_rfsimulator_fdd_05MHz + + oai_enb0=EndsWithBye oai_ue0 + diff --git a/ci-scripts/xml_files/container_4g_rfsim_fdd_05MHz_noS1.xml b/ci-scripts/xml_files/container_4g_rfsim_fdd_05MHz_noS1.xml index 0879e27170..ac057f1862 100644 --- a/ci-scripts/xml_files/container_4g_rfsim_fdd_05MHz_noS1.xml +++ b/ci-scripts/xml_files/container_4g_rfsim_fdd_05MHz_noS1.xml @@ -118,6 +118,9 @@ Undeploy all OAI 4G stack localhost ci-scripts/yaml_files/4g_rfsimulator_fdd_05MHz_noS1 + + oai_enb0=EndsWithBye oai_ue0 + diff --git a/ci-scripts/xml_files/container_4g_rfsim_fdd_10MHz.xml b/ci-scripts/xml_files/container_4g_rfsim_fdd_10MHz.xml index acde953fe8..aca8caf06b 100644 --- a/ci-scripts/xml_files/container_4g_rfsim_fdd_10MHz.xml +++ b/ci-scripts/xml_files/container_4g_rfsim_fdd_10MHz.xml @@ -147,6 +147,9 @@ Undeploy all OAI 4G stack localhost ci-scripts/yaml_files/4g_rfsimulator_fdd_10MHz + + oai_enb0=EndsWithBye oai_ue0 + diff --git a/ci-scripts/xml_files/container_4g_rfsim_fdd_20MHz.xml b/ci-scripts/xml_files/container_4g_rfsim_fdd_20MHz.xml index cf6eb1d838..619fd54bec 100644 --- a/ci-scripts/xml_files/container_4g_rfsim_fdd_20MHz.xml +++ b/ci-scripts/xml_files/container_4g_rfsim_fdd_20MHz.xml @@ -147,6 +147,9 @@ Undeploy all OAI 4G stack localhost ci-scripts/yaml_files/4g_rfsimulator_fdd_20MHz + + oai_enb0=EndsWithBye oai_ue0 + diff --git a/ci-scripts/xml_files/container_4g_rfsim_fembms.xml b/ci-scripts/xml_files/container_4g_rfsim_fembms.xml index f03fb12e76..41708abab2 100644 --- a/ci-scripts/xml_files/container_4g_rfsim_fembms.xml +++ b/ci-scripts/xml_files/container_4g_rfsim_fembms.xml @@ -84,6 +84,9 @@ Undeploy all OAI 4G stack localhost ci-scripts/yaml_files/4g_rfsimulator_fembms + + oai_enb0=EndsWithBye oai_ue0 + diff --git a/ci-scripts/xml_files/container_4g_rfsim_mbms.xml b/ci-scripts/xml_files/container_4g_rfsim_mbms.xml index f41aa98a9f..457adb77b8 100644 --- a/ci-scripts/xml_files/container_4g_rfsim_mbms.xml +++ b/ci-scripts/xml_files/container_4g_rfsim_mbms.xml @@ -84,6 +84,9 @@ Undeploy all OAI 4G stack localhost ci-scripts/yaml_files/4g_rfsimulator_mbms + + oai_enb0=EndsWithBye oai_ue0 + diff --git a/ci-scripts/xml_files/container_4g_rfsim_tdd_05MHz.xml b/ci-scripts/xml_files/container_4g_rfsim_tdd_05MHz.xml index f57ff9eb14..16c61edaf0 100644 --- a/ci-scripts/xml_files/container_4g_rfsim_tdd_05MHz.xml +++ b/ci-scripts/xml_files/container_4g_rfsim_tdd_05MHz.xml @@ -146,6 +146,9 @@ Undeploy all OAI 4G stack localhost ci-scripts/yaml_files/4g_rfsimulator_tdd_05MHz + + oai_enb0=EndsWithBye oai_ue0 + diff --git a/ci-scripts/xml_files/container_5g_e1_rfsim.xml b/ci-scripts/xml_files/container_5g_e1_rfsim.xml index fc3be58e2d..6c8b3940b5 100644 --- a/ci-scripts/xml_files/container_5g_e1_rfsim.xml +++ b/ci-scripts/xml_files/container_5g_e1_rfsim.xml @@ -86,8 +86,9 @@ localhost Undeploy all OAI 5G stack ci-scripts/yaml_files/5g_rfsimulator_e1 - 1,0,0,0 - 1,0,0,0 + + oai-cucp=EndsWithBye oai-cuup=EndsWithBye oai-cuup2=EndsWithBye oai-cuup3=EndsWithBye oai-du=RetxCheck=1,0,0,0 oai-du=EndsWithBye oai-du2=RetxCheck=1,0,0,0 oai-du2=EndsWithBye oai-du3=RetxCheck=1,0,0,0 oai-du3=EndsWithBye oai-nr-ue oai-nr-ue2 oai-nr-ue3 + diff --git a/ci-scripts/xml_files/container_5g_f1_rfsim.xml b/ci-scripts/xml_files/container_5g_f1_rfsim.xml index 7385daacfc..56df31e156 100644 --- a/ci-scripts/xml_files/container_5g_f1_rfsim.xml +++ b/ci-scripts/xml_files/container_5g_f1_rfsim.xml @@ -311,8 +311,9 @@ Undeploy all OAI 5G stack localhost ci-scripts/yaml_files/5g_f1_rfsimulator - 30,100,100,100 - 30,100,100,100 + + oai-cu=EndsWithBye oai-du-pci0=RetxCheck=30,100,100,100 oai-du-pci0=EndsWithBye oai-du-pci1=RetxCheck=30,100,100,100 oai-du-pci1=EndsWithBye oai-nr-ue + diff --git a/ci-scripts/xml_files/container_5g_fdd_rfsim.xml b/ci-scripts/xml_files/container_5g_fdd_rfsim.xml index eb616d9e35..09d0e7784f 100644 --- a/ci-scripts/xml_files/container_5g_fdd_rfsim.xml +++ b/ci-scripts/xml_files/container_5g_fdd_rfsim.xml @@ -113,6 +113,9 @@ Undeploy all OAI 5G stack localhost ci-scripts/yaml_files/5g_fdd_rfsimulator + + oai-gnb=EndsWithBye oai-nr-ue + diff --git a/ci-scripts/xml_files/container_5g_flexric_rfsim.xml b/ci-scripts/xml_files/container_5g_flexric_rfsim.xml index 78fb296697..985f2b623c 100644 --- a/ci-scripts/xml_files/container_5g_flexric_rfsim.xml +++ b/ci-scripts/xml_files/container_5g_flexric_rfsim.xml @@ -197,6 +197,14 @@ localhost ci-scripts/yaml_files/5g_rfsimulator_flexric true + + nearRT-RIC=LastLineContains=Removing E2 Node + xapp-rc-moni=LastLineContains=Test xApp run SUCCESSFULLY + xapp-kpm-moni=LastLineContains=Test xApp run SUCCESSFULLY + xapp-kpm-rc=LastLineContains=Test xApp run SUCCESSFULLY + xapp-gtp-mac-rlc-pdcp-moni=LastLineContains=Test xApp run SUCCESSFULLY + oai-gnb=EndsWithBye oai-nr-ue oai-nr-ue2 + diff --git a/ci-scripts/xml_files/container_5g_rfsim.xml b/ci-scripts/xml_files/container_5g_rfsim.xml index 58199ab5d9..2bc96b7d8c 100644 --- a/ci-scripts/xml_files/container_5g_rfsim.xml +++ b/ci-scripts/xml_files/container_5g_rfsim.xml @@ -243,8 +243,9 @@ Undeploy all OAI 5G stack localhost ci-scripts/yaml_files/5g_rfsimulator - 1,0,0,0 - 1,0,0,0 + + oai-gnb=RetxCheck=1,0,0,0 oai-gnb=EndsWithBye oai-nr-ue oai-nr-ue2 oai-nr-ue3 oai-nr-ue4 oai-nr-ue5 oai-nr-ue6 oai-nr-ue7 oai-nr-ue8 oai-nr-ue9 oai-nr-ue10 + diff --git a/ci-scripts/xml_files/container_5g_rfsim_24prb.xml b/ci-scripts/xml_files/container_5g_rfsim_24prb.xml index 1e7128a6e8..f7f677cb0d 100644 --- a/ci-scripts/xml_files/container_5g_rfsim_24prb.xml +++ b/ci-scripts/xml_files/container_5g_rfsim_24prb.xml @@ -257,6 +257,9 @@ Undeploy all OAI 5G stack localhost ci-scripts/yaml_files/5g_rfsimulator_24prb + + oai-gnb=EndsWithBye oai-nr-ue + diff --git a/ci-scripts/xml_files/container_5g_rfsim_2x2.xml b/ci-scripts/xml_files/container_5g_rfsim_2x2.xml index 06cb9b63db..3c1c33db10 100644 --- a/ci-scripts/xml_files/container_5g_rfsim_2x2.xml +++ b/ci-scripts/xml_files/container_5g_rfsim_2x2.xml @@ -113,8 +113,9 @@ Undeploy all OAI 5G stack localhost ci-scripts/yaml_files/5g_rfsimulator_2x2 - 1,0,0,0 - 1,0,0,0 + + oai-gnb=RetxCheck=1,0,0,0 oai-gnb=EndsWithBye oai-nr-ue + diff --git a/ci-scripts/xml_files/container_5g_rfsim_fdd_phytest.xml b/ci-scripts/xml_files/container_5g_rfsim_fdd_phytest.xml index 4fbb0f6f7e..649663ea93 100644 --- a/ci-scripts/xml_files/container_5g_rfsim_fdd_phytest.xml +++ b/ci-scripts/xml_files/container_5g_rfsim_fdd_phytest.xml @@ -113,8 +113,9 @@ Undeploy all OAI 5G stack localhost ci-scripts/yaml_files/5g_rfsimulator_fdd_phytest - 10,100,100,100 - 10,100,100,100 + + oai-gnb=RetxCheck=10,100,100,100 oai-gnb=EndsWithBye oai-nr-ue + diff --git a/ci-scripts/xml_files/container_5g_rfsim_fr2_66prb.xml b/ci-scripts/xml_files/container_5g_rfsim_fr2_66prb.xml index b64837c839..cb15ffbcc0 100644 --- a/ci-scripts/xml_files/container_5g_rfsim_fr2_66prb.xml +++ b/ci-scripts/xml_files/container_5g_rfsim_fr2_66prb.xml @@ -89,8 +89,9 @@ Undeploy all OAI 5G stack localhost ci-scripts/yaml_files/5g_rfsimulator_fr2_66prb - 10,0,0,0 - 10,0,0,0 + + oai-gnb=RetxCheck=10,0,0,0 oai-gnb=EndsWithBye oai-nr-ue + diff --git a/ci-scripts/xml_files/container_5g_rfsim_multiue.xml b/ci-scripts/xml_files/container_5g_rfsim_multiue.xml index 83bd857c4a..4010e561bc 100644 --- a/ci-scripts/xml_files/container_5g_rfsim_multiue.xml +++ b/ci-scripts/xml_files/container_5g_rfsim_multiue.xml @@ -159,10 +159,11 @@ Undeploy_Object true Undeploy all OAI 5G stack - ci-scripts/yaml_files/5g_rfsimulator_multiue - 1,0,0,0 - 1,0,0,0 localhost + ci-scripts/yaml_files/5g_rfsimulator_multiue + + oai-gnb=RetxCheck=1,0,0,0 oai-gnb=EndsWithBye oai-nr-ue + diff --git a/ci-scripts/xml_files/container_5g_rfsim_n2_ho.xml b/ci-scripts/xml_files/container_5g_rfsim_n2_ho.xml index 9ef14478b1..915fa0e4e6 100644 --- a/ci-scripts/xml_files/container_5g_rfsim_n2_ho.xml +++ b/ci-scripts/xml_files/container_5g_rfsim_n2_ho.xml @@ -227,8 +227,9 @@ Undeploy all OAI 5G stack localhost ci-scripts/yaml_files/5g_rfsimulator_n2_ho - 10,100,100,100 - 10,100,100,100 + + oai-cucp-0=EndsWithBye oai-cuup-0=EndsWithBye oai-du-0=RetxCheck=10,100,100,100 oai-du-0=EndsWithBye oai-nr-ue oai-cucp-1=EndsWithBye oai-cuup-1=EndsWithBye oai-du-1=RetxCheck=10,100,100,100 oai-du-1=EndsWithBye oai-nr-ue + diff --git a/ci-scripts/xml_files/container_5g_rfsim_ntn_geo.xml b/ci-scripts/xml_files/container_5g_rfsim_ntn_geo.xml index 7e291b86fb..3cb18aeb44 100644 --- a/ci-scripts/xml_files/container_5g_rfsim_ntn_geo.xml +++ b/ci-scripts/xml_files/container_5g_rfsim_ntn_geo.xml @@ -138,6 +138,9 @@ Undeploy all OAI 5G stack localhost ci-scripts/yaml_files/5g_rfsimulator_ntn_geo + + oai-gnb=EndsWithBye oai-nr-ue + diff --git a/ci-scripts/xml_files/container_5g_rfsim_ntn_leo.xml b/ci-scripts/xml_files/container_5g_rfsim_ntn_leo.xml index cac6f5f4ee..97d2540ce6 100644 --- a/ci-scripts/xml_files/container_5g_rfsim_ntn_leo.xml +++ b/ci-scripts/xml_files/container_5g_rfsim_ntn_leo.xml @@ -138,6 +138,9 @@ Undeploy all OAI 5G stack localhost ci-scripts/yaml_files/5g_rfsimulator_ntn_leo + + oai-gnb=EndsWithBye oai-nr-ue + diff --git a/ci-scripts/xml_files/container_5g_rfsim_prs.xml b/ci-scripts/xml_files/container_5g_rfsim_prs.xml index 2485e7d503..6e9500c388 100644 --- a/ci-scripts/xml_files/container_5g_rfsim_prs.xml +++ b/ci-scripts/xml_files/container_5g_rfsim_prs.xml @@ -74,8 +74,9 @@ Undeploy all OAI 5G stack localhost ci-scripts/yaml_files/5g_rfsimulator_prs - 30,100,100,100 - 30,100,100,100 + + oai-gnb=RetxCheck=30,100,100,100 oai-gnb=EndsWithBye oai-nr-ue + diff --git a/ci-scripts/xml_files/container_5g_rfsim_sidelink.xml b/ci-scripts/xml_files/container_5g_rfsim_sidelink.xml index f434bb600c..d4d7723915 100644 --- a/ci-scripts/xml_files/container_5g_rfsim_sidelink.xml +++ b/ci-scripts/xml_files/container_5g_rfsim_sidelink.xml @@ -60,21 +60,16 @@ 20 - - Custom_Command - Check that UE synched - localhost - docker logs rfsim5g-oai-nr-ue-2 | grep -m 1 "PSBCH RX:OK" - - Undeploy_Object true Undeploy all OAI 5G stack localhost ci-scripts/yaml_files/5g_rfsimulator_sidelink - 1,0,0,0 - 1,0,0,0 + + oai-nr-ue-1 + oai-nr-ue-2=ContainsString=PSBCH RX:OK + diff --git a/ci-scripts/xml_files/container_5g_rfsim_simple.xml b/ci-scripts/xml_files/container_5g_rfsim_simple.xml index be4912d2b2..541a2f5a29 100644 --- a/ci-scripts/xml_files/container_5g_rfsim_simple.xml +++ b/ci-scripts/xml_files/container_5g_rfsim_simple.xml @@ -80,8 +80,9 @@ Undeploy all OAI 5G stack localhost ci-scripts/yaml_files/5g_rfsimulator - 1,0,0,0 - 1,0,0,0 + + oai-gnb=RetxCheck=1,0,0,0 oai-gnb=EndsWithBye oai-nr-ue oai-nr-ue2 oai-nr-ue3 oai-nr-ue4 oai-nr-ue5 oai-nr-ue6 oai-nr-ue7 oai-nr-ue8 oai-nr-ue9 oai-nr-ue10 + diff --git a/ci-scripts/xml_files/container_5g_rfsim_tdd_dora.xml b/ci-scripts/xml_files/container_5g_rfsim_tdd_dora.xml index 83209d664e..dbea7321ed 100644 --- a/ci-scripts/xml_files/container_5g_rfsim_tdd_dora.xml +++ b/ci-scripts/xml_files/container_5g_rfsim_tdd_dora.xml @@ -95,8 +95,9 @@ Undeploy all OAI 5G stack localhost ci-scripts/yaml_files/5g_rfsimulator_tdd_dora - 0,0,0,0 - 0,0,0,0 + + oai-gnb=RetxCheck=0,0,0,0 oai-gnb=EndsWithBye oai-nr-ue + diff --git a/ci-scripts/xml_files/container_5g_rfsim_u0_25prb.xml b/ci-scripts/xml_files/container_5g_rfsim_u0_25prb.xml index 060f539cde..ef84c97f7c 100644 --- a/ci-scripts/xml_files/container_5g_rfsim_u0_25prb.xml +++ b/ci-scripts/xml_files/container_5g_rfsim_u0_25prb.xml @@ -174,8 +174,9 @@ Undeploy all OAI 5G stack localhost ci-scripts/yaml_files/5g_rfsimulator_u0_25prb - 1,0,0,0 - 1,0,0,0 + + oai-vnf=RetxCheck=0,0,0,0 oai-vnf=EndsWithBye oai-pnf=EndsWithBye oai-nr-ue + diff --git a/ci-scripts/xml_files/container_5g_vrtsim_chanmod.xml b/ci-scripts/xml_files/container_5g_vrtsim_chanmod.xml index c844228640..9198261754 100644 --- a/ci-scripts/xml_files/container_5g_vrtsim_chanmod.xml +++ b/ci-scripts/xml_files/container_5g_vrtsim_chanmod.xml @@ -113,8 +113,9 @@ Undeploy all OAI 5G stack localhost ci-scripts/yaml_files/5g_vrtsim_chanmod - 1,0,0,0 - 1,0,0,0 + + oai-gnb=RetxCheck=1,0,0,0 oai-gnb=EndsWithBye oai-nr-ue + diff --git a/ci-scripts/xml_files/container_5g_vrtsim_chanmod_gh.xml b/ci-scripts/xml_files/container_5g_vrtsim_chanmod_gh.xml index 3d3a9a5e41..353bd68f05 100644 --- a/ci-scripts/xml_files/container_5g_vrtsim_chanmod_gh.xml +++ b/ci-scripts/xml_files/container_5g_vrtsim_chanmod_gh.xml @@ -114,8 +114,9 @@ Undeploy all OAI 5G stack localhost ci-scripts/yaml_files/5g_vrtsim_chanmod - 1,0,0,0 - 1,0,0,0 + + oai-gnb=RetxCheck=1,0,0,0 oai-gnb=EndsWithBye oai-nr-ue + diff --git a/ci-scripts/xml_files/container_5g_vrtsim_cirdb.xml b/ci-scripts/xml_files/container_5g_vrtsim_cirdb.xml index 84a6a527f7..fe08d34adf 100644 --- a/ci-scripts/xml_files/container_5g_vrtsim_cirdb.xml +++ b/ci-scripts/xml_files/container_5g_vrtsim_cirdb.xml @@ -114,8 +114,9 @@ Undeploy all OAI 5G stack localhost ci-scripts/yaml_files/5g_vrtsim_cirdb - 10,0,0,0 - 1,0,0,0 + + oai-gnb=RetxCheck=dl=10,0,0,0;ul=1,0,0,0 oai-gnb=EndsWithBye oai-nr-ue + diff --git a/ci-scripts/xml_files/container_lte_b200_fdd_05Mhz_tm1.xml b/ci-scripts/xml_files/container_lte_b200_fdd_05Mhz_tm1.xml index 614acee309..af703bad33 100644 --- a/ci-scripts/xml_files/container_lte_b200_fdd_05Mhz_tm1.xml +++ b/ci-scripts/xml_files/container_lte_b200_fdd_05Mhz_tm1.xml @@ -183,6 +183,9 @@ Replaces xml_files/enb_usrp210_band7_test_05mhz_tm1.xml Undeploy eNB hutch ci-scripts/yaml_files/lte_b200_fdd_05Mhz_tm1 + + enb_mono_fdd=EndsWithBye + diff --git a/ci-scripts/xml_files/container_lte_b200_fdd_05Mhz_tm1_if4_5.xml b/ci-scripts/xml_files/container_lte_b200_fdd_05Mhz_tm1_if4_5.xml index 243243658b..aa3598126c 100644 --- a/ci-scripts/xml_files/container_lte_b200_fdd_05Mhz_tm1_if4_5.xml +++ b/ci-scripts/xml_files/container_lte_b200_fdd_05Mhz_tm1_if4_5.xml @@ -165,6 +165,9 @@ Undeploy RCC/RRU hutch ci-scripts/yaml_files/lte_b200_fdd_05Mhz_if4.5 + + rru_fdd=EndsWithBye rcc_fdd=EndsWithBye + diff --git a/ci-scripts/xml_files/container_lte_b200_fdd_05Mhz_tm1_no_rrc_activity.xml b/ci-scripts/xml_files/container_lte_b200_fdd_05Mhz_tm1_no_rrc_activity.xml index bd7400cb13..71fd42ccf4 100644 --- a/ci-scripts/xml_files/container_lte_b200_fdd_05Mhz_tm1_no_rrc_activity.xml +++ b/ci-scripts/xml_files/container_lte_b200_fdd_05Mhz_tm1_no_rrc_activity.xml @@ -156,6 +156,9 @@ Replaces xml_files/enb_usrp210_band7_test_05mhz_tm1_rrc_inactivity_no_flexran.xm Undeploy eNB hutch ci-scripts/yaml_files/lte_b200_fdd_05Mhz_tm1_no_rrc_activity + + enb_mono_fdd=EndsWithBye + diff --git a/ci-scripts/xml_files/container_lte_b200_fdd_10Mhz_tm1.xml b/ci-scripts/xml_files/container_lte_b200_fdd_10Mhz_tm1.xml index 92f4376676..a0ea977254 100644 --- a/ci-scripts/xml_files/container_lte_b200_fdd_10Mhz_tm1.xml +++ b/ci-scripts/xml_files/container_lte_b200_fdd_10Mhz_tm1.xml @@ -168,6 +168,9 @@ Replaces xml_files/enb_usrp210_band7_test_10mhz_tm1.xml Undeploy eNB hutch ci-scripts/yaml_files/lte_b200_fdd_10Mhz_tm1 + + enb_mono_fdd=EndsWithBye + diff --git a/ci-scripts/xml_files/container_lte_b200_fdd_10Mhz_tm1_cdrx.xml b/ci-scripts/xml_files/container_lte_b200_fdd_10Mhz_tm1_cdrx.xml index 5e3b64e01b..868a80cec3 100644 --- a/ci-scripts/xml_files/container_lte_b200_fdd_10Mhz_tm1_cdrx.xml +++ b/ci-scripts/xml_files/container_lte_b200_fdd_10Mhz_tm1_cdrx.xml @@ -116,6 +116,9 @@ Replaces xml_files/enb_usrp210_band7_test_10mhz_tm1.xml Undeploy eNB hutch ci-scripts/yaml_files/lte_b200_fdd_10Mhz_tm1_cdrx + + enb_mono_fdd=EndsWithBye + diff --git a/ci-scripts/xml_files/container_lte_b200_fdd_10Mhz_tm1_oaiue.xml b/ci-scripts/xml_files/container_lte_b200_fdd_10Mhz_tm1_oaiue.xml index 5133c17f14..c0b0f91027 100644 --- a/ci-scripts/xml_files/container_lte_b200_fdd_10Mhz_tm1_oaiue.xml +++ b/ci-scripts/xml_files/container_lte_b200_fdd_10Mhz_tm1_oaiue.xml @@ -133,6 +133,9 @@ Undeploy LTE-UE carabe ci-scripts/yaml_files/lte_b200_fdd_10Mhz_oai_ue_magma + + lte_ue0 + @@ -147,6 +150,9 @@ Undeploy eNB hutch ci-scripts/yaml_files/lte_b200_fdd_10Mhz_tm1_magma + + enb_mono_fdd=EndsWithBye + diff --git a/ci-scripts/xml_files/container_lte_b200_fdd_20Mhz_tm1.xml b/ci-scripts/xml_files/container_lte_b200_fdd_20Mhz_tm1.xml index cf092b2653..6a3bf52993 100644 --- a/ci-scripts/xml_files/container_lte_b200_fdd_20Mhz_tm1.xml +++ b/ci-scripts/xml_files/container_lte_b200_fdd_20Mhz_tm1.xml @@ -140,6 +140,9 @@ Replaces xml_files/enb_usrp210_band7_test_10mhz_tm1.xml Undeploy eNB hutch ci-scripts/yaml_files/lte_b200_fdd_20Mhz_tm1 + + enb_mono_fdd=EndsWithBye + diff --git a/ci-scripts/xml_files/container_lte_b200_tdd_05Mhz_tm1.xml b/ci-scripts/xml_files/container_lte_b200_tdd_05Mhz_tm1.xml index 849d6e0140..b20740c0e7 100644 --- a/ci-scripts/xml_files/container_lte_b200_tdd_05Mhz_tm1.xml +++ b/ci-scripts/xml_files/container_lte_b200_tdd_05Mhz_tm1.xml @@ -194,6 +194,9 @@ Replaces xml_files/enb_usrp210_band40_test_05mhz_tm1.xml Undeploy eNB starsky ci-scripts/yaml_files/lte_b200_tdd_05Mhz_tm1 + + enb_mono_tdd=EndsWithBye + diff --git a/ci-scripts/xml_files/container_lte_b200_tdd_05Mhz_tm1_if4_5.xml b/ci-scripts/xml_files/container_lte_b200_tdd_05Mhz_tm1_if4_5.xml index 3b2e5a8022..8d75c79347 100644 --- a/ci-scripts/xml_files/container_lte_b200_tdd_05Mhz_tm1_if4_5.xml +++ b/ci-scripts/xml_files/container_lte_b200_tdd_05Mhz_tm1_if4_5.xml @@ -174,6 +174,9 @@ Undeploy RRU/RCC starsky ci-scripts/yaml_files/lte_b200_tdd_05Mhz_if4.5 + + rru_tdd=EndsWithBye rcc_tdd=EndsWithBye + diff --git a/ci-scripts/xml_files/container_lte_b200_tdd_10Mhz_tm1.xml b/ci-scripts/xml_files/container_lte_b200_tdd_10Mhz_tm1.xml index a947c6774c..74eb50fe06 100644 --- a/ci-scripts/xml_files/container_lte_b200_tdd_10Mhz_tm1.xml +++ b/ci-scripts/xml_files/container_lte_b200_tdd_10Mhz_tm1.xml @@ -187,6 +187,9 @@ Replaces xml_files/enb_usrp210_band40_test_10mhz_tm1.xml Undeploy eNB starsky ci-scripts/yaml_files/lte_b200_tdd_10Mhz_tm1 + + enb_mono_tdd=EndsWithBye + diff --git a/ci-scripts/xml_files/container_lte_b200_tdd_20Mhz_tm1.xml b/ci-scripts/xml_files/container_lte_b200_tdd_20Mhz_tm1.xml index 0888891cb3..1b1f007e0e 100644 --- a/ci-scripts/xml_files/container_lte_b200_tdd_20Mhz_tm1.xml +++ b/ci-scripts/xml_files/container_lte_b200_tdd_20Mhz_tm1.xml @@ -133,6 +133,9 @@ Replaces xml_files/enb_usrp210_band40_test_20mhz_tm1.xml Undeploy eNB starsky ci-scripts/yaml_files/lte_b200_tdd_20Mhz_tm1 + + enb_mono_tdd=EndsWithBye + diff --git a/ci-scripts/xml_files/container_lte_b200_tdd_20Mhz_tm1_default_scheduler.xml b/ci-scripts/xml_files/container_lte_b200_tdd_20Mhz_tm1_default_scheduler.xml index 636abb1a66..cbd196b353 100644 --- a/ci-scripts/xml_files/container_lte_b200_tdd_20Mhz_tm1_default_scheduler.xml +++ b/ci-scripts/xml_files/container_lte_b200_tdd_20Mhz_tm1_default_scheduler.xml @@ -189,6 +189,9 @@ Replaces xml_files/enb_usrp210_band40_test_20mhz_tm1_default_scheduler.xml Undeploy eNB starsky ci-scripts/yaml_files/lte_b200_tdd_20Mhz_tm1_default_scheduler + + enb_mono_tdd=EndsWithBye + diff --git a/ci-scripts/xml_files/container_lte_n3xx_tdd_2x2_tm1.xml b/ci-scripts/xml_files/container_lte_n3xx_tdd_2x2_tm1.xml index 39ac1a7df4..0eab1b9fc1 100644 --- a/ci-scripts/xml_files/container_lte_n3xx_tdd_2x2_tm1.xml +++ b/ci-scripts/xml_files/container_lte_n3xx_tdd_2x2_tm1.xml @@ -125,6 +125,9 @@ Undeploy gNB obelix ci-scripts/yaml_files/lte_n3xx_tdd_2x2_tm1 + + oai-enb=EndsWithBye + diff --git a/ci-scripts/xml_files/container_lte_n3xx_tdd_2x2_tm2.xml b/ci-scripts/xml_files/container_lte_n3xx_tdd_2x2_tm2.xml index e2b9f7ae13..41c3c4f4a7 100644 --- a/ci-scripts/xml_files/container_lte_n3xx_tdd_2x2_tm2.xml +++ b/ci-scripts/xml_files/container_lte_n3xx_tdd_2x2_tm2.xml @@ -125,6 +125,9 @@ Undeploy gNB obelix ci-scripts/yaml_files/lte_n3xx_tdd_2x2_tm2 + + oai-enb=EndsWithBye + diff --git a/ci-scripts/xml_files/container_nsa_b200_quectel.xml b/ci-scripts/xml_files/container_nsa_b200_quectel.xml index a9e859886c..c9b941949c 100644 --- a/ci-scripts/xml_files/container_nsa_b200_quectel.xml +++ b/ci-scripts/xml_files/container_nsa_b200_quectel.xml @@ -192,8 +192,9 @@ Undeploy gNB ofqot ci-scripts/yaml_files/nsa_b200_gnb - 10,100,100,100 - 10,100,100,100 + + gnb_mono_tdd=RetxCheck=10,100,100,100 gnb_mono_tdd=EndsWithBye + @@ -202,6 +203,9 @@ Undeploy eNB nepes ci-scripts/yaml_files/nsa_b200_enb + + enb_mono_fdd=EndsWithBye + diff --git a/ci-scripts/xml_files/container_sa_aerial_quectel.xml b/ci-scripts/xml_files/container_sa_aerial_quectel.xml index 7282513bb8..b5de982e5a 100644 --- a/ci-scripts/xml_files/container_sa_aerial_quectel.xml +++ b/ci-scripts/xml_files/container_sa_aerial_quectel.xml @@ -132,8 +132,9 @@ Undeploy gNB gracehopper1-oai ci-scripts/yaml_files/sa_gnb_aerial - 20,100,100,100 - 20,100,100,100 + + oai-gnb-aerial=RetxCheck=20,100,100,100 oai-gnb-aerial=EndsWithBye + diff --git a/ci-scripts/xml_files/container_sa_aerial_quectel_ul_heavy.xml b/ci-scripts/xml_files/container_sa_aerial_quectel_ul_heavy.xml index 8367316e3a..9d826d2261 100644 --- a/ci-scripts/xml_files/container_sa_aerial_quectel_ul_heavy.xml +++ b/ci-scripts/xml_files/container_sa_aerial_quectel_ul_heavy.xml @@ -121,8 +121,9 @@ Undeploy gNB gracehopper1-oai ci-scripts/yaml_files/sa_gnb_aerial_ul - 20,100,100,100 - 20,100,100,100 + + oai-gnb-aerial=RetxCheck=20,100,100,100 oai-gnb-aerial=EndsWithBye + diff --git a/ci-scripts/xml_files/container_sa_aw2s_asue.xml b/ci-scripts/xml_files/container_sa_aw2s_asue.xml index 6dfbc83187..dadfad3bf5 100644 --- a/ci-scripts/xml_files/container_sa_aw2s_asue.xml +++ b/ci-scripts/xml_files/container_sa_aw2s_asue.xml @@ -177,6 +177,9 @@ Undeploy gNB avra ci-scripts/yaml_files/sa_aw2s_gnb + + oai-gnb=EndsWithBye + diff --git a/ci-scripts/xml_files/container_sa_aw2s_asue_2x2.xml b/ci-scripts/xml_files/container_sa_aw2s_asue_2x2.xml index c7e5ab5721..19a668ff27 100644 --- a/ci-scripts/xml_files/container_sa_aw2s_asue_2x2.xml +++ b/ci-scripts/xml_files/container_sa_aw2s_asue_2x2.xml @@ -235,6 +235,9 @@ Undeploy gNB avra ci-scripts/yaml_files/sa_aw2s_2x2_gnb + + oai-gnb=EndsWithBye + diff --git a/ci-scripts/xml_files/container_sa_b200_quectel.xml b/ci-scripts/xml_files/container_sa_b200_quectel.xml index cb64146091..2891a7b117 100644 --- a/ci-scripts/xml_files/container_sa_b200_quectel.xml +++ b/ci-scripts/xml_files/container_sa_b200_quectel.xml @@ -229,8 +229,9 @@ Undeploy gNB ofqot ci-scripts/yaml_files/sa_b200_gnb - 10,100,100,100 - 10,100,100,100 + + gnb_mono_tdd=RetxCheck=10,100,100,100 gnb_mono_tdd=EndsWithBye + diff --git a/ci-scripts/xml_files/container_sa_e1_b200_quectel.xml b/ci-scripts/xml_files/container_sa_e1_b200_quectel.xml index ce9e1121c3..797c6fd853 100644 --- a/ci-scripts/xml_files/container_sa_e1_b200_quectel.xml +++ b/ci-scripts/xml_files/container_sa_e1_b200_quectel.xml @@ -255,8 +255,9 @@ Undeploy CUCP/CU-UP/DU ofqot ci-scripts/yaml_files/sa_e1_b200_gnb - 10,100,100,100 - 10,100,100,100 + + gnb_cucp=EndsWithBye gnb_cuup=EndsWithBye gnb_du_tdd=RetxCheck=10,100,100,100 gnb_du_tdd=EndsWithBye + diff --git a/ci-scripts/xml_files/container_sa_f1_b200_quectel.xml b/ci-scripts/xml_files/container_sa_f1_b200_quectel.xml index 35103d01e7..875e7856c7 100644 --- a/ci-scripts/xml_files/container_sa_f1_b200_quectel.xml +++ b/ci-scripts/xml_files/container_sa_f1_b200_quectel.xml @@ -263,8 +263,9 @@ Undeploy CU-DU ofqot ci-scripts/yaml_files/sa_f1_b200_gnb - 10,100,100,100 - 10,100,100,100 + + gnb_cu=EndsWithBye gnb_du_fdd=RetxCheck=10,100,100,100 gnb_du_fdd=EndsWithBye + diff --git a/ci-scripts/xml_files/container_sa_f1_ho_b210_quectel.xml b/ci-scripts/xml_files/container_sa_f1_ho_b210_quectel.xml index 2804e3c14e..73e1375046 100644 --- a/ci-scripts/xml_files/container_sa_f1_ho_b210_quectel.xml +++ b/ci-scripts/xml_files/container_sa_f1_ho_b210_quectel.xml @@ -191,6 +191,9 @@ Undeploy CU-DU0 groot ci-scripts/yaml_files/5g_sa_f1_b210_ho + + oai-cu=EndsWithBye oai-du0=EndsWithBye + @@ -199,6 +202,9 @@ Undeploy DU1 rocket ci-scripts/yaml_files/5g_sa_f1_b210_ho + + oai-du1=EndsWithBye + diff --git a/ci-scripts/xml_files/container_sa_fhi72_metanoia_up2_2x2.xml b/ci-scripts/xml_files/container_sa_fhi72_metanoia_up2_2x2.xml index 3129883744..97037157b4 100644 --- a/ci-scripts/xml_files/container_sa_fhi72_metanoia_up2_2x2.xml +++ b/ci-scripts/xml_files/container_sa_fhi72_metanoia_up2_2x2.xml @@ -127,6 +127,9 @@ Undeploy gNB cacofonix ci-scripts/yaml_files/sa_fhi_7.2_metanoia_2x2_gnb + + oai-gnb=EndsWithBye + diff --git a/ci-scripts/xml_files/container_sa_fhi72_vvdn_up2.xml b/ci-scripts/xml_files/container_sa_fhi72_vvdn_up2.xml index c02a12deac..d8548077fd 100644 --- a/ci-scripts/xml_files/container_sa_fhi72_vvdn_up2.xml +++ b/ci-scripts/xml_files/container_sa_fhi72_vvdn_up2.xml @@ -138,6 +138,9 @@ Undeploy gNB cacofonix ci-scripts/yaml_files/sa_fhi_7.2_vvdn_gnb + + oai-gnb=EndsWithBye + diff --git a/ci-scripts/xml_files/container_sa_n2_ho_b210_quectel.xml b/ci-scripts/xml_files/container_sa_n2_ho_b210_quectel.xml index 1f4c7c1981..42390d0f2f 100644 --- a/ci-scripts/xml_files/container_sa_n2_ho_b210_quectel.xml +++ b/ci-scripts/xml_files/container_sa_n2_ho_b210_quectel.xml @@ -160,6 +160,9 @@ Undeploy Monolithic gNB-PCI0 groot ci-scripts/yaml_files/5g_sa_n2_ho_b210 + + oai-gnb-pci0=EndsWithBye + @@ -168,6 +171,9 @@ Undeploy Monolithic gNB-PCI1 rocket ci-scripts/yaml_files/5g_sa_n2_ho_b210 + + oai-gnb-pci1=EndsWithBye + diff --git a/ci-scripts/xml_files/container_sa_n310_2X2_100MHz_quectel.xml b/ci-scripts/xml_files/container_sa_n310_2X2_100MHz_quectel.xml index 0c3cd35b2f..6823b553c4 100644 --- a/ci-scripts/xml_files/container_sa_n310_2X2_100MHz_quectel.xml +++ b/ci-scripts/xml_files/container_sa_n310_2X2_100MHz_quectel.xml @@ -123,8 +123,9 @@ Undeploy gNB matix ci-scripts/yaml_files/5g_sa_n310_2x2_100MHz - 10,100,100,100 - 10,100,100,100 + + oai-gnb=RetxCheck=10,100,100,100 oai-gnb=EndsWithBye + diff --git a/ci-scripts/xml_files/container_sa_n310_2X2_60MHz_quectel.xml b/ci-scripts/xml_files/container_sa_n310_2X2_60MHz_quectel.xml index 5d1b3dcd95..dd4d6d9e96 100644 --- a/ci-scripts/xml_files/container_sa_n310_2X2_60MHz_quectel.xml +++ b/ci-scripts/xml_files/container_sa_n310_2X2_60MHz_quectel.xml @@ -123,8 +123,9 @@ Undeploy gNB matix ci-scripts/yaml_files/5g_sa_n310_2x2_60MHz - 15,100,100,100 - 20,100,100,100 + + oai-gnb=RetxCheck=dl=15,100,100,100;ul=20,100,100,100 oai-gnb=EndsWithBye + diff --git a/ci-scripts/xml_files/container_sa_n310_4X4_60MHz_quectel.xml b/ci-scripts/xml_files/container_sa_n310_4X4_60MHz_quectel.xml index 45d105de9e..694a6aa288 100644 --- a/ci-scripts/xml_files/container_sa_n310_4X4_60MHz_quectel.xml +++ b/ci-scripts/xml_files/container_sa_n310_4X4_60MHz_quectel.xml @@ -123,8 +123,9 @@ Undeploy VNF-PNF matix ci-scripts/yaml_files/5g_sa_n310_4x4_60MHz - 10,100,100,100 - 10,100,100,100 + + oai-vnf=RetxCheck=10,100,100,100 oai-vnf=EndsWithBye oai-pnf=EndsWithBye + diff --git a/ci-scripts/xml_files/container_sa_n310_nrue.xml b/ci-scripts/xml_files/container_sa_n310_nrue.xml index 64311b06cd..1db35faa6b 100644 --- a/ci-scripts/xml_files/container_sa_n310_nrue.xml +++ b/ci-scripts/xml_files/container_sa_n310_nrue.xml @@ -125,6 +125,9 @@ Undeploy nr UE caracal ci-scripts/yaml_files/5g_sa_n310_nrue + + oai-nr-ue + @@ -133,8 +136,9 @@ Undeploy gNB avra ci-scripts/yaml_files/5g_sa_n310_gnb - 20,100,100,100 - 20,100,100,100 + + oai-gnb=RetxCheck=20,100,100,100 oai-gnb=EndsWithBye + diff --git a/ci-scripts/xml_files/container_sa_n310_nrue_longrun.xml b/ci-scripts/xml_files/container_sa_n310_nrue_longrun.xml index 6241a9d78d..987f8355a5 100644 --- a/ci-scripts/xml_files/container_sa_n310_nrue_longrun.xml +++ b/ci-scripts/xml_files/container_sa_n310_nrue_longrun.xml @@ -205,6 +205,9 @@ Undeploy nr UE caracal ci-scripts/yaml_files/5g_sa_n310_nrue + + oai-nr-ue + @@ -213,8 +216,9 @@ Undeploy gNB avra ci-scripts/yaml_files/5g_sa_n310_gnb - 20,100,100,100 - 20,100,100,100 + + oai-gnb=RetxCheck=20,100,100,100 oai-gnb=EndsWithBye + diff --git a/ci-scripts/xml_files/container_sa_sc_b200_quectel.xml b/ci-scripts/xml_files/container_sa_sc_b200_quectel.xml index 82cb032372..d81c855f39 100644 --- a/ci-scripts/xml_files/container_sa_sc_b200_quectel.xml +++ b/ci-scripts/xml_files/container_sa_sc_b200_quectel.xml @@ -183,8 +183,9 @@ Undeploy gNB ofqot ci-scripts/yaml_files/sa_sc_b200_gnb - 10,100,100,100 - 10,100,100,100 + + gnb_mono_tdd=RetxCheck=10,100,100,100 gnb_mono_tdd=EndsWithBye + diff --git a/ci-scripts/xml_files/gnb_phytest_rfemulator_run_100_2x2.xml b/ci-scripts/xml_files/gnb_phytest_rfemulator_run_100_2x2.xml index 8429baa1ba..6af1753555 100644 --- a/ci-scripts/xml_files/gnb_phytest_rfemulator_run_100_2x2.xml +++ b/ci-scripts/xml_files/gnb_phytest_rfemulator_run_100_2x2.xml @@ -60,7 +60,7 @@ true Terminate gNB - nr-softmodem=ContainsString=Bye. + nr-softmodem=EndsWithBye diff --git a/ci-scripts/xml_files/gnb_phytest_usrp_run.xml b/ci-scripts/xml_files/gnb_phytest_usrp_run.xml index f2ad827d29..fcc88f9c04 100644 --- a/ci-scripts/xml_files/gnb_phytest_usrp_run.xml +++ b/ci-scripts/xml_files/gnb_phytest_usrp_run.xml @@ -58,6 +58,9 @@ true Terminate gNB caracal + + nr-softmodem=EndsWithBye + diff --git a/ci-scripts/xml_files/gnb_phytest_usrp_run_100_2x2.xml b/ci-scripts/xml_files/gnb_phytest_usrp_run_100_2x2.xml index d298873582..a4b57f0942 100644 --- a/ci-scripts/xml_files/gnb_phytest_usrp_run_100_2x2.xml +++ b/ci-scripts/xml_files/gnb_phytest_usrp_run_100_2x2.xml @@ -58,6 +58,9 @@ true Terminate gNB caracal + + nr-softmodem=EndsWithBye + diff --git a/ci-scripts/xml_files/gnb_phytest_usrp_run_60.xml b/ci-scripts/xml_files/gnb_phytest_usrp_run_60.xml index 7354fa3596..098e881248 100644 --- a/ci-scripts/xml_files/gnb_phytest_usrp_run_60.xml +++ b/ci-scripts/xml_files/gnb_phytest_usrp_run_60.xml @@ -58,6 +58,9 @@ true Terminate gNB caracal + + nr-softmodem=EndsWithBye + diff --git a/ci-scripts/xml_files/gnb_phytest_usrp_run_60_2x2.xml b/ci-scripts/xml_files/gnb_phytest_usrp_run_60_2x2.xml index 7dd50ca83f..0075201dcf 100644 --- a/ci-scripts/xml_files/gnb_phytest_usrp_run_60_2x2.xml +++ b/ci-scripts/xml_files/gnb_phytest_usrp_run_60_2x2.xml @@ -58,6 +58,9 @@ true Terminate gNB caracal + + nr-softmodem=EndsWithBye + From 378d3a7a6b79163efc1404e88ed393ccc8b64cce Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 22 Jan 2026 07:54:42 +0100 Subject: [PATCH 78/83] Add AnalyzeRTStatsObject() XML step --- ci-scripts/cls_containerize.py | 20 ++++++++++++++++++++ ci-scripts/main.py | 4 ++++ ci-scripts/xml_class_list.yml | 1 + 3 files changed, 25 insertions(+) diff --git a/ci-scripts/cls_containerize.py b/ci-scripts/cls_containerize.py index e21cb3771b..86ee1c2dff 100644 --- a/ci-scripts/cls_containerize.py +++ b/ci-scripts/cls_containerize.py @@ -782,3 +782,23 @@ class Containerize(): else: logging.error('\u001B[1m Undeploying objects Failed\u001B[0m') return success + + def AnalyzeRTStatsObject(self, HTML, node, ctx, thresholds): + logging.info(f'Analyzing realtime stats from server: {node}') + yaml = self.yamlPath.strip('/') + wd = f'{self.eNBSourceCodePath}/{yaml}' + wd_yaml = f'{wd}/docker-compose.y*ml' + + with cls_cmd.getConnection(node) as cmd: + services = GetDeployedServices(cmd, wd_yaml) + s, _ = services[0] # we simply assume something is deployed, if not Exception will report + # similar to BuildRunTests(), use docker cp to avoid problems with permissions + cmd.run(f'docker compose -f {wd_yaml} cp {s}:/opt/oai-gnb/nrL1_stats.log {wd}/') + l1_file = archiveArtifact(cmd, ctx, f"{wd}/nrL1_stats.log") + cmd.run(f'docker compose -f {wd_yaml} cp {s}:/opt/oai-gnb/nrMAC_stats.log {wd}/') + mac_file = archiveArtifact(cmd, ctx, f"{wd}/nrMAC_stats.log") + + logging.info(f"check against thresholds from {thresholds}") + success, datalog_rt_stats = cls_analysis.Analysis.analyze_rt_stats(thresholds, l1_file, mac_file) + HTML.CreateHtmlDataLogTable(datalog_rt_stats) + return success diff --git a/ci-scripts/main.py b/ci-scripts/main.py index 3b40941b91..9e1401fcf0 100644 --- a/ci-scripts/main.py +++ b/ci-scripts/main.py @@ -257,6 +257,10 @@ def ExecuteActionWithParam(action, ctx, node): yaml = test.findtext('stats_cfg') success = RAN.AnalyzeRTStats(HTML, node, ctx, yaml) + elif action == 'AnalyzeRTStats_Object': + yaml = test.findtext('stats_cfg') + success = CONTAINERS.AnalyzeRTStatsObject(HTML, node, ctx, yaml) + else: logging.warning(f"unknown action {action}, skip step") success = True # by default, we skip the step and print a warning diff --git a/ci-scripts/xml_class_list.yml b/ci-scripts/xml_class_list.yml index 7dba0d247a..2fd2787cfd 100755 --- a/ci-scripts/xml_class_list.yml +++ b/ci-scripts/xml_class_list.yml @@ -33,3 +33,4 @@ - Custom_Script - Create_Workspace - AnalyzeRTStats + - AnalyzeRTStats_Object From af19e6bce8321762d8fbd1c849f48aa28095555e Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 26 Feb 2026 16:51:53 +0100 Subject: [PATCH 79/83] Fix dl_absoluteFrequencyPointA in config file Analogously to other files under ci-scripts/. --- .../GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.24PRB.usrpb210.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.24PRB.usrpb210.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.24PRB.usrpb210.conf index 63c63bd80e..0aba023571 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.24PRB.usrpb210.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.24PRB.usrpb210.conf @@ -31,7 +31,7 @@ gNBs = absoluteFrequencySSB = 640320; dl_frequencyBand = 78; # this is 3600 MHz - dl_absoluteFrequencyPointA = 640000; + dl_absoluteFrequencyPointA = 640032; #scs-SpecificCarrierList dl_offstToCarrier = 0; # subcarrierSpacing From 0a437db57c9d53b874c9ec782d97d5556b30af75 Mon Sep 17 00:00:00 2001 From: Jaroslava Fiedlerova Date: Mon, 9 Feb 2026 14:31:16 +0000 Subject: [PATCH 80/83] CI: Add physim tests with CUDA channel simulation --- .../docker/Dockerfile.physim.cuda.ubuntu | 52 +++++++++++++++++++ .../docker-build-and-deploy-physims-cuda.sh | 46 ++++++++++++++++ .../test_physim_cuda_gracehopper.xml | 43 +++++++++++++++ openair1/SIMULATION/tests/CMakeLists.txt | 16 ++++++ 4 files changed, 157 insertions(+) create mode 100644 ci-scripts/docker/Dockerfile.physim.cuda.ubuntu create mode 100755 ci-scripts/scripts/docker-build-and-deploy-physims-cuda.sh create mode 100644 ci-scripts/xml_files/test_physim_cuda_gracehopper.xml diff --git a/ci-scripts/docker/Dockerfile.physim.cuda.ubuntu b/ci-scripts/docker/Dockerfile.physim.cuda.ubuntu new file mode 100644 index 0000000000..264938acd9 --- /dev/null +++ b/ci-scripts/docker/Dockerfile.physim.cuda.ubuntu @@ -0,0 +1,52 @@ +#/* +# * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more +# * contributor license agreements. See the NOTICE file distributed with +# * this work for additional information regarding copyright ownership. +# * The OpenAirInterface Software Alliance licenses this file to You under +# * the OAI Public License, Version 1.1 (the "License"); you may not use this file +# * except in compliance with the License. +# * You may obtain a copy of the License at +# * +# * http://www.openairinterface.org/?page_id=698 +# * +# * Unless required by applicable law or agreed to in writing, software +# * distributed under the License is distributed on an "AS IS" BASIS, +# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# * See the License for the specific language governing permissions and +# * limitations under the License. +# *------------------------------------------------------------------------------- +# * For more information about the OpenAirInterface (OAI) Software Alliance: +# * contact@openairinterface.org +# */ +#--------------------------------------------------------------------- +# +# Dockerfile for the Open-Air-Interface BUILD service +# Valid for Ubuntu 24.04 +# +#--------------------------------------------------------------------- +FROM nvidia/cuda:12.9.1-devel-ubuntu22.04 AS cuda-image +FROM ran-base:develop AS ran-tests + +RUN rm -Rf /oai-ran +COPY --from=cuda-image /usr/local/cuda/ /usr/local/cuda/ + +# Set the LD_LIBRARY_PATH to ensure the system can find the copied libraries. +# This is crucial for applications that use CUDA. +ENV LD_LIBRARY_PATH=/usr/local/cuda/lib64:/usr/local/cuda/targets/sbsa-linux/lib +ENV PATH=/usr/local/cuda/bin:$PATH +ENV C_INCLUDE_PATH=/usr/local/cuda/include + +WORKDIR /oai-ran +COPY . . + +WORKDIR /oai-ran/build +RUN cmake -GNinja -DENABLE_PHYSIM_TESTS=ON -DENABLE_TESTS=ON \ + -DSANITIZE_UNDEFINED=OFF -DSANITIZE_ADDRESS=OFF \ + -DCMAKE_C_FLAGS=-Werror -DCMAKE_CXX_FLAGS=-Werror \ + -DPHYSIM_CHECK_FILES="ThresholdsCuda.cmake" \ + -DCUDA_ENABLE=ON \ + -DUSE_UNIFIED_MEMORY=ON \ + -DUSE_ATS_MEMORY=OFF \ + -DCMAKE_RUNTIME_OUTPUT_DIRECTORY=/oai-ran/cmake_targets/ran_build/build \ + .. && \ + ninja nr_ulsim nr_dlsim diff --git a/ci-scripts/scripts/docker-build-and-deploy-physims-cuda.sh b/ci-scripts/scripts/docker-build-and-deploy-physims-cuda.sh new file mode 100755 index 0000000000..e112d8fc0d --- /dev/null +++ b/ci-scripts/scripts/docker-build-and-deploy-physims-cuda.sh @@ -0,0 +1,46 @@ +#!/bin/bash + +function die() { echo $@; exit 1; } +[ $# -ge 1 ] || die "usage: $0 [ctest-options]" + +IMAGE=ran-physimtests:ci-temp +CONTAINER=ran-physimtests +function cleanup-docker() { + docker stop ${CONTAINER} + docker rm ${CONTAINER} + docker rmi ${IMAGE} + docker volume prune --force +} +trap cleanup-docker EXIT + +set -x +DIR=$1 +RESULT_DIR=${DIR}/ +shift +CTEST_OPT=$@ + +# build physims +docker build --progress=plain --tag ${IMAGE} --file ${DIR}/ci-scripts/docker/Dockerfile.physim.cuda.ubuntu ${DIR} &>> ${RESULT_DIR}/physim_log.txt +if [ $? -ne 0 ]; then + echo "build of physims failed" + exit 1 +fi + +# get a JSON description of all tests to run +docker run -a STDOUT --workdir /oai-ran/build/ --env LD_LIBRARY_PATH=/oai-ran/build/ --rm --name ${CONTAINER} ${IMAGE} ctest ${CTEST_OPT} --show-only=json-v1 &> ${RESULT_DIR}/desc-tests.json +JSON_RES=$? + +# run the actual tests: we don't suppy --rm as we have to copy the files +# similar to unit tests, we can't mount the file where we write physims-5g-run.xml to +# as it would write a file as root, but this script is run as a normal user +docker run -a STDOUT --gpus all --workdir /oai-ran/build/ --env LD_LIBRARY_PATH=/oai-ran/build/ --name ${CONTAINER} ${IMAGE} ctest ${CTEST_OPT} --output-junit results-run.xml --test-output-size-passed 100000 --test-output-size-failed 100000 &>> ${RESULT_DIR}/physim_log.txt +RUN_RES=$? +docker cp ${CONTAINER}:/oai-ran/build/results-run.xml ${RESULT_DIR}/ +docker cp ${CONTAINER}:/oai-ran/build/Testing/Temporary/LastTestsFailed.log ${RESULT_DIR}/ +docker cp ${CONTAINER}:/oai-ran/build/Testing/Temporary/LastTest.log ${RESULT_DIR}/ + +# if both were successful, return 0 +# TODO not sure +#[[ $JSON_RES -eq 0 && $RUN_RES -eq 0 ]] && exit 0 + +exit 0 diff --git a/ci-scripts/xml_files/test_physim_cuda_gracehopper.xml b/ci-scripts/xml_files/test_physim_cuda_gracehopper.xml new file mode 100644 index 0000000000..047ec0abcf --- /dev/null +++ b/ci-scripts/xml_files/test_physim_cuda_gracehopper.xml @@ -0,0 +1,43 @@ + + + physim-tab + PhySim + wrench + + + Create_Workspace + Create new Workspace + localhost + + + + Build_Deploy_PhySim + Build and Deploy Physims with CUDA Channel Simulation + + localhost + -R cuda.5g.physims + + + + diff --git a/openair1/SIMULATION/tests/CMakeLists.txt b/openair1/SIMULATION/tests/CMakeLists.txt index afd7dcffd5..78e7ef9995 100644 --- a/openair1/SIMULATION/tests/CMakeLists.txt +++ b/openair1/SIMULATION/tests/CMakeLists.txt @@ -485,6 +485,22 @@ add_physim_test(cuda.5g.channelsim.test_channel_scalability.test55 "16 channels add_physim_test(cuda.5g.channelsim.test_channel_scalability.test56 "16 channels 61440 samples long channel 2T8R Stream" test_channel_scalability -c 16 -t 2 -r 8 -s 61440 -l 128 -m stream -n 12) add_physim_test(cuda.5g.channelsim.test_channel_scalability.test57 "16 channels 61440 samples long channel 2T8R Serial" test_channel_scalability -c 16 -t 2 -r 8 -s 61440 -l 128 -m serial -n 12) +add_physim_test(cuda.5g.physims.nr_dlsim.test1 "SNR = 30, MCS = 25, 106 PRBs, 1 layer, TDL-A channel, GPU channel simulation" nr_dlsim -n500 -s30 -S30.2 -e25 -b106 -R273 -X 8,9,10,11,12 -P -g A -t 85 -f cuda) +add_physim_test(cuda.5g.physims.nr_dlsim.test2 "SNR = 30, MCS = 25, 106 PRBs, 2 layers, TDL-A channel, GPU channel simulation" nr_dlsim -n500 -s30 -S30.2 -e25 -b106 -R273 -X 8,9,10,11,12 -P -g A -t 49 -f cuda -x2 -z2 -y2) +add_physim_test(cuda.5g.physims.nr_dlsim.test3 "SNR = 30, MCS = 25, 106 PRBs, 2 layers, 4 antennas, TDL-A channel, GPU channel simulation" nr_dlsim -n500 -s30 -S30.2 -e25 -b106 -R273 -X 8,9,10,11,12 -P -g A -t 95 -f cuda -x2 -z4 -y4) +add_physim_test(cuda.5g.physims.nr_dlsim.test4 "SNR = 30, MCS = 25, 273 PRBs, 2 layers, TDL-A channel, GPU channel simulation" nr_dlsim -n500 -s30 -S30.2 -e25 -b273 -R273 -X 8,9,10,11,12 -P -g A -t 32 -f cuda -x2 -z2 -y2) +add_physim_test(cuda.5g.physims.nr_dlsim.test5 "SNR = 30, MCS = 25, 273 PRBs, 2 layers, 4 antennas, TDL-A channel, GPU channel simulation" nr_dlsim -n500 -s30 -S30.2 -e25 -b273 -R273 -X 8,9,10,11,12 -P -g A -t 93 -f cuda -x2 -z4 -y4) +add_physim_test(cuda.5g.physims.nr_dlsim.test6 "SNR = 30, MCS = 25, 106 PRBs, 2 layers, TDL-B channel, GPU channel simulation" nr_dlsim -n500 -s30 -S30.2 -e25 -b106 -R273 -X 8,9,10,11,12 -P -g B -t 43 -f cuda -x2 -z2 -y2) +add_physim_test(cuda.5g.physims.nr_dlsim.test7 "SNR = 30, MCS = 25, 106 PRBs, 2 layers, 4 antennas, TDL-B channel, GPU channel simulation" nr_dlsim -n500 -s30 -S30.2 -e25 -b106 -R273 -X 8,9,10,11,12 -P -g B -t 95 -f cuda -x2 -z4 -y4) +add_physim_test(cuda.5g.physims.nr_dlsim.test8 "SNR = 30, MCS = 25, 273 PRBs, 2 layers, TDL-B channel, GPU channel simulation" nr_dlsim -n500 -s30 -S30.2 -e25 -b273 -R273 -X 8,9,10,11,12 -P -g B -t 32 -f cuda -x2 -z2 -y2) +add_physim_test(cuda.5g.physims.nr_dlsim.test9 "SNR = 30, MCS = 25, 273 PRBs, 2 layers, 4 antennas, TDL-B channel, GPU channel simulation" nr_dlsim -n500 -s30 -S30.2 -e25 -b273 -R273 -X 8,9,10,11,12 -P -g B -t 94 -f cuda -x2 -z4 -y4) + +add_physim_test(cuda.5g.physims.nr_ulsim.test1 "SNR = 30, MCS = 25, 106 PRBs, 1 layer, TDL-A channel, GPU channel simulation" nr_ulsim -n500 -s30 -S30 -m25 -r106 -R106 -C10 -P -g A -t 84 -f cuda) +add_physim_test(cuda.5g.physims.nr_ulsim.test2 "SNR = 30, MCS = 25, 106 PRBs, 2 layers, TDL-A channel, GPU channel simulation" nr_ulsim -n500 -s30 -S30 -m25 -r106 -R106 -C10 -P -g A -t 90 -f cuda -W2 -z2 -y2) +add_physim_test(cuda.5g.physims.nr_ulsim.test3 "SNR = 30, MCS = 25, 273 PRBs, 2 layers, TDL-A channel, GPU channel simulation" nr_ulsim -n500 -s30 -S30 -m25 -r273 -R273 -C10 -P -g A -t 83 -f cuda -W2 -z2 -y2) +add_physim_test(cuda.5g.physims.nr_ulsim.test4 "SNR = 30, MCS = 25, 106 PRBs, 2 layers, TDL-B channel, GPU channel simulation" nr_ulsim -n500 -s30 -S30 -m25 -r106 -R106 -C10 -P -g B -t 78 -f cuda -W2 -z2 -y2) +add_physim_test(cuda.5g.physims.nr_ulsim.test5 "SNR = 30, MCS = 25, 273 PRBs, 2 layers, TDL-B channel, GPU channel simulation" nr_ulsim -n500 -s30 -S30 -m25 -r273 -R273 -C10 -P -g B -t 63 -f cuda -W2 -z2 -y2) + endif() if(PHYSIM_CHECK_FILES) From a77ba75b102f0c6df50bf7f371280b1056cd6818 Mon Sep 17 00:00:00 2001 From: Mario Joa-Ng Date: Tue, 17 Feb 2026 08:51:00 -0500 Subject: [PATCH 81/83] Configure CSI-RS according to beam_id used by UE and reconfigure upon beam change. No need to call get_config_srs() anymore in update_cellGroupConfig_for_BWP_switch(). --- openair1/SIMULATION/NR_PHY/dlsim.c | 3 +- openair1/SIMULATION/NR_PHY/ulsim.c | 3 +- openair2/LAYER2/NR_MAC_gNB/config.c | 2 +- .../NR_MAC_gNB/gNB_scheduler_primitives.c | 56 ++++++++++------ .../LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c | 6 +- .../LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c | 10 +-- openair2/LAYER2/NR_MAC_gNB/mac_proto.h | 5 +- .../LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c | 5 +- openair2/LAYER2/NR_MAC_gNB/nr_radio_config.c | 64 +++++++++++++++---- openair2/LAYER2/NR_MAC_gNB/nr_radio_config.h | 16 ++++- 10 files changed, 122 insertions(+), 48 deletions(-) diff --git a/openair1/SIMULATION/NR_PHY/dlsim.c b/openair1/SIMULATION/NR_PHY/dlsim.c index f1461bc25d..2a77629c07 100644 --- a/openair1/SIMULATION/NR_PHY/dlsim.c +++ b/openair1/SIMULATION/NR_PHY/dlsim.c @@ -814,7 +814,8 @@ int main(int argc, char **argv) prepare_sim_uecap(UE_Capability_nr, scc, mu, N_RB_DL, g_mcsTableIdx, 0); rnti_t rnti = 0x1234; int uid = 0; - NR_CellGroupConfig_t *secondaryCellGroup = get_default_secondaryCellGroup(scc, UE_Capability_nr, 0, 1, &conf, uid); + int ssb_index = 0; + NR_CellGroupConfig_t *secondaryCellGroup = get_default_secondaryCellGroup(scc, UE_Capability_nr, 0, 1, &conf, uid, ssb_index); secondaryCellGroup->spCellConfig->reconfigurationWithSync = get_reconfiguration_with_sync(rnti, uid, scc, frame); /* -U option modify DMRS */ diff --git a/openair1/SIMULATION/NR_PHY/ulsim.c b/openair1/SIMULATION/NR_PHY/ulsim.c index e545d6cba2..0fb660b6a1 100644 --- a/openair1/SIMULATION/NR_PHY/ulsim.c +++ b/openair1/SIMULATION/NR_PHY/ulsim.c @@ -821,7 +821,8 @@ int main(int argc, char *argv[]) prepare_sim_uecap(UE_Capability_nr, scc, mu, N_RB_UL, 0, mcs_table); rnti_t rnti = 0x1234; int uid = 0; - NR_CellGroupConfig_t *secondaryCellGroup = get_default_secondaryCellGroup(scc, UE_Capability_nr, 0, 1, &conf, uid); + int ssb_index = 0; + NR_CellGroupConfig_t *secondaryCellGroup = get_default_secondaryCellGroup(scc, UE_Capability_nr, 0, 1, &conf, uid, ssb_index); secondaryCellGroup->spCellConfig->reconfigurationWithSync = get_reconfiguration_with_sync(rnti, uid, scc, frame); NR_BCCH_BCH_Message_t *mib = get_new_MIB_NR(scc); diff --git a/openair2/LAYER2/NR_MAC_gNB/config.c b/openair2/LAYER2/NR_MAC_gNB/config.c index 005ad05720..7f9fde3317 100644 --- a/openair2/LAYER2/NR_MAC_gNB/config.c +++ b/openair2/LAYER2/NR_MAC_gNB/config.c @@ -1079,7 +1079,7 @@ bool nr_trigger_bwp_switch(uint16_t rnti, int bwp_id) } else if (UE->current_DL_BWP.bwp_id == bwp_id) { LOG_W(NR_MAC, "UE %04x is already on BWP ID %d, not triggering reconfiguration\n", rnti, bwp_id); } else { // UE != NULL && current_DL_BWP.bwp_id != bwp_id - nr_mac_trigger_reconfiguration(nrmac, UE, bwp_id); + nr_mac_trigger_reconfiguration(nrmac, UE, bwp_id, false); success = true; } NR_SCHED_UNLOCK(&nrmac->sched_lock); diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c index 7742b06294..11c20aa1b2 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c @@ -3568,10 +3568,11 @@ void nr_mac_release_ue(gNB_MAC_INST *mac, int rnti) mac_remove_nr_ue(mac, rnti); } -static void beam_switching_procedure(NR_UE_info_t *UE, int new_beam_index) +void beam_switching_procedure(gNB_MAC_INST *mac, NR_UE_info_t *UE, int new_beam_index) { LOG_I(NR_MAC, "[UE %x] Switching to beam with ID %d (from %d)\n", UE->rnti, new_beam_index, UE->UE_beam_index); UE->UE_beam_index = new_beam_index; + nr_mac_trigger_reconfiguration(mac, UE, -1, true); } void nr_mac_update_timers(module_id_t module_id, frame_t frame, slot_t slot) @@ -3614,7 +3615,7 @@ void nr_mac_update_timers(module_id_t module_id, frame_t frame, slot_t slot) } if (nr_timer_tick(&sched_ctrl->tci_beam_switch)) { nr_timer_stop(&sched_ctrl->tci_beam_switch); - beam_switching_procedure(UE, sched_ctrl->UE_mac_ce_ctrl.tci_state_ind.tciStateId); + beam_switching_procedure(mac, UE, sched_ctrl->UE_mac_ce_ctrl.tci_state_ind.tciStateId); } } } @@ -3742,20 +3743,20 @@ void reset_beam_status(NR_beam_info_t *beam_info, int frame, int slot, int16_t b } } -void beam_selection_procedures(gNB_MAC_INST *mac, NR_UE_info_t *UE) +int beam_selection_procedures(gNB_MAC_INST *mac, NR_UE_info_t *UE) { // do not perform beam procedures if there is no beam information if (mac->beam_info.beam_mode == NO_BEAM_MODE) - return; + return -1; // simple beam switching algorithm -> we select beam with highest RSRP from CSI report NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; RSRP_report_t *rsrp_report = &sched_ctrl->CSI_report.ssb_rsrp_report; int new_bf_index = get_beam_from_ssbidx(mac, rsrp_report->resource_id[0]); if (!mac->radio_config.do_TCI) { // if not TCI is configure we switch beam directly - if (UE->UE_beam_index != new_bf_index) - beam_switching_procedure(UE, new_bf_index); - return; + if (UE->UE_beam_index == new_bf_index) + return -1; // no beam change needed + return new_bf_index; } tciStateInd_t *tci = &sched_ctrl->UE_mac_ce_ctrl.tci_state_ind; @@ -3764,7 +3765,7 @@ void beam_selection_procedures(gNB_MAC_INST *mac, NR_UE_info_t *UE) LOG_I(NR_MAC, "[UE %x] Stopping procedure to switch beam, old beam reported as best again\n", UE->rnti); tci->is_scheduled = false; } - return; // no beam change needed + return -1; // no beam change needed } LOG_I(NR_MAC, "[UE %x] Starting procedure to switch beam\n", UE->rnti); @@ -3774,6 +3775,7 @@ void beam_selection_procedures(gNB_MAC_INST *mac, NR_UE_info_t *UE) tci->is_scheduled = true; tci->coresetId = sched_ctrl->coreset->controlResourceSetId; tci->tciStateId = new_bf_index; // assumption: this correspond to the TCI index + return new_bf_index; } void send_initial_ul_rrc_message(int rnti, const uint8_t *sdu, sdu_size_t sdu_len, void *data) @@ -3827,7 +3829,9 @@ bool prepare_initial_ul_rrc_message(gNB_MAC_INST *mac, NR_UE_info_t *UE) int CC_id = 0; int srb_id = 1; const NR_ServingCellConfigCommon_t *scc = mac->common_channels[CC_id].ServingCellConfigCommon; - NR_CellGroupConfig_t *cellGroupConfig = get_initial_cellGroupConfig(UE->uid, scc, &mac->radio_config, &mac->rlc_config); + NR_COMMON_channels_t *cc = &mac->common_channels[CC_id]; + int ssb_index = cc->ssb_index[UE->UE_beam_index]; + NR_CellGroupConfig_t *cellGroupConfig = get_initial_cellGroupConfig(UE->uid, scc, &mac->radio_config, &mac->rlc_config, ssb_index); ASN_STRUCT_FREE(asn_DEF_NR_CellGroupConfig, UE->CellGroup); UE->CellGroup = cellGroupConfig; UE->local_bwp_id = mac->radio_config.first_active_bwp; @@ -3953,24 +3957,40 @@ static bool verify_bwp_switch(const NR_UE_info_t *UE, const nr_mac_config_t *con return false; } -void nr_mac_trigger_reconfiguration(const gNB_MAC_INST *nrmac, NR_UE_info_t *UE, int new_bwp_id) +void nr_mac_trigger_reconfiguration(const gNB_MAC_INST *nrmac, NR_UE_info_t *UE, int new_bwp_id, bool new_beam) { DevAssert(UE->CellGroup != NULL); NR_CellGroupConfig_t *cellGroup_for_UE = NULL; - if (new_bwp_id >= 0) { - AssertFatal(UE->current_DL_BWP.bwp_id == UE->current_UL_BWP.bwp_id, "We only support same BWP for UL and DL\n"); - if (!verify_bwp_switch(UE, &nrmac->radio_config, new_bwp_id)) - return; - else { + if (new_beam) { UE->sc_info.csi_MeasConfig = NULL; // to avoid segfault when freeing csi_MeasConfig in configDedicated - UE->local_bwp_id = new_bwp_id; - cellGroup_for_UE = update_cellGroupConfig_for_BWP_switch(UE->CellGroup, + NR_UE_UL_BWP_t *current_BWP = &UE->current_UL_BWP; + current_BWP->srs_Config = NULL; + int ssb_index = nrmac->common_channels[0].ssb_index[UE->UE_beam_index]; + cellGroup_for_UE = update_cellGroupConfig_for_beam_switch(UE->CellGroup, &nrmac->radio_config, UE->capability, nrmac->common_channels[0].ServingCellConfigCommon, UE->uid, UE->current_DL_BWP.bwp_id, - new_bwp_id); + ssb_index); + } else { + if (new_bwp_id >= 0) { + AssertFatal(UE->current_DL_BWP.bwp_id == UE->current_UL_BWP.bwp_id, "We only support same BWP for UL and DL\n"); + if (!verify_bwp_switch(UE, &nrmac->radio_config, new_bwp_id)) + return; + else { + UE->sc_info.csi_MeasConfig = NULL; // to avoid segfault when freeing csi_MeasConfig in configDedicated + UE->local_bwp_id = new_bwp_id; + int ssb_index = nrmac->common_channels[0].ssb_index[UE->UE_beam_index]; + cellGroup_for_UE = update_cellGroupConfig_for_BWP_switch(UE->CellGroup, + &nrmac->radio_config, + UE->capability, + nrmac->common_channels[0].ServingCellConfigCommon, + UE->uid, + UE->current_DL_BWP.bwp_id, + new_bwp_id, + ssb_index); + } } } uint8_t buf[2048]; diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c index ac0803e1e3..40bcc56ae3 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c @@ -757,6 +757,7 @@ static void extract_pucch_csi_report(NR_CSI_MeasConfig_t *csi_MeasConfig, const int n_slots_frame = nrmac->frame_structure.numb_slots_frame; int cumul_bits = 0; int r_index = -1; + int new_bf_index = -1; for (int csi_report_id = 0; csi_report_id < csi_MeasConfig->csi_ReportConfigToAddModList->list.count; csi_report_id++) { nr_csi_report_t *csi_report = &UE->csi_report_template[csi_report_id]; csi_report->nb_of_csi_ssb_report = 0; @@ -793,7 +794,7 @@ static void extract_pucch_csi_report(NR_CSI_MeasConfig_t *csi_MeasConfig, break; case NR_CSI_ReportConfig__reportQuantity_PR_ssb_Index_RSRP: evaluate_rsrp_report(nrmac, UE, sched_ctrl, csi_report_id, payload, &cumul_bits, reportQuantity_type); - beam_selection_procedures(nrmac, UE); + new_bf_index = beam_selection_procedures(nrmac, UE); break; case NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_CQI: sched_ctrl->CSI_report.cri_ri_li_pmi_cqi_report.print_report = true; @@ -851,6 +852,9 @@ static void extract_pucch_csi_report(NR_CSI_MeasConfig_t *csi_MeasConfig, } } } + if ((new_bf_index !=-1) && !nrmac->radio_config.do_TCI) + // Trigger RRCReconfiguration. Need to be out of the for loop as it may modify csi_MeasConfig + beam_switching_procedure(nrmac, UE, new_bf_index); } static NR_UE_harq_t *find_harq(frame_t frame, slot_t slot, NR_UE_info_t * UE, int harq_round_max) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c index 3282c4a483..481c0ea9f8 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c @@ -879,7 +879,7 @@ static void nr_rx_ra_sdu(const module_id_t mod_id, if (!old_UE->reconfigCellGroup) { LOG_I(NR_MAC, "Received UL_SCH_LCID_C_RNTI with C-RNTI 0x%04x, triggering RRC Reconfiguration\n", crnti); // Trigger RRCReconfiguration - nr_mac_trigger_reconfiguration(mac, old_UE, -1); + nr_mac_trigger_reconfiguration(mac, old_UE, -1, false); // we configure the UE using common search space with DCIX0 while waiting for a reconfiguration configure_UE_BWP(mac, scc, old_UE, false, NR_SearchSpace__searchSpaceType_PR_common, -1, -1); } @@ -1994,13 +1994,13 @@ static int pf_ul(gNB_MAC_INST *nrmac, NR_beam_alloc_t dci_beam = beam_allocation_procedure(&nrmac->beam_info, frame, slot, UE->UE_beam_index, slots_per_frame); if (dci_beam.idx < 0) { - LOG_D(NR_MAC, "[UE %04x][%4d.%2d] Beam could not be allocated\n", UE->rnti, frame, slot); + LOG_D(NR_MAC, "[UE %04x][%4d.%2d] ULSCH DCI Beam could not be allocated\n", UE->rnti, frame, slot); continue; } NR_beam_alloc_t beam = beam_allocation_procedure(&nrmac->beam_info, sched_frame, sched_slot, UE->UE_beam_index, slots_per_frame); if (beam.idx < 0) { - LOG_D(NR_MAC, "[UE %04x][%4d.%2d] Beam could not be allocated\n", UE->rnti, frame, slot); + LOG_D(NR_MAC, "[UE %04x][%4d.%2d] ULSCH Beam could not be allocated\n", UE->rnti, frame, slot); reset_beam_status(&nrmac->beam_info, frame, slot, UE->UE_beam_index, slots_per_frame, dci_beam.new_beam); continue; } @@ -2119,7 +2119,7 @@ static int pf_ul(gNB_MAC_INST *nrmac, NR_beam_alloc_t beam = beam_allocation_procedure(&nrmac->beam_info, sched_frame, sched_slot, iterator->UE->UE_beam_index, slots_per_frame); if (beam.idx < 0) { - LOG_D(NR_MAC, "[UE %04x][%4d.%2d] Beam could not be allocated\n", iterator->UE->rnti, frame, slot); + LOG_D(NR_MAC, "[UE %04x][%4d.%2d] ULSCH Beam could not be allocated\n", iterator->UE->rnti, sched_frame, sched_slot); iterator++; continue; } @@ -2132,7 +2132,7 @@ static int pf_ul(gNB_MAC_INST *nrmac, NR_beam_alloc_t dci_beam = beam_allocation_procedure(&nrmac->beam_info, frame, slot, iterator->UE->UE_beam_index, slots_per_frame); if (dci_beam.idx < 0) { - LOG_D(NR_MAC, "[UE %04x][%4d.%2d] Beam could not be allocated\n", iterator->UE->rnti, frame, slot); + LOG_D(NR_MAC, "[UE %04x][%4d.%2d] ULSCH DCI Beam could not be allocated\n", iterator->UE->rnti, frame, slot); reset_beam_status(&nrmac->beam_info, sched_frame, sched_slot, iterator->UE->UE_beam_index, slots_per_frame, beam.new_beam); iterator++; continue; diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h index efcabbc98a..e616c4a49c 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h @@ -455,7 +455,8 @@ int16_t get_allocated_beam(const NR_beam_info_t *beam_info, int frame, int slot, uint16_t convert_to_fapi_beam(const uint16_t beam_idx, const nr_beam_mode_t mode); NR_beam_alloc_t beam_allocation_procedure(NR_beam_info_t *beam_info, int frame, int slot, int16_t beam_index, int slots_per_frame); void reset_beam_status(NR_beam_info_t *beam_info, int frame, int slot, int16_t beam_index, int slots_per_frame, bool new_beam); -void beam_selection_procedures(gNB_MAC_INST *mac, NR_UE_info_t *UE); +int beam_selection_procedures(gNB_MAC_INST *mac, NR_UE_info_t *UE); +void beam_switching_procedure(gNB_MAC_INST *mac, NR_UE_info_t *UE, int new_beam_index); void nr_sr_reporting(gNB_MAC_INST *nrmac, frame_t frameP, slot_t slotP); bwp_info_t get_pdsch_bwp_start_size(gNB_MAC_INST *nr_mac, NR_UE_info_t *UE); bwp_info_t get_pusch_bwp_start_size(NR_UE_info_t *UE); @@ -483,7 +484,7 @@ void nr_mac_trigger_ul_failure(NR_UE_sched_ctrl_t *sched_ctrl, NR_SubcarrierSpac void nr_mac_reset_ul_failure(NR_UE_sched_ctrl_t *sched_ctrl); bool nr_mac_check_ul_failure(gNB_MAC_INST *nrmac, int rnti, NR_UE_sched_ctrl_t *sched_ctrl); -void nr_mac_trigger_reconfiguration(const gNB_MAC_INST *nrmac, NR_UE_info_t *UE, int new_bwp_id); +void nr_mac_trigger_reconfiguration(const gNB_MAC_INST *nrmac, NR_UE_info_t *UE, int new_bwp_id, bool new_beam); bool nr_mac_add_lcid(NR_UE_sched_ctrl_t *sched_ctrl, const nr_lc_config_t *c); nr_lc_config_t *nr_mac_get_lc_config(NR_UE_sched_ctrl_t* sched_ctrl, int lcid); diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c index 7229b98fd0..9ced91c26b 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c +++ b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c @@ -567,12 +567,13 @@ static NR_UE_info_t *create_new_UE(gNB_MAC_INST *mac, uint32_t cu_id, const NR_C NR_COMMON_channels_t *cc = &mac->common_channels[CC_id]; const NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon; const nr_mac_config_t *configuration = &mac->radio_config; + int ssb_index = cc->ssb_index[UE->UE_beam_index]; if (is_SA) { - cellGroupConfig = get_initial_cellGroupConfig(UE->uid, scc, &mac->radio_config, &mac->rlc_config); + cellGroupConfig = get_initial_cellGroupConfig(UE->uid, scc, &mac->radio_config, &mac->rlc_config, ssb_index); cellGroupConfig->spCellConfig->reconfigurationWithSync = get_reconfiguration_with_sync(UE->rnti, UE->uid, scc, mac->frame); } else { NR_UE_NR_Capability_t *cap = get_ue_nr_cap_from_cg_config_info(cgci); - cellGroupConfig = get_default_secondaryCellGroup(scc, cap, 1, 1, configuration, UE->uid); + cellGroupConfig = get_default_secondaryCellGroup(scc, cap, 1, 1, configuration, UE->uid, ssb_index); cellGroupConfig->spCellConfig->reconfigurationWithSync = get_reconfiguration_with_sync(UE->rnti, UE->uid, scc, mac->frame); // TODO: in NSA we assign capabilities here, otherwise outside => not logic UE->capability = cap; diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_radio_config.c b/openair2/LAYER2/NR_MAC_gNB/nr_radio_config.c index fe4a64da2b..f606902baf 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_radio_config.c +++ b/openair2/LAYER2/NR_MAC_gNB/nr_radio_config.c @@ -379,7 +379,7 @@ static void set_csirs_periodicity(NR_NZP_CSI_RS_Resource_t *nzpcsi0, { nzpcsi0->periodicityAndOffset = calloc(1,sizeof(*nzpcsi0->periodicityAndOffset)); // TODO ideal period to be set according to estimation by the gNB on how fast the channel changes - const int offset = fs->numb_slots_period * id; + const int offset = id; // id = ssb_index/2, offset should be set to ssb_index/2. if (check_periodicity(4, ideal_period, fs)) { nzpcsi0->periodicityAndOffset->present = NR_CSI_ResourcePeriodicityAndOffset_PR_slots4; nzpcsi0->periodicityAndOffset->choice.slots4 = offset; @@ -3391,7 +3391,8 @@ static NR_CSI_MeasConfig_t *get_csiMeasConfig(const NR_ServingCellConfig_t *conf const nr_mac_config_t *configuration, int uid, int bwp_id, - uint64_t bitmap) + uint64_t bitmap, + int ssb_index) { NR_CSI_MeasConfig_t *csi_MeasConfig = calloc(1, sizeof(*csi_MeasConfig)); csi_MeasConfig->csi_SSB_ResourceSetToAddModList = calloc(1, sizeof(*csi_MeasConfig->csi_SSB_ResourceSetToAddModList)); @@ -3431,8 +3432,8 @@ static NR_CSI_MeasConfig_t *get_csiMeasConfig(const NR_ServingCellConfig_t *conf const int pdsch_AntennaPorts = configuration->pdsch_AntennaPorts.N1 * configuration->pdsch_AntennaPorts.N2 * configuration->pdsch_AntennaPorts.XP; - config_csirs(scc, csi_MeasConfig, pdsch_AntennaPorts, curr_bwp, configuration->do_CSIRS, bwp_id); - config_csiim(configuration->do_CSIRS, pdsch_AntennaPorts, curr_bwp, csi_MeasConfig, bwp_id); + config_csirs(scc, csi_MeasConfig, pdsch_AntennaPorts, curr_bwp, configuration->do_CSIRS, ssb_index / 2); + config_csiim(configuration->do_CSIRS, pdsch_AntennaPorts, curr_bwp, csi_MeasConfig, ssb_index / 2); NR_CSI_ResourceConfig_t *csires1 = calloc(1, sizeof(*csires1)); csires1->csi_ResourceConfigId = bwp_id + 20; @@ -3458,7 +3459,7 @@ static NR_CSI_MeasConfig_t *get_csiMeasConfig(const NR_ServingCellConfig_t *conf csires0->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB->nzp_CSI_RS_ResourceSetList = calloc(1, sizeof(*csires0->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB->nzp_CSI_RS_ResourceSetList)); NR_NZP_CSI_RS_ResourceSetId_t *nzp0 = calloc(1, sizeof(*nzp0)); - *nzp0 = bwp_id; + *nzp0 = ssb_index / 2; asn1cSeqAdd(&csires0->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB->nzp_CSI_RS_ResourceSetList->list, nzp0); csires0->bwp_Id = bwp_id; csires0->resourceType = NR_CSI_ResourceConfig__resourceType_periodic; @@ -3472,7 +3473,7 @@ static NR_CSI_MeasConfig_t *get_csiMeasConfig(const NR_ServingCellConfig_t *conf csires2->csi_RS_ResourceSetList.choice.csi_IM_ResourceSetList = calloc(1, sizeof(*csires2->csi_RS_ResourceSetList.choice.csi_IM_ResourceSetList)); NR_CSI_IM_ResourceSetId_t *csiim00 = calloc(1, sizeof(*csiim00)); - *csiim00 = bwp_id; + *csiim00 = ssb_index / 2; asn1cSeqAdd(&csires2->csi_RS_ResourceSetList.choice.csi_IM_ResourceSetList->list, csiim00); csires2->bwp_Id = bwp_id; csires2->resourceType = NR_CSI_ResourceConfig__resourceType_periodic; @@ -3509,7 +3510,8 @@ static NR_CSI_MeasConfig_t *get_csiMeasConfig(const NR_ServingCellConfig_t *conf static NR_SpCellConfig_t *get_initial_SpCellConfig(int uid, const NR_ServingCellConfigCommon_t *scc, - const nr_mac_config_t *configuration) + const nr_mac_config_t *configuration, + int ssb_index) { const int pdsch_AntennaPorts = configuration->pdsch_AntennaPorts.N1 * configuration->pdsch_AntennaPorts.N2 * configuration->pdsch_AntennaPorts.XP; @@ -3573,7 +3575,8 @@ static NR_SpCellConfig_t *get_initial_SpCellConfig(int uid, configuration, uid, first_active_bwp, - bitmap); + bitmap, + ssb_index); fill_harq_IEs(configDedicated, configuration->num_dlharq, configuration->num_ulharq, first_active_bwp); SpCellConfig->spCellConfigDedicated = configDedicated; @@ -3751,12 +3754,13 @@ static bool verify_radio_configuration(int uid, const NR_ServingCellConfigCommon NR_CellGroupConfig_t *get_initial_cellGroupConfig(int uid, const NR_ServingCellConfigCommon_t *scc, const nr_mac_config_t *configuration, - const nr_rlc_configuration_t *default_rlc_config) + const nr_rlc_configuration_t *default_rlc_config, + int ssb_index) { if (!verify_radio_configuration(uid, scc, configuration)) return NULL; - NR_SpCellConfig_t *spCellConfig = get_initial_SpCellConfig(uid, scc, configuration); + NR_SpCellConfig_t *spCellConfig = get_initial_SpCellConfig(uid, scc, configuration, ssb_index); NR_CellGroupConfig_t *cellGroupConfig = calloc(1, sizeof(*cellGroupConfig)); cellGroupConfig->cellGroupId = 0; @@ -3787,7 +3791,8 @@ NR_CellGroupConfig_t *update_cellGroupConfig_for_BWP_switch(NR_CellGroupConfig_t const NR_ServingCellConfigCommon_t *scc, int uid, int old_bwp, - int new_bwp) + int new_bwp, + int ssb_index) { NR_SpCellConfig_t *spCellConfig = cellGroupConfig->spCellConfig; NR_ServingCellConfig_t *configDedicated = spCellConfig->spCellConfigDedicated; @@ -3832,7 +3837,8 @@ NR_CellGroupConfig_t *update_cellGroupConfig_for_BWP_switch(NR_CellGroupConfig_t &local_config, uid, *uplinkConfig->firstActiveUplinkBWP_Id, - bitmap); + bitmap, + ssb_index); // we temporarily need to keep both the old and the new BWP in the CG used by the gNB // while removing the old from the CG sent to the UE @@ -3844,6 +3850,34 @@ NR_CellGroupConfig_t *update_cellGroupConfig_for_BWP_switch(NR_CellGroupConfig_t return clone_cg; } +NR_CellGroupConfig_t *update_cellGroupConfig_for_beam_switch(NR_CellGroupConfig_t *cellGroupConfig, + const nr_mac_config_t *configuration, + const NR_UE_NR_Capability_t *uecap, + const NR_ServingCellConfigCommon_t *scc, + int uid, + int bwp, + int ssb_index) +{ + NR_SpCellConfig_t *spCellConfig = cellGroupConfig->spCellConfig; + NR_ServingCellConfig_t *configDedicated = spCellConfig->spCellConfigDedicated; + + uint64_t bitmap = get_ssb_bitmap(scc); + ASN_STRUCT_FREE(asn_DEF_NR_CSI_MeasConfig, configDedicated->csi_MeasConfig->choice.setup); + configDedicated->csi_MeasConfig->choice.setup = get_csiMeasConfig(configDedicated, + uecap, + scc, + configuration, + uid, + bwp, + bitmap, + ssb_index); + + NR_CellGroupConfig_t *clone_cg = NULL; + const int copy_result = asn_copy(&asn_DEF_NR_CellGroupConfig, (void **)&clone_cg, cellGroupConfig); + AssertFatal(copy_result == 0, "unable to copy NR_CellGroupConfig for cloning\n"); + return clone_cg; +} + void update_cellGroupConfig(NR_CellGroupConfig_t *cellGroupConfig, const int uid, const NR_UE_NR_Capability_t *uecap, @@ -3983,7 +4017,8 @@ NR_CellGroupConfig_t *get_default_secondaryCellGroup(const NR_ServingCellConfigC int scg_id, int servCellIndex, const nr_mac_config_t *configuration, - int uid) + int uid, + int ssb_index) { const nr_pdsch_AntennaPorts_t *pdschap = &configuration->pdsch_AntennaPorts; const int dl_antenna_ports = pdschap->N1 * pdschap->N2 * pdschap->XP; @@ -4134,7 +4169,8 @@ NR_CellGroupConfig_t *get_default_secondaryCellGroup(const NR_ServingCellConfigC configuration, uid, firstActiveUplinkBWP_Id, - bitmap); + bitmap, + ssb_index); configDedicated->sCellDeactivationTimer = NULL; configDedicated->crossCarrierSchedulingConfig = NULL; diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_radio_config.h b/openair2/LAYER2/NR_MAC_gNB/nr_radio_config.h index e2c04aece9..edf53f24f7 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_radio_config.h +++ b/openair2/LAYER2/NR_MAC_gNB/nr_radio_config.h @@ -95,7 +95,8 @@ NR_SIB19_r17_t *get_SIB19_NR(const NR_ServingCellConfigCommon_t *scc); NR_CellGroupConfig_t *get_initial_cellGroupConfig(int uid, const NR_ServingCellConfigCommon_t *scc, const nr_mac_config_t *configuration, - const nr_rlc_configuration_t *default_rlc_config); + const nr_rlc_configuration_t *default_rlc_config, + int ssb_index); void update_cellGroupConfig(NR_CellGroupConfig_t *cellGroupConfig, const int uid, const NR_UE_NR_Capability_t *uecap, @@ -111,7 +112,8 @@ NR_CellGroupConfig_t *get_default_secondaryCellGroup(const NR_ServingCellConfigC int scg_id, int servCellIndex, const nr_mac_config_t *configuration, - int uid); + int uid, + int ssb_index); NR_ReconfigurationWithSync_t *get_reconfiguration_with_sync(rnti_t rnti, uid_t uid, const NR_ServingCellConfigCommon_t *scc, int frame); @@ -133,7 +135,15 @@ NR_CellGroupConfig_t *update_cellGroupConfig_for_BWP_switch(NR_CellGroupConfig_t const NR_ServingCellConfigCommon_t *scc, int uid, int old_bwp, - int new_bwp); + int new_bwp, + int ssb_index); +NR_CellGroupConfig_t *update_cellGroupConfig_for_beam_switch(NR_CellGroupConfig_t *cellGroupConfig, + const nr_mac_config_t *configuration, + const NR_UE_NR_Capability_t *uecap, + const NR_ServingCellConfigCommon_t *scc, + int uid, + int bwp, + int ssb_index); NR_MeasurementTimingConfiguration_t *get_nr_mtc(uint8_t *buf, uint32_t len); measgap_config_t create_measgap_config(const NR_MeasurementTimingConfiguration_t *mtc, int scs, int min_rxtxtime); int encode_measgap_config(const measgap_config_t *c, uint8_t *buf); From f51f5d1f6e5e48eb55b96074d3d645d058e556e9 Mon Sep 17 00:00:00 2001 From: Mario Joa-Ng Date: Thu, 26 Feb 2026 01:17:15 +0100 Subject: [PATCH 82/83] Get ssb_index using UE_beam_index under different beam_mode correctly. --- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c | 16 +++++++++------- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c | 3 ++- .../LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c | 15 +++++++++++---- openair2/LAYER2/NR_MAC_gNB/mac_proto.h | 2 +- openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c | 2 +- 5 files changed, 24 insertions(+), 14 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c index 8d1eda288b..99f0e9bb3c 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c @@ -756,12 +756,14 @@ void nr_initiate_ra_proc(module_id_t module_idP, LOG_A(NR_MAC, "%d.%d UE RA-RNTI %04x TC-RNTI %04x: initiating RA procedure\n", frame, slot, ra->RA_rnti, UE->rnti); - // Configure RA BWP - configure_UE_BWP(nr_mac, scc, UE, true, NR_SearchSpace__searchSpaceType_PR_common, -1, -1); - // return current SSB order in the list of tranmitted SSBs + // return current SSB order in the list of tranmitted SSBs int n_ssb = ssb_index_from_prach(module_idP, frame, slot, preamble_index, freq_index, symbol); UE->UE_beam_index = get_beam_from_ssbidx(nr_mac, cc->ssb_index[n_ssb]); LOG_I(NR_MAC, "UE %04x: Sync beam index %d\n", UE->rnti, UE->UE_beam_index); + + // Configure RA BWP + configure_UE_BWP(nr_mac, scc, UE, true, NR_SearchSpace__searchSpaceType_PR_common, -1, -1); + NR_SCHED_UNLOCK(&nr_mac->sched_lock); } @@ -1483,8 +1485,8 @@ static void nr_generate_Msg2(module_id_t module_idP, const int coresetid = coreset->controlResourceSetId; // Calculate number of symbols int time_domain_assignment = get_dl_tda(nr_mac, slotP); - - NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config = &nr_mac->type0_PDCCH_CSS_config[cc->ssb_index[UE->UE_beam_index]]; + int ssb_index = get_ssbidx_from_beam(nr_mac, UE->UE_beam_index); + NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config = &nr_mac->type0_PDCCH_CSS_config[ssb_index]; int mux_pattern = type0_PDCCH_CSS_config ? type0_PDCCH_CSS_config->type0_pdcch_ss_mux_pattern : 1; NR_tda_info_t tda_info = get_dl_tda_info(dl_bwp, ss->searchSpaceType->present, @@ -1743,9 +1745,9 @@ static void nr_generate_Msg4_MsgB(module_id_t module_idP, reset_beam_status(&nr_mac->beam_info, frameP, slotP, UE->UE_beam_index, n_slots_frame, beam.new_beam); return; } - + int ssb_index = get_ssbidx_from_beam(nr_mac, UE->UE_beam_index); uint8_t time_domain_assignment = get_dl_tda(nr_mac, slotP); - NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config = &nr_mac->type0_PDCCH_CSS_config[cc->ssb_index[UE->UE_beam_index]]; + NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config = &nr_mac->type0_PDCCH_CSS_config[ssb_index]; int mux_pattern = type0_PDCCH_CSS_config ? type0_PDCCH_CSS_config->type0_pdcch_ss_mux_pattern : 1; NR_tda_info_t msg4_tda = get_dl_tda_info(dl_bwp, ss->searchSpaceType->present, diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c index 501543e4be..e511850414 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c @@ -671,7 +671,8 @@ static void other_sib_sched_control(module_id_t module_idP, LOG_D(NR_MAC, "(%d.%d) otherSIB payload %d transmission for ssb number %d\n", frame, slot, payload_idx, beam_index); NR_COMMON_channels_t *cc = &gNB_mac->common_channels[0]; - NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config = &gNB_mac->type0_PDCCH_CSS_config[cc->ssb_index[beam_index]]; + int ssb_index = get_ssbidx_from_beam(gNB_mac, beam_index); + NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config = &gNB_mac->type0_PDCCH_CSS_config[ssb_index]; NR_PDSCH_ConfigCommon_t *pdsch_ConfigCommon = scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup; int time_domain_allocation = 1; NR_tda_info_t tda_info = set_tda_info_from_list(pdsch_ConfigCommon->pdsch_TimeDomainAllocationList, time_domain_allocation); diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c index 11c20aa1b2..884c03bd13 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c @@ -124,6 +124,15 @@ static void determine_aggregation_level_search_order(int agg_level_search_order[ static int nr_mac_interrupt_ue_transmission(gNB_MAC_INST *mac, NR_UE_info_t *UE, int slots, int slots_per_frame); +int get_ssbidx_from_beam(gNB_MAC_INST *mac, int beam_idx) +{ + for (int i = 0; i < MAX_NUM_OF_SSB; i++) + if (beam_idx == mac->beam_index_list[i]) + return i; + AssertFatal(false, "beam_idx %d not found\n", beam_idx); + return 0; +} + uint8_t get_dl_nrOfLayers(const NR_UE_sched_ctrl_t *sched_ctrl, const nr_dci_format_t dci_format) { // TODO check this but it should be enough for now @@ -2913,8 +2922,7 @@ void configure_UE_BWP(gNB_MAC_INST *nr_mac, AssertFatal(sched_ctrl->search_space != NULL, "SearchSpace cannot be null for RA\n"); sched_ctrl->coreset = get_coreset(nr_mac, scc, bwpd, *sched_ctrl->search_space->controlResourceSetId); - NR_COMMON_channels_t *cc = &nr_mac->common_channels[0]; - int ssb_index = cc->ssb_index[UE->UE_beam_index]; + int ssb_index = get_ssbidx_from_beam(nr_mac, UE->UE_beam_index); sched_ctrl->sched_pdcch = set_pdcch_structure(nr_mac, sched_ctrl->search_space, sched_ctrl->coreset, @@ -3829,8 +3837,7 @@ bool prepare_initial_ul_rrc_message(gNB_MAC_INST *mac, NR_UE_info_t *UE) int CC_id = 0; int srb_id = 1; const NR_ServingCellConfigCommon_t *scc = mac->common_channels[CC_id].ServingCellConfigCommon; - NR_COMMON_channels_t *cc = &mac->common_channels[CC_id]; - int ssb_index = cc->ssb_index[UE->UE_beam_index]; + int ssb_index = get_ssbidx_from_beam(mac, UE->UE_beam_index); NR_CellGroupConfig_t *cellGroupConfig = get_initial_cellGroupConfig(UE->uid, scc, &mac->radio_config, &mac->rlc_config, ssb_index); ASN_STRUCT_FREE(asn_DEF_NR_CellGroupConfig, UE->CellGroup); UE->CellGroup = cellGroupConfig; diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h index e616c4a49c..5a59ed67af 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h @@ -56,7 +56,7 @@ void mac_top_init_gNB(ngran_node_t node_type, const nr_rlc_configuration_t *default_rlc_config); void mac_top_destroy_gNB(gNB_MAC_INST *mac); void nr_mac_send_f1_setup_req(void); - +int get_ssbidx_from_beam(gNB_MAC_INST *mac, int beam_idx); void nr_mac_config_scc(gNB_MAC_INST *nrmac, NR_ServingCellConfigCommon_t *scc, const nr_mac_config_t *mac_config); void nr_mac_configure_sib1(gNB_MAC_INST *nrmac, const plmn_id_t *plmn, uint64_t cellID, int tac); bool nr_mac_configure_other_sib(gNB_MAC_INST *nrmac, int num_cu_sib, const f1ap_sib_msg_t cu_sib[num_cu_sib]); diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c index 9ced91c26b..500997d4ce 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c +++ b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c @@ -567,7 +567,7 @@ static NR_UE_info_t *create_new_UE(gNB_MAC_INST *mac, uint32_t cu_id, const NR_C NR_COMMON_channels_t *cc = &mac->common_channels[CC_id]; const NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon; const nr_mac_config_t *configuration = &mac->radio_config; - int ssb_index = cc->ssb_index[UE->UE_beam_index]; + int ssb_index = get_ssbidx_from_beam(mac, UE->UE_beam_index); if (is_SA) { cellGroupConfig = get_initial_cellGroupConfig(UE->uid, scc, &mac->radio_config, &mac->rlc_config, ssb_index); cellGroupConfig->spCellConfig->reconfigurationWithSync = get_reconfiguration_with_sync(UE->rnti, UE->uid, scc, mac->frame); From da287084595e4e8be4d91819dd1628c2d3f539c9 Mon Sep 17 00:00:00 2001 From: Jaroslava Fiedlerova Date: Thu, 22 Jan 2026 07:55:22 +0100 Subject: [PATCH 83/83] CI: Add config files for phytest with 7.2 --- ...nb.sa.band77.273prb.fhi72.4x4-4L-vvdn.conf | 266 ++++++++++++++++++ .../datalog_rt_stats.100.4x4.fhi72.yaml | 28 ++ .../xml_files/gnb_phytest_fhi7.2_docker.xml | 88 ++++++ .../phytest_fhi72/docker-compose.yaml | 22 ++ .../phytest_fhi72/setup_sriov_dummy.sh | 38 +++ 5 files changed, 442 insertions(+) create mode 100644 ci-scripts/conf_files/gnb.sa.band77.273prb.fhi72.4x4-4L-vvdn.conf create mode 100644 ci-scripts/datalog_rt_stats.100.4x4.fhi72.yaml create mode 100644 ci-scripts/xml_files/gnb_phytest_fhi7.2_docker.xml create mode 100644 ci-scripts/yaml_files/phytest_fhi72/docker-compose.yaml create mode 100755 ci-scripts/yaml_files/phytest_fhi72/setup_sriov_dummy.sh diff --git a/ci-scripts/conf_files/gnb.sa.band77.273prb.fhi72.4x4-4L-vvdn.conf b/ci-scripts/conf_files/gnb.sa.band77.273prb.fhi72.4x4-4L-vvdn.conf new file mode 100644 index 0000000000..0b087e7406 --- /dev/null +++ b/ci-scripts/conf_files/gnb.sa.band77.273prb.fhi72.4x4-4L-vvdn.conf @@ -0,0 +1,266 @@ +Active_gNBs = ( "gNB-OAI"); +# Asn1_verbosity, choice in: none, info, annoying +Asn1_verbosity = "none"; + +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 = 208; mnc = 99; mnc_length = 2; snssaiList = ( { sst = 1; }); }); + + nr_cellid = 1; + + ////////// Physical parameters: + + pdsch_AntennaPorts_XP = 2; + pdsch_AntennaPorts_N1 = 2; + maxMIMO_layers = 4; + pusch_AntennaPorts = 4; + do_CSIRS = 0; + do_SRS = 0; + + servingCellConfigCommon = ( + { + #spCellConfigCommon + physCellId = 0; +# downlinkConfigCommon + #frequencyInfoDL + # center frequency = 4049.76 MHz + # selected SSB frequency = 4049.76 MHz + absoluteFrequencySSB = 668640; #669984; + dl_frequencyBand = 77; + # frequency point A = 4000.62 MHz + dl_absoluteFrequencyPointA = 666708; + #scs-SpecificCarrierList + dl_offstToCarrier = 0; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + dl_subcarrierSpacing = 1; + dl_carrierBandwidth = 273; + #initialDownlinkBWP + #genericParameters + initialDLBWPlocationAndBandwidth = 1099; #38.101-1 Table 5.3.2-1 + # +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + initialDLBWPsubcarrierSpacing = 1; + #pdcch-ConfigCommon + initialDLBWPcontrolResourceSetZero = 11; + initialDLBWPsearchSpaceZero = 0; + + #uplinkConfigCommon + #frequencyInfoUL + ul_frequencyBand = 77; + #scs-SpecificCarrierList + ul_offstToCarrier = 0; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + ul_subcarrierSpacing = 1; + ul_carrierBandwidth = 273; + pMax = 23; + #initialUplinkBWP + #genericParameters + initialULBWPlocationAndBandwidth = 1099; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + initialULBWPsubcarrierSpacing = 1; + #rach-ConfigCommon + #rach-ConfigGeneric + prach_ConfigurationIndex = 159; +#prach_msg1_FDM +#0 = one, 1=two, 2=four, 3=eight + prach_msg1_FDM = 0; + prach_msg1_FrequencyStart = 0; + zeroCorrelationZoneConfig = 0; + preambleReceivedTargetPower = -100; +#preamblTransMax (0...10) = (3,4,5,6,7,8,10,20,50,100,200) + preambleTransMax = 7; +#powerRampingStep +# 0=dB0,1=dB2,2=dB4,3=dB6 + powerRampingStep = 2; +#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 = 4; +#one (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, + +# this is the offset between the last PRACH preamble power and the Msg3 PUSCH, 2 times the field value in dB + msg3_DeltaPreamble = 2; + p0_NominalWithGrant = -100; + +# pucch-ConfigCommon setup : +# pucchGroupHopping +# 0 = neither, 1= group hopping, 2=sequence hopping + pucchGroupHopping = 0; + hoppingId = 0; + p0_nominal = -96; + + ssb_PositionsInBurst_Bitmap = 0x1; + +# 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 = 5; + nrofDownlinkSlots = 3; + nrofDownlinkSymbols = 6; + nrofUplinkSlots = 1; + nrofUplinkSymbols = 4; + + ssPBCH_BlockPower = -11; + } + + ); + + + # ------- SCTP definitions + SCTP : + { + # Number of streams to use in input/output + SCTP_INSTREAMS = 2; + SCTP_OUTSTREAMS = 2; + }; + + + ////////// AMF parameters: + amf_ip_address = ({ ipv4 = "172.21.6.5"; }); + + NETWORK_INTERFACES : + { + GNB_IPV4_ADDRESS_FOR_NG_AMF = "172.21.16.209"; + GNB_IPV4_ADDRESS_FOR_NGU = "172.21.16.209"; + GNB_PORT_FOR_S1U = 2152; # Spec 2152 + }; + } +); + +MACRLCs = ( +{ + num_cc = 1; + tr_s_preference = "local_L1"; + tr_n_preference = "local_RRC"; + pusch_TargetSNRx10 = 220; + pucch_TargetSNRx10 = 220; + pusch_FailureThres = 100; +} +); + +L1s = ( +{ + num_cc = 1; + tr_n_preference = "local_mac"; + prach_dtx_threshold = 120 + pucch0_dtx_threshold = 80; + pusch_dtx_threshold = -100; + tx_amp_backoff_dB = 3; + L1_rx_thread_core = 8; + L1_tx_thread_core = 9; + max_ldpc_iterations = 20; + phase_compensation = 0; # needs to match O-RU configuration +} +); + +RUs = ( +{ + local_rf = "no"; + nb_tx = 4; + nb_rx = 4; + att_tx = 0; + att_rx = 0; + bands = [77]; + max_pdschReferenceSignalPower = -27; + max_rxgain = 75; + sf_extension = 0; + eNB_instances = [0]; + ru_thread_core = 10; + sl_ahead = 5; + tr_preference = "raw_if4p5"; # important: activate FHI7.2 + do_precoding = 0; # needs to match O-RU configuration +} +); + +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"; + hw_log_level = "info"; + phy_log_level = "info"; + mac_log_level = "info"; + rlc_log_level = "info"; + pdcp_log_level = "info"; + rrc_log_level = "info"; + ngap_log_level = "info"; + f1ap_log_level = "info"; +}; + +fhi_72 = { + dpdk_devices = ("0000:01:01.0"); + dpdk_iova_mode = "VA"; + system_core = 11; + io_core = 12; + worker_cores = (13); + ru_addr = ("98:ae:71:04:83:e3"); + mtu = 9600; + fh_config = ({ + T1a_cp_dl = (285, 470); + T1a_cp_ul = (285, 429); + T1a_up = (125, 350); + Ta4 = (110, 180); + ru_config = { + iq_width = 9; + iq_width_prach = 9; + }; + }); +}; + diff --git a/ci-scripts/datalog_rt_stats.100.4x4.fhi72.yaml b/ci-scripts/datalog_rt_stats.100.4x4.fhi72.yaml new file mode 100644 index 0000000000..b907b081c1 --- /dev/null +++ b/ci-scripts/datalog_rt_stats.100.4x4.fhi72.yaml @@ -0,0 +1,28 @@ +#this is a configuration file +#used to build real time processing statistics +#for 5G NR phy test (gNB terminate) +Title : Processing Time (us) from datalog_rt_stats.4x4.fhi72.yaml +ColNames : + - Metric + - Average; Max; Count + - Average vs Reference Deviation (Reference Value; Acceptability Deviation Threshold) +Ref : + tx_fhaul : 40.2 + feptx_prec (per port, half_slot) : 12.3 + L1 Tx processing : 221.0 + DLSCH encoding : 141.0 + L1 Rx processing : 332.5 + UL segments decoding : 55.2 + UL Indication : 0.4 + Slot Indication : 14.3 + PUSCH inner-receiver : 421.4 +DeviationThreshold : + tx_fhaul : 0.25 + feptx_prec (per port, half_slot) : 0.25 + L1 Tx processing : 0.25 + DLSCH encoding : 0.25 + L1 Rx processing : 0.25 + UL segments decoding : 0.25 + UL Indication : 1.00 + Slot Indication : 0.50 + PUSCH inner-receiver : 0.25 diff --git a/ci-scripts/xml_files/gnb_phytest_fhi7.2_docker.xml b/ci-scripts/xml_files/gnb_phytest_fhi7.2_docker.xml new file mode 100644 index 0000000000..5386ba4d83 --- /dev/null +++ b/ci-scripts/xml_files/gnb_phytest_fhi7.2_docker.xml @@ -0,0 +1,88 @@ + + + gNB-PHY-Test-100-4x4-FHI72 + Timing phytest 100 MHz 4x4 FHI7.2 + tasks + + + Custom_Script + Setup sriov and network interfaces for dummy (no RU) + bulbul + + + + + Pull_Local_Registry + Pull Images from Local Registry + bulbul + oai-gnb-fhi72 + + + + Create_Workspace + Create new Workspace + bulbul + + + + Deploy_Object + Initialize gNB FHI7.2 + bulbul + ci-scripts/yaml_files/phytest_fhi72 + oai-gnb + + + + IdleSleep + Sleep + 60 + + + + AnalyzeRTStats_Object + Analyze Real-Time Stats + datalog_rt_stats.100.4x4.fhi72.yaml + bulbul + + + + Undeploy_Object + bulbul + true + Terminate gNB + ci-scripts/yaml_files/phytest_fhi72 + + oai-gnb=EndsWithBye + + + + + Clean_Test_Server_Images + true + Clean Test Images on Test Server + bulbul + oai-gnb-fhi72 + + + diff --git a/ci-scripts/yaml_files/phytest_fhi72/docker-compose.yaml b/ci-scripts/yaml_files/phytest_fhi72/docker-compose.yaml new file mode 100644 index 0000000000..46fbc24302 --- /dev/null +++ b/ci-scripts/yaml_files/phytest_fhi72/docker-compose.yaml @@ -0,0 +1,22 @@ +services: + oai-gnb: + image: ${REGISTRY-oaisoftwarealliance/}${GNB_IMG:-oai-gnb-fhi72}:${TAG:-develop} + container_name: oai-gnb-phytest + cap_add: + - IPC_LOCK + - SYS_NICE + cap_drop: + - ALL + environment: + USE_ADDITIONAL_OPTIONS: --phy-test -q -M 273 -m 27 -l 4 -D 231 -T 273 -t 16 -L 2 -U 528 --log_config.global_log_options level,nocolor,time --thread-pool 16,17,18,19,20,21,22,23 + devices: + - /dev/vfio:/dev/vfio/ + volumes: + - ../../conf_files/gnb.sa.band77.273prb.fhi72.4x4-4L-vvdn.conf:/opt/oai-gnb/etc/gnb.conf + - /dev/hugepages:/dev/hugepages + cpuset: "8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23" + healthcheck: + test: /bin/bash -c "pgrep nr-softmodem" + interval: 10s + timeout: 5s + retries: 5 diff --git a/ci-scripts/yaml_files/phytest_fhi72/setup_sriov_dummy.sh b/ci-scripts/yaml_files/phytest_fhi72/setup_sriov_dummy.sh new file mode 100755 index 0000000000..c18affb0a9 --- /dev/null +++ b/ci-scripts/yaml_files/phytest_fhi72/setup_sriov_dummy.sh @@ -0,0 +1,38 @@ +#!/bin/sh +set -eu + +pci_addr() +{ + PF_IF=$1 + VF_INDEX=$2 + SYSFS_PATH="/sys/class/net/${PF_IF}/device/virtfn${VF_INDEX}" + + if [ ! -e "$SYSFS_PATH" ]; then + echo "VF $VF_INDEX not found for interface $PF_IF" + exit 1 + fi + PCI_ADDR=$(basename "$(readlink "$SYSFS_PATH")") + echo "$PCI_ADDR" +} +IF_NAME=ens1f0np0 +## O-DU C Plane MAC ADDR and VLAN +C_U_PLANE_MAC_ADD=22:11:55:33:99:55 +C_U_PLANE_VLAN=123 +MTU=9000 +DPDK_DEVBIND_PREFIX=/home/oaicicd/test/dpdk-stable-22.11.7/bin +NUM_VFs=1 +sudo ethtool -G $IF_NAME rx 8160 tx 8160 +sudo sh -c "echo 0 > /sys/class/net/$IF_NAME/device/sriov_numvfs" +sudo sh -c "echo $NUM_VFs > /sys/class/net/$IF_NAME/device/sriov_numvfs" +C_U_PLANE_PCI=$(pci_addr $IF_NAME 0) +# this next 2 lines is for C/U planes +sudo ip link set $IF_NAME vf 0 mac $C_U_PLANE_MAC_ADD vlan $C_U_PLANE_VLAN spoofchk off mtu $MTU +sleep 1 +sudo modprobe iavf +sudo ${DPDK_DEVBIND_PREFIX}/dpdk-devbind.py --unbind $C_U_PLANE_PCI +sudo modprobe vfio-pci +sudo ${DPDK_DEVBIND_PREFIX}/dpdk-devbind.py --bind vfio-pci $C_U_PLANE_PCI +echo "Successfully configured C-PLANE and U-PLANE: + - C-PLANE MAC: $C_U_PLANE_MAC_ADD, VLAN: $C_U_PLANE_VLAN, PCI: $C_U_PLANE_PCI" +exit 0 +