From f2389987d4609336ded549da5e688fa0f556e0ce Mon Sep 17 00:00:00 2001 From: francescomani Date: Fri, 24 Oct 2025 11:33:49 +0200 Subject: [PATCH 01/69] improvements in formatting and LOGs in DMRS common functions at MAC --- openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c | 89 +++++++++++-------- 1 file changed, 54 insertions(+), 35 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c index 1a5431bdd2..3b26bf0a35 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c @@ -2246,7 +2246,6 @@ int32_t get_l_prime(uint8_t duration_in_symbols, // For PDSCH Mapping TypeA, ld is duration between first OFDM of the slot and last OFDM symbol of the scheduled PUSCH resources // For TypeB, ld is the duration of the scheduled PUSCH resources uint8_t ld = (mapping_type == typeA) ? (duration_in_symbols + start_symbol) : duration_in_symbols; - uint8_t l0 = (dmrs_typeA_position == NR_MIB__dmrs_TypeA_Position_pos2) ? 2 : 3 ; uint8_t colomn = additional_pos; @@ -2260,20 +2259,27 @@ int32_t get_l_prime(uint8_t duration_in_symbols, row = ld - 3; uint32_t l_prime; + int l0 = (dmrs_typeA_position == NR_MIB__dmrs_TypeA_Position_pos2) ? 2 : 3; + int l0_shift; if (pusch_maxLength == pusch_len1) { l_prime = table_6_4_1_1_3_3_pusch_dmrs_positions_l[row][colomn]; - l0 = 1 << l0; - } - else { + l0_shift = 1 << l0; + } else { l_prime = table_6_4_1_1_3_4_pusch_dmrs_positions_l[row][colomn]; - l0 = 1<= 0, "invalid l_prime < 0\n"); - LOG_D(NR_MAC, "PUSCH - l0:%d, ld:%d,row:%d, column:%d, addpos:%d, maxlen:%d\n", l0, ld, row, colomn, additional_pos, pusch_maxLength); - AssertFatal(l_prime>=0,"invalid l_prime < 0\n"); - - l_prime = (mapping_type == typeA) ? (l_prime | l0) : (l_prime << start_symbol); - LOG_D(MAC, " PUSCH DMRS MASK in HEX:%x\n", l_prime); + l_prime = (mapping_type == typeA) ? (l_prime | l0_shift) : (l_prime << start_symbol); + LOG_D(NR_MAC, + "PUSCH - l0:%d, ld:%d, row:%d, column:%d, addpos:%d, maxlen:%d DMRS MASK in HEX:%x\n", + (mapping_type == typeA) ? l0 : 0, + ld, + row, + colomn, + additional_pos, + pusch_maxLength, + l_prime); return l_prime; } @@ -3163,13 +3169,21 @@ int16_t fill_dmrs_mask(const NR_PDSCH_Config_t *pdsch_Config, int dmrs_AdditionalPosition = 0; NR_DMRS_DownlinkConfig_t *dmrs_config = NULL; - LOG_D(MAC, "NrofSymbols:%d, startSymbol:%d, mappingtype:%d, dmrs_TypeA_Position:%d\n", NrOfSymbols, startSymbol, mappingtype, dmrs_TypeA_Position); + LOG_D(NR_MAC, + "NrofSymbols:%d, startSymbol:%d, mappingtype:%d, dmrs_TypeA_Position:%d\n", + NrOfSymbols, + startSymbol, + mappingtype, + dmrs_TypeA_Position); int l0 = 0; // type B if (mappingtype == typeA) { - if (dmrs_TypeA_Position == NR_ServingCellConfigCommon__dmrs_TypeA_Position_pos2) l0 = 2; - else if (dmrs_TypeA_Position == NR_ServingCellConfigCommon__dmrs_TypeA_Position_pos3) l0 = 3; - else AssertFatal(1==0,"Illegal dmrs_TypeA_Position %d\n",(int)dmrs_TypeA_Position); + if (dmrs_TypeA_Position == NR_ServingCellConfigCommon__dmrs_TypeA_Position_pos2) + l0 = 2; + else if (dmrs_TypeA_Position == NR_ServingCellConfigCommon__dmrs_TypeA_Position_pos3) + l0 = 3; + else + AssertFatal(false, "Illegal dmrs_TypeA_Position %d\n", (int)dmrs_TypeA_Position); } // in case of DCI FORMAT 1_0 or dedicated pdsch config not received additionposition = pos2, len1 should be used // referred to section 5.1.6.2 in 38.214 @@ -3177,14 +3191,16 @@ int16_t fill_dmrs_mask(const NR_PDSCH_Config_t *pdsch_Config, if (pdsch_Config != NULL) { if (mappingtype == typeA) { // Type A - if (dci_format != NR_DL_DCI_FORMAT_1_0 && - pdsch_Config->dmrs_DownlinkForPDSCH_MappingTypeA && pdsch_Config->dmrs_DownlinkForPDSCH_MappingTypeA->present == NR_SetupRelease_DMRS_DownlinkConfig_PR_setup) + if (dci_format != NR_DL_DCI_FORMAT_1_0 + && pdsch_Config->dmrs_DownlinkForPDSCH_MappingTypeA + && pdsch_Config->dmrs_DownlinkForPDSCH_MappingTypeA->present == NR_SetupRelease_DMRS_DownlinkConfig_PR_setup) dmrs_config = (NR_DMRS_DownlinkConfig_t *)pdsch_Config->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup; } else if (mappingtype == typeB) { - if (pdsch_Config->dmrs_DownlinkForPDSCH_MappingTypeB && pdsch_Config->dmrs_DownlinkForPDSCH_MappingTypeB->present == NR_SetupRelease_DMRS_DownlinkConfig_PR_setup) + if (pdsch_Config->dmrs_DownlinkForPDSCH_MappingTypeB + && pdsch_Config->dmrs_DownlinkForPDSCH_MappingTypeB->present == NR_SetupRelease_DMRS_DownlinkConfig_PR_setup) dmrs_config = (NR_DMRS_DownlinkConfig_t *)pdsch_Config->dmrs_DownlinkForPDSCH_MappingTypeB->choice.setup; } else { - AssertFatal(1==0,"Incorrect Mappingtype\n"); + AssertFatal(false, "Incorrect Mappingtype\n"); } // default values of additionalposition is pos2 @@ -3192,49 +3208,52 @@ int16_t fill_dmrs_mask(const NR_PDSCH_Config_t *pdsch_Config, dmrs_AdditionalPosition = *dmrs_config->dmrs_AdditionalPosition; } - uint8_t ld, row, column; - int32_t l_prime = -1; - // columns 0-3 for TypeA, 4-7 for TypeB - column = (mappingtype == typeA) ? dmrs_AdditionalPosition : (dmrs_AdditionalPosition + 4); + int column = (mappingtype == typeA) ? dmrs_AdditionalPosition : (dmrs_AdditionalPosition + 4); // Section 7.4.1.1.2 in Spec 38.211 // For PDSCH Mapping TypeA, ld is duration between first OFDM of the slot and last OFDM symbol of the scheduled PDSCH resources // For TypeB, ld is the duration of the scheduled PDSCH resources - ld = (mappingtype == typeA) ? (NrOfSymbols + startSymbol) : NrOfSymbols; + int ld = (mappingtype == typeA) ? (NrOfSymbols + startSymbol) : NrOfSymbols; AssertFatal(ld > 2 && ld < 15,"Illegal NrOfSymbols according to Table 5.1.2.1-1 Spec 38.214 %d\n",ld); AssertFatal((NrOfSymbols + startSymbol) < 15,"Illegal S+L according to Table 5.1.2.1-1 Spec 38.214 S:%d L:%d\n",startSymbol, NrOfSymbols); if (mappingtype == typeA) { - // Section 7.4.1.1.2 in Spec 38.211 AssertFatal((l0 == 2) || (l0 == 3 && dmrs_AdditionalPosition != 3),"Wrong config, If dmrs_TypeA_Position POS3, ADD POS cannot be POS3 \n"); - // Table 5.1.2.1-1 in Spec 38.214 AssertFatal(startSymbol <= l0, "Wrong config, Start symbol %d cannot be later than dmrs_TypeA_Position %d \n", startSymbol, l0); - // Section 7.4.1.1.2 in Spec 38.211 AssertFatal(l0 == 2 || (l0 == 3 && (ld != 3 && ld != 4)), "ld 3 or 4 symbols only possible with dmrs_TypeA_Position POS2 \n"); } // number of front loaded symbols + int l_prime, row, l0_shift; if (length == 1) { row = ld - 2; l_prime = table_7_4_1_1_2_3_pdsch_dmrs_positions_l[row][column]; - l0 = 1 << l0; - } - else { + l0_shift = 1 << l0; + } else { row = (ld < 4) ? 0 : (ld - 3); l_prime = table_7_4_1_1_2_4_pdsch_dmrs_positions_l[row][column]; - l0 = 1<= 0, + "ERROR in configuration. Check Time Domain allocation of this Grant. l_prime < 1. row:%d, column:%d\n", + row, + column); - LOG_D(MAC, "l0:%d, ld:%d,row:%d, column:%d, addpos:%d, maxlen:%d\n", l0, ld, row, column, dmrs_AdditionalPosition, length); - AssertFatal(l_prime>=0,"ERROR in configuration.Check Time Domain allocation of this Grant. l_prime < 1. row:%d, column:%d\n", row, column); - - l_prime = (mappingtype == typeA) ? (l_prime | l0) : (l_prime << startSymbol); - LOG_D(MAC, " PDSCH DMRS MASK in HEX:%x\n", l_prime); + l_prime = (mappingtype == typeA) ? (l_prime | l0_shift) : (l_prime << startSymbol); + LOG_D(NR_MAC, + "l0:%d, ld:%d, row:%d, column:%d, addpos:%d, maxlen:%d, DMRS MASK in HEX:%x\n", + (mappingtype == typeA) ? l0 : 0, + ld, + row, + column, + dmrs_AdditionalPosition, + length, + l_prime); return l_prime; } From b67c6396882e08fa0865f4902bdfa60aa58e9982 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Mon, 27 Oct 2025 16:47:24 +0100 Subject: [PATCH 02/69] Handle GTP receiver errors On error, exit the GTP thread after printing a diagnostic message. This avoids also an error flagged by address sanitizer for use-after-free. [GTPU] [91] Recvfrom failed (Bad file descriptor) ================================================================= ==285377==ERROR: AddressSanitizer: heap-use-after-free on address 0x7cd7b7fe5590 at pc 0x0000006a9e18 bp 0x7b97ad4e1d50 sp 0x7b97ad4e1d48 READ of size 4 at 0x7cd7b7fe5590 thread T8 ================================================================= ==285377==ERROR: LeakSanitizer: detected memory leaks Direct leak of 160 byte(s) in 1 object(s) allocated from: #0 0x0000006a9e17 in gtpv1uReceiver /home/richie/oai/openair3/ocp-gtpu/gtp_itf.cpp:1346 #1 0x7f97b9a28ee5 in asan_thread_start(void*) (/lib64/libasan.so.8+0x28ee5) (BuildId: 10b8ccd49f75c21babf1d7abe51bb63589d8471f) #2 0x7f97b8e7ff53 in start_thread (/lib64/libc.so.6+0x71f53) (BuildId: 48c4b9b1efb1df15da8e787f489128bf31893317) #3 0x7f97b8f0332b in __clone3 (/lib64/libc.so.6+0xf532b) (BuildId: 48c4b9b1efb1df15da8e787f489128bf31893317) #0 0x7f97b9ae60cb in memalign (/lib64/libasan.so.8+0xe60cb) (BuildId: 10b8ccd49f75c21babf1d7abe51bb63589d8471f) #1 0x000000471039 in newNotifiedFIFO_elt /home/richie/oai/common/utils/threadPool/notified_fifo.h:75 #2 0x000000471039 in tx_func /home/richie/oai/executables/nr-gnb.c:107 #3 0x000000471039 in L1_tx_thread /home/richie/oai/executables/nr-gnb.c:167 #4 0x7f97b9a28ee5 in asan_thread_start(void*) (/lib64/libasan.so.8+0x28ee5) (BuildId: 10b8ccd49f75c21babf1d7abe51bb63589d8471f) 0x7cd7b7fe5590 is located 336 bytes inside of 400-byte region [0x7cd7b7fe5440,0x7cd7b7fe55d0) freed by thread T0 here: SUMMARY: AddressSanitizer: 160 byte(s) leaked in 1 allocation(s). --- openair3/ocp-gtpu/gtp_itf.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/openair3/ocp-gtpu/gtp_itf.cpp b/openair3/ocp-gtpu/gtp_itf.cpp index aca2fcbb32..cb73bfd06c 100644 --- a/openair3/ocp-gtpu/gtp_itf.cpp +++ b/openair3/ocp-gtpu/gtp_itf.cpp @@ -1283,7 +1283,7 @@ static int Gtpv1uHandleGpdu(int h, uint8_t *msgBuf, uint32_t msgBufLen, const st return !GTPNOK; } -static void gtpv1uReceiveHandleMessage(int h) +static bool gtpv1uReceiveHandleMessage(int h) { uint8_t udpData[65536]; int udpDataLen; @@ -1293,19 +1293,19 @@ static void gtpv1uReceiveHandleMessage(int h) if ((udpDataLen = recvfrom(h, udpData, sizeof(udpData), 0, (struct sockaddr *)&addr, &from_len)) < 0) { LOG_E(GTPU, "[%d] Recvfrom failed (%s)\n", h, strerror(errno)); - return; + return false; } else if (udpDataLen == 0) { LOG_W(GTPU, "[%d] Recvfrom returned 0\n", h); - return; + return true; } else { if (udpDataLen < (int)sizeof(Gtpv1uMsgHeaderT)) { LOG_W(GTPU, "[%d] received malformed gtp packet \n", h); - return; + return true; } Gtpv1uMsgHeaderT *msg = (Gtpv1uMsgHeaderT *)udpData; if ((int)(ntohs(msg->msgLength) + sizeof(Gtpv1uMsgHeaderT)) != udpDataLen) { LOG_W(GTPU, "[%d] received malformed gtp packet length\n", h); - return; + return true; } LOG_D(GTPU, "[%d] Received GTP data, msg type: %x\n", h, msg->msgType); switch (msg->msgType) { @@ -1337,13 +1337,13 @@ static void gtpv1uReceiveHandleMessage(int h) break; } } + return true; } static void* gtpv1uReceiver(void *thr) { gtpThread_t *gt = (gtpThread_t *)thr; - while (true) { - gtpv1uReceiveHandleMessage(gt->h); + while (gtpv1uReceiveHandleMessage(gt->h)) { } LOG_W(GTPU, "exiting thread\n"); return NULL; From e40ccbb535ee1b6a81826ba9aabafab9da197021 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Mon, 27 Oct 2025 16:49:57 +0100 Subject: [PATCH 03/69] Stop GTP receiver thread on exit Stop the receive thread before closing the socket, which avoids an error message when stopping the GTP softmodem: [GTPU] [91] Recvfrom failed (Bad file descriptor) [GTPU] exiting thread --- openair3/ocp-gtpu/gtp_itf.cpp | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/openair3/ocp-gtpu/gtp_itf.cpp b/openair3/ocp-gtpu/gtp_itf.cpp index cb73bfd06c..c524129098 100644 --- a/openair3/ocp-gtpu/gtp_itf.cpp +++ b/openair3/ocp-gtpu/gtp_itf.cpp @@ -152,6 +152,7 @@ class gtpEndPoint { } }; +static void gtpv1uReceiverCancel(pthread_t t); class gtpEndPoints { public: pthread_mutex_t gtp_lock = PTHREAD_MUTEX_INITIALIZER; @@ -168,8 +169,10 @@ class gtpEndPoints { ~gtpEndPoints() { // automatically close all sockets on quit - for (const auto &p : instances) + for (const auto &p : instances) { + gtpv1uReceiverCancel(p.second.thrData.t); close(p.first); + } } }; @@ -1349,6 +1352,15 @@ static void* gtpv1uReceiver(void *thr) return NULL; } +static void gtpv1uReceiverCancel(pthread_t t) +{ + int rc; + rc = pthread_cancel(t); + DevAssert(rc == 0); + rc = pthread_join(t, NULL); + DevAssert(rc == 0); +} + #include void *gtpv1uTask(void *args) @@ -1370,6 +1382,8 @@ void *gtpv1uTask(void *args) // DATA TO BE SENT TO UDP case TERMINATE_MESSAGE: + LOG_W(GTPU, "Exiting GTP instance %ld\n", myInstance); + itti_exit_task(); break; case TIMER_HAS_EXPIRED: From 9b97fd9b62010f09ef19df161f183c92dab127a2 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 23 Oct 2025 19:27:15 +0200 Subject: [PATCH 04/69] Measure tx_func()/rx_func() job duration --- executables/nr-gnb.c | 8 ++++++++ openair1/PHY/defs_gNB.h | 3 +++ 2 files changed, 11 insertions(+) diff --git a/executables/nr-gnb.c b/executables/nr-gnb.c index 505adf825c..2be0ee80ad 100644 --- a/executables/nr-gnb.c +++ b/executables/nr-gnb.c @@ -147,7 +147,9 @@ void *L1_rx_thread(void *arg) if (res == NULL) break; processingData_L1_t *info = (processingData_L1_t *)NotifiedFifoData(res); + start_meas(&gNB->l1_rx_proc); rx_func(info); + stop_meas(&gNB->l1_rx_proc); delNotifiedFIFO_elt(res); } return NULL; @@ -161,7 +163,9 @@ void *L1_tx_thread(void *arg) { if (res == NULL) // stopping condition, happens only when queue is freed break; processingData_L1tx_t *info = (processingData_L1tx_t *)NotifiedFifoData(res); + start_meas(&gNB->l1_tx_proc); tx_func(info); + stop_meas(&gNB->l1_tx_proc); delNotifiedFIFO_elt(res); } return NULL; @@ -226,6 +230,8 @@ static void rx_func(processingData_L1_t *info) static size_t dump_L1_meas_stats(PHY_VARS_gNB *gNB, RU_t *ru, char *output, size_t outputlen) { const char *begin = output; const char *end = output + outputlen; + output += print_meas_log(&gNB->l1_tx_proc, "L1 Tx job", NULL, NULL, output, end - output); + output += print_meas_log(&gNB->l1_rx_proc, "L1 Rx job", NULL, NULL, output, end - output); output += print_meas_log(&gNB->phy_proc_tx, "L1 Tx processing", NULL, NULL, output, end - output); output += print_meas_log(&gNB->dlsch_encoding_stats, "DLSCH encoding", NULL, NULL, output, end - output); output += print_meas_log(&gNB->dlsch_scrambling_stats, "DLSCH scrambling", NULL, NULL, output, end-output); @@ -290,6 +296,8 @@ void *nrL1_stats_thread(void *param) { return NULL; } + reset_meas(&gNB->l1_tx_proc); + reset_meas(&gNB->l1_rx_proc); reset_meas(&gNB->phy_proc_tx); reset_meas(&gNB->dlsch_encoding_stats); reset_meas(&gNB->phy_proc_rx); diff --git a/openair1/PHY/defs_gNB.h b/openair1/PHY/defs_gNB.h index fb549d4734..aec28272ef 100644 --- a/openair1/PHY/defs_gNB.h +++ b/openair1/PHY/defs_gNB.h @@ -494,6 +494,9 @@ typedef struct PHY_VARS_gNB_s { bool enable_analog_das; + time_stats_t l1_tx_proc; + time_stats_t l1_rx_proc; + time_stats_t phy_proc_tx; time_stats_t phy_proc_rx; time_stats_t rx_prach; From 7e8245c4127655dcc30c399a8bd178ff759434c0 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Fri, 24 Oct 2025 10:23:49 +0200 Subject: [PATCH 05/69] nrMAC_stats.log thread: correctly lock scheduler for stats --- openair2/LAYER2/NR_MAC_gNB/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/main.c b/openair2/LAYER2/NR_MAC_gNB/main.c index fa66125bf7..2df930f3ff 100644 --- a/openair2/LAYER2/NR_MAC_gNB/main.c +++ b/openair2/LAYER2/NR_MAC_gNB/main.c @@ -87,7 +87,6 @@ void *nrmac_stats_thread(void *arg) { char *p = output; NR_SCHED_LOCK(&gNB->sched_lock); p += dump_mac_stats(gNB, p, end - p, false); - NR_SCHED_UNLOCK(&gNB->sched_lock); p += snprintf(p, end - p, "\n"); p += print_meas_log(&gNB->gNB_scheduler, "gNB_scheduler", NULL, NULL, p, end - p); p += print_meas_log(&gNB->rx_ulsch_sdu, "rx_ulsch_sdu", NULL, NULL, p, end - p); @@ -97,6 +96,7 @@ void *nrmac_stats_thread(void *arg) { p += print_meas_log(&gNB->rlc_data_req, "rlc_data_req", NULL, NULL, p, end - p); p += print_meas_log(&gNB->nr_srs_ri_computation_timer, "UL-RI computation time", NULL, NULL, p, end - p); p += print_meas_log(&gNB->nr_srs_tpmi_computation_timer, "UL-TPMI computation time", NULL, NULL, p, end - p); + NR_SCHED_UNLOCK(&gNB->sched_lock); fwrite(output, p - output, 1, file); fflush(file); sleep(1); From 07f06f8c06f2f33ed0e5a49a6e610363ebd92c4d Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Fri, 24 Oct 2025 10:25:47 +0200 Subject: [PATCH 06/69] nrMAC_stats.log: handle file errors, add truncate to reset file truncate resets the file size to 0. Without this, e.g., when disconnecting a UE, the old UE remains at the end and is not overwritten, which is confusing. --- openair2/LAYER2/NR_MAC_gNB/main.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/main.c b/openair2/LAYER2/NR_MAC_gNB/main.c index 2df930f3ff..4b8196fc1b 100644 --- a/openair2/LAYER2/NR_MAC_gNB/main.c +++ b/openair2/LAYER2/NR_MAC_gNB/main.c @@ -97,10 +97,16 @@ void *nrmac_stats_thread(void *arg) { p += print_meas_log(&gNB->nr_srs_ri_computation_timer, "UL-RI computation time", NULL, NULL, p, end - p); p += print_meas_log(&gNB->nr_srs_tpmi_computation_timer, "UL-TPMI computation time", NULL, NULL, p, end - p); NR_SCHED_UNLOCK(&gNB->sched_lock); - fwrite(output, p - output, 1, file); - fflush(file); + size_t len = p - output; + if (fwrite(output, len, 1, file) != 1 || fflush(file) != 0) { + LOG_E(NR_MAC, "error while writing nrMAC_stats.log: %d, %s\n", errno, strerror(errno)); + break; + } sleep(1); - fseek(file,0,SEEK_SET); + if (ftruncate(fileno(file), 0) != 0 || fseek(file, 0, SEEK_SET) != 0) { + LOG_E(NR_MAC, "error while writing nrMAC_stats.log: %d, %s\n", errno, strerror(errno)); + break; + } } fclose(file); return NULL; From 7df8243a2ed8ad02c5047326dca90cf0bb3a9ad5 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Fri, 24 Oct 2025 10:55:22 +0200 Subject: [PATCH 07/69] Remove NR MAC's UE-specific lock There is the (global) sched_lock that prevents concurrent access. A dedicated UE lock does not make sense in that case. Worse, this lock does not prevent all concurrent UE accesses (e.g., there are many loops over UEs that are not protected), so it's also wrong. --- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c | 3 +-- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c | 8 ++------ openair2/LAYER2/NR_MAC_gNB/main.c | 3 --- openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h | 1 - 4 files changed, 3 insertions(+), 12 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c index 5e9cd47a79..520aa6dfe1 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c @@ -2115,10 +2115,9 @@ static void nr_fill_rar(uint8_t Mod_idP, NR_UE_info_t *UE, uint8_t *dlsch_buffer * The corresponding function to add is add_new_UE_RA(). */ void nr_release_ra_UE(gNB_MAC_INST *mac, rnti_t rnti) { + NR_SCHED_ENSURE_LOCKED(&mac->sched_lock); NR_UEs_t *UE_info = &mac->UE_info; - NR_SCHED_LOCK(&UE_info->mutex); NR_UE_info_t *UE = remove_UE_from_list(NR_NB_RA_PROC_MAX, UE_info->access_ue_list, rnti); - NR_SCHED_UNLOCK(&UE_info->mutex); if (UE) { delete_nr_ue_data(UE, mac->common_channels, &UE_info->uid_allocator); } else { diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c index 4e55941420..d5cda66b5b 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c @@ -3033,18 +3033,17 @@ bool transition_ra_connected_nr_ue(gNB_MAC_INST *nr_mac, NR_UE_info_t *UE) * To remove the UE, use mac_remove_nr_ue(). */ bool add_connected_nr_ue(gNB_MAC_INST *nr_mac, NR_UE_info_t *UE) { + NR_SCHED_ENSURE_LOCKED(&nr_mac->sched_lock); + LOG_I(NR_MAC, "Adding new UE context with RNTI 0x%04x\n", UE->rnti); NR_UEs_t *UE_info = &nr_mac->UE_info; dump_nr_list(UE_info->connected_ue_list); AssertFatal(!UE->ra, "UE in connected cannot have RA process\n"); - NR_SCHED_LOCK(&UE_info->mutex); - bool success = add_UE_to_list(MAX_MOBILES_PER_GNB, UE_info->connected_ue_list, UE); if (!success) { LOG_E(NR_MAC,"Try to add UE %04x but the list is full\n", UE->rnti); delete_nr_ue_data(UE, NULL, &UE_info->uid_allocator); - NR_SCHED_UNLOCK(&UE_info->mutex); return false; } @@ -3057,7 +3056,6 @@ bool add_connected_nr_ue(gNB_MAC_INST *nr_mac, NR_UE_info_t *UE) init_bler_stats(&nr_mac->dl_bler, &sched_ctrl->dl_bler_stats, nr_mac->frame); init_bler_stats(&nr_mac->ul_bler, &sched_ctrl->ul_bler_stats, nr_mac->frame); - NR_SCHED_UNLOCK(&UE_info->mutex); dump_nr_list(UE_info->connected_ue_list); return true; } @@ -3110,9 +3108,7 @@ void mac_remove_nr_ue(gNB_MAC_INST *nr_mac, rnti_t rnti) /* already mutex protected */ NR_SCHED_ENSURE_LOCKED(&nr_mac->sched_lock); NR_UEs_t *UE_info = &nr_mac->UE_info; - NR_SCHED_LOCK(&UE_info->mutex); NR_UE_info_t *UE = remove_UE_from_list(MAX_MOBILES_PER_GNB + 1, UE_info->connected_ue_list, rnti); - NR_SCHED_UNLOCK(&UE_info->mutex); if (UE) delete_nr_ue_data(UE, nr_mac->common_channels, &UE_info->uid_allocator); else diff --git a/openair2/LAYER2/NR_MAC_gNB/main.c b/openair2/LAYER2/NR_MAC_gNB/main.c index 4b8196fc1b..ec8fe2010d 100644 --- a/openair2/LAYER2/NR_MAC_gNB/main.c +++ b/openair2/LAYER2/NR_MAC_gNB/main.c @@ -127,7 +127,6 @@ size_t dump_mac_stats(gNB_MAC_INST *gNB, char *output, size_t strlen, bool reset * scheduler to be locked*/ NR_SCHED_ENSURE_LOCKED(&gNB->sched_lock); - NR_SCHED_LOCK(&gNB->UE_info.mutex); UE_iterator(gNB->UE_info.connected_ue_list, UE) { NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; NR_mac_stats_t *stats = &UE->mac_stats; @@ -237,7 +236,6 @@ size_t dump_mac_stats(gNB_MAC_INST *gNB, char *output, size_t strlen, bool reset stats->ul.lc_bytes[c->lcid]); } } - NR_SCHED_UNLOCK(&gNB->UE_info.mutex); return output - begin; } @@ -304,7 +302,6 @@ void mac_top_init_gNB(ngran_node_t node_type, pthread_mutex_init(&RC.nrmac[i]->sched_lock, NULL); - pthread_mutex_init(&RC.nrmac[i]->UE_info.mutex, NULL); uid_linear_allocator_init(&RC.nrmac[i]->UE_info.uid_allocator); if (get_softmodem_params()->phy_test) { diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h index 026d8d563e..a5b21d2bc0 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h +++ b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h @@ -797,7 +797,6 @@ typedef struct { typedef struct { /// scheduling control info // last element always NULL - pthread_mutex_t mutex; NR_UE_info_t *connected_ue_list[MAX_MOBILES_PER_GNB + 1]; NR_UE_info_t *access_ue_list[NR_NB_RA_PROC_MAX + 1]; // bitmap of CSI-RS already scheduled in current slot From 48faffc131efcdf90e34cca0c81bbe4dbd1f7370 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Fri, 24 Oct 2025 14:19:05 +0200 Subject: [PATCH 08/69] dump_mac_stats(): avoid overflow The call to snprintf() as was used is wrong: we use the return value to advance output, but the man page says > The functions snprintf() and vsnprintf() do not write more than size > bytes (including the terminating null byte ('\0')). If the output was > truncated due to this limit, then the return value is the number of > characters (excluding the terminating null byte) which would have been > written to the final string if enough space had been available. > Thus, a return value of size or more means that the output was > truncated. Thus, output could go beyond end, and we get a stack overflow. Instead, encapsulate the call to snprintf() checking this condition, and only advancing output as intended, limiting to 0 if we are at the end of the buffer. This avoids this error: ==964825==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7be799f51988 at pc 0x7fe7d66b0d39 bp 0x7be79b825ef0 sp 0x7be79b8256c0 WRITE of size 3 at 0x7be799f51988 thread T24 #0 0x7fe7d66b0d38 in vsnprintf (/lib64/libasan.so.8+0xb0d38) (BuildId: 10b8ccd49f75c21babf1d7abe51bb63589d8471f) #1 0x7fe7d66b2d44 in snprintf (/lib64/libasan.so.8+0xb2d44) (BuildId: 10b8ccd49f75c21babf1d7abe51bb63589d8471f) #2 0x0000008fe7c6 in dump_mac_stats /home/richie/w/refactor-dlsch/openair2/LAYER2/NR_MAC_gNB/main.c:183 #3 0x00000092071a in gNB_dlsch_ulsch_scheduler /home/richie/w/refactor-dlsch/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c:200 #4 0x0000008f8f78 in run_scheduler_monolithic /home/richie/w/refactor-dlsch/openair2/NR_PHY_INTERFACE/NR_IF_Module.c:399 --- openair2/LAYER2/NR_MAC_gNB/main.c | 70 ++++++++++++++++++------------- 1 file changed, 42 insertions(+), 28 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/main.c b/openair2/LAYER2/NR_MAC_gNB/main.c index ec8fe2010d..705bca639a 100644 --- a/openair2/LAYER2/NR_MAC_gNB/main.c +++ b/openair2/LAYER2/NR_MAC_gNB/main.c @@ -118,6 +118,19 @@ void clear_mac_stats(gNB_MAC_INST *gNB) { } } +static char *st_append(char *start, const char *end, const char *format, ...) +{ + size_t space = end - start; + va_list args; + va_start(args, format); + size_t written = vsnprintf(start, space, format, args); + va_end(args); + if (written <= space) + return start + written; + else + return (char *)end; +} + size_t dump_mac_stats(gNB_MAC_INST *gNB, char *output, size_t strlen, bool reset_rsrp) { const char *begin = output; @@ -133,39 +146,39 @@ size_t dump_mac_stats(gNB_MAC_INST *gNB, char *output, size_t strlen, bool reset const int avg_rsrp = stats->num_rsrp_meas > 0 ? stats->cumul_rsrp / stats->num_rsrp_meas : 0; const int avg_sinrx10 = stats->num_sinr_meas > 0 ? stats->cumul_sinrx10 / stats->num_sinr_meas : 0; - output += snprintf(output, end - output, "UE RNTI %04x CU-UE-ID ", UE->rnti); + output = st_append(output, end, "UE RNTI %04x CU-UE-ID ", UE->rnti); if (du_exists_f1_ue_data(UE->rnti)) { f1_ue_data_t ued = du_get_f1_ue_data(UE->rnti); - output += snprintf(output, end - output, "%d", ued.secondary_ue); + output = st_append(output, end, "%d", ued.secondary_ue); } else { - output += snprintf(output, end - output, "(none)"); + output = st_append(output, end, "(none)"); } bool in_sync = !sched_ctrl->ul_failure; - output += snprintf(output, - end - output, + output = st_append(output, + end, " %s PH %d dB PCMAX %d dBm", in_sync ? "in-sync" : "out-of-sync", sched_ctrl->ph, sched_ctrl->pcmax); if (stats->num_rsrp_meas) - output += snprintf(output, end - output, ", average RSRP %d (%d meas)", avg_rsrp, stats->num_rsrp_meas); + output = st_append(output, end, ", average RSRP %d (%d meas)", avg_rsrp, stats->num_rsrp_meas); if (stats->num_sinr_meas) { - output += snprintf(output, - end - output, + output = st_append(output, + end, ", average SINR %d.%d (%d meas)", avg_sinrx10 / 10, avg_sinrx10 % 10, stats->num_sinr_meas); } - output += snprintf(output, end - output, "\n"); + output = st_append(output, end, "\n"); if(sched_ctrl->CSI_report.cri_ri_li_pmi_cqi_report.print_report) - output += snprintf(output, - end - output, + output = st_append(output, + end, "UE %04x: CQI %d, RI %d, PMI (%d,%d)\n", UE->rnti, sched_ctrl->CSI_report.cri_ri_li_pmi_cqi_report.wb_cqi_1tb, @@ -174,18 +187,18 @@ size_t dump_mac_stats(gNB_MAC_INST *gNB, char *output, size_t strlen, bool reset sched_ctrl->CSI_report.cri_ri_li_pmi_cqi_report.pmi_x2); if (stats->srs_stats[0] != '\0') { - output += snprintf(output, end - output, "UE %04x: %s\n", UE->rnti, stats->srs_stats); + output = st_append(output, end, "UE %04x: %s\n", UE->rnti, stats->srs_stats); } - output += snprintf(output, - end - output, + output = st_append(output, + end, "UE %04x: dlsch_rounds ", UE->rnti); - output += snprintf(output, end - output, "%"PRIu64, stats->dl.rounds[0]); + output = st_append(output, end, "%"PRIu64, stats->dl.rounds[0]); for (int i = 1; i < gNB->dl_bler.harq_round_max; i++) - output += snprintf(output, end - output, "/%"PRIu64, stats->dl.rounds[i]); + output = st_append(output, end, "/%"PRIu64, stats->dl.rounds[i]); - output += snprintf(output, - end - output, + output = st_append(output, + end, ", dlsch_errors %"PRIu64", pucch0_DTX %d, BLER %.5f MCS (%d) %d CCE fail %d\n", stats->dl.errors, stats->pucch0_DTX, @@ -199,15 +212,15 @@ size_t dump_mac_stats(gNB_MAC_INST *gNB, char *output, size_t strlen, bool reset stats->num_sinr_meas = 0; stats->cumul_sinrx10 = 0; } - output += snprintf(output, - end - output, + output = st_append(output, + end, "UE %04x: ulsch_rounds ", UE->rnti); - output += snprintf(output, end - output, "%"PRIu64, stats->ul.rounds[0]); + output = st_append(output, end, "%"PRIu64, stats->ul.rounds[0]); for (int i = 1; i < gNB->ul_bler.harq_round_max; i++) - output += snprintf(output, end - output, "/%"PRIu64, stats->ul.rounds[i]); + output = st_append(output, end, "/%"PRIu64, stats->ul.rounds[i]); - output += snprintf(output, - end - output, + output = st_append(output, + end, ", ulsch_errors %"PRIu64", ulsch_DTX %d, BLER %.5f MCS (%d) %d (Qm %d deltaMCS %d dB) NPRB %d SNR %d.%d dB CCE fail %d\n", stats->ul.errors, stats->ulsch_DTX, @@ -220,15 +233,15 @@ size_t dump_mac_stats(gNB_MAC_INST *gNB, char *output, size_t strlen, bool reset sched_ctrl->pusch_snrx10 / 10, sched_ctrl->pusch_snrx10 % 10, sched_ctrl->ul_cce_fail); - output += snprintf(output, - end - output, + output = st_append(output, + end, "UE %04x: MAC: TX %14"PRIu64" RX %14"PRIu64" bytes\n", UE->rnti, stats->dl.total_bytes, stats->ul.total_bytes); for (int i = 0; i < seq_arr_size(&sched_ctrl->lc_config); i++) { const nr_lc_config_t *c = seq_arr_at(&sched_ctrl->lc_config, i); - output += snprintf(output, - end - output, + output = st_append(output, + end, "UE %04x: LCID %d: TX %14"PRIu64" RX %14"PRIu64" bytes\n", UE->rnti, c->lcid, @@ -236,6 +249,7 @@ size_t dump_mac_stats(gNB_MAC_INST *gNB, char *output, size_t strlen, bool reset stats->ul.lc_bytes[c->lcid]); } } + DevAssert(output <= end); return output - begin; } From 6549acdba9c7f0a2a08b757782f278c6b7c27be4 Mon Sep 17 00:00:00 2001 From: francescomani Date: Tue, 28 Oct 2025 18:06:39 +0100 Subject: [PATCH 09/69] fix for CSI payload sizes in PUCCH structure at UE --- openair2/LAYER2/NR_MAC_UE/mac_defs.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_UE/mac_defs.h b/openair2/LAYER2/NR_MAC_UE/mac_defs.h index f8b9f18c11..b43937d362 100644 --- a/openair2/LAYER2/NR_MAC_UE/mac_defs.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_defs.h @@ -307,8 +307,8 @@ typedef struct { NR_PUCCH_Resource_t *pucch_resource; uint32_t ack_payload; uint8_t sr_payload; - uint32_t csi_part1_payload; - uint32_t csi_part2_payload; + uint64_t csi_part1_payload; + uint64_t csi_part2_payload; int n_sr; int n_csi; int n_harq; From 93cadc9d631415b3e3948fdc93336edea28714eb Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Tue, 28 Oct 2025 12:01:38 +0100 Subject: [PATCH 10/69] Truncate nrL1_stats.log before writing Without this, the remainder of the file remains in place, and this can be confusing if the total file size reduces. --- executables/nr-gnb.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/executables/nr-gnb.c b/executables/nr-gnb.c index 2be0ee80ad..aa1a496559 100644 --- a/executables/nr-gnb.c +++ b/executables/nr-gnb.c @@ -314,13 +314,16 @@ void *nrL1_stats_thread(void *param) { reset_meas(&gNB->dlsch_precoding_stats); while (!oai_exit) { sleep(1); + if (ftruncate(fileno(fd), 0) != 0 || fseek(fd, 0, SEEK_SET) != 0) { + LOG_E(NR_MAC, "error while writing nrL1_stats.log: %d, %s\n", errno, strerror(errno)); + break; + } dump_nr_I0_stats(fd,gNB); dump_pdsch_stats(fd,gNB); dump_pusch_stats(fd,gNB); dump_L1_meas_stats(gNB, ru, output, L1STATSSTRLEN); fprintf(fd,"%s\n",output); fflush(fd); - fseek(fd,0,SEEK_SET); } fclose(fd); return(NULL); From e57789adb2725756af4e6c49c8f1eb2a2969c621 Mon Sep 17 00:00:00 2001 From: francescomani Date: Wed, 29 Oct 2025 10:52:39 +0100 Subject: [PATCH 11/69] prevent assertion in case of no measurements configured for CSI-RS at UE --- openair1/PHY/NR_UE_TRANSPORT/csi_rx.c | 5 +++++ openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c | 1 - 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/openair1/PHY/NR_UE_TRANSPORT/csi_rx.c b/openair1/PHY/NR_UE_TRANSPORT/csi_rx.c index c28830e4d7..26cad50f12 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/csi_rx.c +++ b/openair1/PHY/NR_UE_TRANSPORT/csi_rx.c @@ -905,6 +905,11 @@ void nr_ue_csi_rs_procedures(PHY_VARS_NR_UE *ue, rxdataF); + if (csirs_config_pdu->measurement_bitmap == 0) { + LOG_D(NR_PHY, "No CSI-RS measurements configured\n"); + return; + } + uint32_t noise_power = 0; int16_t log2_re = 0; int16_t log2_maxh = 0; diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c index 3825a49fd2..714d2eacfd 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c @@ -1918,7 +1918,6 @@ uint8_t set_csirs_measurement_bitmap(NR_CSI_MeasConfig_t *csi_measconfig, NR_CSI AssertFatal(false, "Unexpected measurement report type %d\n", report_config->reportQuantity.present); } } - AssertFatal(meas_bitmap > 0, "Expected to have at least 1 measurement configured for CSI-RS\n"); return meas_bitmap; } From 5e32eb67f6a909c5f0c96db6e4b37bb7c6203a47 Mon Sep 17 00:00:00 2001 From: francescomani Date: Wed, 29 Oct 2025 11:02:19 +0100 Subject: [PATCH 12/69] remove unnecessary do_CSIRS from CI config files --- ci-scripts/conf_files/gnb-du.sa.band78.106prb.usrpb200.conf | 1 - .../conf_files/gnb.sa.band78.106prb.rfsim.neighbour.conf | 2 -- ci-scripts/conf_files/gnb.sa.band78.51prb.aw2s.ddsuu.conf | 4 ---- .../conf_files/untested/gnb.sa.band78.fr1.51PRB.usrpb210.conf | 3 --- 4 files changed, 10 deletions(-) diff --git a/ci-scripts/conf_files/gnb-du.sa.band78.106prb.usrpb200.conf b/ci-scripts/conf_files/gnb-du.sa.band78.106prb.usrpb200.conf index 23475e3838..4daf7c62fd 100644 --- a/ci-scripts/conf_files/gnb-du.sa.band78.106prb.usrpb200.conf +++ b/ci-scripts/conf_files/gnb-du.sa.band78.106prb.usrpb200.conf @@ -23,7 +23,6 @@ gNBs = ////////// Physical parameters: min_rxtxtime = 2; - do_CSIRS = 1; do_SRS = 1; servingCellConfigCommon = ( diff --git a/ci-scripts/conf_files/gnb.sa.band78.106prb.rfsim.neighbour.conf b/ci-scripts/conf_files/gnb.sa.band78.106prb.rfsim.neighbour.conf index 6322d1463c..7bfceaf620 100644 --- a/ci-scripts/conf_files/gnb.sa.band78.106prb.rfsim.neighbour.conf +++ b/ci-scripts/conf_files/gnb.sa.band78.106prb.rfsim.neighbour.conf @@ -18,8 +18,6 @@ gNBs = ////////// Physical parameters: - do_CSIRS = 0; - do_SRS = 0; min_rxtxtime = 6; servingCellConfigCommon = ( diff --git a/ci-scripts/conf_files/gnb.sa.band78.51prb.aw2s.ddsuu.conf b/ci-scripts/conf_files/gnb.sa.band78.51prb.aw2s.ddsuu.conf index e9f3089019..69cf8b7330 100644 --- a/ci-scripts/conf_files/gnb.sa.band78.51prb.aw2s.ddsuu.conf +++ b/ci-scripts/conf_files/gnb.sa.band78.51prb.aw2s.ddsuu.conf @@ -21,10 +21,6 @@ gNBs = nr_cellid = 12345678L ////////// Physical parameters: - pdsch_AntennaPorts_XP = 1; - pusch_AntennaPorts = 1; - do_CSIRS = 1; - do_SRS = 0; uess_agg_levels = [2, 2, 2, 0, 0]; servingCellConfigCommon = ( diff --git a/ci-scripts/conf_files/untested/gnb.sa.band78.fr1.51PRB.usrpb210.conf b/ci-scripts/conf_files/untested/gnb.sa.band78.fr1.51PRB.usrpb210.conf index 7242b91190..7bdbe7127c 100644 --- a/ci-scripts/conf_files/untested/gnb.sa.band78.fr1.51PRB.usrpb210.conf +++ b/ci-scripts/conf_files/untested/gnb.sa.band78.fr1.51PRB.usrpb210.conf @@ -17,9 +17,6 @@ gNBs = ////////// Physical parameters: - do_CSIRS = 0; - do_SRS = 0; - servingCellConfigCommon = ( { #spCellConfigCommon From 10bda8417637ee0ba11d720903320c537631fc29 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Wed, 22 Oct 2025 11:36:47 +0200 Subject: [PATCH 13/69] Limit statistics of UE to configurable threshold The gNB will stop the periodical logging of UEs in MAC Info level after a configurable number of UEs have been printed, by default 8. Set it to 17 in some CI tests to ensure we still get all UEs for the time being, as the CI might depend on this. --- .../conf_files/gnb.sa.band78.106prb.rfsim.yaml | 1 + .../gnb.sa.band78.51prb.aw2s.ddsuu.conf | 1 + doc/MAC/mac-usage.md | 3 +++ openair2/GNB_APP/MACRLC_nr_paramdef.h | 5 +++++ openair2/GNB_APP/gnb_config.c | 2 ++ openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c | 15 ++++++++++++++- openair2/LAYER2/NR_MAC_gNB/main.c | 2 ++ openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h | 5 +++++ 8 files changed, 33 insertions(+), 1 deletion(-) diff --git a/ci-scripts/conf_files/gnb.sa.band78.106prb.rfsim.yaml b/ci-scripts/conf_files/gnb.sa.band78.106prb.rfsim.yaml index 6240b62104..918bdc9802 100644 --- a/ci-scripts/conf_files/gnb.sa.band78.106prb.rfsim.yaml +++ b/ci-scripts/conf_files/gnb.sa.band78.106prb.rfsim.yaml @@ -146,6 +146,7 @@ MACRLCs: tr_n_preference: local_RRC pusch_TargetSNRx10: 200 pucch_TargetSNRx10: 200 + stats_max_ue: 17 L1s: - num_cc: 1 diff --git a/ci-scripts/conf_files/gnb.sa.band78.51prb.aw2s.ddsuu.conf b/ci-scripts/conf_files/gnb.sa.band78.51prb.aw2s.ddsuu.conf index e9f3089019..95e86caefe 100644 --- a/ci-scripts/conf_files/gnb.sa.band78.51prb.aw2s.ddsuu.conf +++ b/ci-scripts/conf_files/gnb.sa.band78.51prb.aw2s.ddsuu.conf @@ -186,6 +186,7 @@ MACRLCs = ( tr_n_preference = "local_RRC"; pusch_TargetSNRx10 = 200; pucch_TargetSNRx10 = 200; + stats_max_ue = 17; } ); diff --git a/doc/MAC/mac-usage.md b/doc/MAC/mac-usage.md index f4583b7a23..09ef02c560 100644 --- a/doc/MAC/mac-usage.md +++ b/doc/MAC/mac-usage.md @@ -236,6 +236,9 @@ In the `MACRLCs` section of the gNB/DU configuration file: case RSSI reaches the threshold and prevents ADC railing. Unit depends on RSSI reporting config. * `pucch_RSSI_Threshold`: Same as above but for PUCCH +* `stats_max_ue` (default 8): maximum number of UEs to show in periodical + stats; beyond this number, periodical statistics will be disabled (it can + still be seen in `nrMAC_stats.log`. Use `0` to disable periodical stats. In the `gNBs` section of the gNB/DU configuration file: some of the parameters affect RRC configuration (CellGroupConfig) of a UE, and are therefore listed diff --git a/openair2/GNB_APP/MACRLC_nr_paramdef.h b/openair2/GNB_APP/MACRLC_nr_paramdef.h index a6299b10cc..6bd02cf74a 100644 --- a/openair2/GNB_APP/MACRLC_nr_paramdef.h +++ b/openair2/GNB_APP/MACRLC_nr_paramdef.h @@ -79,6 +79,7 @@ #define CONFIG_STRING_MACRLC_BEAM_WEIGHTS_LIST "beam_weights" #define CONFIG_STRING_MACRLC_PUSCH_RSSI_THRESHOLD "pusch_RSSI_Threshold" #define CONFIG_STRING_MACRLC_PUCCH_RSSI_THRESHOLD "pucch_RSSI_Threshold" +#define CONFIG_STRING_MACRLC_STATS_MAX_UE "stats_max_ue" #define HLP_MACRLC_UL_PRBBLACK "SNR threshold to decide whether a PRB will be blacklisted or not" #define HLP_MACRLC_DL_BLER_UP "Upper threshold of BLER to decrease DL MCS" @@ -98,6 +99,7 @@ #define HLP_MACRLC_BEAMS_PERIOD "set of beams that can be simultaneously allocated in a period" #define HLP_MACRLC_PUSCH_RSSI_THRESHOLD "Limits PUSCH TPC commands based on RSSI to prevent ADC railing. Value range [-1280, 0], unit 0.1 dBm/dBFS" #define HLP_MACRLC_PUCCH_RSSI_THRESHOLD "Limits PUCCH TPC commands based on RSSI to prevent ADC railing. Value range [-1280, 0], unit 0.1 dBm/dBFS" +#define HLP_MACRLC_STATS_MAX_UE "Maximum number of UEs before disabling periodical output (0 to disable)" /*-------------------------------------------------------------------------------------------------------------------------------------------------------*/ /* MacRLC configuration parameters */ @@ -149,6 +151,7 @@ 0, .iptr=NULL, .defintval=0, TYPE_INT, 0}, \ {CONFIG_STRING_MACRLC_PUCCH_RSSI_THRESHOLD, HLP_MACRLC_PUCCH_RSSI_THRESHOLD, \ 0, .iptr=NULL, .defintval=0, TYPE_INT, 0}, \ + {CONFIG_STRING_MACRLC_STATS_MAX_UE, HLP_MACRLC_STATS_MAX_UE, 0, .iptr=NULL, .defintval=8, TYPE_INT, 0}, \ } // clang-format off @@ -194,6 +197,7 @@ #define MACRLC_BEAMWEIGHTS_IDX 39 #define MACRLC_PUSCH_RSSI_THRES_IDX 40 #define MACRLC_PUCCH_RSSI_THRES_IDX 41 +#define MACRLC_STATS_MAX_UE_IDX 42 #define MACRLCPARAMS_CHECK { \ { .s5 = { NULL } }, \ @@ -238,6 +242,7 @@ { .s5 = { NULL } }, \ { .s2 = { config_check_intrange, {-1280, 0}} }, /* PUSCH RSSI threshold range */ \ { .s2 = { config_check_intrange, {-1280, 0}} }, /* PUCCH RSSI threshold range */ \ + { .s5 = { NULL } }, \ } /*---------------------------------------------------------------------------------------------------------------------------------------------------------*/ diff --git a/openair2/GNB_APP/gnb_config.c b/openair2/GNB_APP/gnb_config.c index 45532572cd..bd49df26be 100644 --- a/openair2/GNB_APP/gnb_config.c +++ b/openair2/GNB_APP/gnb_config.c @@ -1580,6 +1580,8 @@ void RCconfig_nr_macrlc(configmodule_interface_t *cfg) AssertFatal(1 == 0, "MACRLC %d: %s unknown southbound midhaul\n", j, *(MacRLC_ParamList.paramarray[j][MACRLC_TRANSPORT_S_PREFERENCE_IDX].strptr)); } RC.nrmac[j]->ulsch_max_frame_inactivity = *(MacRLC_ParamList.paramarray[j][MACRLC_ULSCH_MAX_FRAME_INACTIVITY].uptr); + RC.nrmac[j]->stats_max_ue = *MacRLC_ParamList.paramarray[j][MACRLC_STATS_MAX_UE_IDX].iptr; + RC.nrmac[j]->print_ue_stats = RC.nrmac[j]->stats_max_ue > 0; NR_bler_options_t *dl_bler_options = &RC.nrmac[j]->dl_bler; dl_bler_options->upper = *(MacRLC_ParamList.paramarray[j][MACRLC_DL_BLER_TARGET_UPPER_IDX].dblptr); dl_bler_options->lower = *(MacRLC_ParamList.paramarray[j][MACRLC_DL_BLER_TARGET_LOWER_IDX].dblptr); diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c index 46ad8069da..a102411721 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c @@ -195,10 +195,23 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP, frame_t frame, slot_t slo } bool wait_prach_completed = gNB->num_scheduled_prach_rx >= NUM_PRACH_RX_FOR_NOISE_ESTIMATE; - if ((wait_prach_completed || get_softmodem_params()->phy_test) && (slot == 0) && (frame & 127) == 0) { + if (gNB->print_ue_stats && (wait_prach_completed || get_softmodem_params()->phy_test) && (slot == 0) && (frame & 127) == 0) { char stats_output[32656] = {0}; dump_mac_stats(gNB, stats_output, sizeof(stats_output), true); LOG_I(NR_MAC, "Frame.Slot %d.%d\n%s\n", frame, slot, stats_output); + + // TODO: this should be replaced with a size() operation on connected_ue_list + int num_ue = 0; + UE_iterator(gNB->UE_info.connected_ue_list, it) { + (void) it; // not used + num_ue++; + } + if (gNB->print_ue_stats && num_ue > gNB->stats_max_ue) { + gNB->print_ue_stats = false; + LOG_W(NR_MAC, + "periodical UE stats deactivated after reaching %d UEs, please check nrMAC_stats.log, or increase MACRLCs.[0].stats_max_ue\n", + gNB->stats_max_ue); + } } nr_measgap_scheduling(gNB, frame, slot); diff --git a/openair2/LAYER2/NR_MAC_gNB/main.c b/openair2/LAYER2/NR_MAC_gNB/main.c index 705bca639a..f3f070b0e7 100644 --- a/openair2/LAYER2/NR_MAC_gNB/main.c +++ b/openair2/LAYER2/NR_MAC_gNB/main.c @@ -314,6 +314,8 @@ void mac_top_init_gNB(ngran_node_t node_type, RC.nrmac[i]->cset0_bwp_start = 0; RC.nrmac[i]->cset0_bwp_size = 0; + RC.nrmac[i]->print_ue_stats = true; + pthread_mutex_init(&RC.nrmac[i]->sched_lock, NULL); uid_linear_allocator_init(&RC.nrmac[i]->UE_info.uid_allocator); diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h index a5b21d2bc0..5bd786df90 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h +++ b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h @@ -974,6 +974,11 @@ typedef struct gNB_MAC_INST_s { f1_config_t f1_config; int16_t frame; + /// number of UEs to exceed to disable stats + int stats_max_ue; + /// if stats are currently enabled + bool print_ue_stats; + pthread_mutex_t sched_lock; mac_stats_t mac_stats; From 91b3ca77f650a289b262269fde68a0e1eb750bcc Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Mon, 27 Oct 2025 17:16:43 +0100 Subject: [PATCH 14/69] QFI 0 is a valid QFI QFI 0 is a valid QFI: don't check for qfi <= 0, as uint8 cannot be negative. Also, correctly use SDAP_MAP_RULE_EMPTY for a DRB ID (which need to be larger than 0). --- openair2/SDAP/nr_sdap/nr_sdap_entity.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/openair2/SDAP/nr_sdap/nr_sdap_entity.c b/openair2/SDAP/nr_sdap/nr_sdap_entity.c index f0e791c683..9ff9e39471 100644 --- a/openair2/SDAP/nr_sdap/nr_sdap_entity.c +++ b/openair2/SDAP/nr_sdap/nr_sdap_entity.c @@ -210,8 +210,8 @@ static void nr_sdap_rx_entity(nr_sdap_entity_t *entity, { /* The offset of the SDAP header, it might be 0 if has_sdap_rx is not true in the pdcp entity. */ int offset=0; - int qfi = buf[0] & 0x3F; // QFI is always the first 6 bits in the first octet - if (qfi <= 0 || qfi >= SDAP_MAX_QFI) { + uint8_t qfi = buf[0] & 0x3F; // QFI is always the first 6 bits in the first octet + if (qfi >= SDAP_MAX_QFI) { LOG_E(SDAP, "Invalid QFI %d received in SDAP header\n", qfi); return; } @@ -450,7 +450,7 @@ static void nr_sdap_add_qos_flows_to_drb(nr_sdap_entity_t *entity, const sdap_co for (int i = 0; i < sdap->mappedQFIs2AddCount; i++) { uint8_t qfi = sdap->mappedQFIs2Add[i]; LOG_D(SDAP, "Adding QFI to DRB mapping rules: %d mapped QFIs for DRB %d\n", sdap->mappedQFIs2AddCount, sdap->drb_id); - if (qfi < SDAP_MAX_QFI && qfi > SDAP_MAP_RULE_EMPTY && sdap->drb_id > 0 && sdap->drb_id <= MAX_DRBS_PER_UE) { + if (qfi < SDAP_MAX_QFI && sdap->drb_id > SDAP_MAP_RULE_EMPTY && sdap->drb_id <= MAX_DRBS_PER_UE) { entity->qfi2drb_map_add(entity, qfi, sdap->drb_id, sdap->role); } else { LOG_E(SDAP, "Failed to add qfi2drb mapping: QFI=%d, DRB=%d\n", qfi, sdap->drb_id); From a416db39ba44806ce1750fb75493897df5d9a400 Mon Sep 17 00:00:00 2001 From: Guido Casati Date: Mon, 27 Oct 2025 18:05:22 +0100 Subject: [PATCH 15/69] Pass SDAP config by pointer sdap_config_t is more than 1kB large. Avoid excessive copying by passing it by reference. --- openair2/LAYER2/nr_pdcp/cucp_cuup_handler.c | 2 +- openair2/RRC/NR/rrc_gNB_nsa.c | 2 +- openair2/RRC/NR_UE/rrc_UE.c | 2 +- openair2/SDAP/nr_sdap/nr_sdap_entity.c | 16 ++++++++-------- openair2/SDAP/nr_sdap/nr_sdap_entity.h | 2 +- 5 files changed, 12 insertions(+), 12 deletions(-) diff --git a/openair2/LAYER2/nr_pdcp/cucp_cuup_handler.c b/openair2/LAYER2/nr_pdcp/cucp_cuup_handler.c index ed9cc37c18..4b95963257 100644 --- a/openair2/LAYER2/nr_pdcp/cucp_cuup_handler.c +++ b/openair2/LAYER2/nr_pdcp/cucp_cuup_handler.c @@ -153,7 +153,7 @@ static void e1_add_bearers(const int ue_id, const NR_DRB_ToAddModList_t *addMod, // get SDAP config sdap_config_t sdap = nr_sdap_get_config(GNB_FLAG_YES, drb->cnAssociation->choice.sdap_Config, drb->drb_Identity); // add SDAP entity - nr_sdap_addmod_entity(GNB_FLAG_YES, ue_id, sdap); + nr_sdap_addmod_entity(GNB_FLAG_YES, ue_id, &sdap); // add PDCP entity nr_pdcp_add_drb(GNB_FLAG_YES, ue_id, drb->pdcp_Config, &sdap, sp); } diff --git a/openair2/RRC/NR/rrc_gNB_nsa.c b/openair2/RRC/NR/rrc_gNB_nsa.c index 996dc3528e..3e3c462145 100644 --- a/openair2/RRC/NR/rrc_gNB_nsa.c +++ b/openair2/RRC/NR/rrc_gNB_nsa.c @@ -177,7 +177,7 @@ static void rrc_nsa_add_drb(const int ue_id, sdap.drb_id = drb->drb_Identity; sdap.defaultDRB = true; // add SDAP entity (terminated at gNB, since it's EPC) - nr_sdap_addmod_entity(GNB_FLAG_YES, ue_id, sdap); + nr_sdap_addmod_entity(GNB_FLAG_YES, ue_id, &sdap); // add PDCP entity nr_pdcp_add_drb(GNB_FLAG_YES, ue_id, drb->pdcp_Config, &sdap, sp); } diff --git a/openair2/RRC/NR_UE/rrc_UE.c b/openair2/RRC/NR_UE/rrc_UE.c index 6681eed855..15c713cb26 100644 --- a/openair2/RRC/NR_UE/rrc_UE.c +++ b/openair2/RRC/NR_UE/rrc_UE.c @@ -619,7 +619,7 @@ static void rrc_ue_add_bearer(const int ue_id, const NR_DRB_ToAddMod_t *drb, con sdap = nr_sdap_get_config(GNB_FLAG_NO, drb->cnAssociation->choice.sdap_Config, drb->drb_Identity); } // add SDAP entity - nr_sdap_addmod_entity(GNB_FLAG_NO, ue_id, sdap); + nr_sdap_addmod_entity(GNB_FLAG_NO, ue_id, &sdap); // add PDCP entity nr_pdcp_add_drb(GNB_FLAG_NO, ue_id, drb->pdcp_Config, &sdap, sp); } diff --git a/openair2/SDAP/nr_sdap/nr_sdap_entity.c b/openair2/SDAP/nr_sdap/nr_sdap_entity.c index 9ff9e39471..389213986e 100644 --- a/openair2/SDAP/nr_sdap/nr_sdap_entity.c +++ b/openair2/SDAP/nr_sdap/nr_sdap_entity.c @@ -487,13 +487,13 @@ static void nr_sdap_qfi2drb_map_update(nr_sdap_entity_t *entity, const sdap_conf * @param is_gnb, indicates whether it is for gNB or UE * @param ue_id, UE ID * @param sdap, SDAP configuration */ -static void nr_sdap_add_entity(const int is_gnb, const ue_id_t ue_id, const sdap_config_t sdap) +static void nr_sdap_add_entity(const int is_gnb, const ue_id_t ue_id, const sdap_config_t *sdap) { nr_sdap_entity_t *sdap_entity = calloc_or_fail(1, sizeof(*sdap_entity)); // SDAP entity ids sdap_entity->ue_id = ue_id; - sdap_entity->pdusession_id = sdap.pdusession_id; + sdap_entity->pdusession_id = sdap->pdusession_id; sdap_entity->is_gnb = is_gnb; // rx/tx entities @@ -513,13 +513,13 @@ static void nr_sdap_add_entity(const int is_gnb, const ue_id_t ue_id, const sdap sdap_entity->pdusession_sock = -1; // set default DRB - if (sdap.defaultDRB) { - sdap_entity->default_drb = sdap.drb_id; + if (sdap->defaultDRB) { + sdap_entity->default_drb = sdap->drb_id; LOG_I(SDAP, "Default DRB for the created SDAP entity: DRB %d \n", sdap_entity->default_drb); } // Add QoS flows to the DRB (initial configuration) - nr_sdap_add_qos_flows_to_drb(sdap_entity, &sdap); + nr_sdap_add_qos_flows_to_drb(sdap_entity, sdap); // update SDAP entity list pointers sdap_entity->next_entity = sdap_info.sdap_entity_llist; @@ -533,11 +533,11 @@ static void nr_sdap_add_entity(const int is_gnb, const ue_id_t ue_id, const sdap } /** @brief Add or modify an SDAP entity if it already exists */ -void nr_sdap_addmod_entity(const int is_gnb, const ue_id_t ue_id, const sdap_config_t sdap) +void nr_sdap_addmod_entity(const int is_gnb, const ue_id_t ue_id, const sdap_config_t *sdap) { - nr_sdap_entity_t *sdap_entity = nr_sdap_get_entity(ue_id, sdap.pdusession_id); + nr_sdap_entity_t *sdap_entity = nr_sdap_get_entity(ue_id, sdap->pdusession_id); if (sdap_entity) { - sdap_entity->qfi2drb_map_update(sdap_entity, &sdap); + sdap_entity->qfi2drb_map_update(sdap_entity, sdap); } else { nr_sdap_add_entity(is_gnb, ue_id, sdap); } diff --git a/openair2/SDAP/nr_sdap/nr_sdap_entity.h b/openair2/SDAP/nr_sdap/nr_sdap_entity.h index a206189035..e96836ac79 100644 --- a/openair2/SDAP/nr_sdap/nr_sdap_entity.h +++ b/openair2/SDAP/nr_sdap/nr_sdap_entity.h @@ -172,7 +172,7 @@ sdap_config_t nr_sdap_get_config(const int is_gnb, const NR_SDAP_Config_t *sdap_ void nr_sdap_release_drb(ue_id_t ue_id, int drb_id, int pdusession_id); /** @brief Add or modify an SDAP entity based on whether it already exists */ -void nr_sdap_addmod_entity(const int is_gnb, const ue_id_t ue_id, const sdap_config_t sdap); +void nr_sdap_addmod_entity(const int is_gnb, const ue_id_t ue_id, const sdap_config_t *sdap); /** * @brief Function to delete a single SDAP Entity based on the ue_id and pdusession_id. From 459e20fe99e6b4666e8e2f679ca6ccf2d74a2027 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Mon, 27 Oct 2025 18:47:19 +0100 Subject: [PATCH 16/69] E1AP: correctly free entire PDU Free memory including the "base pointer". Fix two places in which it was on the stack to harmonize. The only stack variable is in reception of new E1 messages (e1ap_handle_message()), which uses ASN_STRUCT_FREE_CONTENTS_ONLY(). This fixes bugs similar to these logs: Direct leak of 40 byte(s) in 1 object(s) allocated from: #0 0x7f418f4e68a3 in calloc (/lib64/libasan.so.8+0xe68a3) (BuildId: 10b8ccd49f75c21babf1d7abe51bb63589d8471f) #1 0x00000049e367 in calloc_or_fail /home/richie/oai/common/utils/utils.h:74 #2 0x00000049e367 in encode_e1_bearer_context_release_command /home/richie/oai/openair2/E1AP/lib/e1ap_bearer_context_management.c:1235 #3 0x000000482951 in e1apCUCP_send_BEARER_CONTEXT_RELEASE_COMMAND /home/richie/oai/openair2/E1AP/e1ap.c:546 #4 0x000000482951 in E1AP_CUCP_task /home/richie/oai/openair2/E1AP/e1ap.c:856 #5 0x7f418f428ee5 in asan_thread_start(void*) (/lib64/libasan.so.8+0x28ee5) (BuildId: 10b8ccd49f75c21babf1d7abe51bb63589d8471f) Direct leak of 40 byte(s) in 1 object(s) allocated from: #0 0x7f418f4e68a3 in calloc (/lib64/libasan.so.8+0xe68a3) (BuildId: 10b8ccd49f75c21babf1d7abe51bb63589d8471f) #1 0x00000049380a in calloc_or_fail /home/richie/oai/common/utils/utils.h:74 #2 0x00000049380a in encode_E1_bearer_context_setup_request /home/richie/oai/openair2/E1AP/lib/e1ap_bearer_context_management.c:578 #3 0x00000047f6a2 in e1apCUCP_send_BEARER_CONTEXT_SETUP_REQUEST /home/richie/oai/openair2/E1AP/e1ap.c:378 #4 0x0000004829f8 in E1AP_CUCP_task /home/richie/oai/openair2/E1AP/e1ap.c:846 #5 0x7f418f428ee5 in asan_thread_start(void*) (/lib64/libasan.so.8+0x28ee5) (BuildId: 10b8ccd49f75c21babf1d7abe51bb63589d8471f) Direct leak of 40 byte(s) in 1 object(s) allocated from: #0 0x7f418f4e68a3 in calloc (/lib64/libasan.so.8+0xe68a3) (BuildId: 10b8ccd49f75c21babf1d7abe51bb63589d8471f) #1 0x00000046ede7 in calloc_or_fail /home/richie/oai/common/utils/utils.h:74 #2 0x00000046ede7 in encode_e1ap_cuup_setup_response /home/richie/oai/openair2/E1AP/lib/e1ap_interface_management.c:305 #3 0x00000047e412 in e1ap_send_SETUP_RESPONSE /home/richie/oai/openair2/E1AP/e1ap.c:167 #4 0x000000482a68 in E1AP_CUCP_task /home/richie/oai/openair2/E1AP/e1ap.c:836 #5 0x7f418f428ee5 in asan_thread_start(void*) (/lib64/libasan.so.8+0x28ee5) (BuildId: 10b8ccd49f75c21babf1d7abe51bb63589d8471f) --- openair2/E1AP/e1ap.c | 10 +++++----- openair2/E1AP/e1ap_common.c | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/openair2/E1AP/e1ap.c b/openair2/E1AP/e1ap.c index 1eff4ea529..168366f351 100644 --- a/openair2/E1AP/e1ap.c +++ b/openair2/E1AP/e1ap.c @@ -125,8 +125,8 @@ static void e1_task_handle_sctp_data_ind(instance_t instance, sctp_data_ind_t *s int e1ap_send_RESET(bool isCu, sctp_assoc_t assoc_id, E1AP_Reset_t *Reset) { AssertFatal(false, "Not implemented yet\n"); - E1AP_E1AP_PDU_t pdu = {0}; - return e1ap_encode_send(isCu, assoc_id, &pdu, 0, __func__); + E1AP_E1AP_PDU_t *pdu = calloc_or_fail(1, sizeof(*pdu)); + return e1ap_encode_send(isCu, assoc_id, pdu, 0, __func__); } int e1ap_send_RESET_ACKNOWLEDGE(instance_t instance, E1AP_Reset_t *Reset) @@ -304,9 +304,9 @@ static void fill_CONFIGURATION_UPDATE(E1AP_E1AP_PDU_t *pdu) void e1apCUUP_send_CONFIGURATION_UPDATE(sctp_assoc_t assoc_id) { - E1AP_E1AP_PDU_t pdu = {0}; - fill_CONFIGURATION_UPDATE(&pdu); - e1ap_encode_send(UPtype, assoc_id, &pdu, 0, __func__); + E1AP_E1AP_PDU_t *pdu = calloc_or_fail(1, sizeof(*pdu)); + fill_CONFIGURATION_UPDATE(pdu); + e1ap_encode_send(UPtype, assoc_id, pdu, 0, __func__); } int e1apCUCP_send_gNB_DU_CONFIGURATION_FAILURE(void) diff --git a/openair2/E1AP/e1ap_common.c b/openair2/E1AP/e1ap_common.c index 330d29567a..e102c7e151 100644 --- a/openair2/E1AP/e1ap_common.c +++ b/openair2/E1AP/e1ap_common.c @@ -226,7 +226,7 @@ int e1ap_encode_send(E1_t type, sctp_assoc_t assoc_id, E1AP_E1AP_PDU_t *pdu, uin void *buffer = NULL; ssize_t encoded = aper_encode_to_new_buffer(&asn_DEF_E1AP_E1AP_PDU, 0, pdu, &buffer); - ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_E1AP_E1AP_PDU, pdu); + ASN_STRUCT_FREE(asn_DEF_E1AP_E1AP_PDU, pdu); if (encoded < 0) { LOG_E(E1AP, "%s: Failed to encode E1AP message\n", func); From eee9c4cf33dbc9475947762539f06e8ad8440fe6 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Mon, 27 Oct 2025 18:50:45 +0100 Subject: [PATCH 17/69] Fix two direct memory leaks of CU-UP tester Direct leak of 100 byte(s) in 1 object(s) allocated from: #0 0x7f6585ee6f2b in malloc (/lib64/libasan.so.8+0xe6f2b) (BuildId: 10b8ccd49f75c21babf1d7abe51bb63589d8471f) #1 0x000000414a0d in malloc_or_fail /home/richie/oai/common/utils/utils.h:86 #2 0x0000004061c9 in main /home/richie/oai/tests/nr-cuup/nr-cuup-load-test.c:544 #3 0x7f6585211574 in __libc_start_call_main (/lib64/libc.so.6+0x3574) (BuildId: 48c4b9b1efb1df15da8e787f489128bf31893317) #4 0x7f6585211627 in __libc_start_main@GLIBC_2.2.5 (/lib64/libc.so.6+0x3627) (BuildId: 48c4b9b1efb1df15da8e787f489128bf31893317) #5 0x000000413034 in _start (/home/richie/oai/build/tests/nr-cuup/nr-cuup-load-test+0x413034) (BuildId: 8af0132792b03fa12ba95b5623865c9a8a5625a3) Direct leak of 100 byte(s) in 1 object(s) allocated from: #0 0x7f6585ee6f2b in malloc (/lib64/libasan.so.8+0xe6f2b) (BuildId: 10b8ccd49f75c21babf1d7abe51bb63589d8471f) #1 0x000000414a0d in malloc_or_fail /home/richie/oai/common/utils/utils.h:86 #2 0x0000004061ff in main /home/richie/oai/tests/nr-cuup/nr-cuup-load-test.c:546 #3 0x7f6585211574 in __libc_start_call_main (/lib64/libc.so.6+0x3574) (BuildId: 48c4b9b1efb1df15da8e787f489128bf31893317) #4 0x7f6585211627 in __libc_start_main@GLIBC_2.2.5 (/lib64/libc.so.6+0x3627) (BuildId: 48c4b9b1efb1df15da8e787f489128bf31893317) #5 0x000000413034 in _start (/home/richie/oai/build/tests/nr-cuup/nr-cuup-load-test+0x413034) (BuildId: 8af0132792b03fa12ba95b5623865c9a8a5625a3) --- tests/nr-cuup/nr-cuup-load-test.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/nr-cuup/nr-cuup-load-test.c b/tests/nr-cuup/nr-cuup-load-test.c index 533b119c9e..8cc5256744 100644 --- a/tests/nr-cuup/nr-cuup-load-test.c +++ b/tests/nr-cuup/nr-cuup-load-test.c @@ -664,6 +664,9 @@ int main(int argc, char *argv[]) success = false; } + free(ng_ip); + free(f1_ip); + if (success) LOG_A(GNB_APP, "test succeeded\n"); else From 155ee5ad42ee054164a07b3f9f46c78ad86c14cc Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Mon, 27 Oct 2025 18:51:49 +0100 Subject: [PATCH 18/69] Fix direct memory leak on E1 message reception Direct leak of 8 byte(s) in 1 object(s) allocated from: #0 0x7f7bc7ee68a3 in calloc (/lib64/libasan.so.8+0xe68a3) (BuildId: 10b8ccd49f75c21babf1d7abe51bb63589d8471f) #1 0x0000004abfa6 in calloc_or_fail /home/richie/oai/common/utils/utils.h:74 #2 0x0000004abfa6 in decode_e1ap_cuup_setup_request /home/richie/oai/openair2/E1AP/lib/e1ap_interface_management.c:219 #3 0x00000046a9f5 in e1apCUCP_handle_SETUP_REQUEST /home/richie/oai/openair2/E1AP/e1ap.c:187 #4 0x000000470b35 in e1ap_handle_message /home/richie/oai/openair2/E1AP/e1ap.c:109 #5 0x000000470b35 in e1_task_handle_sctp_data_ind /home/richie/oai/openair2/E1AP/e1ap.c:120 #6 0x00000047717b in E1AP_CUCP_task /home/richie/oai/openair2/E1AP/e1ap.c:832 #7 0x7f7bc7e28ee5 in asan_thread_start(void*) (/lib64/libasan.so.8+0x28ee5) (BuildId: 10b8ccd49f75c21babf1d7abe51bb63589d8471f) Direct leak of 8 byte(s) in 1 object(s) allocated from: #0 0x7f7bc7ee68a3 in calloc (/lib64/libasan.so.8+0xe68a3) (BuildId: 10b8ccd49f75c21babf1d7abe51bb63589d8471f) #1 0x0000004ac30c in calloc_or_fail /home/richie/oai/common/utils/utils.h:74 #2 0x0000004ac30c in decode_e1ap_cuup_setup_request /home/richie/oai/openair2/E1AP/lib/e1ap_interface_management.c:194 #3 0x00000046a9f5 in e1apCUCP_handle_SETUP_REQUEST /home/richie/oai/openair2/E1AP/e1ap.c:187 #4 0x000000470b35 in e1ap_handle_message /home/richie/oai/openair2/E1AP/e1ap.c:109 #5 0x000000470b35 in e1_task_handle_sctp_data_ind /home/richie/oai/openair2/E1AP/e1ap.c:120 #6 0x00000047717b in E1AP_CUCP_task /home/richie/oai/openair2/E1AP/e1ap.c:832 #7 0x7f7bc7e28ee5 in asan_thread_start(void*) (/lib64/libasan.so.8+0x28ee5) (BuildId: 10b8ccd49f75c21babf1d7abe51bb63589d8471f) --- tests/nr-cuup/nr-cuup-load-test.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/nr-cuup/nr-cuup-load-test.c b/tests/nr-cuup/nr-cuup-load-test.c index 8cc5256744..0774b26b1b 100644 --- a/tests/nr-cuup/nr-cuup-load-test.c +++ b/tests/nr-cuup/nr-cuup-load-test.c @@ -28,6 +28,7 @@ #include "openair3/SCTP/sctp_eNB_task.h" #include "openair2/E1AP/e1ap.h" #include "openair3/ocp-gtpu/gtp_itf.h" +#include "openair2/E1AP/lib/e1ap_interface_management.h" configmodule_interface_t *uniqCfg; @@ -90,6 +91,7 @@ static void setup_cuup(sctp_assoc_t *assoc_id, e1ap_nssai_t *nssai) DevAssert(req->plmn[0].slice != NULL); *nssai = *req->plmn[0].slice; DevAssert(assoc_id != 0); + free_e1ap_cuup_setup_request(req); itti_free(TASK_GNB_APP, itti_req); // acknowledge the E1 setup request with a response From a2b127f643ba5095fbc1c3b19f249746706542b1 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Mon, 27 Oct 2025 18:54:19 +0100 Subject: [PATCH 19/69] CU-UP: fix direct memory leak Note that this strdup has been intentioally created for debugging purposes in core files. See also: 1ab3b8dd8e0a ("add version signature in core files...") --- executables/nr-cuup.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/executables/nr-cuup.c b/executables/nr-cuup.c index 403f78ddb3..0c2c9cdf3f 100644 --- a/executables/nr-cuup.c +++ b/executables/nr-cuup.c @@ -150,7 +150,8 @@ int main(int argc, char **argv) time_manager_start(tick_functions, tick_functions_count, TIME_SOURCE_REALTIME); // strdup to put the sring in the core file for post mortem identification - LOG_I(HW, "Version: %s\n", strdup(OAI_PACKAGE_VERSION)); + char *v = strdup(OAI_PACKAGE_VERSION); + LOG_I(HW, "Version: %s\n", v); set_softmodem_sighandler(); itti_init(TASK_MAX, tasks_info); int rc; @@ -189,6 +190,8 @@ int main(int argc, char **argv) time_manager_finish(); + free(v); + logClean(); printf("Bye.\n"); return 0; From e9bf6344b01372a1fcd36cbb62381d92b0b276cf Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Mon, 27 Oct 2025 18:56:42 +0100 Subject: [PATCH 20/69] SCTP: fix a memory leak call freeaddrinfo() before return'ing from the function. --- openair3/SCTP/sctp_eNB_task.c | 1 + 1 file changed, 1 insertion(+) diff --git a/openair3/SCTP/sctp_eNB_task.c b/openair3/SCTP/sctp_eNB_task.c index 82afa451c0..567a166491 100644 --- a/openair3/SCTP/sctp_eNB_task.c +++ b/openair3/SCTP/sctp_eNB_task.c @@ -477,6 +477,7 @@ static void sctp_handle_new_association_req(const instance_t instance, if (errno != EINPROGRESS) { SCTP_ERROR("Connect failed: %s\n", strerror(errno)); sctp_itti_send_association_resp(requestor, instance, -1, req->ulp_cnx_id, SCTP_STATE_UNREACHABLE, 0, 0); + freeaddrinfo(serv); close(sd); return; } else { From eced5afdf72f95948fdf81452528bfcd469cc23d Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Tue, 28 Oct 2025 08:25:06 +0100 Subject: [PATCH 21/69] Add CU-UP functional test to ctest Use the CU-UP load tester to test the functionality of the CU-UP and its loader tester. The requirements on this load test are intentionally low, as it will be run with other unit tests in parallel, and should still pass. It uses an existing configuration file for the CU-UP. The test script runs the CU-UP, runs the load tester, stops the CU-UP, and returns the load tester return value as test result (which will be 0=success if all packets have been received). --- tests/nr-cuup/CMakeLists.txt | 10 ++++++++++ tests/nr-cuup/nr-cuup-functional-test.sh | 21 +++++++++++++++++++++ 2 files changed, 31 insertions(+) create mode 100755 tests/nr-cuup/nr-cuup-functional-test.sh diff --git a/tests/nr-cuup/CMakeLists.txt b/tests/nr-cuup/CMakeLists.txt index 02becb2496..9d48fd89e2 100644 --- a/tests/nr-cuup/CMakeLists.txt +++ b/tests/nr-cuup/CMakeLists.txt @@ -1,4 +1,14 @@ add_executable(nr-cuup-load-test nr-cuup-load-test.c) +add_dependencies(nr-cuup-load-test params_libconfig) target_link_libraries(nr-cuup-load-test PRIVATE GTPV1U ${T_LIB} utils ITTI e1ap SCTP_CLIENT) target_link_libraries(nr-cuup-load-test PRIVATE asn1_lte_rrc_hdrs asn1_nr_rrc_hdrs) # ITTI + +if(ENABLE_TESTS) + # we add also nr-cuup as it is required for the test + add_dependencies(tests nr-cuup-load-test nr-cuup) + add_test(NAME nr_cuup_functional_test + COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/nr-cuup-functional-test.sh ${CMAKE_CURRENT_SOURCE_DIR}/load-test.conf + WORKING_DIRECTORY ${CMAKE_BINARY_DIR} + ) +endif() diff --git a/tests/nr-cuup/nr-cuup-functional-test.sh b/tests/nr-cuup/nr-cuup-functional-test.sh new file mode 100755 index 0000000000..28a9b3779a --- /dev/null +++ b/tests/nr-cuup/nr-cuup-functional-test.sh @@ -0,0 +1,21 @@ +#!/bin/bash + +# this script takes one argument, which is the path to the CU-UP configuration +if [ $# -ne 1 ]; then + echo "usage: $0 " + exit 1 +fi + +CONFIG=$1 + +set -x + +# current dir should be CMAKE_BINARY_DIR +./nr-cuup -O ${CONFIG} & +CUUP_PID=$! + +timeout 5s ./tests/nr-cuup/nr-cuup-load-test -t 3 -d 10 -u 10 +RET=$? + +kill ${CUUP_PID} +exit ${RET} From 3e23c796c9779de32d8d59ea34e81b3362eb9394 Mon Sep 17 00:00:00 2001 From: Jaroslava Fiedlerova Date: Mon, 27 Oct 2025 16:07:04 +0000 Subject: [PATCH 22/69] CI: ensure clean iperf3 server startup by killing existing processes on same port Before starting a new iperf3 server instance in CI tests, explicitly kill any existing iperf3 processes bound to the same port. This prevents conflicts or failures caused by leftover iperf3 servers from previous runs that did not terminate properly or on time. The cleanup is performed using `pkill` before launching the new server. --- ci-scripts/cls_oaicitest.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/ci-scripts/cls_oaicitest.py b/ci-scripts/cls_oaicitest.py index 2b31f41064..144bc24da6 100644 --- a/ci-scripts/cls_oaicitest.py +++ b/ci-scripts/cls_oaicitest.py @@ -503,6 +503,11 @@ class OaiCiTest(): t = iperf_time * 2.5 cmd_ue.run(f'rm {client_filename}', reportNonZero=False, silent=True) if cn.runIperf3Server(): + # Clean up any existing iperf3 server processes on this port. + ret = cmd_svr.run(f"{cn.getCmdPrefix()} pkill -f '.*iperf3.*{port}'", reportNonZero=False) + # If pkill succeeds, it means there was a leftover iperf3 server. + if ret.returncode == 0: + logging.warning(f'Iperf3 server on port {port} detected and terminated') cmd_svr.run(f'{cn.getCmdPrefix()} timeout -vk3 {t} iperf3 -s -B {svrIP} -p {port} -1 {jsonReport} >> /dev/null &', timeout=t) cmd_ue.run(f'{ue.getCmdPrefix()} timeout -vk3 {t} {iperf_ue} -B {ueIP} -c {svrIP} -p {port} {iperf_opt} {jsonReport} {serverReport} -O 5 >> {client_filename}', timeout=t) dest_filename = archiveArtifact(cmd_ue, ctx, client_filename) From 9be94881a36feec81d32de1988942568d62bc721 Mon Sep 17 00:00:00 2001 From: Jaroslava Fiedlerova Date: Tue, 28 Oct 2025 08:41:22 +0000 Subject: [PATCH 23/69] CI: correct testcase description in RFSim5G tests --- ci-scripts/xml_files/container_5g_f1_rfsim.xml | 4 ++-- ci-scripts/xml_files/container_5g_rfsim.xml | 4 ++-- ci-scripts/xml_files/container_5g_rfsim_24prb.xml | 4 ++-- ci-scripts/xml_files/container_5g_rfsim_2x2.xml | 4 ++-- ci-scripts/xml_files/container_5g_rfsim_fdd_phytest.xml | 4 ++-- ci-scripts/xml_files/container_5g_rfsim_multiue.xml | 4 ++-- ci-scripts/xml_files/container_5g_rfsim_n2_ho.xml | 4 ++-- ci-scripts/xml_files/container_5g_rfsim_u0_25prb.xml | 4 ++-- 8 files changed, 16 insertions(+), 16 deletions(-) diff --git a/ci-scripts/xml_files/container_5g_f1_rfsim.xml b/ci-scripts/xml_files/container_5g_f1_rfsim.xml index d8dc580a04..49a28e4a9f 100644 --- a/ci-scripts/xml_files/container_5g_f1_rfsim.xml +++ b/ci-scripts/xml_files/container_5g_f1_rfsim.xml @@ -138,7 +138,7 @@ Iperf - Iperf (DL/3Mbps/UDP)(30 sec) + Iperf (DL/3Mbps/UDP)(20 sec) -u -b 3M -t 20 -R rfsim5g_ue localhost @@ -150,7 +150,7 @@ Iperf - Iperf (UL/3Mbps/UDP)(30 sec) + Iperf (UL/3Mbps/UDP)(20 sec) -u -b 3M -t 20 rfsim5g_ue localhost diff --git a/ci-scripts/xml_files/container_5g_rfsim.xml b/ci-scripts/xml_files/container_5g_rfsim.xml index e2566bfd25..89cbe35dfa 100644 --- a/ci-scripts/xml_files/container_5g_rfsim.xml +++ b/ci-scripts/xml_files/container_5g_rfsim.xml @@ -196,7 +196,7 @@ Iperf - Iperf (DL/3Mbps/UDP)(30 sec) + Iperf (DL/3Mbps/UDP)(20 sec) -u -b 3M -t 20 -R rfsim5g_ue localhost @@ -208,7 +208,7 @@ Iperf - Iperf (UL/1Mbps/UDP)(30 sec) + Iperf (UL/1Mbps/UDP)(20 sec) -u -b 1M -t 20 rfsim5g_ue localhost diff --git a/ci-scripts/xml_files/container_5g_rfsim_24prb.xml b/ci-scripts/xml_files/container_5g_rfsim_24prb.xml index 849c91a7b0..470c5e9539 100644 --- a/ci-scripts/xml_files/container_5g_rfsim_24prb.xml +++ b/ci-scripts/xml_files/container_5g_rfsim_24prb.xml @@ -121,7 +121,7 @@ Iperf - Iperf (DL/3Mbps/UDP)(30 sec) + Iperf (DL/3Mbps/UDP)(20 sec) -u -b 3M -t 20 -R rfsim5g_ue localhost @@ -133,7 +133,7 @@ Iperf - Iperf (UL/1Mbps/UDP)(30 sec) + Iperf (UL/1Mbps/UDP)(20 sec) -u -b 1M -t 20 rfsim5g_ue localhost diff --git a/ci-scripts/xml_files/container_5g_rfsim_2x2.xml b/ci-scripts/xml_files/container_5g_rfsim_2x2.xml index ed0e11807c..636df9e729 100644 --- a/ci-scripts/xml_files/container_5g_rfsim_2x2.xml +++ b/ci-scripts/xml_files/container_5g_rfsim_2x2.xml @@ -97,7 +97,7 @@ Iperf - Iperf (DL/10Mbps/UDP)(30 sec) + Iperf (DL/10Mbps/UDP)(20 sec) -u -b 10M -t 20 -R rfsim5g_ue localhost @@ -109,7 +109,7 @@ Iperf - Iperf (UL/3Mbps/UDP)(30 sec) + Iperf (UL/3Mbps/UDP)(20 sec) -u -b 3M -t 20 rfsim5g_ue localhost 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 4ff5dbedc8..2a180440d0 100644 --- a/ci-scripts/xml_files/container_5g_rfsim_fdd_phytest.xml +++ b/ci-scripts/xml_files/container_5g_rfsim_fdd_phytest.xml @@ -97,7 +97,7 @@ Iperf - Iperf (DL/30kbps/UDP)(30 sec) + Iperf (DL/30kbps/UDP)(20 sec) -u -b 0.03M -t 20 -R -c 10.0.1.1 rfsim5g_ue localhost @@ -109,7 +109,7 @@ Iperf - Iperf (UL/30kbps/UDP)(30 sec) + Iperf (UL/30kbps/UDP)(20 sec) -u -b 0.03M -t 20 -c 10.0.1.1 rfsim5g_ue localhost diff --git a/ci-scripts/xml_files/container_5g_rfsim_multiue.xml b/ci-scripts/xml_files/container_5g_rfsim_multiue.xml index 215f58c2a7..4296fdf970 100644 --- a/ci-scripts/xml_files/container_5g_rfsim_multiue.xml +++ b/ci-scripts/xml_files/container_5g_rfsim_multiue.xml @@ -155,7 +155,7 @@ Iperf - Iperf (DL/3Mbps/UDP)(30 sec) + Iperf (DL/3Mbps/UDP)(20 sec) -u -b 3M -t 20 -R rfsim5g_multiue1 localhost @@ -167,7 +167,7 @@ Iperf - Iperf (UL/1Mbps/UDP)(30 sec) + Iperf (UL/1Mbps/UDP)(20 sec) -u -b 1M -t 20 rfsim5g_multiue1 localhost 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 5da417c284..814f258e0a 100644 --- a/ci-scripts/xml_files/container_5g_rfsim_n2_ho.xml +++ b/ci-scripts/xml_files/container_5g_rfsim_n2_ho.xml @@ -120,7 +120,7 @@ Iperf - Iperf (DL/10Mbps/UDP)(30 sec) + Iperf (DL/10Mbps/UDP)(20 sec) -u -b 3M -t 20 -R rfsim5g_ue localhost @@ -132,7 +132,7 @@ Iperf - Iperf (UL/4Mbps/UDP)(30 sec) + Iperf (UL/4Mbps/UDP)(20 sec) -u -b 1M -t 20 rfsim5g_ue localhost 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 f70c81732e..c7668c5022 100644 --- a/ci-scripts/xml_files/container_5g_rfsim_u0_25prb.xml +++ b/ci-scripts/xml_files/container_5g_rfsim_u0_25prb.xml @@ -117,7 +117,7 @@ Iperf - Iperf (DL/3Mbps/UDP)(30 sec) + Iperf (DL/3Mbps/UDP)(20 sec) -u -b 3M -t 20 -R rfsim5g_ue localhost @@ -129,7 +129,7 @@ Iperf - Iperf (UL/1Mbps/UDP)(30 sec) + Iperf (UL/1Mbps/UDP)(20 sec) -u -b 1M -t 20 rfsim5g_ue localhost From 7157d4bcd185ee9b64f940a2adb74f2ab2e52e85 Mon Sep 17 00:00:00 2001 From: Laurent THOMAS Date: Fri, 19 Sep 2025 11:51:29 +0200 Subject: [PATCH 24/69] add trace when the main NR UE thread ends and when NR UE sets oai_exit variable --- executables/nr-ue.c | 2 +- executables/nr-uesoftmodem.c | 10 +++------- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/executables/nr-ue.c b/executables/nr-ue.c index e7132e15cf..5721b45f8d 100644 --- a/executables/nr-ue.c +++ b/executables/nr-ue.c @@ -1091,7 +1091,7 @@ void *UE_thread(void *arg) stream_status = STREAM_STATUS_SYNCED; tx_wait_for_dlsch[slot] = 0; } - + LOG_W(NR_PHY, "UE main thread is ending\n"); return NULL; } diff --git a/executables/nr-uesoftmodem.c b/executables/nr-uesoftmodem.c index fbac6402f5..ca6c48dbef 100644 --- a/executables/nr-uesoftmodem.c +++ b/executables/nr-uesoftmodem.c @@ -139,10 +139,7 @@ int create_tasks_nrue(uint32_t ue_nb) { void exit_function(const char *file, const char *function, const int line, const char *s, const int assert) { int CC_id; - - if (s != NULL) { - printf("%s:%d %s() Exiting OAI softmodem: %s\n",file,line, function, s); - } + LOG_W(NR_PHY, "called by: %s:%d %s() Exiting OAI softmodem: %s\n", file, line, function, s ? s : "no msg"); oai_exit = 1; @@ -496,9 +493,8 @@ int main(int argc, char **argv) printf("Entering ITTI signals handler\n"); printf("TYPE TO TERMINATE\n"); itti_wait_tasks_end(trigger_deregistration); - printf("Returned from ITTI signal handler\n"); - oai_exit=1; - printf("oai_exit=%d\n",oai_exit); + LOG_W(NR_PHY, "Returned from ITTI signal handler\n"); + oai_exit = 1; if (ouput_vcd) vcd_signal_dumper_close(); From e54738c7e4567c27c41a7b0cbb4ef1f70d95cebc Mon Sep 17 00:00:00 2001 From: Laurent THOMAS Date: Tue, 19 Aug 2025 12:12:52 +0200 Subject: [PATCH 25/69] flush command line printf, it is called before log module initialisation --- common/config/config_load_configmodule.c | 1 + 1 file changed, 1 insertion(+) diff --git a/common/config/config_load_configmodule.c b/common/config/config_load_configmodule.c index cfe05042ce..f5dfe6137f 100644 --- a/common/config/config_load_configmodule.c +++ b/common/config/config_load_configmodule.c @@ -240,6 +240,7 @@ configmodule_interface_t *load_configmodule(int argc, for (int i=0; i Date: Thu, 14 Aug 2025 12:16:20 +0200 Subject: [PATCH 26/69] Remove prach_ifft from premanent allocation Allocate on the stack when necessary. --- openair1/PHY/INIT/nr_init.c | 7 +- openair1/PHY/NR_TRANSPORT/nr_prach.c | 220 +++++++++++---------------- openair1/PHY/defs_gNB.h | 2 - 3 files changed, 87 insertions(+), 142 deletions(-) diff --git a/openair1/PHY/INIT/nr_init.c b/openair1/PHY/INIT/nr_init.c index 778903be91..23334c8626 100644 --- a/openair1/PHY/INIT/nr_init.c +++ b/openair1/PHY/INIT/nr_init.c @@ -190,8 +190,7 @@ void phy_init_nr_gNB(PHY_VARS_gNB *gNB) common_vars->debugBuff_sample_offset = 0; // PRACH - prach_vars->rxsigF = (int16_t **)malloc16_clear(Prx*sizeof(int16_t*)); - prach_vars->prach_ifft = (int32_t *)malloc16_clear(1024*2*sizeof(int32_t)); + prach_vars->rxsigF = (int16_t **)malloc16_clear(Prx * sizeof(int16_t *)); init_prach_list(gNB); @@ -266,10 +265,6 @@ void phy_free_nr_gNB(PHY_VARS_gNB *gNB) free_and_zero(common_vars->debugBuff); - NR_gNB_PRACH* prach_vars = &gNB->prach_vars; - free_and_zero(prach_vars->rxsigF); - free_and_zero(prach_vars->prach_ifft); - for (int ULSCH_id = 0; ULSCH_id < gNB->max_nb_pusch; ULSCH_id++) { NR_gNB_PUSCH *pusch_vars = &gNB->pusch_vars[ULSCH_id]; for (int i = 0; i < n_buf; i++) { diff --git a/openair1/PHY/NR_TRANSPORT/nr_prach.c b/openair1/PHY/NR_TRANSPORT/nr_prach.c index 76d9b1185f..f278d4c845 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_prach.c +++ b/openair1/PHY/NR_TRANSPORT/nr_prach.c @@ -452,81 +452,67 @@ void rx_nr_prach(PHY_VARS_gNB *gNB, { AssertFatal(gNB != NULL, "Can only be called from gNB\n"); nfapi_nr_prach_config_t *cfg = &gNB->gNB_config.prach_config; - NR_DL_FRAME_PARMS *fp; + c16_t **rxsigF = (c16_t **)gNB->prach_vars.rxsigF; + uint16_t preamble_index0 = 0; + uint16_t numshift = 0; + int first_nonzero_root_idx = 0; + bool new_dft = false; + int log2_ifft_size = 10; - uint16_t rootSequenceIndex; - int numrootSequenceIndex; - uint8_t restricted_set; - uint8_t n_ra_prb=0xFF; - int nb_rx; + NR_DL_FRAME_PARMS *fp = &gNB->frame_parms; - int16_t **rxsigF = gNB->prach_vars.rxsigF; + const int nb_rx = gNB->gNB_config.carrier_config.num_rx_ant.value; + const int rootSequenceIndex = cfg->num_prach_fd_occasions_list[prach_pdu->num_ra].prach_root_sequence_index.value; + const int numrootSequenceIndex = cfg->num_prach_fd_occasions_list[prach_pdu->num_ra].num_root_sequences.value; + const int NCS = prach_pdu->num_cs; // cfg->num_prach_fd_occasions_list[0].prach_zero_corr_conf.value; + const int prach_sequence_length = cfg->prach_sequence_length.value; + const int msg1_frequencystart = cfg->num_prach_fd_occasions_list[prach_pdu->num_ra].k1.value; + const int restricted_set = cfg->restricted_set_config.value; + const int prach_fmt = prach_pdu->prach_format; + const int N_ZC = prach_sequence_length == 0 ? 839 : 139; - uint8_t preamble_index; - uint16_t NCS=99,NCS2; - uint16_t preamble_offset=0,preamble_offset_old; - int16_t preamble_shift=0; - uint32_t preamble_shift2; - uint16_t preamble_index0=0,n_shift_ra=0,n_shift_ra_bar; - uint16_t d_start=0; - uint16_t numshift=0; - const uint16_t *prach_root_sequence_map; - uint8_t not_found; - uint16_t u; - int16_t *Xu=0; - uint16_t first_nonzero_root_idx=0; - uint8_t new_dft=0; - int32_t lev; - int16_t levdB; - int log2_ifft_size=10; - int16_t prach_ifft_tmp[2048*2] __attribute__((aligned(32))); - int32_t *prach_ifft=(int32_t*)NULL; - - fp = &gNB->frame_parms; + LOG_D(PHY, + "L1 PRACH RX: rooSequenceIndex %d, numRootSeqeuences %d, NCS %d, N_ZC %d, format %d \n", + rootSequenceIndex, + numrootSequenceIndex, + NCS, + N_ZC, + prach_fmt); - nb_rx = gNB->gNB_config.carrier_config.num_rx_ant.value; - rootSequenceIndex = cfg->num_prach_fd_occasions_list[prach_pdu->num_ra].prach_root_sequence_index.value; - numrootSequenceIndex = cfg->num_prach_fd_occasions_list[prach_pdu->num_ra].num_root_sequences.value; - NCS = prach_pdu->num_cs;//cfg->num_prach_fd_occasions_list[0].prach_zero_corr_conf.value; - int prach_sequence_length = cfg->prach_sequence_length.value; - int msg1_frequencystart = cfg->num_prach_fd_occasions_list[prach_pdu->num_ra].k1.value; - // int num_unused_root_sequences = cfg->num_prach_fd_occasions_list[0].num_unused_root_sequences.value; - // cfg->num_prach_fd_occasions_list[0].unused_root_sequences_list - - restricted_set = cfg->restricted_set_config.value; - - uint8_t prach_fmt = prach_pdu->prach_format; - uint16_t N_ZC = (prach_sequence_length==0)?839:139; - - LOG_D(PHY,"L1 PRACH RX: rooSequenceIndex %d, numRootSeqeuences %d, NCS %d, N_ZC %d, format %d \n",rootSequenceIndex,numrootSequenceIndex,NCS,N_ZC,prach_fmt); - - prach_ifft = gNB->prach_vars.prach_ifft; if (LOG_DEBUGFLAG(DEBUG_PRACH)) { - if ((frame&1023) < 20) LOG_D(PHY,"PRACH (gNB) : running rx_prach for slot %d, msg1_frequencystart %d, rootSequenceIndex %d\n", slot, msg1_frequencystart, rootSequenceIndex); + if ((frame & 1023) < 20) + LOG_D(PHY, + "PRACH (gNB) : running rx_prach for slot %d, msg1_frequencystart %d, rootSequenceIndex %d\n", + slot, + msg1_frequencystart, + rootSequenceIndex); } start_meas(&gNB->rx_prach); - prach_root_sequence_map = (cfg->prach_sequence_length.value==0) ? prach_root_sequence_map_0_3 : prach_root_sequence_map_abc; + const uint16_t *prach_root_sequence_map = + cfg->prach_sequence_length.value == 0 ? prach_root_sequence_map_0_3 : prach_root_sequence_map_abc; // PDP is oversampled, e.g. 1024 sample instead of 839 // Adapt the NCS (zero-correlation zones) with oversampling factor e.g. 1024/839 - NCS2 = (N_ZC==839) ? ((NCS<<10)/839) : ((NCS<<8)/139); + int NCS2 = N_ZC == 839 ? (NCS << 10) / 839 : (NCS << 8) / 139; - if (NCS2==0) NCS2 = N_ZC; + if (NCS2 == 0) + NCS2 = N_ZC; + int preamble_offset = 0, preamble_offset_old = 99; - preamble_offset_old = 99; - - *max_preamble_energy = 0; *max_preamble_delay = 0; *max_preamble = 0; - int16_t prachF[2 * 1024]; - for (preamble_index=0 ; preamble_index<64 ; preamble_index++) { + int16_t preamble_shift = 0; + const int dft_sz = N_ZC == 839 ? 1024 : 256; + int32_t prach_ifft[dft_sz] __attribute__((aligned(32))); + for (int preamble_index = 0; preamble_index < 64; preamble_index++) { if (LOG_DEBUGFLAG(DEBUG_PRACH)) { - int en = dB_fixed(signal_energy((int32_t*)&rxsigF[0][0],(N_ZC==839) ? 840: 140)); - if (en>60) LOG_D(PHY,"frame %d, slot %d : Trying preamble %d \n",frame,slot,preamble_index); + int en = dB_fixed(signal_energy((int32_t *)rxsigF[0], N_ZC == 839 ? 840 : 140)); + if (en > 60) + LOG_D(PHY, "frame %d, slot %d : Trying preamble %d \n", frame, slot, preamble_index); } if (restricted_set == 0) { // This is the relative offset in the root sequence table (5.7.2-4 from 36.211) for the given preamble index @@ -534,48 +520,43 @@ void rx_nr_prach(PHY_VARS_gNB *gNB, if (preamble_offset != preamble_offset_old) { preamble_offset_old = preamble_offset; - new_dft = 1; + new_dft = true; // This is the \nu corresponding to the preamble index preamble_shift = 0; - } - - else { - preamble_shift -= NCS; + } else { + preamble_shift -= NCS; if (preamble_shift < 0) - preamble_shift+=N_ZC; + preamble_shift += N_ZC; } } else { // This is the high-speed case - new_dft = 0; + new_dft = false; uint16_t nr_du[NR_PRACH_SEQ_LEN_L - 1]; nr_fill_du(N_ZC, prach_root_sequence_map, nr_du); // set preamble_offset to initial rootSequenceIndex and look if we need more root sequences for this // preamble index and find the corresponding cyclic shift // Check if all shifts for that root have been processed + int n_shift_ra = 0, n_shift_ra_bar, d_start = 0; if (preamble_index0 == numshift) { - not_found = 1; - new_dft = 1; + bool not_found = true; + new_dft = true; preamble_index0 -= numshift; - //(preamble_offset==0 && numshift==0) ? (preamble_offset) : (preamble_offset++); - - while (not_found == 1) { + while (not_found) { // current root depending on rootSequenceIndex int index = (rootSequenceIndex + preamble_offset) % N_ZC; - - u = prach_root_sequence_map[index]; - + int u = nr_du[prach_root_sequence_map[index]]; uint16_t n_group_ra = 0; - - if ((nr_du[u] < (N_ZC / 3)) && (nr_du[u] >= NCS) ) { - n_shift_ra = nr_du[u] / NCS; - d_start = (nr_du[u] << 1) + (n_shift_ra * NCS); + + if (u < (N_ZC / 3) && u >= NCS) { + n_shift_ra = u / NCS; + d_start = (u << 1) + (n_shift_ra * NCS); n_group_ra = N_ZC / d_start; - n_shift_ra_bar = max(0, (N_ZC-(nr_du[u] << 1) - (n_group_ra * d_start)) / N_ZC); - } else if ((nr_du[u] >= (N_ZC / 3)) && (nr_du[u] <= ((N_ZC - NCS) >> 1))) { - n_shift_ra = (N_ZC - (nr_du[u] << 1)) / NCS; - d_start = N_ZC - (nr_du[u] << 1) + (n_shift_ra * NCS); - n_group_ra = nr_du[u] / d_start; - n_shift_ra_bar = min(n_shift_ra, max(0, (nr_du[u]- (n_group_ra * d_start)) / NCS)); + n_shift_ra_bar = max(0, (N_ZC - (u << 1) - (n_group_ra * d_start)) / N_ZC); + } else if (u >= (N_ZC / 3) && u <= ((N_ZC - NCS) >> 1)) { + n_shift_ra = (N_ZC - (u << 1)) / NCS; + d_start = N_ZC - (u << 1) + (n_shift_ra * NCS); + n_group_ra = u / d_start; + n_shift_ra_bar = min(n_shift_ra, max(0, (u - (n_group_ra * d_start)) / NCS)); } else { n_shift_ra = 0; n_shift_ra_bar = 0; @@ -584,12 +565,13 @@ void rx_nr_prach(PHY_VARS_gNB *gNB, // This is the number of cyclic shifts for the current root u numshift = (n_shift_ra * n_group_ra) + n_shift_ra_bar; // skip to next root and recompute parameters if numshift==0 - (numshift>0) ? (not_found = 0) : (preamble_offset++); + numshift > 0 ? not_found = false : preamble_offset++; } } if (n_shift_ra>0) - preamble_shift = -((d_start * (preamble_index0/n_shift_ra)) + ((preamble_index0%n_shift_ra)*NCS)); // minus because the channel is h(t -\tau + Cv) + preamble_shift = -(d_start * (preamble_index0 / n_shift_ra) + + (preamble_index0 % n_shift_ra) * NCS); // minus because the channel is h(t -\tau + Cv) else preamble_shift = 0; @@ -604,7 +586,7 @@ void rx_nr_prach(PHY_VARS_gNB *gNB, // Compute DFT of RX signal (conjugate input, results in conjugate output) for each new rootSequenceIndex if (LOG_DEBUGFLAG(DEBUG_PRACH)) { - int en = dB_fixed(signal_energy((int32_t*)&rxsigF[0][0],840)); + int en = dB_fixed(signal_energy((int32_t *)rxsigF[0], 840)); if (en>60) LOG_D(PHY, "frame %d, slot %d : preamble index %d, NCS %d, N_ZC/NCS %d: offset %d, preamble shift %d , en %d)\n", @@ -620,42 +602,30 @@ void rx_nr_prach(PHY_VARS_gNB *gNB, LOG_D(PHY,"PRACH RX preamble_index %d, preamble_offset %d\n",preamble_index,preamble_offset); + if (new_dft) { + new_dft = false; - if (new_dft == 1) { - new_dft = 0; - - Xu = (int16_t*)gNB->X_u[preamble_offset-first_nonzero_root_idx]; - + c16_t *Xu = (c16_t *)gNB->X_u[preamble_offset - first_nonzero_root_idx]; LOG_D(PHY,"PRACH RX new dft preamble_offset-first_nonzero_root_idx %d\n",preamble_offset-first_nonzero_root_idx); - memset(prach_ifft,0,((N_ZC==839) ? 2048 : 256)*sizeof(int32_t)); - memset(prachF, 0, sizeof(int16_t) * 2 * 1024); + memset(prach_ifft, 0, sizeof(prach_ifft)); if (LOG_DUMPFLAG(DEBUG_PRACH)) { LOG_M("prach_rxF0.m","prach_rxF0",rxsigF[0],N_ZC,1,1); LOG_M("prach_rxF1.m","prach_rxF1",rxsigF[1],6144,1,1); } - + c16_t prachF[dft_sz] __attribute__((aligned(32))); for (int aa = 0; aa < nb_rx; aa++) { - // Do componentwise product with Xu* on each antenna - - for (int offset = 0; offset < (N_ZC << 1); offset += 2) { - prachF[offset] = (int16_t)(((int32_t)Xu[offset]*rxsigF[aa][offset] + (int32_t)Xu[offset+1]*rxsigF[aa][offset+1])>>15); - prachF[offset+1] = (int16_t)(((int32_t)Xu[offset]*rxsigF[aa][offset+1] - (int32_t)Xu[offset+1]*rxsigF[aa][offset])>>15); + // Do componentwise product with Xu* on each antenna + for (int offset = 0; offset < N_ZC; offset++) { + prachF[offset] = c16MulConjShift(Xu[offset], rxsigF[aa][offset], 15); } - + memset(prachF + N_ZC, 0, sizeof(*prachF) * (dft_sz - N_ZC)); // Now do IFFT of size 1024 (N_ZC=839) or 256 (N_ZC=139) - if (N_ZC == 839) { - idft(IDFT_1024, prachF, prach_ifft_tmp, 1); - // compute energy and accumulate over receive antennas - for (int i = 0; i < 1024; i++) - prach_ifft[i] += (int32_t)prach_ifft_tmp[i<<1]*(int32_t)prach_ifft_tmp[i<<1] + (int32_t)prach_ifft_tmp[1+(i<<1)]*(int32_t)prach_ifft_tmp[1+(i<<1)]; - } else { - idft(IDFT_256, prachF, prach_ifft_tmp, 1); - log2_ifft_size = 8; - // compute energy and accumulate over receive antennas and repetitions for BR - for (int i = 0; i < 256; i++) - prach_ifft[i] += (int32_t)prach_ifft_tmp[i<<1]*(int32_t)prach_ifft_tmp[(i<<1)] + (int32_t)prach_ifft_tmp[1+(i<<1)]*(int32_t)prach_ifft_tmp[1+(i<<1)]; - } + c16_t prach_ifft_tmp[dft_sz] __attribute__((aligned(32))); + idft(get_idft(dft_sz), (int16_t *)prachF, (int16_t *)prach_ifft_tmp, 1); + // compute energy and accumulate over receive antennas + for (int i = 0; i < dft_sz; i++) + prach_ifft[i] += squaredMod(prach_ifft_tmp[i]); if (LOG_DUMPFLAG(DEBUG_PRACH)) { if (aa == 0) @@ -678,14 +648,14 @@ void rx_nr_prach(PHY_VARS_gNB *gNB, } } // new dft - - // check energy in nth time shift, for - preamble_shift2 = ((preamble_shift==0) ? 0 : ((preamble_shift<*max_preamble_energy) { LOG_D(PHY,"preamble_index %d, delay %d en %d dB > %d dB\n",preamble_index,i,levdB,*max_preamble_energy); *max_preamble_energy = levdB; @@ -693,8 +663,7 @@ void rx_nr_prach(PHY_VARS_gNB *gNB, *max_preamble = preamble_index; } } - }// preamble_index - + } // preamble_index // The conversion from *max_preamble_delay from TA value is done here. // It is normalized to the 30.72 Ms/s, considering the numerology, N_RB and the sampling rate @@ -721,23 +690,6 @@ void rx_nr_prach(PHY_VARS_gNB *gNB, } else *TA = *TA/2; - if (LOG_DUMPFLAG(DEBUG_PRACH)) { - //int en = dB_fixed(signal_energy((int32_t*)&rxsigF[0][0],840)); - // if (en>60) { - int k = (12 * n_ra_prb) - 6 * fp->N_RB_UL; - if (k < 0) - k += fp->ofdm_symbol_size; - - k*=12; - k+=13; - k*=2; - - LOG_M("rxsigF.m","prach_rxF", &rxsigF[0][0], 12288, 1, 1); - LOG_M("prach_rxF_comp0.m","prach_rxF_comp0", prachF, 1024, 1, 1); - LOG_M("Xu.m","xu", Xu, N_ZC, 1, 1); - LOG_M("prach_ifft0.m","prach_t0", prach_ifft, 1024, 1, 1); - // } - } stop_meas(&gNB->rx_prach); } diff --git a/openair1/PHY/defs_gNB.h b/openair1/PHY/defs_gNB.h index ebf459402e..9575e33c7b 100644 --- a/openair1/PHY/defs_gNB.h +++ b/openair1/PHY/defs_gNB.h @@ -151,8 +151,6 @@ typedef struct { /// second index: rx antenna [0..63] (hard coded) \note Hard coded array size indexed by \c nb_antennas_rx. /// third index: frequency-domain sample [0..ofdm_symbol_size*12[ int16_t **rxsigF; - /// \brief local buffer to compute prach_ifft - int32_t *prach_ifft; gNB_PRACH_list_t list[NUMBER_OF_NR_PRACH_MAX]; } NR_gNB_PRACH; From f11361343cf6a8e98f0aaa31065ecdcc58d6df28 Mon Sep 17 00:00:00 2001 From: Laurent THOMAS Date: Tue, 16 Sep 2025 11:55:57 +0200 Subject: [PATCH 27/69] add management of nb tx antennas=0 in rfsimulator code trace the error of 0 antennas, and avoid infinite loop of calls to read 0 bytes --- radio/rfsimulator/simulator.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/radio/rfsimulator/simulator.c b/radio/rfsimulator/simulator.c index 13a414fed6..94234a755f 100644 --- a/radio/rfsimulator/simulator.c +++ b/radio/rfsimulator/simulator.c @@ -688,6 +688,8 @@ static int rfsimulator_write_internal(rfsimulator_state_t *t, if (b->conn_sock >= 0) { samplesBlockHeader_t header = {nsamps, nbAnt, timestamp}; + if (!nbAnt) + LOG_E(HW, "rfsimulator sending 0 tx antennas\n"); fullwrite(b->conn_sock, &header, sizeof(header), t); if (nbAnt == 1) { fullwrite(b->conn_sock, samplesVoid[0], sampleToByte(nsamps, nbAnt), t); @@ -796,6 +798,8 @@ static void process_recv_header(rfsimulator_state_t *t, buffer_t *b, bool first_ // We have a transmission hole to fill, like TDD // we create no signal samples up to the beginning of this reception int nbAnt = b->th.nbAnt; + if (!nbAnt) + LOG_E(HW, "rfsimulator receive 0 rx antennas\n"); if (b->th.timestamp - b->lastReceivedTS < CirSize) { // case we wrap at circular buffer end for (uint64_t index = b->lastReceivedTS; index < b->th.timestamp; index++) { @@ -822,6 +826,8 @@ static void process_recv_header(rfsimulator_state_t *t, buffer_t *b, bool first_ b->transferPtr = (char *)&b->circularBuf[(b->lastReceivedTS * b->th.nbAnt) % CirSize]; // we now need to read the samples b->remainToTransfer = sampleToByte(b->th.size, b->th.nbAnt); + if (!b->remainToTransfer) + b->headerMode = true; // We got a header with 0 antennas, no I/Q to read return; } From 7d90d9b23e60355ec104ab15a03334549c3d84fb Mon Sep 17 00:00:00 2001 From: Laurent THOMAS Date: Wed, 29 Oct 2025 15:35:04 +0100 Subject: [PATCH 28/69] log: make input parameters const --- common/utils/LOG/log.c | 8 +++++++- common/utils/LOG/log.h | 10 ++++++++-- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/common/utils/LOG/log.c b/common/utils/LOG/log.c index 1fe2280c15..91c97ac1ac 100644 --- a/common/utils/LOG/log.c +++ b/common/utils/LOG/log.c @@ -145,7 +145,13 @@ static const char *const log_level_highlight_end[] = {LOG_RESET, LOG_RESET, LOG_RESET, LOG_RESET, LOG_RESET, LOG_RESET}; /*!< \brief Optional end-format strings for highlighting */ static void log_output_memory(log_component_t *c, const char *file, const char *func, int line, int comp, int level, const char* format,va_list args); -int write_file_matlab(const char *fname, const char *vname, void *data, int length, int dec, unsigned int format, int multiVec) +int write_file_matlab(const char *fname, + const char *vname, + const void *data, + int length, + int dec, + unsigned int format, + int multiVec) { FILE *fp=NULL; int i; diff --git a/common/utils/LOG/log.h b/common/utils/LOG/log.h index 1f7474253c..a8c7becfdf 100644 --- a/common/utils/LOG/log.h +++ b/common/utils/LOG/log.h @@ -316,8 +316,14 @@ void close_log_mem(void); #define MATLAB_CSHORT_BRACKET1 13 #define MATLAB_CSHORT_BRACKET2 14 #define MATLAB_CSHORT_BRACKET3 15 - -int32_t write_file_matlab(const char *fname, const char *vname, void *data, int length, int dec, unsigned int format, int multiVec); + +int32_t write_file_matlab(const char *fname, + const char *vname, + const void *data, + int length, + int dec, + unsigned int format, + int multiVec); #define write_output(a, b, c, d, e, f) write_file_matlab(a, b, c, d, e, f, 0) /*----------------macro definitions for reading log configuration from the config module */ From a07c03e65f260f2053c52d279de4b364d71d6f16 Mon Sep 17 00:00:00 2001 From: Laurent THOMAS Date: Wed, 29 Oct 2025 12:14:31 +0100 Subject: [PATCH 29/69] MAC: use pointers, rewrite FAPI PDU alloc --- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c | 27 +++++++++---------- 1 file changed, 13 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 5e9cd47a79..88c9c875ea 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c @@ -60,7 +60,7 @@ static int16_t ssb_index_from_prach(module_id_t module_idP, gNB_MAC_INST *gNB = RC.nrmac[module_idP]; NR_COMMON_channels_t *cc = &gNB->common_channels[0]; NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon; - nfapi_nr_config_request_scf_t *cfg = &RC.nrmac[module_idP]->config[0]; + nfapi_nr_config_request_scf_t *cfg = &gNB->config[0]; NR_RACH_ConfigCommon_t *rach_ConfigCommon = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup; uint8_t config_index = rach_ConfigCommon->rach_ConfigGeneric.prach_ConfigurationIndex; uint8_t fdm = cfg->prach_config.num_prach_fd_occasions.value; @@ -351,10 +351,10 @@ void schedule_nr_prach(module_id_t module_idP, frame_t frameP, slot_t slotP) msgacc = initialUplinkBWP->ext1->msgA_ConfigCommon_r16->choice.setup; int slots_frame = gNB->frame_structure.numb_slots_frame; int index = ul_buffer_index(frameP, slotP, slots_frame, gNB->UL_tti_req_ahead_size); - nfapi_nr_ul_tti_request_t *UL_tti_req = &RC.nrmac[module_idP]->UL_tti_req_ahead[0][index]; - nfapi_nr_config_request_scf_t *cfg = &RC.nrmac[module_idP]->config[0]; + nfapi_nr_ul_tti_request_t *UL_tti_req = &gNB->UL_tti_req_ahead[0][index]; + nfapi_nr_config_request_scf_t *cfg = &gNB->config[0]; - if (is_ul_slot(slotP, &RC.nrmac[module_idP]->frame_structure)) { + if (is_ul_slot(slotP, &gNB->frame_structure)) { const NR_RACH_ConfigGeneric_t *rach_ConfigGeneric = &rach_ConfigCommon->rach_ConfigGeneric; uint8_t config_index = rach_ConfigGeneric->prach_ConfigurationIndex; int slot_index = 0; @@ -390,16 +390,15 @@ void schedule_nr_prach(module_id_t module_idP, frame_t frameP, slot_t slotP) uint32_t N_t_slot = cc->prach_info.N_t_slot; uint32_t start_symb = cc->prach_info.start_symbol; for (int fdm_index = 0; fdm_index < fdm; fdm_index++) { // one structure per frequency domain occasion - AssertFatal(UL_tti_req->n_pdus < sizeof(UL_tti_req->pdus_list) / sizeof(UL_tti_req->pdus_list[0]), - "Invalid UL_tti_req->n_pdus %d\n", - UL_tti_req->n_pdus); - - UL_tti_req->pdus_list[UL_tti_req->n_pdus].pdu_type = NFAPI_NR_UL_CONFIG_PRACH_PDU_TYPE; - UL_tti_req->pdus_list[UL_tti_req->n_pdus].pdu_size = sizeof(nfapi_nr_prach_pdu_t); - nfapi_nr_prach_pdu_t *prach_pdu = &UL_tti_req->pdus_list[UL_tti_req->n_pdus].prach_pdu; - memset(prach_pdu, 0, sizeof(nfapi_nr_prach_pdu_t)); + AssertFatal(UL_tti_req->n_pdus < sizeofArray(UL_tti_req->pdus_list), "Invalid UL_tti_req->n_pdus %d\n", UL_tti_req->n_pdus); + nfapi_nr_ul_tti_request_number_of_pdus_t *newpdu = UL_tti_req->pdus_list + UL_tti_req->n_pdus; + *newpdu = (nfapi_nr_ul_tti_request_number_of_pdus_t){ + .pdu_type = NFAPI_NR_UL_CONFIG_PRACH_PDU_TYPE, + .pdu_size = sizeof(nfapi_nr_prach_pdu_t), + }; UL_tti_req->n_pdus += 1; int num_td_occ = 0; + nfapi_nr_prach_pdu_t *prach_pdu = &newpdu->prach_pdu; for (int td_index = 0; td_index < N_t_slot; td_index++) { uint32_t config_period = cc->prach_info.x; prach_occasion_id = (((frameP % (cc->max_association_period * config_period))/config_period) * cc->total_prach_occasions_per_config_period) + @@ -1123,7 +1122,7 @@ static void nr_add_msg3(module_id_t module_idP, int CC_id, frame_t frameP, slot_ const uint16_t mask = SL_to_bitmap(ra->msg3_startsymb, ra->msg3_nbSymb); int slots_frame = mac->frame_structure.numb_slots_frame; int buffer_index = ul_buffer_index(ra->Msg3_frame, ra->Msg3_slot, slots_frame, mac->vrb_map_UL_size); - uint16_t *vrb_map_UL = &RC.nrmac[module_idP]->common_channels[CC_id].vrb_map_UL[ra->Msg3_beam.idx][buffer_index * MAX_BWP_SIZE]; + uint16_t *vrb_map_UL = &mac->common_channels[CC_id].vrb_map_UL[ra->Msg3_beam.idx][buffer_index * MAX_BWP_SIZE]; for (int i = 0; i < ra->msg3_nb_rb; ++i) { AssertFatal(!(vrb_map_UL[i + ra->msg3_first_rb + ra->msg3_bwp_start] & mask), "RB %d in %4d.%2d is already taken, cannot allocate Msg3!\n", @@ -1135,7 +1134,7 @@ static void nr_add_msg3(module_id_t module_idP, int CC_id, frame_t frameP, slot_ LOG_D(NR_MAC, "UE %04x: %d.%d RA is active, Msg3 in (%d,%d)\n", UE->rnti, frameP, slotP, ra->Msg3_frame, ra->Msg3_slot); buffer_index = ul_buffer_index(ra->Msg3_frame, ra->Msg3_slot, slots_frame, mac->UL_tti_req_ahead_size); - nfapi_nr_ul_tti_request_t *future_ul_tti_req = &RC.nrmac[module_idP]->UL_tti_req_ahead[CC_id][buffer_index]; + nfapi_nr_ul_tti_request_t *future_ul_tti_req = &mac->UL_tti_req_ahead[CC_id][buffer_index]; AssertFatal(future_ul_tti_req->SFN == ra->Msg3_frame && future_ul_tti_req->Slot == ra->Msg3_slot, "future UL_tti_req's frame.slot %d.%d does not match PUSCH %d.%d\n", From f5c1d18638f6cbf850415f2b36b97e77eb9dd0ff Mon Sep 17 00:00:00 2001 From: Laurent THOMAS Date: Thu, 18 Sep 2025 16:20:08 +0200 Subject: [PATCH 30/69] Fix bug in "freeing" prach occasions scheduler after decoding first occasion Release PRACH only after treating the entire PRACH slot/work. Also, release only once, not on every decoding occasion. --- openair1/SCHED_NR/nr_prach_procedures.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openair1/SCHED_NR/nr_prach_procedures.c b/openair1/SCHED_NR/nr_prach_procedures.c index c56a37ca1d..7dfe05dccd 100644 --- a/openair1/SCHED_NR/nr_prach_procedures.c +++ b/openair1/SCHED_NR/nr_prach_procedures.c @@ -87,8 +87,6 @@ void L1_nr_prach_procedures(PHY_VARS_gNB *gNB, int frame, int slot, nfapi_nr_rac &max_preamble[0], &max_preamble_energy[0], &max_preamble_delay[0]); - LOG_D(NR_PHY,"Freeing PRACH entry %d\n",prach_id); - free_nr_prach_entry(gNB,prach_id); LOG_D(NR_PHY,"[RAPROC] Frame %d, slot %d, occasion %d (prachStartSymbol %d) : Most likely preamble %d, energy %d.%d dB delay %d (prach_energy counter %d)\n", frame,slot,prach_oc,prachStartSymbol, max_preamble[0], @@ -142,6 +140,8 @@ void L1_nr_prach_procedures(PHY_VARS_gNB *gNB, int frame, int slot, nfapi_nr_rac gNB->prach_energy_counter++; } //if prach_id>0 rach_ind->slot = prach_start_slot; + LOG_D(NR_PHY,"Freeing PRACH entry %d\n",prach_id); + free_nr_prach_entry(gNB,prach_id); } // for NUMBER_OF_NR_PRACH_OCCASION_MAX VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_PRACH_RX,0); } From a4d3eb9fadf0abf02102c11a445cec190d7ab80c Mon Sep 17 00:00:00 2001 From: Laurent THOMAS Date: Thu, 14 Aug 2025 10:10:16 +0200 Subject: [PATCH 31/69] replace fix array index by pointers for prach lists in gNB --- executables/nr-ru.c | 9 +- openair1/PHY/NR_TRANSPORT/nr_prach.c | 78 ++++----- .../PHY/NR_TRANSPORT/nr_transport_proto.h | 10 +- openair1/SCHED/nfapi_nr_dummy.c | 16 +- openair1/SCHED_NR/fapi_nr_l1.c | 6 +- openair1/SCHED_NR/nr_prach_procedures.c | 149 +++++++++--------- 6 files changed, 137 insertions(+), 131 deletions(-) diff --git a/executables/nr-ru.c b/executables/nr-ru.c index 20deff5725..bf701f8abc 100644 --- a/executables/nr-ru.c +++ b/executables/nr-ru.c @@ -1208,8 +1208,8 @@ void *ru_thread(void *param) proc->tti_rx * gNB->frame_parms.samples_per_slot_wCP); // Do PRACH RU processing - int prach_id = find_nr_prach_ru(ru, proc->frame_rx, proc->tti_rx, SEARCH_EXIST); - if (prach_id >= 0) { + RU_PRACH_list_t *p = find_nr_prach_ru(ru, proc->frame_rx, proc->tti_rx, SEARCH_EXIST); + if (p) { VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_RU_PRACH_RX, 1 ); T(T_GNB_PHY_PRACH_INPUT_SIGNAL, @@ -1218,12 +1218,11 @@ void *ru_thread(void *param) T_INT(0), T_BUFFER(&ru->common.rxdata[0][fp->get_samples_slot_timestamp(proc->tti_rx - 1, fp, 0) /*-ru->N_TA_offset*/], (fp->get_samples_per_slot(proc->tti_rx - 1, fp) + fp->get_samples_per_slot(proc->tti_rx, fp)) * 4)); - RU_PRACH_list_t *p = ru->prach_list + prach_id; int N_dur = get_nr_prach_duration(p->fmt); for (int prach_oc = 0; prach_oc < p->num_prach_ocas; prach_oc++) { int prachStartSymbol = p->prachStartSymbol + prach_oc * N_dur; - int beam_id = ru->prach_list[prach_id].beam ? ru->prach_list[prach_id].beam[prach_oc] : 0; + int beam_id = p->beam ? p->beam[prach_oc] : 0; //comment FK: the standard 38.211 section 5.3.2 has one extra term +14*N_RA_slot. This is because there prachStartSymbol is given wrt to start of the 15kHz slot or 60kHz slot. Here we work slot based, so this function is anyway only called in slots where there is PRACH. Its up to the MAC to schedule another PRACH PDU in the case there are there N_RA_slot \in {0,1}. rx_nr_prach_ru(ru, p->fmt, // could also use format @@ -1235,7 +1234,7 @@ void *ru_thread(void *param) proc->frame_rx, proc->tti_rx); } - free_nr_ru_prach_entry(ru,prach_id); + free_nr_ru_prach_entry(ru, p); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_RU_PRACH_RX, 0); } // end if (prach_id >= 0) } // end if (ru->feprx) diff --git a/openair1/PHY/NR_TRANSPORT/nr_prach.c b/openair1/PHY/NR_TRANSPORT/nr_prach.c index f278d4c845..12c045e551 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_prach.c +++ b/openair1/PHY/NR_TRANSPORT/nr_prach.c @@ -46,34 +46,38 @@ void init_prach_list(PHY_VARS_gNB *gNB) } } -void free_nr_prach_entry(PHY_VARS_gNB *gNB, int prach_id) +void free_nr_prach_entry(PHY_VARS_gNB *gNB, gNB_PRACH_list_t *p) { - gNB->prach_vars.list[prach_id].frame = -1; - gNB->prach_vars.list[prach_id].slot = -1; - gNB->prach_vars.list[prach_id].num_slots = -1; - free_and_zero(gNB->prach_vars.list[prach_id].beam_nb); + for (uint16_t i = 0; i < NUMBER_OF_NR_PRACH_MAX; i++) { + if (p == gNB->prach_vars.list + i) { + p->frame = -1; + p->slot = -1; + p->num_slots = -1; + free_and_zero(p->beam_nb); + break; + } + } } -int16_t find_nr_prach(PHY_VARS_gNB *gNB,int frame, int slot, find_type_t type) { - +gNB_PRACH_list_t *find_nr_prach(PHY_VARS_gNB *gNB, int frame, int slot, find_type_t type) +{ AssertFatal(gNB!=NULL,"gNB is null\n"); for (uint16_t i=0; iprach_vars.list + i; LOG_D(PHY, "searching for PRACH in %d.%d prach_index %d=> %d.%d\n", frame, slot, i, p->frame, p->slot); if ((type == SEARCH_EXIST_OR_FREE) && (p->frame == -1) && (p->slot == -1)) { - return i; + return p; } else if ((type == SEARCH_EXIST) && (p->frame == frame) && (p->slot + p->num_slots - 1 == slot)) { - return i; + return p; } } - return -1; + return NULL; } -int nr_fill_prach(PHY_VARS_gNB *gNB, int SFN, int Slot, nfapi_nr_prach_pdu_t *prach_pdu) +gNB_PRACH_list_t *nr_fill_prach(PHY_VARS_gNB *gNB, int SFN, int Slot, nfapi_nr_prach_pdu_t *prach_pdu) { - int prach_id = find_nr_prach(gNB, SFN, Slot, SEARCH_EXIST_OR_FREE); - AssertFatal(((prach_id >= 0) && (prach_id < NUMBER_OF_NR_PRACH_MAX)), "illegal or no prach_id found!!! prach_id %d\n", prach_id); - gNB_PRACH_list_t *prach = &gNB->prach_vars.list[prach_id]; + gNB_PRACH_list_t *prach = find_nr_prach(gNB, SFN, Slot, SEARCH_EXIST_OR_FREE); + AssertFatal(prach, "prach list full!!!\n"); prach->frame = SFN; prach->slot = Slot; const int format = prach_pdu->prach_format; @@ -94,9 +98,8 @@ int nr_fill_prach(PHY_VARS_gNB *gNB, int SFN, int Slot, nfapi_nr_prach_pdu_t *pr bitmap); } } - LOG_D(NR_PHY,"Copying prach pdu %d bytes to index %d\n", (int)sizeof(*prach_pdu), prach_id); - memcpy(&prach->pdu, prach_pdu, sizeof(*prach_pdu)); - return prach_id; + prach->pdu = *prach_pdu; + return prach; } void init_prach_ru_list(RU_t *ru) @@ -110,7 +113,7 @@ void init_prach_ru_list(RU_t *ru) pthread_mutex_init(&ru->prach_list_mutex, NULL); } -int16_t find_nr_prach_ru(RU_t *ru,int frame,int slot, find_type_t type) +RU_PRACH_list_t *find_nr_prach_ru(RU_t *ru, int frame, int slot, find_type_t type) { AssertFatal(ru != NULL, "ru is null\n"); pthread_mutex_lock(&ru->prach_list_mutex); @@ -119,41 +122,44 @@ int16_t find_nr_prach_ru(RU_t *ru,int frame,int slot, find_type_t type) LOG_D(PHY, "searching for PRACH in %d.%d : prach_index %d=> %d.%d\n", frame, slot, i, p->frame, p->slot); if ((type == SEARCH_EXIST_OR_FREE) && (p->frame == -1) && (p->slot == -1)) { pthread_mutex_unlock(&ru->prach_list_mutex); - return i; + return p; } else if ((type == SEARCH_EXIST) && (p->frame == frame) && (p->slot + p->num_slots - 1 == slot)) { pthread_mutex_unlock(&ru->prach_list_mutex); - return i; + return p; } } pthread_mutex_unlock(&ru->prach_list_mutex); - return -1; + return NULL; } void nr_fill_prach_ru(RU_t *ru, int SFN, int Slot, nfapi_nr_prach_pdu_t *prach_pdu, int *beam_id) { - int prach_id = find_nr_prach_ru(ru, SFN, Slot, SEARCH_EXIST_OR_FREE); - AssertFatal((prach_id >= 0) && (prach_id < NUMBER_OF_NR_PRACH_MAX), - "illegal or no prach_id found!!! prach_id %d\n", - prach_id); + RU_PRACH_list_t *prach = find_nr_prach_ru(ru, SFN, Slot, SEARCH_EXIST_OR_FREE); + AssertFatal(prach, "ru prach list full\n"); pthread_mutex_lock(&ru->prach_list_mutex); - ru->prach_list[prach_id].frame = SFN; - ru->prach_list[prach_id].slot = Slot; + prach->frame = SFN; + prach->slot = Slot; const int fmt = prach_pdu->prach_format; - ru->prach_list[prach_id].num_slots = (fmt < 4) ? get_long_prach_dur(fmt, ru->nr_frame_parms->numerology_index) : 1; - ru->prach_list[prach_id].fmt = fmt; - ru->prach_list[prach_id].numRA = prach_pdu->num_ra; - ru->prach_list[prach_id].beam = beam_id; - ru->prach_list[prach_id].prachStartSymbol = prach_pdu->prach_start_symbol; - ru->prach_list[prach_id].num_prach_ocas = prach_pdu->num_prach_ocas; + prach->num_slots = (fmt < 4) ? get_long_prach_dur(fmt, ru->nr_frame_parms->numerology_index) : 1; + prach->fmt = fmt; + prach->numRA = prach_pdu->num_ra; + prach->beam = beam_id; + prach->prachStartSymbol = prach_pdu->prach_start_symbol; + prach->num_prach_ocas = prach_pdu->num_prach_ocas; pthread_mutex_unlock(&ru->prach_list_mutex); } -void free_nr_ru_prach_entry(RU_t *ru, int prach_id) +void free_nr_ru_prach_entry(RU_t *ru, RU_PRACH_list_t *p) { pthread_mutex_lock(&ru->prach_list_mutex); - ru->prach_list[prach_id].frame = -1; - ru->prach_list[prach_id].slot = -1; + for (int i = 0; i < NUMBER_OF_NR_RU_PRACH_MAX; i++) { + if (p == ru->prach_list + i) { + p->frame = -1; + p->slot = -1; + break; + } + } pthread_mutex_unlock(&ru->prach_list_mutex); } diff --git a/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h b/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h index a7769dc84d..8547a1415d 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h +++ b/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h @@ -200,7 +200,7 @@ void nr_fill_ulsch(PHY_VARS_gNB *gNB, int slot, nfapi_nr_pusch_pdu_t *ulsch_pdu); -int nr_fill_prach(PHY_VARS_gNB *gNB, int SFN, int Slot, nfapi_nr_prach_pdu_t *prach_pdu); +gNB_PRACH_list_t *nr_fill_prach(PHY_VARS_gNB *gNB, int SFN, int Slot, nfapi_nr_prach_pdu_t *prach_pdu); void rx_nr_prach(PHY_VARS_gNB *gNB, nfapi_nr_prach_pdu_t *prach_pdu, @@ -223,8 +223,8 @@ void rx_nr_prach_ru(RU_t *ru, void nr_fill_prach_ru(RU_t *ru,int SFN, int Slot, nfapi_nr_prach_pdu_t *prach_pdu, int *beam_nb); -int16_t find_nr_prach(PHY_VARS_gNB *gNB,int frame,int slot, find_type_t type); -int16_t find_nr_prach_ru(RU_t *ru,int frame,int slot, find_type_t type); +gNB_PRACH_list_t *find_nr_prach(PHY_VARS_gNB *gNB, int frame, int slot, find_type_t type); +RU_PRACH_list_t *find_nr_prach_ru(RU_t *ru, int frame, int slot, find_type_t type); void nr_fill_pucch(PHY_VARS_gNB *gNB, int frame, @@ -247,10 +247,10 @@ int nr_get_srs_signal(PHY_VARS_gNB *gNB, void init_prach_list(PHY_VARS_gNB *gNB); void init_prach_ru_list(RU_t *ru); -void free_nr_ru_prach_entry(RU_t *ru, int prach_id); +void free_nr_ru_prach_entry(RU_t *ru, RU_PRACH_list_t *p); int get_nr_prach_duration(uint8_t prach_format); -void free_nr_prach_entry(PHY_VARS_gNB *gNB, int prach_id); +void free_nr_prach_entry(PHY_VARS_gNB *gNB, gNB_PRACH_list_t *); void nr_decode_pucch1(c16_t **rxdataF, pucch_GroupHopping_t pucch_GroupHopping, diff --git a/openair1/SCHED/nfapi_nr_dummy.c b/openair1/SCHED/nfapi_nr_dummy.c index 9c9ecea443..4e4dea190d 100644 --- a/openair1/SCHED/nfapi_nr_dummy.c +++ b/openair1/SCHED/nfapi_nr_dummy.c @@ -37,15 +37,13 @@ void nr_fill_pucch(PHY_VARS_gNB *gNB, int frame, int slot, nfapi_nr_pucch_pdu_t *pucch_pdu){} -void nr_fill_prach(PHY_VARS_gNB *gNB, - int SFN, - int Slot, - nfapi_nr_prach_pdu_t *prach_pdu){} -void nr_fill_prach_ru(RU_t *ru, - int SFN, - int Slot, - nfapi_nr_prach_pdu_t *prach_pdu){} - +gNB_PRACH_list_t nr_fill_prach(PHY_VARS_gNB *gNB, int SFN, int Slot, nfapi_nr_prach_pdu_t *prach_pdu) +{ +} +RU_PRACH_list_t nr_fill_prach_ru(RU_t *ru, int SFN, int Slot, nfapi_nr_prach_pdu_t *prach_pdu) +{ +} + void nr_phy_config_request(NR_PHY_Config_t *gNB){} void install_nr_schedule_handlers(NR_IF_Module_t *if_inst){} diff --git a/openair1/SCHED_NR/fapi_nr_l1.c b/openair1/SCHED_NR/fapi_nr_l1.c index 74a2178982..8b88b0195a 100644 --- a/openair1/SCHED_NR/fapi_nr_l1.c +++ b/openair1/SCHED_NR/fapi_nr_l1.c @@ -154,9 +154,9 @@ void nr_schedule_ul_tti_req(PHY_VARS_gNB *gNB, nfapi_nr_ul_tti_request_t *UL_tti UL_tti_req->SFN, UL_tti_req->Slot); nfapi_nr_prach_pdu_t *prach_pdu = &UL_tti_req->pdus_list[i].prach_pdu; - int id = nr_fill_prach(gNB, UL_tti_req->SFN, UL_tti_req->Slot, prach_pdu); - if (gNB->RU_list[0]->if_south == LOCAL_RF || gNB->RU_list[0]->if_south == REMOTE_IF5) - nr_fill_prach_ru(gNB->RU_list[0], UL_tti_req->SFN, UL_tti_req->Slot, prach_pdu, gNB->prach_vars.list[id].beam_nb); + gNB_PRACH_list_t *prach = nr_fill_prach(gNB, UL_tti_req->SFN, UL_tti_req->Slot, prach_pdu); + if (prach && (gNB->RU_list[0]->if_south == LOCAL_RF || gNB->RU_list[0]->if_south == REMOTE_IF5)) + nr_fill_prach_ru(gNB->RU_list[0], UL_tti_req->SFN, UL_tti_req->Slot, prach_pdu, prach->beam_nb); break; case NFAPI_NR_UL_CONFIG_SRS_PDU_TYPE: LOG_D(NR_PHY, diff --git a/openair1/SCHED_NR/nr_prach_procedures.c b/openair1/SCHED_NR/nr_prach_procedures.c index 7dfe05dccd..9e581e1a00 100644 --- a/openair1/SCHED_NR/nr_prach_procedures.c +++ b/openair1/SCHED_NR/nr_prach_procedures.c @@ -63,85 +63,88 @@ void L1_nr_prach_procedures(PHY_VARS_gNB *gNB, int frame, int slot, nfapi_nr_rac ru=gNB->RU_list[0]; - int prach_id = find_nr_prach(gNB, frame, slot, SEARCH_EXIST); - if (prach_id >= 0) { - LOG_D(NR_PHY,"%d.%d Got prach entry id %d\n",frame,slot,prach_id); - nfapi_nr_prach_pdu_t *prach_pdu = &gNB->prach_vars.list[prach_id].pdu; - const int prach_start_slot = gNB->prach_vars.list[prach_id].slot; - uint8_t prachStartSymbol; - int N_dur = get_nr_prach_duration(prach_pdu->prach_format); + gNB_PRACH_list_t *prach_id = find_nr_prach(gNB, frame, slot, SEARCH_EXIST); + if (!prach_id) { + return; + } - for(int prach_oc = 0; prach_oc < prach_pdu->num_prach_ocas; prach_oc++) { - for (ru_aa=0,aa=0;ru_aanb_rx;ru_aa++,aa++) { - gNB->prach_vars.rxsigF[aa] = ru->prach_rxsigF[prach_oc][ru_aa]; - } + LOG_D(NR_PHY, "%d.%d Got prach entry\n", frame, slot); + nfapi_nr_prach_pdu_t *prach_pdu = &prach_id->pdu; + const int prach_start_slot = prach_id->slot; + uint8_t prachStartSymbol; + int N_dur = get_nr_prach_duration(prach_pdu->prach_format); - prachStartSymbol = prach_pdu->prach_start_symbol + prach_oc * N_dur; - //comment FK: the standard 38.211 section 5.3.2 has one extra term +14*N_RA_slot. This is because there prachStartSymbol is given wrt to start of the 15kHz slot or 60kHz slot. Here we work slot based, so this function is anyway only called in slots where there is PRACH. Its up to the MAC to schedule another PRACH PDU in the case there are there N_RA_slot \in {0,1}. + for (int prach_oc = 0; prach_oc < prach_pdu->num_prach_ocas; prach_oc++) { + for (ru_aa = 0, aa = 0; ru_aa < ru->nb_rx; ru_aa++, aa++) { + gNB->prach_vars.rxsigF[aa] = ru->prach_rxsigF[prach_oc][ru_aa]; + } - rx_nr_prach(gNB, - prach_pdu, - prach_oc, - frame, - slot, - &max_preamble[0], - &max_preamble_energy[0], - &max_preamble_delay[0]); - LOG_D(NR_PHY,"[RAPROC] Frame %d, slot %d, occasion %d (prachStartSymbol %d) : Most likely preamble %d, energy %d.%d dB delay %d (prach_energy counter %d)\n", - frame,slot,prach_oc,prachStartSymbol, - max_preamble[0], - max_preamble_energy[0]/10, - max_preamble_energy[0]%10, - max_preamble_delay[0], - gNB->prach_energy_counter); + prachStartSymbol = prach_pdu->prach_start_symbol + prach_oc * N_dur; + // comment FK: the standard 38.211 section 5.3.2 has one extra term +14*N_RA_slot. This is because there prachStartSymbol is + // given wrt to start of the 15kHz slot or 60kHz slot. Here we work slot based, so this function is anyway only called in slots + // where there is PRACH. Its up to the MAC to schedule another PRACH PDU in the case there are there N_RA_slot \in {0,1}. - if ((gNB->prach_energy_counter == NUM_PRACH_RX_FOR_NOISE_ESTIMATE) - && (max_preamble_energy[0] > gNB->measurements.prach_I0 + gNB->prach_thres) - && (rach_ind->number_of_pdus < MAX_NUM_NR_RX_RACH_PDUS)) { - LOG_A(NR_PHY, - "[RAPROC] %d.%d Initiating RA procedure with preamble %d, energy %d.%d dB (I0 %d, thres %d), delay %d start symbol " - "%u freq index %u\n", - frame, - prach_start_slot, - max_preamble[0], - max_preamble_energy[0] / 10, - max_preamble_energy[0] % 10, - gNB->measurements.prach_I0, - gNB->prach_thres, - max_preamble_delay[0], - prachStartSymbol, - prach_pdu->num_ra); + rx_nr_prach(gNB, prach_pdu, prach_oc, frame, slot, &max_preamble[0], &max_preamble_energy[0], &max_preamble_delay[0]); + LOG_D(NR_PHY, + "[RAPROC] Frame %d, slot %d, occasion %d (prachStartSymbol %d) : Most likely preamble %d, energy %d.%d dB delay %d " + "(prach_energy counter %d)\n", + frame, + slot, + prach_oc, + prachStartSymbol, + max_preamble[0], + max_preamble_energy[0] / 10, + max_preamble_energy[0] % 10, + max_preamble_delay[0], + gNB->prach_energy_counter); - T(T_ENB_PHY_INITIATE_RA_PROCEDURE, - T_INT(gNB->Mod_id), - T_INT(frame), - T_INT(slot), - T_INT(max_preamble[0]), - T_INT(max_preamble_energy[0]), - T_INT(max_preamble_delay[0])); + if ((gNB->prach_energy_counter == NUM_PRACH_RX_FOR_NOISE_ESTIMATE) + && (max_preamble_energy[0] > gNB->measurements.prach_I0 + gNB->prach_thres) + && (rach_ind->number_of_pdus < MAX_NUM_NR_RX_RACH_PDUS)) { + LOG_A(NR_PHY, + "[RAPROC] %d.%d Initiating RA procedure with preamble %d, energy %d.%d dB (I0 %d, thres %d), delay %d start symbol " + "%u freq index %u\n", + frame, + prach_start_slot, + max_preamble[0], + max_preamble_energy[0] / 10, + max_preamble_energy[0] % 10, + gNB->measurements.prach_I0, + gNB->prach_thres, + max_preamble_delay[0], + prachStartSymbol, + prach_pdu->num_ra); - nfapi_nr_prach_indication_pdu_t *ind = rach_ind->pdu_list + rach_ind->number_of_pdus; - ind->phy_cell_id = gNB->gNB_config.cell_config.phy_cell_id.value; - ind->symbol_index = prachStartSymbol; - ind->slot_index = slot; - ind->freq_index = prach_pdu->num_ra; - ind->avg_rssi = (max_preamble_energy[0] < 631) ? (128 + (max_preamble_energy[0] / 5)) : 254; - ind->avg_snr = 0xff; // invalid for now + T(T_ENB_PHY_INITIATE_RA_PROCEDURE, + T_INT(gNB->Mod_id), + T_INT(frame), + T_INT(slot), + T_INT(max_preamble[0]), + T_INT(max_preamble_energy[0]), + T_INT(max_preamble_delay[0])); - ind->num_preamble = 1; - ind->preamble_list[0].preamble_index = max_preamble[0]; - ind->preamble_list[0].timing_advance = max_preamble_delay[0]; - ind->preamble_list[0].preamble_pwr = 0xffffffff; - rach_ind->number_of_pdus++; - } - gNB->measurements.prach_I0 = ((gNB->measurements.prach_I0*900)>>10) + ((max_preamble_energy[0]*124)>>10); - if (frame==0) LOG_I(PHY,"prach_I0 = %d.%d dB\n",gNB->measurements.prach_I0/10,gNB->measurements.prach_I0%10); - if (gNB->prach_energy_counter < NUM_PRACH_RX_FOR_NOISE_ESTIMATE) - gNB->prach_energy_counter++; - } //if prach_id>0 - rach_ind->slot = prach_start_slot; - LOG_D(NR_PHY,"Freeing PRACH entry %d\n",prach_id); - free_nr_prach_entry(gNB,prach_id); - } // for NUMBER_OF_NR_PRACH_OCCASION_MAX + nfapi_nr_prach_indication_pdu_t *ind = rach_ind->pdu_list + rach_ind->number_of_pdus; + ind->phy_cell_id = gNB->gNB_config.cell_config.phy_cell_id.value; + ind->symbol_index = prachStartSymbol; + ind->slot_index = slot; + ind->freq_index = prach_pdu->num_ra; + ind->avg_rssi = (max_preamble_energy[0] < 631) ? (128 + (max_preamble_energy[0] / 5)) : 254; + ind->avg_snr = 0xff; // invalid for now + + ind->num_preamble = 1; + ind->preamble_list[0].preamble_index = max_preamble[0]; + ind->preamble_list[0].timing_advance = max_preamble_delay[0]; + ind->preamble_list[0].preamble_pwr = 0xffffffff; + rach_ind->number_of_pdus++; + } + gNB->measurements.prach_I0 = ((gNB->measurements.prach_I0 * 900) >> 10) + ((max_preamble_energy[0] * 124) >> 10); + if (frame == 0) + LOG_I(PHY, "prach_I0 = %d.%d dB\n", gNB->measurements.prach_I0 / 10, gNB->measurements.prach_I0 % 10); + if (gNB->prach_energy_counter < NUM_PRACH_RX_FOR_NOISE_ESTIMATE) + gNB->prach_energy_counter++; + } // if prach_id>0 + rach_ind->slot = prach_start_slot; + LOG_D(NR_PHY, "Freeing PRACH entry\n"); + free_nr_prach_entry(gNB, prach_id); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_PRACH_RX,0); } From 88cecd707be45000c53b39ec5c74cf090bda1d48 Mon Sep 17 00:00:00 2001 From: Laurent THOMAS Date: Thu, 14 Aug 2025 10:53:34 +0200 Subject: [PATCH 32/69] regroup similar lists for "ru" and "gNB" in a common definition Merge the identical sizes. Use correct naming: it is a element of a list, not a list --- executables/nr-ru.c | 14 ++--- openair1/PHY/NR_TRANSPORT/nr_prach.c | 54 ++++++++++--------- .../PHY/NR_TRANSPORT/nr_transport_proto.h | 10 ++-- openair1/PHY/defs_RU.h | 14 +---- openair1/PHY/defs_common.h | 25 +++++++++ openair1/PHY/defs_gNB.h | 14 +---- openair1/SCHED_NR/fapi_nr_l1.c | 4 +- openair1/SCHED_NR/nr_prach_procedures.c | 2 +- 8 files changed, 70 insertions(+), 67 deletions(-) diff --git a/executables/nr-ru.c b/executables/nr-ru.c index bf701f8abc..0e507e5260 100644 --- a/executables/nr-ru.c +++ b/executables/nr-ru.c @@ -1208,7 +1208,7 @@ void *ru_thread(void *param) proc->tti_rx * gNB->frame_parms.samples_per_slot_wCP); // Do PRACH RU processing - RU_PRACH_list_t *p = find_nr_prach_ru(ru, proc->frame_rx, proc->tti_rx, SEARCH_EXIST); + prach_item_t *p = find_nr_prach_ru(ru, proc->frame_rx, proc->tti_rx, SEARCH_EXIST); if (p) { VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_RU_PRACH_RX, 1 ); @@ -1218,15 +1218,15 @@ void *ru_thread(void *param) T_INT(0), T_BUFFER(&ru->common.rxdata[0][fp->get_samples_slot_timestamp(proc->tti_rx - 1, fp, 0) /*-ru->N_TA_offset*/], (fp->get_samples_per_slot(proc->tti_rx - 1, fp) + fp->get_samples_per_slot(proc->tti_rx, fp)) * 4)); - int N_dur = get_nr_prach_duration(p->fmt); + int N_dur = get_nr_prach_duration(p->lower.fmt); - for (int prach_oc = 0; prach_oc < p->num_prach_ocas; prach_oc++) { - int prachStartSymbol = p->prachStartSymbol + prach_oc * N_dur; - int beam_id = p->beam ? p->beam[prach_oc] : 0; + for (int prach_oc = 0; prach_oc < p->lower.num_prach_ocas; prach_oc++) { + int prachStartSymbol = p->lower.prachStartSymbol + prach_oc * N_dur; + int beam_id = p->lower.beam ? p->lower.beam[prach_oc] : 0; //comment FK: the standard 38.211 section 5.3.2 has one extra term +14*N_RA_slot. This is because there prachStartSymbol is given wrt to start of the 15kHz slot or 60kHz slot. Here we work slot based, so this function is anyway only called in slots where there is PRACH. Its up to the MAC to schedule another PRACH PDU in the case there are there N_RA_slot \in {0,1}. rx_nr_prach_ru(ru, - p->fmt, // could also use format - p->numRA, + p->lower.fmt, // could also use format + p->lower.numRA, beam_id, prachStartSymbol, p->slot, diff --git a/openair1/PHY/NR_TRANSPORT/nr_prach.c b/openair1/PHY/NR_TRANSPORT/nr_prach.c index 12c045e551..7329465f02 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_prach.c +++ b/openair1/PHY/NR_TRANSPORT/nr_prach.c @@ -46,24 +46,24 @@ void init_prach_list(PHY_VARS_gNB *gNB) } } -void free_nr_prach_entry(PHY_VARS_gNB *gNB, gNB_PRACH_list_t *p) +void free_nr_prach_entry(PHY_VARS_gNB *gNB, prach_item_t *p) { for (uint16_t i = 0; i < NUMBER_OF_NR_PRACH_MAX; i++) { if (p == gNB->prach_vars.list + i) { p->frame = -1; p->slot = -1; p->num_slots = -1; - free_and_zero(p->beam_nb); + free_and_zero(p->upper.beam_nb); break; } } } -gNB_PRACH_list_t *find_nr_prach(PHY_VARS_gNB *gNB, int frame, int slot, find_type_t type) +prach_item_t *find_nr_prach(PHY_VARS_gNB *gNB, int frame, int slot, find_type_t type) { AssertFatal(gNB!=NULL,"gNB is null\n"); for (uint16_t i=0; iprach_vars.list + i; + prach_item_t *p = gNB->prach_vars.list + i; LOG_D(PHY, "searching for PRACH in %d.%d prach_index %d=> %d.%d\n", frame, slot, i, p->frame, p->slot); if ((type == SEARCH_EXIST_OR_FREE) && (p->frame == -1) && (p->slot == -1)) { return p; @@ -74,28 +74,29 @@ gNB_PRACH_list_t *find_nr_prach(PHY_VARS_gNB *gNB, int frame, int slot, find_typ return NULL; } -gNB_PRACH_list_t *nr_fill_prach(PHY_VARS_gNB *gNB, int SFN, int Slot, nfapi_nr_prach_pdu_t *prach_pdu) +prach_item_t *nr_fill_prach(PHY_VARS_gNB *gNB, int SFN, int Slot, nfapi_nr_prach_pdu_t *prach_pdu) { - gNB_PRACH_list_t *prach = find_nr_prach(gNB, SFN, Slot, SEARCH_EXIST_OR_FREE); + prach_item_t *prach = find_nr_prach(gNB, SFN, Slot, SEARCH_EXIST_OR_FREE); AssertFatal(prach, "prach list full!!!\n"); prach->frame = SFN; prach->slot = Slot; + prach->type=prach_upper; const int format = prach_pdu->prach_format; prach->num_slots = (format < 4) ? get_long_prach_dur(format, gNB->frame_parms.numerology_index) : 1; if (gNB->common_vars.beam_id) { int n_symb = get_nr_prach_duration(prach_pdu->prach_format); - prach->beam_nb = calloc(prach_pdu->beamforming.dig_bf_interface, sizeof(*prach->beam_nb)); + prach->upper.beam_nb = calloc(prach_pdu->beamforming.dig_bf_interface, sizeof(*prach->upper.beam_nb)); for (int i = 0; i < prach_pdu->beamforming.dig_bf_interface; i++) { int fapi_beam_idx = prach_pdu->beamforming.prgs_list[0].dig_bf_interface_list[i].beam_idx; int start_symb = prach_pdu->prach_start_symbol + i * n_symb; int bitmap = SL_to_bitmap(start_symb, n_symb); - prach->beam_nb[i] = beam_index_allocation(gNB->enable_analog_das, - fapi_beam_idx, - &gNB->gNB_config.analog_beamforming_ve, - &gNB->common_vars, - Slot, - NR_NUMBER_OF_SYMBOLS_PER_SLOT, - bitmap); + prach->upper.beam_nb[i] = beam_index_allocation(gNB->enable_analog_das, + fapi_beam_idx, + &gNB->gNB_config.analog_beamforming_ve, + &gNB->common_vars, + Slot, + NR_NUMBER_OF_SYMBOLS_PER_SLOT, + bitmap); } } prach->pdu = *prach_pdu; @@ -105,7 +106,7 @@ gNB_PRACH_list_t *nr_fill_prach(PHY_VARS_gNB *gNB, int SFN, int Slot, nfapi_nr_p void init_prach_ru_list(RU_t *ru) { AssertFatal(ru != NULL, "ru is null\n"); - for (int i = 0; i < NUMBER_OF_NR_RU_PRACH_MAX; i++) { + for (int i = 0; i < NUMBER_OF_NR_PRACH_MAX; i++) { ru->prach_list[i].frame = -1; ru->prach_list[i].slot = -1; ru->prach_list[i].num_slots = -1; @@ -113,12 +114,12 @@ void init_prach_ru_list(RU_t *ru) pthread_mutex_init(&ru->prach_list_mutex, NULL); } -RU_PRACH_list_t *find_nr_prach_ru(RU_t *ru, int frame, int slot, find_type_t type) +prach_item_t *find_nr_prach_ru(RU_t *ru, int frame, int slot, find_type_t type) { AssertFatal(ru != NULL, "ru is null\n"); pthread_mutex_lock(&ru->prach_list_mutex); - for (int i = 0; i < NUMBER_OF_NR_RU_PRACH_MAX; i++) { - RU_PRACH_list_t *p = ru->prach_list + i; + for (int i = 0; i < NUMBER_OF_NR_PRACH_MAX; i++) { + prach_item_t *p = ru->prach_list + i; LOG_D(PHY, "searching for PRACH in %d.%d : prach_index %d=> %d.%d\n", frame, slot, i, p->frame, p->slot); if ((type == SEARCH_EXIST_OR_FREE) && (p->frame == -1) && (p->slot == -1)) { pthread_mutex_unlock(&ru->prach_list_mutex); @@ -134,7 +135,7 @@ RU_PRACH_list_t *find_nr_prach_ru(RU_t *ru, int frame, int slot, find_type_t typ void nr_fill_prach_ru(RU_t *ru, int SFN, int Slot, nfapi_nr_prach_pdu_t *prach_pdu, int *beam_id) { - RU_PRACH_list_t *prach = find_nr_prach_ru(ru, SFN, Slot, SEARCH_EXIST_OR_FREE); + prach_item_t *prach = find_nr_prach_ru(ru, SFN, Slot, SEARCH_EXIST_OR_FREE); AssertFatal(prach, "ru prach list full\n"); pthread_mutex_lock(&ru->prach_list_mutex); @@ -142,18 +143,19 @@ void nr_fill_prach_ru(RU_t *ru, int SFN, int Slot, nfapi_nr_prach_pdu_t *prach_p prach->slot = Slot; const int fmt = prach_pdu->prach_format; prach->num_slots = (fmt < 4) ? get_long_prach_dur(fmt, ru->nr_frame_parms->numerology_index) : 1; - prach->fmt = fmt; - prach->numRA = prach_pdu->num_ra; - prach->beam = beam_id; - prach->prachStartSymbol = prach_pdu->prach_start_symbol; - prach->num_prach_ocas = prach_pdu->num_prach_ocas; + prach->type=prach_lower; + prach->lower.fmt = fmt; + prach->lower.numRA = prach_pdu->num_ra; + prach->lower.beam = beam_id; + prach->lower.prachStartSymbol = prach_pdu->prach_start_symbol; + prach->lower.num_prach_ocas = prach_pdu->num_prach_ocas; pthread_mutex_unlock(&ru->prach_list_mutex); } -void free_nr_ru_prach_entry(RU_t *ru, RU_PRACH_list_t *p) +void free_nr_ru_prach_entry(RU_t *ru, prach_item_t *p) { pthread_mutex_lock(&ru->prach_list_mutex); - for (int i = 0; i < NUMBER_OF_NR_RU_PRACH_MAX; i++) { + for (int i = 0; i < NUMBER_OF_NR_PRACH_MAX; i++) { if (p == ru->prach_list + i) { p->frame = -1; p->slot = -1; diff --git a/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h b/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h index 8547a1415d..20568e8020 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h +++ b/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h @@ -200,7 +200,7 @@ void nr_fill_ulsch(PHY_VARS_gNB *gNB, int slot, nfapi_nr_pusch_pdu_t *ulsch_pdu); -gNB_PRACH_list_t *nr_fill_prach(PHY_VARS_gNB *gNB, int SFN, int Slot, nfapi_nr_prach_pdu_t *prach_pdu); +prach_item_t *nr_fill_prach(PHY_VARS_gNB *gNB, int SFN, int Slot, nfapi_nr_prach_pdu_t *prach_pdu); void rx_nr_prach(PHY_VARS_gNB *gNB, nfapi_nr_prach_pdu_t *prach_pdu, @@ -223,8 +223,8 @@ void rx_nr_prach_ru(RU_t *ru, void nr_fill_prach_ru(RU_t *ru,int SFN, int Slot, nfapi_nr_prach_pdu_t *prach_pdu, int *beam_nb); -gNB_PRACH_list_t *find_nr_prach(PHY_VARS_gNB *gNB, int frame, int slot, find_type_t type); -RU_PRACH_list_t *find_nr_prach_ru(RU_t *ru, int frame, int slot, find_type_t type); +prach_item_t *find_nr_prach(PHY_VARS_gNB *gNB, int frame, int slot, find_type_t type); +prach_item_t *find_nr_prach_ru(RU_t *ru, int frame, int slot, find_type_t type); void nr_fill_pucch(PHY_VARS_gNB *gNB, int frame, @@ -247,10 +247,10 @@ int nr_get_srs_signal(PHY_VARS_gNB *gNB, void init_prach_list(PHY_VARS_gNB *gNB); void init_prach_ru_list(RU_t *ru); -void free_nr_ru_prach_entry(RU_t *ru, RU_PRACH_list_t *p); +void free_nr_ru_prach_entry(RU_t *ru, prach_item_t *p); int get_nr_prach_duration(uint8_t prach_format); -void free_nr_prach_entry(PHY_VARS_gNB *gNB, gNB_PRACH_list_t *); +void free_nr_prach_entry(PHY_VARS_gNB *gNB, prach_item_t *); void nr_decode_pucch1(c16_t **rxdataF, pucch_GroupHopping_t pucch_GroupHopping, diff --git a/openair1/PHY/defs_RU.h b/openair1/PHY/defs_RU.h index e72465c4a9..8116dfbc4b 100644 --- a/openair1/PHY/defs_RU.h +++ b/openair1/PHY/defs_RU.h @@ -190,18 +190,6 @@ typedef struct { task_ans_t *ans; } feptx_cmd_t; -typedef struct { - int frame; - int slot; - int fmt; - int numRA; - int prachStartSymbol; - int num_prach_ocas; - int num_slots; - int *beam; -} RU_PRACH_list_t; - -#define NUMBER_OF_NR_RU_PRACH_MAX 8 #define NUMBER_OF_NR_RU_PRACH_OCCASIONS_MAX 12 #define RU_RX_SLOT_DEPTH 4 typedef struct RU_proc_t_s { @@ -605,7 +593,7 @@ typedef struct RU_t_s { /// beamforming weight vectors int32_t **beam_weights[NUMBER_OF_eNB_MAX+1][15]; /// prach commands - RU_PRACH_list_t prach_list[NUMBER_OF_NR_RU_PRACH_MAX]; + prach_item_t prach_list[NUMBER_OF_NR_PRACH_MAX]; /// mutex for prach_list access pthread_mutex_t prach_list_mutex; /// received frequency-domain signal for PRACH (IF4p5 RRU) diff --git a/openair1/PHY/defs_common.h b/openair1/PHY/defs_common.h index b6619efc6e..085fbc15a4 100644 --- a/openair1/PHY/defs_common.h +++ b/openair1/PHY/defs_common.h @@ -998,6 +998,31 @@ typedef struct { bool failed; } decode_abort_t; +// TODO will be removed in a late commit +#include "nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h" +#define NUMBER_OF_NR_PRACH_MAX 8 +typedef struct { + int frame; + int slot; + int num_slots; // prach duration in slots + enum { prach_upper, prach_lower } type; + union { + struct { + // identifier for concurrent beams + int *beam_nb; + nfapi_nr_prach_pdu_t pdu; + } upper; + struct { + int fmt; + int numRA; + int prachStartSymbol; + int num_prach_ocas; + int *beam; + } lower; + }; + nfapi_nr_prach_pdu_t pdu; +} prach_item_t; + static inline void init_abort(decode_abort_t *ab) { int ret = pthread_mutex_init(&ab->mutex_failure, NULL); diff --git a/openair1/PHY/defs_gNB.h b/openair1/PHY/defs_gNB.h index 9575e33c7b..f62d19ba3a 100644 --- a/openair1/PHY/defs_gNB.h +++ b/openair1/PHY/defs_gNB.h @@ -134,24 +134,12 @@ typedef struct { nfapi_nr_dl_tti_ssb_pdu ssb_pdu; } NR_gNB_SSB_t; -typedef struct { - int frame; - int slot; - // identifier for concurrent beams - // prach duration in slots - int num_slots; - int *beam_nb; - nfapi_nr_prach_pdu_t pdu; -} gNB_PRACH_list_t; - -#define NUMBER_OF_NR_PRACH_MAX 8 - typedef struct { /// \brief ?. /// second index: rx antenna [0..63] (hard coded) \note Hard coded array size indexed by \c nb_antennas_rx. /// third index: frequency-domain sample [0..ofdm_symbol_size*12[ int16_t **rxsigF; - gNB_PRACH_list_t list[NUMBER_OF_NR_PRACH_MAX]; + prach_item_t list[NUMBER_OF_NR_PRACH_MAX]; } NR_gNB_PRACH; typedef struct { diff --git a/openair1/SCHED_NR/fapi_nr_l1.c b/openair1/SCHED_NR/fapi_nr_l1.c index 8b88b0195a..fa5167adff 100644 --- a/openair1/SCHED_NR/fapi_nr_l1.c +++ b/openair1/SCHED_NR/fapi_nr_l1.c @@ -154,9 +154,9 @@ void nr_schedule_ul_tti_req(PHY_VARS_gNB *gNB, nfapi_nr_ul_tti_request_t *UL_tti UL_tti_req->SFN, UL_tti_req->Slot); nfapi_nr_prach_pdu_t *prach_pdu = &UL_tti_req->pdus_list[i].prach_pdu; - gNB_PRACH_list_t *prach = nr_fill_prach(gNB, UL_tti_req->SFN, UL_tti_req->Slot, prach_pdu); + prach_item_t *prach = nr_fill_prach(gNB, UL_tti_req->SFN, UL_tti_req->Slot, prach_pdu); if (prach && (gNB->RU_list[0]->if_south == LOCAL_RF || gNB->RU_list[0]->if_south == REMOTE_IF5)) - nr_fill_prach_ru(gNB->RU_list[0], UL_tti_req->SFN, UL_tti_req->Slot, prach_pdu, prach->beam_nb); + nr_fill_prach_ru(gNB->RU_list[0], UL_tti_req->SFN, UL_tti_req->Slot, prach_pdu, prach->upper.beam_nb); break; case NFAPI_NR_UL_CONFIG_SRS_PDU_TYPE: LOG_D(NR_PHY, diff --git a/openair1/SCHED_NR/nr_prach_procedures.c b/openair1/SCHED_NR/nr_prach_procedures.c index 9e581e1a00..cc38665757 100644 --- a/openair1/SCHED_NR/nr_prach_procedures.c +++ b/openair1/SCHED_NR/nr_prach_procedures.c @@ -63,7 +63,7 @@ void L1_nr_prach_procedures(PHY_VARS_gNB *gNB, int frame, int slot, nfapi_nr_rac ru=gNB->RU_list[0]; - gNB_PRACH_list_t *prach_id = find_nr_prach(gNB, frame, slot, SEARCH_EXIST); + prach_item_t *prach_id = find_nr_prach(gNB, frame, slot, SEARCH_EXIST); if (!prach_id) { return; } From 4dd340b6bb52df20bc7e48f3bc8a6384e800e18f Mon Sep 17 00:00:00 2001 From: Laurent THOMAS Date: Thu, 14 Aug 2025 11:39:36 +0200 Subject: [PATCH 33/69] merge almost duplicated code for ru prach list and gNB prach list (gNB is not the proper name, it is CU+DU, gNB is RU+CU+DU) --- executables/nr-ru.c | 4 +- openair1/PHY/INIT/nr_init.c | 2 +- openair1/PHY/INIT/nr_init_ru.c | 4 +- openair1/PHY/NR_TRANSPORT/nr_prach.c | 143 +++++++----------- .../PHY/NR_TRANSPORT/nr_transport_proto.h | 10 +- openair1/PHY/defs_RU.h | 5 +- openair1/PHY/defs_common.h | 11 +- openair1/PHY/defs_gNB.h | 2 +- openair1/SCHED/nfapi_nr_dummy.c | 5 +- openair1/SCHED_NR/nr_prach_procedures.c | 4 +- openair1/SIMULATION/NR_PHY/prachsim.c | 12 +- 11 files changed, 79 insertions(+), 123 deletions(-) diff --git a/executables/nr-ru.c b/executables/nr-ru.c index 0e507e5260..1c2e1acaf1 100644 --- a/executables/nr-ru.c +++ b/executables/nr-ru.c @@ -1208,7 +1208,7 @@ void *ru_thread(void *param) proc->tti_rx * gNB->frame_parms.samples_per_slot_wCP); // Do PRACH RU processing - prach_item_t *p = find_nr_prach_ru(ru, proc->frame_rx, proc->tti_rx, SEARCH_EXIST); + prach_item_t *p = find_nr_prach(&ru->prach_list, proc->frame_rx, proc->tti_rx, SEARCH_EXIST); if (p) { VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_RU_PRACH_RX, 1 ); @@ -1234,7 +1234,7 @@ void *ru_thread(void *param) proc->frame_rx, proc->tti_rx); } - free_nr_ru_prach_entry(ru, p); + free_nr_prach_entry(&ru->prach_list, p); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_RU_PRACH_RX, 0); } // end if (prach_id >= 0) } // end if (ru->feprx) diff --git a/openair1/PHY/INIT/nr_init.c b/openair1/PHY/INIT/nr_init.c index 23334c8626..75145c78a4 100644 --- a/openair1/PHY/INIT/nr_init.c +++ b/openair1/PHY/INIT/nr_init.c @@ -192,7 +192,7 @@ void phy_init_nr_gNB(PHY_VARS_gNB *gNB) // PRACH prach_vars->rxsigF = (int16_t **)malloc16_clear(Prx * sizeof(int16_t *)); - init_prach_list(gNB); + init_prach_list(&gNB->prach_vars.list, prach_upper); int N_RB_UL = cfg->carrier_config.ul_grid_size[cfg->ssb_config.scs_common.value].value; int n_buf = Prx*max_ul_mimo_layers; diff --git a/openair1/PHY/INIT/nr_init_ru.c b/openair1/PHY/INIT/nr_init_ru.c index ca753938a6..6ad085eb4c 100644 --- a/openair1/PHY/INIT/nr_init_ru.c +++ b/openair1/PHY/INIT/nr_init_ru.c @@ -27,8 +27,6 @@ #include #include "openair1/PHY/defs_RU.h" -void init_prach_ru_list(RU_t *ru); - void nr_phy_init_RU(RU_t *ru) { NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms; @@ -132,7 +130,7 @@ void nr_phy_init_RU(RU_t *ru) LOG_D(PHY, "[INIT] %s() ru->num_gNB:%d \n", __FUNCTION__, ru->num_gNB); } // !=IF5 - init_prach_ru_list(ru); + init_prach_list(&ru->prach_list, prach_lower); } void nr_phy_free_RU(RU_t *ru) diff --git a/openair1/PHY/NR_TRANSPORT/nr_prach.c b/openair1/PHY/NR_TRANSPORT/nr_prach.c index 7329465f02..9fab6254ca 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_prach.c +++ b/openair1/PHY/NR_TRANSPORT/nr_prach.c @@ -36,51 +36,57 @@ #include "PHY/NR_TRANSPORT/nr_transport_common_proto.h" #include "openair1/PHY/NR_TRANSPORT/nr_prach.h" -void init_prach_list(PHY_VARS_gNB *gNB) +void init_prach_list(prach_list_t *l, prach_type_t t) { - AssertFatal(gNB != NULL, "gNB is null\n"); - for (int i = 0; i < NUMBER_OF_NR_PRACH_MAX; i++){ - gNB->prach_vars.list[i].frame = -1; - gNB->prach_vars.list[i].slot = -1; - gNB->prach_vars.list[i].num_slots = -1; - } + pthread_mutex_init(&l->prach_list_mutex, NULL); + for (prach_item_t *p = l->list; p < l->list + NUMBER_OF_NR_PRACH_MAX; p++) + *p = (prach_item_t){.frame = -1, .slot = -1, .type = t}; } -void free_nr_prach_entry(PHY_VARS_gNB *gNB, prach_item_t *p) +void free_nr_prach_entry(prach_list_t *l, prach_item_t *p) { - for (uint16_t i = 0; i < NUMBER_OF_NR_PRACH_MAX; i++) { - if (p == gNB->prach_vars.list + i) { - p->frame = -1; - p->slot = -1; - p->num_slots = -1; - free_and_zero(p->upper.beam_nb); + pthread_mutex_lock(&l->prach_list_mutex); + if (p->type == prach_upper) + free_and_zero(p->upper.beam_nb); + *p = (prach_item_t){.frame = -1, .slot = -1, .num_slots = -1}; + pthread_mutex_unlock(&l->prach_list_mutex); +} + +prach_item_t *find_nr_prach(prach_list_t *l, int frame, int slot, find_type_t type) +{ + pthread_mutex_lock(&l->prach_list_mutex); + prach_item_t *p = l->list; + prach_item_t *end = p + NUMBER_OF_NR_PRACH_MAX; + for (; p < end; p++) + if (p->frame == frame && (p->slot + p->num_slots - 1) == slot) break; + if (p == end) { + if (type == SEARCH_EXIST) { + pthread_mutex_unlock(&l->prach_list_mutex); + return NULL; } + for (p = l->list; p < end; p++) + if (p->frame == -1 && p->slot == -1) + break; } -} - -prach_item_t *find_nr_prach(PHY_VARS_gNB *gNB, int frame, int slot, find_type_t type) -{ - AssertFatal(gNB!=NULL,"gNB is null\n"); - for (uint16_t i=0; iprach_vars.list + i; - LOG_D(PHY, "searching for PRACH in %d.%d prach_index %d=> %d.%d\n", frame, slot, i, p->frame, p->slot); - if ((type == SEARCH_EXIST_OR_FREE) && (p->frame == -1) && (p->slot == -1)) { - return p; - } else if ((type == SEARCH_EXIST) && (p->frame == frame) && (p->slot + p->num_slots - 1 == slot)) { - return p; - } + if (p == end) { + pthread_mutex_unlock(&l->prach_list_mutex); + return NULL; } - return NULL; + // mark it used, it will be filled later + p->frame = frame; + pthread_mutex_unlock(&l->prach_list_mutex); + return p; } prach_item_t *nr_fill_prach(PHY_VARS_gNB *gNB, int SFN, int Slot, nfapi_nr_prach_pdu_t *prach_pdu) { - prach_item_t *prach = find_nr_prach(gNB, SFN, Slot, SEARCH_EXIST_OR_FREE); - AssertFatal(prach, "prach list full!!!\n"); - prach->frame = SFN; - prach->slot = Slot; - prach->type=prach_upper; + prach_item_t *prach = find_nr_prach(&gNB->prach_vars.list, SFN, Slot, SEARCH_EXIST_OR_FREE); + if (!prach) { + LOG_W(PHY, "no free space for a new detected rach, discarding\n"); + return NULL; + } + *prach = (prach_item_t){.frame = SFN, .slot = Slot, .type = prach_upper}; const int format = prach_pdu->prach_format; prach->num_slots = (format < 4) ? get_long_prach_dur(format, gNB->frame_parms.numerology_index) : 1; if (gNB->common_vars.beam_id) { @@ -103,66 +109,23 @@ prach_item_t *nr_fill_prach(PHY_VARS_gNB *gNB, int SFN, int Slot, nfapi_nr_prach return prach; } -void init_prach_ru_list(RU_t *ru) -{ - AssertFatal(ru != NULL, "ru is null\n"); - for (int i = 0; i < NUMBER_OF_NR_PRACH_MAX; i++) { - ru->prach_list[i].frame = -1; - ru->prach_list[i].slot = -1; - ru->prach_list[i].num_slots = -1; - } - pthread_mutex_init(&ru->prach_list_mutex, NULL); -} - -prach_item_t *find_nr_prach_ru(RU_t *ru, int frame, int slot, find_type_t type) -{ - AssertFatal(ru != NULL, "ru is null\n"); - pthread_mutex_lock(&ru->prach_list_mutex); - for (int i = 0; i < NUMBER_OF_NR_PRACH_MAX; i++) { - prach_item_t *p = ru->prach_list + i; - LOG_D(PHY, "searching for PRACH in %d.%d : prach_index %d=> %d.%d\n", frame, slot, i, p->frame, p->slot); - if ((type == SEARCH_EXIST_OR_FREE) && (p->frame == -1) && (p->slot == -1)) { - pthread_mutex_unlock(&ru->prach_list_mutex); - return p; - } else if ((type == SEARCH_EXIST) && (p->frame == frame) && (p->slot + p->num_slots - 1 == slot)) { - pthread_mutex_unlock(&ru->prach_list_mutex); - return p; - } - } - pthread_mutex_unlock(&ru->prach_list_mutex); - return NULL; -} - void nr_fill_prach_ru(RU_t *ru, int SFN, int Slot, nfapi_nr_prach_pdu_t *prach_pdu, int *beam_id) { - prach_item_t *prach = find_nr_prach_ru(ru, SFN, Slot, SEARCH_EXIST_OR_FREE); - AssertFatal(prach, "ru prach list full\n"); - - pthread_mutex_lock(&ru->prach_list_mutex); - prach->frame = SFN; - prach->slot = Slot; - const int fmt = prach_pdu->prach_format; - prach->num_slots = (fmt < 4) ? get_long_prach_dur(fmt, ru->nr_frame_parms->numerology_index) : 1; - prach->type=prach_lower; - prach->lower.fmt = fmt; - prach->lower.numRA = prach_pdu->num_ra; - prach->lower.beam = beam_id; - prach->lower.prachStartSymbol = prach_pdu->prach_start_symbol; - prach->lower.num_prach_ocas = prach_pdu->num_prach_ocas; - pthread_mutex_unlock(&ru->prach_list_mutex); -} - -void free_nr_ru_prach_entry(RU_t *ru, prach_item_t *p) -{ - pthread_mutex_lock(&ru->prach_list_mutex); - for (int i = 0; i < NUMBER_OF_NR_PRACH_MAX; i++) { - if (p == ru->prach_list + i) { - p->frame = -1; - p->slot = -1; - break; - } + prach_item_t *prach = find_nr_prach(&ru->prach_list, SFN, Slot, SEARCH_EXIST_OR_FREE); + if (!prach) { + LOG_E(PHY, "no prach memory found\n"); + return; } - pthread_mutex_unlock(&ru->prach_list_mutex); + const int fmt = prach_pdu->prach_format; + *prach = (prach_item_t){.frame = SFN, + .slot = Slot, + .type = prach_lower, + .num_slots = (fmt < 4) ? get_long_prach_dur(fmt, ru->nr_frame_parms->numerology_index) : 1, + .lower = {.fmt = fmt, + .numRA = prach_pdu->num_ra, + .beam = beam_id, + .prachStartSymbol = prach_pdu->prach_start_symbol, + .num_prach_ocas = prach_pdu->num_prach_ocas}}; } void rx_nr_prach_ru(RU_t *ru, diff --git a/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h b/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h index 20568e8020..f43e4cdcdb 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h +++ b/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h @@ -222,10 +222,7 @@ void rx_nr_prach_ru(RU_t *ru, int subframe); void nr_fill_prach_ru(RU_t *ru,int SFN, int Slot, nfapi_nr_prach_pdu_t *prach_pdu, int *beam_nb); - -prach_item_t *find_nr_prach(PHY_VARS_gNB *gNB, int frame, int slot, find_type_t type); -prach_item_t *find_nr_prach_ru(RU_t *ru, int frame, int slot, find_type_t type); - +prach_item_t *find_nr_prach(prach_list_t *, int frame, int slot, find_type_t type); void nr_fill_pucch(PHY_VARS_gNB *gNB, int frame, int slot, @@ -245,12 +242,9 @@ int nr_get_srs_signal(PHY_VARS_gNB *gNB, c16_t srs_received_signal[][gNB->frame_parms.ofdm_symbol_size * (1 << srs_pdu->num_symbols)], c16_t srs_received_noise[][gNB->frame_parms.ofdm_symbol_size * (1 << srs_pdu->num_symbols)]); -void init_prach_list(PHY_VARS_gNB *gNB); -void init_prach_ru_list(RU_t *ru); -void free_nr_ru_prach_entry(RU_t *ru, prach_item_t *p); int get_nr_prach_duration(uint8_t prach_format); -void free_nr_prach_entry(PHY_VARS_gNB *gNB, prach_item_t *); +void free_nr_prach_entry(prach_list_t *, prach_item_t *); void nr_decode_pucch1(c16_t **rxdataF, pucch_GroupHopping_t pucch_GroupHopping, diff --git a/openair1/PHY/defs_RU.h b/openair1/PHY/defs_RU.h index 8116dfbc4b..3d85c96af8 100644 --- a/openair1/PHY/defs_RU.h +++ b/openair1/PHY/defs_RU.h @@ -592,10 +592,7 @@ typedef struct RU_t_s { int32_t *bw_list[NUMBER_OF_eNB_MAX+1]; /// beamforming weight vectors int32_t **beam_weights[NUMBER_OF_eNB_MAX+1][15]; - /// prach commands - prach_item_t prach_list[NUMBER_OF_NR_PRACH_MAX]; - /// mutex for prach_list access - pthread_mutex_t prach_list_mutex; + prach_list_t prach_list; /// received frequency-domain signal for PRACH (IF4p5 RRU) int16_t **prach_rxsigF[NUMBER_OF_NR_RU_PRACH_OCCASIONS_MAX]; /// received frequency-domain signal for PRACH BR (IF4p5 RRU) diff --git a/openair1/PHY/defs_common.h b/openair1/PHY/defs_common.h index 085fbc15a4..79f1763842 100644 --- a/openair1/PHY/defs_common.h +++ b/openair1/PHY/defs_common.h @@ -1001,11 +1001,12 @@ typedef struct { // TODO will be removed in a late commit #include "nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h" #define NUMBER_OF_NR_PRACH_MAX 8 +typedef enum { prach_upper, prach_lower } prach_type_t; typedef struct { int frame; int slot; int num_slots; // prach duration in slots - enum { prach_upper, prach_lower } type; + prach_type_t type; union { struct { // identifier for concurrent beams @@ -1023,6 +1024,14 @@ typedef struct { nfapi_nr_prach_pdu_t pdu; } prach_item_t; +typedef struct { + /// prach commands + prach_item_t list[NUMBER_OF_NR_PRACH_MAX]; + /// mutex for prach_list access + pthread_mutex_t prach_list_mutex; +} prach_list_t; +void init_prach_list(prach_list_t *, prach_type_t); + static inline void init_abort(decode_abort_t *ab) { int ret = pthread_mutex_init(&ab->mutex_failure, NULL); diff --git a/openair1/PHY/defs_gNB.h b/openair1/PHY/defs_gNB.h index f62d19ba3a..da3b4bcb01 100644 --- a/openair1/PHY/defs_gNB.h +++ b/openair1/PHY/defs_gNB.h @@ -139,7 +139,7 @@ typedef struct { /// second index: rx antenna [0..63] (hard coded) \note Hard coded array size indexed by \c nb_antennas_rx. /// third index: frequency-domain sample [0..ofdm_symbol_size*12[ int16_t **rxsigF; - prach_item_t list[NUMBER_OF_NR_PRACH_MAX]; + prach_list_t list; } NR_gNB_PRACH; typedef struct { diff --git a/openair1/SCHED/nfapi_nr_dummy.c b/openair1/SCHED/nfapi_nr_dummy.c index 4e4dea190d..87c1ea576f 100644 --- a/openair1/SCHED/nfapi_nr_dummy.c +++ b/openair1/SCHED/nfapi_nr_dummy.c @@ -37,10 +37,7 @@ void nr_fill_pucch(PHY_VARS_gNB *gNB, int frame, int slot, nfapi_nr_pucch_pdu_t *pucch_pdu){} -gNB_PRACH_list_t nr_fill_prach(PHY_VARS_gNB *gNB, int SFN, int Slot, nfapi_nr_prach_pdu_t *prach_pdu) -{ -} -RU_PRACH_list_t nr_fill_prach_ru(RU_t *ru, int SFN, int Slot, nfapi_nr_prach_pdu_t *prach_pdu) +void nr_fill_prach(PHY_VARS_gNB *gNB, int SFN, int Slot, nfapi_nr_prach_pdu_t *prach_pdu) { } diff --git a/openair1/SCHED_NR/nr_prach_procedures.c b/openair1/SCHED_NR/nr_prach_procedures.c index cc38665757..b649398456 100644 --- a/openair1/SCHED_NR/nr_prach_procedures.c +++ b/openair1/SCHED_NR/nr_prach_procedures.c @@ -63,7 +63,7 @@ void L1_nr_prach_procedures(PHY_VARS_gNB *gNB, int frame, int slot, nfapi_nr_rac ru=gNB->RU_list[0]; - prach_item_t *prach_id = find_nr_prach(gNB, frame, slot, SEARCH_EXIST); + prach_item_t *prach_id = find_nr_prach(&gNB->prach_vars.list, frame, slot, SEARCH_EXIST); if (!prach_id) { return; } @@ -145,6 +145,6 @@ void L1_nr_prach_procedures(PHY_VARS_gNB *gNB, int frame, int slot, nfapi_nr_rac } // if prach_id>0 rach_ind->slot = prach_start_slot; LOG_D(NR_PHY, "Freeing PRACH entry\n"); - free_nr_prach_entry(gNB, prach_id); + free_nr_prach_entry(&gNB->prach_vars.list, prach_id); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_PRACH_RX,0); } diff --git a/openair1/SIMULATION/NR_PHY/prachsim.c b/openair1/SIMULATION/NR_PHY/prachsim.c index 35e242cad3..3eda15fc6f 100644 --- a/openair1/SIMULATION/NR_PHY/prachsim.c +++ b/openair1/SIMULATION/NR_PHY/prachsim.c @@ -151,9 +151,7 @@ int main(int argc, char **argv){ NR_DL_FRAME_PARMS *frame_parms; nfapi_nr_prach_config_t *prach_config; - nfapi_nr_prach_pdu_t *prach_pdu; fapi_nr_prach_config_t *ue_prach_config; - fapi_nr_ul_config_prach_pdu *ue_prach_pdu; channel_desc_t *UE2gNB; SCM_t channel_model = Rayleigh1; @@ -417,7 +415,6 @@ int main(int argc, char **argv){ ru = RC.ru[0]; frame_parms = &gNB->frame_parms; prach_config = &gNB->gNB_config.prach_config; - prach_pdu = &gNB->prach_vars.list[0].pdu; frame_parms = &gNB->frame_parms; //to be initialized I suppose (maybe not necessary for PBCH) s_re = malloc(2*sizeof(double*)); @@ -561,9 +558,6 @@ int main(int argc, char **argv){ prach_config->restricted_set_config.value = restrictedSetConfig; prach_config->prach_sequence_length.value = prach_sequence_length; prach_config->prach_sub_c_spacing.value = mu; - prach_pdu->num_cs = get_NCS(NCS_config, format0, restrictedSetConfig); - prach_config->num_prach_fd_occasions_list[fd_occasion].num_root_sequences.value = 1+(64/(N_ZC/prach_pdu->num_cs)); - prach_pdu->prach_format = prach_format; memcpy((void*)&ru->config,(void*)&RC.gNB[0]->gNB_config,sizeof(ru->config)); RC.nb_nr_L1_inst=1; @@ -573,6 +567,10 @@ int main(int argc, char **argv){ phy_init_nr_gNB(gNB); nr_phy_init_RU(ru); + nfapi_nr_prach_pdu_t *prach_pdu = &gNB->prach_vars.list.list[0].pdu; + prach_pdu->num_cs = get_NCS(NCS_config, format0, restrictedSetConfig); + prach_config->num_prach_fd_occasions_list[fd_occasion].num_root_sequences.value = 1+(64/(N_ZC/prach_pdu->num_cs)); + prach_pdu->prach_format = prach_format; // Configure UE UE = malloc(sizeof(PHY_VARS_NR_UE)); @@ -588,7 +586,7 @@ int main(int argc, char **argv){ exit(-1); } - ue_prach_pdu = &UE->prach_vars[0]->prach_pdu; + fapi_nr_ul_config_prach_pdu *ue_prach_pdu = &UE->prach_vars[0]->prach_pdu; ue_prach_config = &UE->nrUE_config.prach_config; txdata = UE->common_vars.txData; From cffb07d798c3b3d466d269cd6d0ecd0d2d2296d0 Mon Sep 17 00:00:00 2001 From: Laurent THOMAS Date: Thu, 14 Aug 2025 15:17:13 +0200 Subject: [PATCH 34/69] remove permanent prach rxsigF in gNB and simplify the data structure --- executables/nr-gnb.c | 3 +- openair1/PHY/INIT/nr_init.c | 8 ++--- openair1/PHY/INIT/nr_init_ru.c | 8 ++--- openair1/PHY/NR_TRANSPORT/nr_prach.c | 28 ++++++++------- .../PHY/NR_TRANSPORT/nr_transport_proto.h | 3 +- openair1/PHY/defs_RU.h | 2 +- openair1/PHY/defs_gNB.h | 10 +----- openair1/SCHED_NR/nr_prach_procedures.c | 17 ++++----- openair1/SIMULATION/NR_PHY/prachsim.c | 36 ++++++++++--------- 9 files changed, 51 insertions(+), 64 deletions(-) diff --git a/executables/nr-gnb.c b/executables/nr-gnb.c index 16ad366a0e..0e4fba9812 100644 --- a/executables/nr-gnb.c +++ b/executables/nr-gnb.c @@ -389,8 +389,7 @@ void init_eNB_afterRU(void) AssertFatal(gNB->RU_list[ru_id]->common.rxdataF != NULL, "RU %d : common.rxdataF is NULL\n", gNB->RU_list[ru_id]->idx); AssertFatal(gNB->RU_list[ru_id]->prach_rxsigF != NULL, "RU %d : prach_rxsigF is NULL\n", gNB->RU_list[ru_id]->idx); for (int i = 0; i < gNB->RU_list[ru_id]->nb_rx; aa++, i++) { - LOG_I(PHY,"Attaching RU %d antenna %d to gNB antenna %d\n", gNB->RU_list[ru_id]->idx, i, aa); - gNB->prach_vars.rxsigF[aa] = gNB->RU_list[ru_id]->prach_rxsigF[0][i]; + LOG_I(PHY, "Attaching RU %d antenna %d to gNB antenna %d\n", gNB->RU_list[ru_id]->idx, i, aa); for (int b = 0; b < gNB->RU_list[ru_id]->num_beams_period; b++) { int idx = i + b * gNB->RU_list[ru_id]->nb_rx; gNB->common_vars.rxdataF[b][aa] = (c16_t *)gNB->RU_list[ru_id]->common.rxdataF[idx]; diff --git a/openair1/PHY/INIT/nr_init.c b/openair1/PHY/INIT/nr_init.c index 75145c78a4..88c539ccd3 100644 --- a/openair1/PHY/INIT/nr_init.c +++ b/openair1/PHY/INIT/nr_init.c @@ -104,9 +104,7 @@ void phy_init_nr_gNB(PHY_VARS_gNB *gNB) // shortcuts NR_DL_FRAME_PARMS *const fp = &gNB->frame_parms; nfapi_nr_config_request_scf_t *cfg = &gNB->gNB_config; - NR_gNB_COMMON *const common_vars = &gNB->common_vars; - NR_gNB_PRACH *const prach_vars = &gNB->prach_vars; - + NR_gNB_COMMON *const common_vars = &gNB->common_vars; common_vars->analog_bf = cfg->analog_beamforming_ve.analog_bf_vendor_ext.value; LOG_I(PHY, "L1 configured with%s analog beamforming\n", common_vars->analog_bf ? "" : "out"); if (common_vars->analog_bf) { @@ -190,9 +188,7 @@ void phy_init_nr_gNB(PHY_VARS_gNB *gNB) common_vars->debugBuff_sample_offset = 0; // PRACH - prach_vars->rxsigF = (int16_t **)malloc16_clear(Prx * sizeof(int16_t *)); - - init_prach_list(&gNB->prach_vars.list, prach_upper); + init_prach_list(&gNB->prach_list, prach_upper); int N_RB_UL = cfg->carrier_config.ul_grid_size[cfg->ssb_config.scs_common.value].value; int n_buf = Prx*max_ul_mimo_layers; diff --git a/openair1/PHY/INIT/nr_init_ru.c b/openair1/PHY/INIT/nr_init_ru.c index 6ad085eb4c..d485e4977d 100644 --- a/openair1/PHY/INIT/nr_init_ru.c +++ b/openair1/PHY/INIT/nr_init_ru.c @@ -116,12 +116,12 @@ void nr_phy_init_RU(RU_t *ru) // AssertFatal(ru->nb_rx <= sizeof(ru->prach_rxsigF) / sizeof(ru->prach_rxsigF[0]), // "nb_antennas_rx too large"); for (int j = 0; j < NUMBER_OF_NR_RU_PRACH_OCCASIONS_MAX; j++) { - ru->prach_rxsigF[j] = (int16_t**)malloc(nb_rx_streams * sizeof(int16_t*)); - + ru->prach_rxsigF[j] = malloc(nb_rx_streams * sizeof(*ru->prach_rxsigF)); + for (int i = 0; i < nb_rx_streams; i++) { // largest size for PRACH FFT is 4x98304 (16*24576) - ru->prach_rxsigF[j][i] = (int16_t*)malloc16_clear(4 * 98304 * 2 * sizeof(int16_t)); - LOG_D(PHY,"[INIT] prach_vars->rxsigF[%d] = %p\n", i, ru->prach_rxsigF[j][i]); + ru->prach_rxsigF[j][i] = malloc16_clear(4 * 98304 * 2 * sizeof(**ru->prach_rxsigF)); + LOG_D(PHY, "[INIT] prach_vars->rxsigF[%d] = %p\n", i, ru->prach_rxsigF[j][i]); } } diff --git a/openair1/PHY/NR_TRANSPORT/nr_prach.c b/openair1/PHY/NR_TRANSPORT/nr_prach.c index 9fab6254ca..371160437a 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_prach.c +++ b/openair1/PHY/NR_TRANSPORT/nr_prach.c @@ -81,7 +81,7 @@ prach_item_t *find_nr_prach(prach_list_t *l, int frame, int slot, find_type_t ty prach_item_t *nr_fill_prach(PHY_VARS_gNB *gNB, int SFN, int Slot, nfapi_nr_prach_pdu_t *prach_pdu) { - prach_item_t *prach = find_nr_prach(&gNB->prach_vars.list, SFN, Slot, SEARCH_EXIST_OR_FREE); + prach_item_t *prach = find_nr_prach(&gNB->prach_list, SFN, Slot, SEARCH_EXIST_OR_FREE); if (!prach) { LOG_W(PHY, "no free space for a new detected rach, discarding\n"); return NULL; @@ -171,7 +171,7 @@ void rx_nr_prach_ru(RU_t *ru, prachStartSymbol, prachOccasion); - int16_t **rxsigF = ru->prach_rxsigF[prachOccasion]; + c16_t **rxsigF = (c16_t **)ru->prach_rxsigF[prachOccasion]; AssertFatal(ru->if_south == LOCAL_RF || ru->if_south == REMOTE_IF5, "we shouldn't call this if if_south != LOCAL_RF or REMOTE_IF5\n"); @@ -392,23 +392,25 @@ void rx_nr_prach_ru(RU_t *ru, // do DFT int16_t *prach2 = prach[aa] + (2*Ncp); // times 2 for complex samples for (int i = 0; i < reps; i++) - dft(dftsize, prach2 + 2*dftlen*i, rxsigF[aa] + 2*dftlen*i, 1); + dft(dftsize, prach2 + 2 * dftlen * i, (int16_t *)rxsigF[aa] + 2 * dftlen * i, 1); //LOG_M("ru_rxsigF_tmp.m","rxsFtmp", rxsigF[aa], dftlen*2*reps, 1, 1); //Coherent combining of PRACH repetitions (assumes channel does not change, to be revisted for "long" PRACH) LOG_D(PHY,"Doing PRACH combining of %d reptitions N_ZC %d\n",reps,N_ZC); - int16_t rxsigF_tmp[N_ZC<<1]; - // if (k+N_ZC > dftlen) { // PRACH signal is split around DC - int16_t *rxsigF2=rxsigF[aa]; - int k2=k<<1; + c16_t rxsigF_tmp[N_ZC]; + // if (k+N_ZC > dftlen) { // PRACH signal is split around DC + c16_t *rxsigF2 = rxsigF[aa]; + int k2 = k; - for (int j=0;jgNB_config.prach_config; - c16_t **rxsigF = (c16_t **)gNB->prach_vars.rxsigF; uint16_t preamble_index0 = 0; uint16_t numshift = 0; int first_nonzero_root_idx = 0; diff --git a/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h b/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h index f43e4cdcdb..db391dacc0 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h +++ b/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h @@ -209,7 +209,8 @@ void rx_nr_prach(PHY_VARS_gNB *gNB, int subframe, uint16_t *max_preamble, uint16_t *max_preamble_energy, - uint16_t *max_preamble_delay); + uint16_t *max_preamble_delay, + c16_t **rxsigF); void rx_nr_prach_ru(RU_t *ru, int prach_fmt, diff --git a/openair1/PHY/defs_RU.h b/openair1/PHY/defs_RU.h index 3d85c96af8..b94d0b1c56 100644 --- a/openair1/PHY/defs_RU.h +++ b/openair1/PHY/defs_RU.h @@ -593,7 +593,7 @@ typedef struct RU_t_s { /// beamforming weight vectors int32_t **beam_weights[NUMBER_OF_eNB_MAX+1][15]; prach_list_t prach_list; - /// received frequency-domain signal for PRACH (IF4p5 RRU) + /// received frequency-domain signal for PRACH (IF4p5 RRU) int16_t **prach_rxsigF[NUMBER_OF_NR_RU_PRACH_OCCASIONS_MAX]; /// received frequency-domain signal for PRACH BR (IF4p5 RRU) int16_t **prach_rxsigF_br[4]; diff --git a/openair1/PHY/defs_gNB.h b/openair1/PHY/defs_gNB.h index da3b4bcb01..ad08cc1df1 100644 --- a/openair1/PHY/defs_gNB.h +++ b/openair1/PHY/defs_gNB.h @@ -134,14 +134,6 @@ typedef struct { nfapi_nr_dl_tti_ssb_pdu ssb_pdu; } NR_gNB_SSB_t; -typedef struct { - /// \brief ?. - /// second index: rx antenna [0..63] (hard coded) \note Hard coded array size indexed by \c nb_antennas_rx. - /// third index: frequency-domain sample [0..ofdm_symbol_size*12[ - int16_t **rxsigF; - prach_list_t list; -} NR_gNB_PRACH; - typedef struct { uint8_t NumPRSResources; prs_config_t prs_cfg[NR_MAX_PRS_RESOURCES_PER_SET]; @@ -416,7 +408,7 @@ typedef struct PHY_VARS_gNB_s { int max_nb_pusch; NR_gNB_COMMON common_vars; - NR_gNB_PRACH prach_vars; + prach_list_t prach_list; NR_gNB_PRS prs_vars; NR_gNB_PUSCH *pusch_vars; NR_gNB_PUCCH_t *pucch; diff --git a/openair1/SCHED_NR/nr_prach_procedures.c b/openair1/SCHED_NR/nr_prach_procedures.c index b649398456..74a98dc7f7 100644 --- a/openair1/SCHED_NR/nr_prach_procedures.c +++ b/openair1/SCHED_NR/nr_prach_procedures.c @@ -52,10 +52,6 @@ void L1_nr_prach_procedures(PHY_VARS_gNB *gNB, int frame, int slot, nfapi_nr_rac uint16_t max_preamble[4]={0},max_preamble_energy[4]={0},max_preamble_delay[4]={0}; RU_t *ru; - int aa=0; - int ru_aa; - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_PRACH_RX,1); rach_ind->sfn = frame; rach_ind->slot = slot; @@ -63,7 +59,7 @@ void L1_nr_prach_procedures(PHY_VARS_gNB *gNB, int frame, int slot, nfapi_nr_rac ru=gNB->RU_list[0]; - prach_item_t *prach_id = find_nr_prach(&gNB->prach_vars.list, frame, slot, SEARCH_EXIST); + prach_item_t *prach_id = find_nr_prach(&gNB->prach_list, frame, slot, SEARCH_EXIST); if (!prach_id) { return; } @@ -75,16 +71,15 @@ void L1_nr_prach_procedures(PHY_VARS_gNB *gNB, int frame, int slot, nfapi_nr_rac int N_dur = get_nr_prach_duration(prach_pdu->prach_format); for (int prach_oc = 0; prach_oc < prach_pdu->num_prach_ocas; prach_oc++) { - for (ru_aa = 0, aa = 0; ru_aa < ru->nb_rx; ru_aa++, aa++) { - gNB->prach_vars.rxsigF[aa] = ru->prach_rxsigF[prach_oc][ru_aa]; - } - prachStartSymbol = prach_pdu->prach_start_symbol + prach_oc * N_dur; // comment FK: the standard 38.211 section 5.3.2 has one extra term +14*N_RA_slot. This is because there prachStartSymbol is // given wrt to start of the 15kHz slot or 60kHz slot. Here we work slot based, so this function is anyway only called in slots // where there is PRACH. Its up to the MAC to schedule another PRACH PDU in the case there are there N_RA_slot \in {0,1}. - rx_nr_prach(gNB, prach_pdu, prach_oc, frame, slot, &max_preamble[0], &max_preamble_energy[0], &max_preamble_delay[0]); + c16_t *rxsigF[ru->nb_rx]; + for (int i = 0; i < ru->nb_rx; ++i) + rxsigF[i] = (c16_t *)ru->prach_rxsigF[prach_oc][i]; + rx_nr_prach(gNB, prach_pdu, prach_oc, frame, slot, &max_preamble[0], &max_preamble_energy[0], &max_preamble_delay[0], rxsigF); LOG_D(NR_PHY, "[RAPROC] Frame %d, slot %d, occasion %d (prachStartSymbol %d) : Most likely preamble %d, energy %d.%d dB delay %d " "(prach_energy counter %d)\n", @@ -145,6 +140,6 @@ void L1_nr_prach_procedures(PHY_VARS_gNB *gNB, int frame, int slot, nfapi_nr_rac } // if prach_id>0 rach_ind->slot = prach_start_slot; LOG_D(NR_PHY, "Freeing PRACH entry\n"); - free_nr_prach_entry(&gNB->prach_vars.list, prach_id); + free_nr_prach_entry(&gNB->prach_list, prach_id); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_PRACH_RX,0); } diff --git a/openair1/SIMULATION/NR_PHY/prachsim.c b/openair1/SIMULATION/NR_PHY/prachsim.c index 3eda15fc6f..9f2e06762c 100644 --- a/openair1/SIMULATION/NR_PHY/prachsim.c +++ b/openair1/SIMULATION/NR_PHY/prachsim.c @@ -567,7 +567,7 @@ int main(int argc, char **argv){ phy_init_nr_gNB(gNB); nr_phy_init_RU(ru); - nfapi_nr_prach_pdu_t *prach_pdu = &gNB->prach_vars.list.list[0].pdu; + nfapi_nr_prach_pdu_t *prach_pdu = &gNB->prach_list.list[0].pdu; prach_pdu->num_cs = get_NCS(NCS_config, format0, restrictedSetConfig); prach_config->num_prach_fd_occasions_list[fd_occasion].num_root_sequences.value = 1+(64/(N_ZC/prach_pdu->num_cs)); prach_pdu->prach_format = prach_format; @@ -769,25 +769,27 @@ int main(int argc, char **argv){ nr_slot_fep_ul(frame_parms, ru->common.rxdata[aa], ru->common.rxdataF[aa], l, slot, ru->N_TA_offset); } } + rx_nr_prach_ru(ru, prach_format, numRA, 0, prachStartSymbol, slot, prachOccasion, frame, slot); + c16_t *rxsigF[ru->nb_rx]; + for (int i = 0; i < ru->nb_rx; ++i) + rxsigF[i] = (c16_t *)ru->prach_rxsigF[prachOccasion][i]; + if (n_frames == 1) + printf("ncs %d,num_seq %d\n", + prach_pdu->num_cs, + prach_config->num_prach_fd_occasions_list[fd_occasion].num_root_sequences.value); + rx_nr_prach(gNB, prach_pdu, prachOccasion, frame, subframe, &preamble_rx, &preamble_energy, &preamble_delay, rxsigF); - rx_nr_prach_ru(ru, prach_format, numRA, 0, prachStartSymbol, slot, prachOccasion, frame, slot); + // printf(" preamble_energy %d preamble_rx %d preamble_tx %d \n", preamble_energy, preamble_rx, preamble_tx); - for (int i = 0; i < ru->nb_rx; ++i) - gNB->prach_vars.rxsigF[i] = ru->prach_rxsigF[prachOccasion][i]; - if (n_frames == 1) printf("ncs %d,num_seq %d\n",prach_pdu->num_cs, prach_config->num_prach_fd_occasions_list[fd_occasion].num_root_sequences.value); - rx_nr_prach(gNB, prach_pdu, prachOccasion, frame, subframe, &preamble_rx, &preamble_energy, &preamble_delay); + if (preamble_rx != preamble_tx) + prach_errors++; + else + delay_avg += (double)preamble_delay; - // printf(" preamble_energy %d preamble_rx %d preamble_tx %d \n", preamble_energy, preamble_rx, preamble_tx); + N_ZC = (prach_sequence_length) ? 139 : 839; - if (preamble_rx != preamble_tx) - prach_errors++; - else - delay_avg += (double)preamble_delay; - - N_ZC = (prach_sequence_length) ? 139 : 839; - - if (n_frames==1) { - printf("preamble %d (tx %d) : energy %d, delay %d\n",preamble_rx,preamble_tx,preamble_energy,preamble_delay); + if (n_frames == 1) { + printf("preamble %d (tx %d) : energy %d, delay %d\n", preamble_rx, preamble_tx, preamble_energy, preamble_delay); #ifdef NR_PRACH_DEBUG LOG_M("prach0.m","prach0", &txdata[0][prach_start], frame_parms->samples_per_subframe, 1, 1); LOG_M("rxsig0.m","rxs0", &ru->common.rxdata[0][subframe*frame_parms->samples_per_subframe], frame_parms->samples_per_subframe, 1, 1); @@ -797,7 +799,7 @@ int main(int argc, char **argv){ LOG_M("prach_preamble.m","prachp", &gNB->X_u[0], N_ZC, 1, 1); LOG_M("ue_prach_preamble.m","prachp", &UE->X_u[0], N_ZC, 1, 1); #endif - } + } } printf("SNR %f dB, UE Speed %f km/h: errors %u/%d (delay %f)\n", SNR, ue_speed, prach_errors, n_frames, delay_avg/(double)(n_frames-prach_errors)); From d005336cb89ee5237a295cc5fd9897a0bf8d2ff6 Mon Sep 17 00:00:00 2001 From: Laurent THOMAS Date: Thu, 14 Aug 2025 15:41:12 +0200 Subject: [PATCH 35/69] Simplify PRACH beam handling, remove race Simplify by removing a small malloc and memcpy() the beams. This should also remove the data race between ru and gNB/CU-DU --- executables/nr-ru.c | 2 +- openair1/PHY/NR_TRANSPORT/nr_prach.c | 24 ++++++++++++------------ openair1/PHY/defs_common.h | 3 +-- openair1/SCHED_NR/fapi_nr_l1.c | 2 +- 4 files changed, 15 insertions(+), 16 deletions(-) diff --git a/executables/nr-ru.c b/executables/nr-ru.c index 1c2e1acaf1..f28f2919c4 100644 --- a/executables/nr-ru.c +++ b/executables/nr-ru.c @@ -1222,7 +1222,7 @@ void *ru_thread(void *param) for (int prach_oc = 0; prach_oc < p->lower.num_prach_ocas; prach_oc++) { int prachStartSymbol = p->lower.prachStartSymbol + prach_oc * N_dur; - int beam_id = p->lower.beam ? p->lower.beam[prach_oc] : 0; + int beam_id = p->beams[prach_oc]; //comment FK: the standard 38.211 section 5.3.2 has one extra term +14*N_RA_slot. This is because there prachStartSymbol is given wrt to start of the 15kHz slot or 60kHz slot. Here we work slot based, so this function is anyway only called in slots where there is PRACH. Its up to the MAC to schedule another PRACH PDU in the case there are there N_RA_slot \in {0,1}. rx_nr_prach_ru(ru, p->lower.fmt, // could also use format diff --git a/openair1/PHY/NR_TRANSPORT/nr_prach.c b/openair1/PHY/NR_TRANSPORT/nr_prach.c index 371160437a..3c2eb73e77 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_prach.c +++ b/openair1/PHY/NR_TRANSPORT/nr_prach.c @@ -46,8 +46,6 @@ void init_prach_list(prach_list_t *l, prach_type_t t) void free_nr_prach_entry(prach_list_t *l, prach_item_t *p) { pthread_mutex_lock(&l->prach_list_mutex); - if (p->type == prach_upper) - free_and_zero(p->upper.beam_nb); *p = (prach_item_t){.frame = -1, .slot = -1, .num_slots = -1}; pthread_mutex_unlock(&l->prach_list_mutex); } @@ -91,25 +89,27 @@ prach_item_t *nr_fill_prach(PHY_VARS_gNB *gNB, int SFN, int Slot, nfapi_nr_prach prach->num_slots = (format < 4) ? get_long_prach_dur(format, gNB->frame_parms.numerology_index) : 1; if (gNB->common_vars.beam_id) { int n_symb = get_nr_prach_duration(prach_pdu->prach_format); - prach->upper.beam_nb = calloc(prach_pdu->beamforming.dig_bf_interface, sizeof(*prach->upper.beam_nb)); + AssertFatal(prach_pdu->beamforming.dig_bf_interface < NFAPI_MAX_NUM_BG_IF, + "impossible beams size %d\n", + prach_pdu->beamforming.dig_bf_interface); for (int i = 0; i < prach_pdu->beamforming.dig_bf_interface; i++) { int fapi_beam_idx = prach_pdu->beamforming.prgs_list[0].dig_bf_interface_list[i].beam_idx; int start_symb = prach_pdu->prach_start_symbol + i * n_symb; int bitmap = SL_to_bitmap(start_symb, n_symb); - prach->upper.beam_nb[i] = beam_index_allocation(gNB->enable_analog_das, - fapi_beam_idx, - &gNB->gNB_config.analog_beamforming_ve, - &gNB->common_vars, - Slot, - NR_NUMBER_OF_SYMBOLS_PER_SLOT, - bitmap); + prach->beams[i] = beam_index_allocation(gNB->enable_analog_das, + fapi_beam_idx, + &gNB->gNB_config.analog_beamforming_ve, + &gNB->common_vars, + Slot, + NR_NUMBER_OF_SYMBOLS_PER_SLOT, + bitmap); } } prach->pdu = *prach_pdu; return prach; } -void nr_fill_prach_ru(RU_t *ru, int SFN, int Slot, nfapi_nr_prach_pdu_t *prach_pdu, int *beam_id) +void nr_fill_prach_ru(RU_t *ru, int SFN, int Slot, nfapi_nr_prach_pdu_t *prach_pdu, int *beams) { prach_item_t *prach = find_nr_prach(&ru->prach_list, SFN, Slot, SEARCH_EXIST_OR_FREE); if (!prach) { @@ -123,9 +123,9 @@ void nr_fill_prach_ru(RU_t *ru, int SFN, int Slot, nfapi_nr_prach_pdu_t *prach_p .num_slots = (fmt < 4) ? get_long_prach_dur(fmt, ru->nr_frame_parms->numerology_index) : 1, .lower = {.fmt = fmt, .numRA = prach_pdu->num_ra, - .beam = beam_id, .prachStartSymbol = prach_pdu->prach_start_symbol, .num_prach_ocas = prach_pdu->num_prach_ocas}}; + memcpy(prach->beams, beams, sizeof(prach->beams)); } void rx_nr_prach_ru(RU_t *ru, diff --git a/openair1/PHY/defs_common.h b/openair1/PHY/defs_common.h index 79f1763842..b9923a1b8b 100644 --- a/openair1/PHY/defs_common.h +++ b/openair1/PHY/defs_common.h @@ -1006,11 +1006,11 @@ typedef struct { int frame; int slot; int num_slots; // prach duration in slots + int beams[NFAPI_MAX_NUM_BG_IF]; prach_type_t type; union { struct { // identifier for concurrent beams - int *beam_nb; nfapi_nr_prach_pdu_t pdu; } upper; struct { @@ -1018,7 +1018,6 @@ typedef struct { int numRA; int prachStartSymbol; int num_prach_ocas; - int *beam; } lower; }; nfapi_nr_prach_pdu_t pdu; diff --git a/openair1/SCHED_NR/fapi_nr_l1.c b/openair1/SCHED_NR/fapi_nr_l1.c index fa5167adff..09419d4e84 100644 --- a/openair1/SCHED_NR/fapi_nr_l1.c +++ b/openair1/SCHED_NR/fapi_nr_l1.c @@ -156,7 +156,7 @@ void nr_schedule_ul_tti_req(PHY_VARS_gNB *gNB, nfapi_nr_ul_tti_request_t *UL_tti nfapi_nr_prach_pdu_t *prach_pdu = &UL_tti_req->pdus_list[i].prach_pdu; prach_item_t *prach = nr_fill_prach(gNB, UL_tti_req->SFN, UL_tti_req->Slot, prach_pdu); if (prach && (gNB->RU_list[0]->if_south == LOCAL_RF || gNB->RU_list[0]->if_south == REMOTE_IF5)) - nr_fill_prach_ru(gNB->RU_list[0], UL_tti_req->SFN, UL_tti_req->Slot, prach_pdu, prach->upper.beam_nb); + nr_fill_prach_ru(gNB->RU_list[0], UL_tti_req->SFN, UL_tti_req->Slot, prach_pdu, prach->beams); break; case NFAPI_NR_UL_CONFIG_SRS_PDU_TYPE: LOG_D(NR_PHY, From c48e0b1a3223c0666b7bd5576487f7673e2e7168 Mon Sep 17 00:00:00 2001 From: Laurent THOMAS Date: Mon, 18 Aug 2025 16:57:47 +0200 Subject: [PATCH 36/69] merge variants of prach_item_t as this is the same in gNB and RU --- executables/nr-ru.c | 10 +++---- openair1/PHY/INIT/nr_init.c | 2 +- openair1/PHY/INIT/nr_init_ru.c | 2 +- openair1/PHY/NR_TRANSPORT/nr_prach.c | 26 +++++++------------ .../PHY/NR_TRANSPORT/nr_transport_proto.h | 2 +- openair1/PHY/defs_common.h | 16 +----------- openair1/SCHED/nfapi_lte_dummy.c | 5 +--- openair1/SCHED_NR/fapi_nr_l1.c | 2 +- openair1/SIMULATION/NR_PHY/prachsim.c | 7 ++--- 9 files changed, 24 insertions(+), 48 deletions(-) diff --git a/executables/nr-ru.c b/executables/nr-ru.c index f28f2919c4..ae610beacd 100644 --- a/executables/nr-ru.c +++ b/executables/nr-ru.c @@ -1218,15 +1218,15 @@ void *ru_thread(void *param) T_INT(0), T_BUFFER(&ru->common.rxdata[0][fp->get_samples_slot_timestamp(proc->tti_rx - 1, fp, 0) /*-ru->N_TA_offset*/], (fp->get_samples_per_slot(proc->tti_rx - 1, fp) + fp->get_samples_per_slot(proc->tti_rx, fp)) * 4)); - int N_dur = get_nr_prach_duration(p->lower.fmt); + int N_dur = get_nr_prach_duration(p->pdu.prach_format); - for (int prach_oc = 0; prach_oc < p->lower.num_prach_ocas; prach_oc++) { - int prachStartSymbol = p->lower.prachStartSymbol + prach_oc * N_dur; + for (int prach_oc = 0; prach_oc < p->pdu.num_prach_ocas; prach_oc++) { + int prachStartSymbol = p->pdu.prach_start_symbol + prach_oc * N_dur; int beam_id = p->beams[prach_oc]; //comment FK: the standard 38.211 section 5.3.2 has one extra term +14*N_RA_slot. This is because there prachStartSymbol is given wrt to start of the 15kHz slot or 60kHz slot. Here we work slot based, so this function is anyway only called in slots where there is PRACH. Its up to the MAC to schedule another PRACH PDU in the case there are there N_RA_slot \in {0,1}. rx_nr_prach_ru(ru, - p->lower.fmt, // could also use format - p->lower.numRA, + p->pdu.prach_format, // could also use format + p->pdu.num_ra, beam_id, prachStartSymbol, p->slot, diff --git a/openair1/PHY/INIT/nr_init.c b/openair1/PHY/INIT/nr_init.c index 88c539ccd3..7a360e30ff 100644 --- a/openair1/PHY/INIT/nr_init.c +++ b/openair1/PHY/INIT/nr_init.c @@ -188,7 +188,7 @@ void phy_init_nr_gNB(PHY_VARS_gNB *gNB) common_vars->debugBuff_sample_offset = 0; // PRACH - init_prach_list(&gNB->prach_list, prach_upper); + init_prach_list(&gNB->prach_list); int N_RB_UL = cfg->carrier_config.ul_grid_size[cfg->ssb_config.scs_common.value].value; int n_buf = Prx*max_ul_mimo_layers; diff --git a/openair1/PHY/INIT/nr_init_ru.c b/openair1/PHY/INIT/nr_init_ru.c index d485e4977d..30ec333c70 100644 --- a/openair1/PHY/INIT/nr_init_ru.c +++ b/openair1/PHY/INIT/nr_init_ru.c @@ -130,7 +130,7 @@ void nr_phy_init_RU(RU_t *ru) LOG_D(PHY, "[INIT] %s() ru->num_gNB:%d \n", __FUNCTION__, ru->num_gNB); } // !=IF5 - init_prach_list(&ru->prach_list, prach_lower); + init_prach_list(&ru->prach_list); } void nr_phy_free_RU(RU_t *ru) diff --git a/openair1/PHY/NR_TRANSPORT/nr_prach.c b/openair1/PHY/NR_TRANSPORT/nr_prach.c index 3c2eb73e77..d1e337ce2e 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_prach.c +++ b/openair1/PHY/NR_TRANSPORT/nr_prach.c @@ -36,11 +36,11 @@ #include "PHY/NR_TRANSPORT/nr_transport_common_proto.h" #include "openair1/PHY/NR_TRANSPORT/nr_prach.h" -void init_prach_list(prach_list_t *l, prach_type_t t) +void init_prach_list(prach_list_t *l) { pthread_mutex_init(&l->prach_list_mutex, NULL); for (prach_item_t *p = l->list; p < l->list + NUMBER_OF_NR_PRACH_MAX; p++) - *p = (prach_item_t){.frame = -1, .slot = -1, .type = t}; + *p = (prach_item_t){.frame = -1, .slot = -1}; } void free_nr_prach_entry(prach_list_t *l, prach_item_t *p) @@ -84,9 +84,10 @@ prach_item_t *nr_fill_prach(PHY_VARS_gNB *gNB, int SFN, int Slot, nfapi_nr_prach LOG_W(PHY, "no free space for a new detected rach, discarding\n"); return NULL; } - *prach = (prach_item_t){.frame = SFN, .slot = Slot, .type = prach_upper}; - const int format = prach_pdu->prach_format; - prach->num_slots = (format < 4) ? get_long_prach_dur(format, gNB->frame_parms.numerology_index) : 1; + const int fmt = prach_pdu->prach_format; + *prach = (prach_item_t){.frame = SFN, + .slot = Slot, + .num_slots = (fmt < 4) ? get_long_prach_dur(fmt, gNB->frame_parms.numerology_index) : 1}; if (gNB->common_vars.beam_id) { int n_symb = get_nr_prach_duration(prach_pdu->prach_format); AssertFatal(prach_pdu->beamforming.dig_bf_interface < NFAPI_MAX_NUM_BG_IF, @@ -109,23 +110,14 @@ prach_item_t *nr_fill_prach(PHY_VARS_gNB *gNB, int SFN, int Slot, nfapi_nr_prach return prach; } -void nr_fill_prach_ru(RU_t *ru, int SFN, int Slot, nfapi_nr_prach_pdu_t *prach_pdu, int *beams) +void nr_fill_prach_ru(RU_t *ru, prach_item_t *gnb_prach) { - prach_item_t *prach = find_nr_prach(&ru->prach_list, SFN, Slot, SEARCH_EXIST_OR_FREE); + prach_item_t *prach = find_nr_prach(&ru->prach_list, gnb_prach->frame, gnb_prach->slot, SEARCH_EXIST_OR_FREE); if (!prach) { LOG_E(PHY, "no prach memory found\n"); return; } - const int fmt = prach_pdu->prach_format; - *prach = (prach_item_t){.frame = SFN, - .slot = Slot, - .type = prach_lower, - .num_slots = (fmt < 4) ? get_long_prach_dur(fmt, ru->nr_frame_parms->numerology_index) : 1, - .lower = {.fmt = fmt, - .numRA = prach_pdu->num_ra, - .prachStartSymbol = prach_pdu->prach_start_symbol, - .num_prach_ocas = prach_pdu->num_prach_ocas}}; - memcpy(prach->beams, beams, sizeof(prach->beams)); + *prach = *gnb_prach; } void rx_nr_prach_ru(RU_t *ru, diff --git a/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h b/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h index db391dacc0..1d1ef0a56d 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h +++ b/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h @@ -222,7 +222,7 @@ void rx_nr_prach_ru(RU_t *ru, int frame, int subframe); -void nr_fill_prach_ru(RU_t *ru,int SFN, int Slot, nfapi_nr_prach_pdu_t *prach_pdu, int *beam_nb); +void nr_fill_prach_ru(RU_t *ru,prach_item_t * ); prach_item_t *find_nr_prach(prach_list_t *, int frame, int slot, find_type_t type); void nr_fill_pucch(PHY_VARS_gNB *gNB, int frame, diff --git a/openair1/PHY/defs_common.h b/openair1/PHY/defs_common.h index b9923a1b8b..b469555354 100644 --- a/openair1/PHY/defs_common.h +++ b/openair1/PHY/defs_common.h @@ -1001,25 +1001,11 @@ typedef struct { // TODO will be removed in a late commit #include "nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h" #define NUMBER_OF_NR_PRACH_MAX 8 -typedef enum { prach_upper, prach_lower } prach_type_t; typedef struct { int frame; int slot; int num_slots; // prach duration in slots int beams[NFAPI_MAX_NUM_BG_IF]; - prach_type_t type; - union { - struct { - // identifier for concurrent beams - nfapi_nr_prach_pdu_t pdu; - } upper; - struct { - int fmt; - int numRA; - int prachStartSymbol; - int num_prach_ocas; - } lower; - }; nfapi_nr_prach_pdu_t pdu; } prach_item_t; @@ -1029,7 +1015,7 @@ typedef struct { /// mutex for prach_list access pthread_mutex_t prach_list_mutex; } prach_list_t; -void init_prach_list(prach_list_t *, prach_type_t); +void init_prach_list(prach_list_t *); static inline void init_abort(decode_abort_t *ab) { diff --git a/openair1/SCHED/nfapi_lte_dummy.c b/openair1/SCHED/nfapi_lte_dummy.c index d61f0d0548..5d9b5b7a76 100644 --- a/openair1/SCHED/nfapi_lte_dummy.c +++ b/openair1/SCHED/nfapi_lte_dummy.c @@ -45,10 +45,7 @@ void nr_fill_prach(PHY_VARS_gNB *gNB, int SFN, int Slot, nfapi_nr_prach_pdu_t *prach_pdu){} -void nr_fill_prach_ru(RU_t *ru, - int SFN, - int Slot, - nfapi_nr_prach_pdu_t *prach_pdu){} +void nr_fill_prach_ru(RU_t *ru,prach_item_t *gnb_prach){} void nr_phy_config_request(NR_PHY_Config_t *gNB){} diff --git a/openair1/SCHED_NR/fapi_nr_l1.c b/openair1/SCHED_NR/fapi_nr_l1.c index 09419d4e84..6d0a3ee7da 100644 --- a/openair1/SCHED_NR/fapi_nr_l1.c +++ b/openair1/SCHED_NR/fapi_nr_l1.c @@ -156,7 +156,7 @@ void nr_schedule_ul_tti_req(PHY_VARS_gNB *gNB, nfapi_nr_ul_tti_request_t *UL_tti nfapi_nr_prach_pdu_t *prach_pdu = &UL_tti_req->pdus_list[i].prach_pdu; prach_item_t *prach = nr_fill_prach(gNB, UL_tti_req->SFN, UL_tti_req->Slot, prach_pdu); if (prach && (gNB->RU_list[0]->if_south == LOCAL_RF || gNB->RU_list[0]->if_south == REMOTE_IF5)) - nr_fill_prach_ru(gNB->RU_list[0], UL_tti_req->SFN, UL_tti_req->Slot, prach_pdu, prach->beams); + nr_fill_prach_ru(gNB->RU_list[0], prach); break; case NFAPI_NR_UL_CONFIG_SRS_PDU_TYPE: LOG_D(NR_PHY, diff --git a/openair1/SIMULATION/NR_PHY/prachsim.c b/openair1/SIMULATION/NR_PHY/prachsim.c index 9f2e06762c..9eb9c5c9c5 100644 --- a/openair1/SIMULATION/NR_PHY/prachsim.c +++ b/openair1/SIMULATION/NR_PHY/prachsim.c @@ -774,9 +774,10 @@ int main(int argc, char **argv){ for (int i = 0; i < ru->nb_rx; ++i) rxsigF[i] = (c16_t *)ru->prach_rxsigF[prachOccasion][i]; if (n_frames == 1) - printf("ncs %d,num_seq %d\n", - prach_pdu->num_cs, - prach_config->num_prach_fd_occasions_list[fd_occasion].num_root_sequences.value); + LOG_I(PHY, + "ncs %d,num_seq %d\n", + prach_pdu->num_cs, + prach_config->num_prach_fd_occasions_list[fd_occasion].num_root_sequences.value); rx_nr_prach(gNB, prach_pdu, prachOccasion, frame, subframe, &preamble_rx, &preamble_energy, &preamble_delay, rxsigF); // printf(" preamble_energy %d preamble_rx %d preamble_tx %d \n", preamble_energy, preamble_rx, preamble_tx); From d24e010367a6c1aeea041e1090fada293622aaca Mon Sep 17 00:00:00 2001 From: Laurent THOMAS Date: Thu, 11 Sep 2025 17:30:46 +0200 Subject: [PATCH 37/69] simplify computation of ru->prach_rxsigF[prachOccasion][aa] --- openair1/PHY/NR_TRANSPORT/nr_prach.c | 66 +++++++------------ .../PHY/NR_TRANSPORT/nr_transport_proto.h | 1 - openair1/SCHED_NR/nr_prach_procedures.c | 2 +- openair1/SIMULATION/NR_PHY/prachsim.c | 2 +- 4 files changed, 27 insertions(+), 44 deletions(-) diff --git a/openair1/PHY/NR_TRANSPORT/nr_prach.c b/openair1/PHY/NR_TRANSPORT/nr_prach.c index d1e337ce2e..40a2900e15 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_prach.c +++ b/openair1/PHY/NR_TRANSPORT/nr_prach.c @@ -133,8 +133,6 @@ void rx_nr_prach_ru(RU_t *ru, AssertFatal(ru != NULL,"ru is null\n"); NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms; - int slot2 = slot; - int16_t *prach[ru->nb_rx]; int prach_sequence_length = ru->config.prach_config.prach_sequence_length.value; int msg1_frequencystart = ru->config.prach_config.num_prach_fd_occasions_list[numRA].k1.value; const uint8_t prach_mu = ru->config.prach_config.prach_sub_c_spacing.value; @@ -162,19 +160,8 @@ void rx_nr_prach_ru(RU_t *ru, numRA, prachStartSymbol, prachOccasion); - - c16_t **rxsigF = (c16_t **)ru->prach_rxsigF[prachOccasion]; - AssertFatal(ru->if_south == LOCAL_RF || ru->if_south == REMOTE_IF5, "we shouldn't call this if if_south != LOCAL_RF or REMOTE_IF5\n"); - - for (int aa = 0; aa < ru->nb_rx; aa++) { - if (prach_sequence_length == 0) - slot2 = prachStartSlot; - int idx = aa + beam * ru->nb_rx; - prach[aa] = (int16_t*)&ru->common.rxdata[idx][fp->get_samples_slot_timestamp(slot2, fp, 0) + sample_offset_slot - ru->N_TA_offset]; - } - int reps; int Ncp; int dftlen; @@ -183,11 +170,11 @@ void rx_nr_prach_ru(RU_t *ru, if (prach_sequence_length == 0) { LOG_D(PHY, "PRACH (ru %d) in %d.%d, format %d, msg1_frequencyStart %d\n", - ru->idx, - frame, - slot2, - prachFormat, - msg1_frequencystart); + ru->idx, + frame, + prachStartSlot, + prachFormat, + msg1_frequencystart); switch (prachFormat) { case 0: reps = 1; @@ -371,7 +358,7 @@ void rx_nr_prach_ru(RU_t *ru, int n_ra_prb = msg1_frequencystart; int k = (12*n_ra_prb) - 6*fp->N_RB_UL; - int N_ZC = (prach_sequence_length==0)?839:139; + int N_ZC = (prach_sequence_length == 0) ? 839 : 139; if (k<0) k+=(fp->ofdm_symbol_size); @@ -379,36 +366,34 @@ void rx_nr_prach_ru(RU_t *ru, k+=kbar; for (int aa=0; aanb_rx; aa++) { - AssertFatal(prach[aa]!=NULL,"prach[%d] is null\n",aa); + int slot2 = prach_sequence_length ? slot : prachStartSlot; + int idx = aa + beam * ru->nb_rx; + c16_t *prach = + (c16_t *)&ru->common.rxdata[idx][fp->get_samples_slot_timestamp(slot2, fp, 0) + sample_offset_slot - ru->N_TA_offset]; // do DFT - int16_t *prach2 = prach[aa] + (2*Ncp); // times 2 for complex samples - for (int i = 0; i < reps; i++) - dft(dftsize, prach2 + 2 * dftlen * i, (int16_t *)rxsigF[aa] + 2 * dftlen * i, 1); - - //LOG_M("ru_rxsigF_tmp.m","rxsFtmp", rxsigF[aa], dftlen*2*reps, 1, 1); - - //Coherent combining of PRACH repetitions (assumes channel does not change, to be revisted for "long" PRACH) - LOG_D(PHY,"Doing PRACH combining of %d reptitions N_ZC %d\n",reps,N_ZC); + c16_t *prach2 = prach + Ncp; c16_t rxsigF_tmp[N_ZC]; - // if (k+N_ZC > dftlen) { // PRACH signal is split around DC - c16_t *rxsigF2 = rxsigF[aa]; - int k2 = k; - - for (int j = 0; j < N_ZC; j++, k2++) { - if (k2 == dftlen) - k2 = 0; - rxsigF_tmp[j] = rxsigF2[k2]; - for (int i = 1; i < reps; i++) - rxsigF_tmp[j] = c16add(rxsigF_tmp[j], rxsigF2[k2 + i * dftlen]); + memset(rxsigF_tmp, 0, sizeof(rxsigF_tmp)); + for (int i = 0; i < reps; i++, prach2 += dftlen) { + c16_t tmp[dftlen] __attribute__((aligned(32))); + dft(dftsize, (int16_t *)prach2, (int16_t *)tmp, 1); + // Coherent combining of PRACH repetitions (assumes channel does not change, to be revisted for "long" PRACH) + LOG_D(PHY, "Doing PRACH combining of %d reptitions N_ZC %d\n", reps, N_ZC); + // if (k+N_ZC > dftlen) { // PRACH signal is split around DC + int k2 = k; + for (int j = 0; j < N_ZC; j++, k2++) { + if (k2 == dftlen) + k2 = 0; + rxsigF_tmp[j] = c16add(rxsigF_tmp[j], tmp[k2]); + } } - memcpy(rxsigF2, rxsigF_tmp, N_ZC * sizeof(*rxsigF2)); + memcpy(ru->prach_rxsigF[prachOccasion][aa], rxsigF_tmp, sizeof(rxsigF_tmp)); } } void rx_nr_prach(PHY_VARS_gNB *gNB, nfapi_nr_prach_pdu_t *prach_pdu, - int prachOccasion, int frame, int slot, uint16_t *max_preamble, @@ -658,4 +643,3 @@ void rx_nr_prach(PHY_VARS_gNB *gNB, stop_meas(&gNB->rx_prach); } - diff --git a/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h b/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h index 1d1ef0a56d..2cbe1fde77 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h +++ b/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h @@ -204,7 +204,6 @@ prach_item_t *nr_fill_prach(PHY_VARS_gNB *gNB, int SFN, int Slot, nfapi_nr_prach void rx_nr_prach(PHY_VARS_gNB *gNB, nfapi_nr_prach_pdu_t *prach_pdu, - int prachOccasion, int frame, int subframe, uint16_t *max_preamble, diff --git a/openair1/SCHED_NR/nr_prach_procedures.c b/openair1/SCHED_NR/nr_prach_procedures.c index 74a98dc7f7..632269eeed 100644 --- a/openair1/SCHED_NR/nr_prach_procedures.c +++ b/openair1/SCHED_NR/nr_prach_procedures.c @@ -79,7 +79,7 @@ void L1_nr_prach_procedures(PHY_VARS_gNB *gNB, int frame, int slot, nfapi_nr_rac c16_t *rxsigF[ru->nb_rx]; for (int i = 0; i < ru->nb_rx; ++i) rxsigF[i] = (c16_t *)ru->prach_rxsigF[prach_oc][i]; - rx_nr_prach(gNB, prach_pdu, prach_oc, frame, slot, &max_preamble[0], &max_preamble_energy[0], &max_preamble_delay[0], rxsigF); + rx_nr_prach(gNB, prach_pdu, frame, slot, max_preamble, max_preamble_energy, max_preamble_delay, rxsigF); LOG_D(NR_PHY, "[RAPROC] Frame %d, slot %d, occasion %d (prachStartSymbol %d) : Most likely preamble %d, energy %d.%d dB delay %d " "(prach_energy counter %d)\n", diff --git a/openair1/SIMULATION/NR_PHY/prachsim.c b/openair1/SIMULATION/NR_PHY/prachsim.c index 9eb9c5c9c5..e5f64fff5d 100644 --- a/openair1/SIMULATION/NR_PHY/prachsim.c +++ b/openair1/SIMULATION/NR_PHY/prachsim.c @@ -778,7 +778,7 @@ int main(int argc, char **argv){ "ncs %d,num_seq %d\n", prach_pdu->num_cs, prach_config->num_prach_fd_occasions_list[fd_occasion].num_root_sequences.value); - rx_nr_prach(gNB, prach_pdu, prachOccasion, frame, subframe, &preamble_rx, &preamble_energy, &preamble_delay, rxsigF); + rx_nr_prach(gNB, prach_pdu, frame, subframe, &preamble_rx, &preamble_energy, &preamble_delay, rxsigF); // printf(" preamble_energy %d preamble_rx %d preamble_tx %d \n", preamble_energy, preamble_rx, preamble_tx); From 180f83d196f12463042f6759cfe469367861c7a1 Mon Sep 17 00:00:00 2001 From: Laurent THOMAS Date: Wed, 29 Oct 2025 12:13:25 +0100 Subject: [PATCH 38/69] Refactor L1_nr_prach_procedures --- openair1/SCHED_NR/nr_prach_procedures.c | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/openair1/SCHED_NR/nr_prach_procedures.c b/openair1/SCHED_NR/nr_prach_procedures.c index 632269eeed..db01294da5 100644 --- a/openair1/SCHED_NR/nr_prach_procedures.c +++ b/openair1/SCHED_NR/nr_prach_procedures.c @@ -67,11 +67,10 @@ void L1_nr_prach_procedures(PHY_VARS_gNB *gNB, int frame, int slot, nfapi_nr_rac LOG_D(NR_PHY, "%d.%d Got prach entry\n", frame, slot); nfapi_nr_prach_pdu_t *prach_pdu = &prach_id->pdu; const int prach_start_slot = prach_id->slot; - uint8_t prachStartSymbol; int N_dur = get_nr_prach_duration(prach_pdu->prach_format); for (int prach_oc = 0; prach_oc < prach_pdu->num_prach_ocas; prach_oc++) { - prachStartSymbol = prach_pdu->prach_start_symbol + prach_oc * N_dur; + uint prachStartSymbol = prach_pdu->prach_start_symbol + prach_oc * N_dur; // comment FK: the standard 38.211 section 5.3.2 has one extra term +14*N_RA_slot. This is because there prachStartSymbol is // given wrt to start of the 15kHz slot or 60kHz slot. Here we work slot based, so this function is anyway only called in slots // where there is PRACH. Its up to the MAC to schedule another PRACH PDU in the case there are there N_RA_slot \in {0,1}. @@ -119,17 +118,16 @@ void L1_nr_prach_procedures(PHY_VARS_gNB *gNB, int frame, int slot, nfapi_nr_rac T_INT(max_preamble_delay[0])); nfapi_nr_prach_indication_pdu_t *ind = rach_ind->pdu_list + rach_ind->number_of_pdus; - ind->phy_cell_id = gNB->gNB_config.cell_config.phy_cell_id.value; - ind->symbol_index = prachStartSymbol; - ind->slot_index = slot; - ind->freq_index = prach_pdu->num_ra; - ind->avg_rssi = (max_preamble_energy[0] < 631) ? (128 + (max_preamble_energy[0] / 5)) : 254; - ind->avg_snr = 0xff; // invalid for now - - ind->num_preamble = 1; - ind->preamble_list[0].preamble_index = max_preamble[0]; - ind->preamble_list[0].timing_advance = max_preamble_delay[0]; - ind->preamble_list[0].preamble_pwr = 0xffffffff; + *ind = (nfapi_nr_prach_indication_pdu_t){ + .phy_cell_id = gNB->gNB_config.cell_config.phy_cell_id.value, + .symbol_index = prachStartSymbol, + .slot_index = slot, + .freq_index = prach_pdu->num_ra, + .avg_rssi = (max_preamble_energy[0] < 631) ? (128 + (max_preamble_energy[0] / 5)) : 254, + .avg_snr = 0xff, // invalid for now + .num_preamble = 1, + .preamble_list = { + {.preamble_index = max_preamble[0], .timing_advance = max_preamble_delay[0], .preamble_pwr = 0xffffffff}}}; rach_ind->number_of_pdus++; } gNB->measurements.prach_I0 = ((gNB->measurements.prach_I0 * 900) >> 10) + ((max_preamble_energy[0] * 124) >> 10); From 4f39ba8f513519446714f99d3b0d2f6929f9cea5 Mon Sep 17 00:00:00 2001 From: Laurent THOMAS Date: Wed, 29 Oct 2025 12:10:40 +0100 Subject: [PATCH 39/69] create a trace group for nr rach --- common/utils/LOG/log.h | 5 +++-- common/utils/T/T_messages.txt | 21 +++++++++++++++++++++ executables/nr-ru.c | 2 +- openair1/PHY/NR_TRANSPORT/nr_prach.c | 15 +++++++++++---- openair1/SCHED_NR/fapi_nr_l1.c | 1 + openair1/SCHED_NR/nr_prach_procedures.c | 4 ++-- 6 files changed, 39 insertions(+), 9 deletions(-) diff --git a/common/utils/LOG/log.h b/common/utils/LOG/log.h index a8c7becfdf..c873b0d418 100644 --- a/common/utils/LOG/log.h +++ b/common/utils/LOG/log.h @@ -168,8 +168,9 @@ static const char *const flag_name[] = {FOREACH_FLAG(FLAG_TEXT) ""}; COMP_DEF(GNB_APP, log) \ COMP_DEF(NR_RRC, log) \ COMP_DEF(NR_MAC, log) \ - COMP_DEF(NR_MAC_DCI, log) \ - COMP_DEF(NR_PHY_DCI, log) \ + COMP_DEF(NR_MAC_DCI, log) \ + COMP_DEF(NR_PHY_DCI, log) \ + COMP_DEF(NR_PHY_RACH, log) \ COMP_DEF(NR_PHY, log) \ COMP_DEF(LOADER, log) \ COMP_DEF(ASN1, log) \ diff --git a/common/utils/T/T_messages.txt b/common/utils/T/T_messages.txt index 2f17b62ea5..cd81deda2b 100644 --- a/common/utils/T/T_messages.txt +++ b/common/utils/T/T_messages.txt @@ -519,6 +519,27 @@ ID = LEGACY_NR_PHY_TRACE GROUP = ALL:LEGACY_NR_PHY:LEGACY_GROUP_TRACE:LEGACY FORMAT = string,log +ID = LEGACY_NR_PHY_RACH_INFO + DESC = NR_PHY_RACH legacy logs - info level + GROUP = ALL:LEGACY_NR_PHY_RACH:LEGACY_GROUP_INFO:LEGACY + FORMAT = string,log +ID = LEGACY_NR_PHY_RACH_ERROR + DESC = NR_PHY_RACH legacy logs - error level + GROUP = ALL:LEGACY_NR_PHY_RACH:LEGACY_GROUP_ERROR:LEGACY + FORMAT = string,log +ID = LEGACY_NR_PHY_RACH_WARNING + DESC = NR_PHY_RACH legacy logs - warning level + GROUP = ALL:LEGACY_NR_PHY_RACH:LEGACY_GROUP_WARNING:LEGACY + FORMAT = string,log +ID = LEGACY_NR_PHY_RACH_DEBUG + DESC = NR_PHY_RACH legacy logs - debug level + GROUP = ALL:LEGACY_NR_PHY_RACH:LEGACY_GROUP_DEBUG:LEGACY + FORMAT = string,log +ID = LEGACY_NR_PHY_RACH_TRACE + DESC = NR_PHY_RACH legacy logs - trace level + GROUP = ALL:LEGACY_NR_PHY_RACH:LEGACY_GROUP_TRACE:LEGACY + FORMAT = string,log + ID = LEGACY_S1AP_INFO DESC = S1AP legacy logs - info level GROUP = ALL:LEGACY_S1AP:LEGACY_GROUP_INFO:LEGACY diff --git a/executables/nr-ru.c b/executables/nr-ru.c index ae610beacd..60270d9d0f 100644 --- a/executables/nr-ru.c +++ b/executables/nr-ru.c @@ -1219,7 +1219,7 @@ void *ru_thread(void *param) T_BUFFER(&ru->common.rxdata[0][fp->get_samples_slot_timestamp(proc->tti_rx - 1, fp, 0) /*-ru->N_TA_offset*/], (fp->get_samples_per_slot(proc->tti_rx - 1, fp) + fp->get_samples_per_slot(proc->tti_rx, fp)) * 4)); int N_dur = get_nr_prach_duration(p->pdu.prach_format); - + LOG_D(NR_PHY_RACH, "%d.%d try to decode %d occasions \n", frame, slot, p->pdu.num_prach_ocas); for (int prach_oc = 0; prach_oc < p->pdu.num_prach_ocas; prach_oc++) { int prachStartSymbol = p->pdu.prach_start_symbol + prach_oc * N_dur; int beam_id = p->beams[prach_oc]; diff --git a/openair1/PHY/NR_TRANSPORT/nr_prach.c b/openair1/PHY/NR_TRANSPORT/nr_prach.c index 40a2900e15..425e20dd84 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_prach.c +++ b/openair1/PHY/NR_TRANSPORT/nr_prach.c @@ -46,6 +46,8 @@ void init_prach_list(prach_list_t *l) void free_nr_prach_entry(prach_list_t *l, prach_item_t *p) { pthread_mutex_lock(&l->prach_list_mutex); + if (p->frame == -1) + LOG_E(NR_PHY_RACH, "Freeing a not allocated prach entry\n"); *p = (prach_item_t){.frame = -1, .slot = -1, .num_slots = -1}; pthread_mutex_unlock(&l->prach_list_mutex); } @@ -421,7 +423,7 @@ void rx_nr_prach(PHY_VARS_gNB *gNB, const int prach_fmt = prach_pdu->prach_format; const int N_ZC = prach_sequence_length == 0 ? 839 : 139; - LOG_D(PHY, + LOG_D(NR_PHY_RACH, "L1 PRACH RX: rooSequenceIndex %d, numRootSeqeuences %d, NCS %d, N_ZC %d, format %d \n", rootSequenceIndex, numrootSequenceIndex, @@ -550,7 +552,12 @@ void rx_nr_prach(PHY_VARS_gNB *gNB, en); } - LOG_D(PHY,"PRACH RX preamble_index %d, preamble_offset %d\n",preamble_index,preamble_offset); + LOG_D(NR_PHY_RACH, + "PRACH RX preamble_index %d, preamble_offset %d, preamb shift %d new dft %d\n", + preamble_index, + preamble_offset, + preamble_shift, + new_dft); if (new_dft) { new_dft = false; @@ -606,8 +613,8 @@ void rx_nr_prach(PHY_VARS_gNB *gNB, for (int i = 0; i < NCS2; i++) { int lev = prach_ifft[preamble_shift2 + i]; int levdB = dB_fixed_times10(lev); - if (levdB>*max_preamble_energy) { - LOG_D(PHY,"preamble_index %d, delay %d en %d dB > %d dB\n",preamble_index,i,levdB,*max_preamble_energy); + if (levdB > *max_preamble_energy || (levdB == *max_preamble_energy && *max_preamble_delay > i)) { + LOG_D(NR_PHY_RACH, "preamble_index %d, delay %d en %d dB > %d dB\n", preamble_index, i, levdB, *max_preamble_energy); *max_preamble_energy = levdB; *max_preamble_delay = i; // Note: This has to be normalized to the 30.72 Ms/s sampling rate *max_preamble = preamble_index; diff --git a/openair1/SCHED_NR/fapi_nr_l1.c b/openair1/SCHED_NR/fapi_nr_l1.c index 6d0a3ee7da..ad6f90e6e8 100644 --- a/openair1/SCHED_NR/fapi_nr_l1.c +++ b/openair1/SCHED_NR/fapi_nr_l1.c @@ -154,6 +154,7 @@ void nr_schedule_ul_tti_req(PHY_VARS_gNB *gNB, nfapi_nr_ul_tti_request_t *UL_tti UL_tti_req->SFN, UL_tti_req->Slot); nfapi_nr_prach_pdu_t *prach_pdu = &UL_tti_req->pdus_list[i].prach_pdu; + LOG_D(NR_PHY_RACH, "Add prach decoding request for %d.%d\n", UL_tti_req->SFN, UL_tti_req->Slot); prach_item_t *prach = nr_fill_prach(gNB, UL_tti_req->SFN, UL_tti_req->Slot, prach_pdu); if (prach && (gNB->RU_list[0]->if_south == LOCAL_RF || gNB->RU_list[0]->if_south == REMOTE_IF5)) nr_fill_prach_ru(gNB->RU_list[0], prach); diff --git a/openair1/SCHED_NR/nr_prach_procedures.c b/openair1/SCHED_NR/nr_prach_procedures.c index db01294da5..caaa579ad0 100644 --- a/openair1/SCHED_NR/nr_prach_procedures.c +++ b/openair1/SCHED_NR/nr_prach_procedures.c @@ -64,8 +64,8 @@ void L1_nr_prach_procedures(PHY_VARS_gNB *gNB, int frame, int slot, nfapi_nr_rac return; } - LOG_D(NR_PHY, "%d.%d Got prach entry\n", frame, slot); nfapi_nr_prach_pdu_t *prach_pdu = &prach_id->pdu; + LOG_D(NR_PHY_RACH, "%d.%d, prachstart slot %d prach entry occas %d\n", frame, slot, prach_id->slot, prach_pdu->num_prach_ocas); const int prach_start_slot = prach_id->slot; int N_dur = get_nr_prach_duration(prach_pdu->prach_format); @@ -137,7 +137,7 @@ void L1_nr_prach_procedures(PHY_VARS_gNB *gNB, int frame, int slot, nfapi_nr_rac gNB->prach_energy_counter++; } // if prach_id>0 rach_ind->slot = prach_start_slot; - LOG_D(NR_PHY, "Freeing PRACH entry\n"); + LOG_D(NR_PHY_RACH, "Freeing PRACH entry\n"); free_nr_prach_entry(&gNB->prach_list, prach_id); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_PRACH_RX,0); } From d745e6fcd313fa18f98b48b86dd46b24571b9440 Mon Sep 17 00:00:00 2001 From: Laurent THOMAS Date: Fri, 19 Sep 2025 15:08:26 +0200 Subject: [PATCH 40/69] Make the decidated structure the PRACH decoding values contextual The function rx_nr_prach become autonomous, it doesn't read anymore global variables So, it can become (later) a threadpool work, that will send a message when it finishes rx_nr_prach_ru() still use some global variables, but it is executed in sequence, inside the ru main loop, that limits the probability of race conditions --- executables/nr-ru.c | 52 +-- openair1/PHY/NR_TRANSPORT/nr_prach.c | 366 +++++++++--------- .../PHY/NR_TRANSPORT/nr_transport_proto.h | 24 +- openair1/PHY/defs_common.h | 11 + openair1/SCHED_NR/fapi_nr_l1.c | 4 + openair1/SCHED_NR/nr_prach_procedures.c | 41 +- openair1/SIMULATION/NR_PHY/prachsim.c | 114 ++++-- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c | 7 +- 8 files changed, 314 insertions(+), 305 deletions(-) diff --git a/executables/nr-ru.c b/executables/nr-ru.c index 60270d9d0f..9e4e6a5384 100644 --- a/executables/nr-ru.c +++ b/executables/nr-ru.c @@ -1034,7 +1034,7 @@ void *ru_thread(void *param) RU_t *ru = (RU_t *)param; RU_proc_t *proc = &ru->proc; NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms; - PHY_VARS_gNB *gNB = RC.gNB[0]; + PHY_VARS_gNB *gNB = RC.gNB[0]; // this RU main loop handes only one RU int ret; int slot = fp->slots_per_frame-1; int frame = 1023; @@ -1047,7 +1047,7 @@ void *ru_thread(void *param) // set default return value sprintf(threadname,"ru_thread %u",ru->idx); LOG_I(PHY,"Starting RU %d (%s,%s) on cpu %d\n",ru->idx,NB_functions[ru->function],NB_timing[ru->if_timing],sched_getcpu()); - ru->config = RC.gNB[0]->gNB_config; + ru->config = gNB->gNB_config; nr_init_frame_parms(&ru->config, fp); nr_dump_frame_parms(fp); @@ -1179,12 +1179,17 @@ void *ru_thread(void *param) proc->timestamp_tx += fp->get_samples_per_slot(i % fp->slots_per_frame, fp); proc->tti_tx = (proc->tti_rx + ru->sl_ahead) % fp->slots_per_frame; proc->frame_tx = proc->tti_rx > proc->tti_tx ? (proc->frame_rx + 1) & 1023 : proc->frame_rx; - LOG_D(PHY,"AFTER fh_south_in - SFN/SL:%d%d RU->proc[RX:%d.%d TX:%d.%d] RC.gNB[0]:[RX:%d%d TX(SFN):%d]\n", - frame,slot, - proc->frame_rx,proc->tti_rx, - proc->frame_tx,proc->tti_tx, - RC.gNB[0]->proc.frame_rx,RC.gNB[0]->proc.slot_rx, - RC.gNB[0]->proc.frame_tx); + LOG_D(PHY, + "AFTER fh_south_in - SFN/SL:%d%d RU->proc[RX:%d.%d TX:%d.%d] RC.gNB[0]:[RX:%d%d TX(SFN):%d]\n", + frame, + slot, + proc->frame_rx, + proc->tti_rx, + proc->frame_tx, + proc->tti_tx, + gNB->proc.frame_rx, + gNB->proc.slot_rx, + gNB->proc.frame_tx); if (ru->idx != 0) proc->frame_tx = (proc->frame_tx + proc->frame_offset) & 1023; @@ -1199,7 +1204,7 @@ void *ru_thread(void *param) LOG_D(NR_PHY, "Setting %d.%d (%d) to busy\n", proc->frame_rx, proc->tti_rx, proc->tti_rx % RU_RX_SLOT_DEPTH); //LOG_M("rxdata.m","rxs",ru->common.rxdata[0],1228800,1,1); LOG_D(PHY,"RU proc: frame_rx = %d, tti_rx = %d\n", proc->frame_rx, proc->tti_rx); - gNBscopeCopy(RC.gNB[0], + gNBscopeCopy(gNB, gNBRxdataF, ru->common.rxdataF[0], sizeof(c16_t), @@ -1208,33 +1213,12 @@ void *ru_thread(void *param) proc->tti_rx * gNB->frame_parms.samples_per_slot_wCP); // Do PRACH RU processing - prach_item_t *p = find_nr_prach(&ru->prach_list, proc->frame_rx, proc->tti_rx, SEARCH_EXIST); + prach_item_t *p = find_nr_prach(&gNB->prach_list, proc->frame_rx, proc->tti_rx, SEARCH_EXIST); if (p) { VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_RU_PRACH_RX, 1 ); - - T(T_GNB_PHY_PRACH_INPUT_SIGNAL, - T_INT(proc->frame_rx), - T_INT(proc->tti_rx), - T_INT(0), - T_BUFFER(&ru->common.rxdata[0][fp->get_samples_slot_timestamp(proc->tti_rx - 1, fp, 0) /*-ru->N_TA_offset*/], - (fp->get_samples_per_slot(proc->tti_rx - 1, fp) + fp->get_samples_per_slot(proc->tti_rx, fp)) * 4)); - int N_dur = get_nr_prach_duration(p->pdu.prach_format); - LOG_D(NR_PHY_RACH, "%d.%d try to decode %d occasions \n", frame, slot, p->pdu.num_prach_ocas); - for (int prach_oc = 0; prach_oc < p->pdu.num_prach_ocas; prach_oc++) { - int prachStartSymbol = p->pdu.prach_start_symbol + prach_oc * N_dur; - int beam_id = p->beams[prach_oc]; - //comment FK: the standard 38.211 section 5.3.2 has one extra term +14*N_RA_slot. This is because there prachStartSymbol is given wrt to start of the 15kHz slot or 60kHz slot. Here we work slot based, so this function is anyway only called in slots where there is PRACH. Its up to the MAC to schedule another PRACH PDU in the case there are there N_RA_slot \in {0,1}. - rx_nr_prach_ru(ru, - p->pdu.prach_format, // could also use format - p->pdu.num_ra, - beam_id, - prachStartSymbol, - p->slot, - prach_oc, - proc->frame_rx, - proc->tti_rx); - } - free_nr_prach_entry(&ru->prach_list, p); + // this fills ru->prach_rxsigF for processing by gNB + p->rxsigF = (c16_t ***)ru->prach_rxsigF; + rx_nr_prach_ru(p, ru->common.rxdata, ru->nr_frame_parms, ru->N_TA_offset); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_RU_PRACH_RX, 0); } // end if (prach_id >= 0) } // end if (ru->feprx) diff --git a/openair1/PHY/NR_TRANSPORT/nr_prach.c b/openair1/PHY/NR_TRANSPORT/nr_prach.c index 425e20dd84..0bdb538f20 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_prach.c +++ b/openair1/PHY/NR_TRANSPORT/nr_prach.c @@ -87,9 +87,8 @@ prach_item_t *nr_fill_prach(PHY_VARS_gNB *gNB, int SFN, int Slot, nfapi_nr_prach return NULL; } const int fmt = prach_pdu->prach_format; - *prach = (prach_item_t){.frame = SFN, - .slot = Slot, - .num_slots = (fmt < 4) ? get_long_prach_dur(fmt, gNB->frame_parms.numerology_index) : 1}; + NR_DL_FRAME_PARMS *fp = &gNB->frame_parms; + *prach = (prach_item_t){.frame = SFN, .slot = Slot, .num_slots = (fmt < 4) ? get_long_prach_dur(fmt, fp->numerology_index) : 1}; if (gNB->common_vars.beam_id) { int n_symb = get_nr_prach_duration(prach_pdu->prach_format); AssertFatal(prach_pdu->beamforming.dig_bf_interface < NFAPI_MAX_NUM_BG_IF, @@ -109,6 +108,18 @@ prach_item_t *nr_fill_prach(PHY_VARS_gNB *gNB, int SFN, int Slot, nfapi_nr_prach } } prach->pdu = *prach_pdu; + nfapi_nr_prach_config_t *cfg = &gNB->gNB_config.prach_config; + nfapi_nr_num_prach_fd_occasions_t *occ = &cfg->num_prach_fd_occasions_list[prach_pdu->num_ra]; + prach->rootSequenceIndex = occ->prach_root_sequence_index.value; + prach->numrootSequenceIndex = occ->num_root_sequences.value; + prach->msg1_frequencystart = occ->k1.value; + prach->mu = cfg->prach_sub_c_spacing.value; + prach->prach_sequence_length = cfg->prach_sequence_length.value; + prach->restricted_set = cfg->restricted_set_config.value; + prach->numerology_index = fp->numerology_index; + prach->nb_rx = gNB->gNB_config.carrier_config.num_rx_ant.value; + prach->Xu = gNB->X_u; + prach->rx_prach = &gNB->rx_prach; return prach; } @@ -122,152 +133,140 @@ void nr_fill_prach_ru(RU_t *ru, prach_item_t *gnb_prach) *prach = *gnb_prach; } -void rx_nr_prach_ru(RU_t *ru, - int prachFormat, - int numRA, - int beam, - int prachStartSymbol, - int prachStartSlot, - int prachOccasion, - int frame, - int slot) +static void rx_nr_prach_ru_internal(prach_item_t *p, + int beam_id, + int prachStartSymbol, + int prachOccasion, + int32_t **rxdata, + NR_DL_FRAME_PARMS *fp, + int N_TA_offset) { - AssertFatal(ru != NULL,"ru is null\n"); - - NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms; - int prach_sequence_length = ru->config.prach_config.prach_sequence_length.value; - int msg1_frequencystart = ru->config.prach_config.num_prach_fd_occasions_list[numRA].k1.value; - const uint8_t prach_mu = ru->config.prach_config.prach_sub_c_spacing.value; - int sample_offset_slot; + const int sum = fp->ofdm_symbol_size + fp->nb_prefix_samples; + const int sum0 = fp->ofdm_symbol_size + fp->nb_prefix_samples0; if (prachStartSymbol == 0) { sample_offset_slot = 0; } else if (fp->slots_per_subframe == 1) { if (prachStartSymbol <= 7) - sample_offset_slot = (fp->ofdm_symbol_size + fp->nb_prefix_samples) * (prachStartSymbol - 1) + (fp->ofdm_symbol_size + fp->nb_prefix_samples0); + sample_offset_slot = sum * (prachStartSymbol - 1) + sum0; else - sample_offset_slot = (fp->ofdm_symbol_size + fp->nb_prefix_samples) * (prachStartSymbol - 2) + (fp->ofdm_symbol_size + fp->nb_prefix_samples0) * 2; + sample_offset_slot = sum * (prachStartSymbol - 2) + sum0 * 2; } else { - if (!(slot%(fp->slots_per_subframe/2))) - sample_offset_slot = (fp->ofdm_symbol_size + fp->nb_prefix_samples) * (prachStartSymbol - 1) + (fp->ofdm_symbol_size + fp->nb_prefix_samples0); + if (!(p->slot % (fp->slots_per_subframe / 2))) + sample_offset_slot = sum * (prachStartSymbol - 1) + sum0; else - sample_offset_slot = (fp->ofdm_symbol_size + fp->nb_prefix_samples) * prachStartSymbol; + sample_offset_slot = sum * prachStartSymbol; } LOG_D(PHY, "frame %d, slot %d: doing rx_nr_prach_ru for format %d, numRA %d, prachStartSymbol %d, prachOccasion %d\n", - frame, - slot, - prachFormat, - numRA, + p->frame, + p->slot, + p->pdu.prach_format, + p->pdu.num_ra, prachStartSymbol, prachOccasion); - AssertFatal(ru->if_south == LOCAL_RF || ru->if_south == REMOTE_IF5, - "we shouldn't call this if if_south != LOCAL_RF or REMOTE_IF5\n"); int reps; int Ncp; int dftlen; - int mu = fp->numerology_index; + int mu = p->numerology_index; - if (prach_sequence_length == 0) { + if (p->prach_sequence_length == 0) { LOG_D(PHY, - "PRACH (ru %d) in %d.%d, format %d, msg1_frequencyStart %d\n", - ru->idx, - frame, - prachStartSlot, - prachFormat, - msg1_frequencystart); - switch (prachFormat) { - case 0: - reps = 1; - Ncp = 3168; - dftlen = 24576; - break; + "PRACH in %d.%d, format %d, msg1_frequencyStart %d\n", + p->frame, + p->slot, + p->pdu.prach_format, + p->msg1_frequencystart); + switch (p->pdu.prach_format) { + case 0: + reps = 1; + Ncp = 3168; + dftlen = 24576; + break; - case 1: - reps = 2; - Ncp = 21024; - dftlen = 24576; - break; + case 1: + reps = 2; + Ncp = 21024; + dftlen = 24576; + break; - case 2: - reps = 4; - Ncp = 4688; - dftlen = 24576; - break; + case 2: + reps = 4; + Ncp = 4688; + dftlen = 24576; + break; - case 3: - reps = 4; - Ncp = 3168; - dftlen = 6144; - break; + case 3: + reps = 4; + Ncp = 3168; + dftlen = 6144; + break; - default: - AssertFatal(1==0, "Illegal prach format %d for length 839\n", prachFormat); - break; + default: + AssertFatal(1 == 0, "Illegal prach format %d for length 839\n", p->pdu.prach_format); + break; } - } - else { + } else { LOG_D(PHY, - "PRACH (ru %d) in %d.%d, format %s, msg1_frequencyStart %d,startSymbol %d\n", - ru->idx, - frame, - slot, - prachfmt[prachFormat], - msg1_frequencystart, - prachStartSymbol); - switch (prachFormat) { - case 4: //A1 - reps = 2; - Ncp = 288 >> mu; - break; + "PRACH in %d.%d, format %s, msg1_frequencyStart %d,startSymbol %d\n", + p->frame, + p->slot, + prachfmt[p->pdu.prach_format], + p->msg1_frequencystart, + prachStartSymbol); + switch (p->pdu.prach_format) { + case 4: // A1 + reps = 2; + Ncp = 288 >> mu; + break; - case 5: //A2 - reps = 4; - Ncp = 576 >> mu; - break; + case 5: // A2 + reps = 4; + Ncp = 576 >> mu; + break; - case 6: //A3 - reps = 6; - Ncp = 864 >> mu; - break; + case 6: // A3 + reps = 6; + Ncp = 864 >> mu; + break; - case 7: //B1 - reps = 2; - Ncp = 216 >> mu; - break; + case 7: // B1 + reps = 2; + Ncp = 216 >> mu; + break; - /* - // B2 and B3 do not exist in FAPI - case 4: //B2 - reps = 4; - Ncp = 360 >> mu; - break; + /* + // B2 and B3 do not exist in FAPI + case 4: //B2 + reps = 4; + Ncp = 360 >> mu; + break; - case 5: //B3 - reps = 6; - Ncp = 504 >> mu; - break; - */ + case 5: //B3 + reps = 6; + Ncp = 504 >> mu; + break; + */ - case 8: //B4 - reps = 12; - Ncp = 936 >> mu; - break; + case 8: // B4 + reps = 12; + Ncp = 936 >> mu; + break; - case 9: //C0 - reps = 1; - Ncp = 1240 >> mu; - break; + case 9: // C0 + reps = 1; + Ncp = 1240 >> mu; + break; - case 10: //C2 - reps = 4; - Ncp = 2048 >> mu; - break; + case 10: // C2 + reps = 4; + Ncp = 2048 >> mu; + break; - default: - AssertFatal(1==0,"unknown prach format %x\n",prachFormat); - break; + default: + AssertFatal(1 == 0, "unknown prach format %x\n", p->pdu.prach_format); + break; } dftlen = 2048 >> mu; } @@ -275,12 +274,11 @@ void rx_nr_prach_ru(RU_t *ru, //actually what we should be checking here is how often the current prach crosses a 0.5ms boundary. //I am not quite sure for which paramter set this would be the case, //so I will ignore it for now and just check if the prach starts on a 0.5ms boundary - if(fp->numerology_index == 0) { + if (p->numerology_index == 0) { if (prachStartSymbol == 0 || prachStartSymbol == 7) Ncp += 16; - } - else { - if (slot%(fp->slots_per_subframe/2)==0 && prachStartSymbol == 0) + } else { + if (p->slot % (fp->slots_per_subframe / 2) == 0 && prachStartSymbol == 0) Ncp += 16; } @@ -351,27 +349,27 @@ void rx_nr_prach_ru(RU_t *ru, // Do forward transform if (LOG_DEBUGFLAG(DEBUG_PRACH)) { - LOG_D(PHY, "rx_prach: Doing PRACH FFT for nb_rx:%d Ncp:%d dftlen:%d\n", ru->nb_rx, Ncp, dftlen); + LOG_D(PHY, "rx_prach: Doing PRACH FFT for nb_rx:%d Ncp:%d dftlen:%d\n", p->nb_rx, Ncp, dftlen); } - const unsigned int K = get_prach_K(prach_sequence_length, prachFormat, fp->numerology_index, prach_mu); - const uint8_t kbar = get_PRACH_k_bar(prach_mu, fp->numerology_index); + const unsigned int K = get_prach_K(p->prach_sequence_length, p->pdu.prach_format, p->numerology_index, p->mu); + const uint8_t kbar = get_PRACH_k_bar(p->mu, p->numerology_index); - int n_ra_prb = msg1_frequencystart; + int n_ra_prb = p->msg1_frequencystart; int k = (12*n_ra_prb) - 6*fp->N_RB_UL; - int N_ZC = (prach_sequence_length == 0) ? 839 : 139; + int N_ZC = (p->prach_sequence_length == 0) ? 839 : 139; if (k<0) k+=(fp->ofdm_symbol_size); k*=K; k+=kbar; - for (int aa=0; aanb_rx; aa++) { - int slot2 = prach_sequence_length ? slot : prachStartSlot; - int idx = aa + beam * ru->nb_rx; - c16_t *prach = - (c16_t *)&ru->common.rxdata[idx][fp->get_samples_slot_timestamp(slot2, fp, 0) + sample_offset_slot - ru->N_TA_offset]; + for (int aa = 0; aa < p->nb_rx; aa++) { + // Fixme: slot or slot makes no sense ??? + int slot2 = p->prach_sequence_length ? p->slot : p->slot; + int idx = aa + beam_id * p->nb_rx; + c16_t *prach = (c16_t *)&rxdata[idx][fp->get_samples_slot_timestamp(slot2, fp, 0) + sample_offset_slot - N_TA_offset]; // do DFT c16_t *prach2 = prach + Ncp; @@ -390,60 +388,56 @@ void rx_nr_prach_ru(RU_t *ru, rxsigF_tmp[j] = c16add(rxsigF_tmp[j], tmp[k2]); } } - memcpy(ru->prach_rxsigF[prachOccasion][aa], rxsigF_tmp, sizeof(rxsigF_tmp)); + memcpy(p->rxsigF[prachOccasion][aa], rxsigF_tmp, sizeof(rxsigF_tmp)); } } -void rx_nr_prach(PHY_VARS_gNB *gNB, - nfapi_nr_prach_pdu_t *prach_pdu, - int frame, - int slot, - uint16_t *max_preamble, - uint16_t *max_preamble_energy, - uint16_t *max_preamble_delay, - c16_t **rxsigF) +void rx_nr_prach_ru(prach_item_t *p, int32_t **rxdata, NR_DL_FRAME_PARMS *fp, int N_TA_offset) { - AssertFatal(gNB != NULL, "Can only be called from gNB\n"); - nfapi_nr_prach_config_t *cfg = &gNB->gNB_config.prach_config; + int N_dur = get_nr_prach_duration(p->pdu.prach_format); + LOG_D(NR_PHY_RACH, "%d.%d try to decode %d occasions \n", p->frame, p->slot, p->pdu.num_prach_ocas); + for (int prach_oc = 0; prach_oc < p->pdu.num_prach_ocas; prach_oc++) { + int prachStartSymbol = p->pdu.prach_start_symbol + prach_oc * N_dur; + int beam_id = p->beams[prach_oc]; + // comment FK: the standard 38.211 section 5.3.2 has one extra term +14*N_RA_slot. This is because there prachStartSymbol is + // given wrt to start of the 15kHz slot or 60kHz slot. Here we work slot based, so this function is anyway only called in slots + // where there is PRACH. Its up to the MAC to schedule another PRACH PDU in the case there are there N_RA_slot \in {0,1}. + rx_nr_prach_ru_internal(p, beam_id, prachStartSymbol, prach_oc, rxdata, fp, N_TA_offset); + } +} + +rx_prach_out_t rx_nr_prach(const prach_item_t *in, int occasion) +{ + rx_prach_out_t out = {}; + c16_t **input = in->rxsigF[occasion]; uint16_t preamble_index0 = 0; uint16_t numshift = 0; int first_nonzero_root_idx = 0; bool new_dft = false; int log2_ifft_size = 10; - NR_DL_FRAME_PARMS *fp = &gNB->frame_parms; - - const int nb_rx = gNB->gNB_config.carrier_config.num_rx_ant.value; - const int rootSequenceIndex = cfg->num_prach_fd_occasions_list[prach_pdu->num_ra].prach_root_sequence_index.value; - const int numrootSequenceIndex = cfg->num_prach_fd_occasions_list[prach_pdu->num_ra].num_root_sequences.value; - const int NCS = prach_pdu->num_cs; // cfg->num_prach_fd_occasions_list[0].prach_zero_corr_conf.value; - const int prach_sequence_length = cfg->prach_sequence_length.value; - const int msg1_frequencystart = cfg->num_prach_fd_occasions_list[prach_pdu->num_ra].k1.value; - const int restricted_set = cfg->restricted_set_config.value; - const int prach_fmt = prach_pdu->prach_format; - const int N_ZC = prach_sequence_length == 0 ? 839 : 139; + const int nb_rx = in->nb_rx; + const int NCS = in->pdu.num_cs; + const int prach_fmt = in->pdu.prach_format; + const int N_ZC = in->prach_sequence_length == 0 ? 839 : 139; LOG_D(NR_PHY_RACH, "L1 PRACH RX: rooSequenceIndex %d, numRootSeqeuences %d, NCS %d, N_ZC %d, format %d \n", - rootSequenceIndex, - numrootSequenceIndex, + in->rootSequenceIndex, + in->numrootSequenceIndex, NCS, N_ZC, prach_fmt); if (LOG_DEBUGFLAG(DEBUG_PRACH)) { - if ((frame & 1023) < 20) - LOG_D(PHY, - "PRACH (gNB) : running rx_prach for slot %d, msg1_frequencystart %d, rootSequenceIndex %d\n", - slot, - msg1_frequencystart, - rootSequenceIndex); + if ((in->frame & 1023) < 20) + LOG_D(PHY, "PRACH (gNB) : running rx_prach for slot %d, rootSequenceIndex %d\n", in->slot, in->rootSequenceIndex); } - start_meas(&gNB->rx_prach); + start_meas(in->rx_prach); const uint16_t *prach_root_sequence_map = - cfg->prach_sequence_length.value == 0 ? prach_root_sequence_map_0_3 : prach_root_sequence_map_abc; + in->prach_sequence_length == 0 ? prach_root_sequence_map_0_3 : prach_root_sequence_map_abc; // PDP is oversampled, e.g. 1024 sample instead of 839 // Adapt the NCS (zero-correlation zones) with oversampling factor e.g. 1024/839 @@ -454,19 +448,16 @@ void rx_nr_prach(PHY_VARS_gNB *gNB, int preamble_offset = 0, preamble_offset_old = 99; - *max_preamble_energy = 0; - *max_preamble_delay = 0; - *max_preamble = 0; int16_t preamble_shift = 0; const int dft_sz = N_ZC == 839 ? 1024 : 256; int32_t prach_ifft[dft_sz] __attribute__((aligned(32))); for (int preamble_index = 0; preamble_index < 64; preamble_index++) { if (LOG_DEBUGFLAG(DEBUG_PRACH)) { - int en = dB_fixed(signal_energy((int32_t *)rxsigF[0], N_ZC == 839 ? 840 : 140)); + int en = dB_fixed(signal_energy((int32_t *)input[0], N_ZC == 839 ? 840 : 140)); if (en > 60) - LOG_D(PHY, "frame %d, slot %d : Trying preamble %d \n", frame, slot, preamble_index); + LOG_D(PHY, "frame %d, slot %d : Trying preamble %d \n", in->frame, in->slot, preamble_index); } - if (restricted_set == 0) { + if (in->restricted_set == 0) { // This is the relative offset in the root sequence table (5.7.2-4 from 36.211) for the given preamble index preamble_offset = ((NCS==0)? preamble_index : (preamble_index/(N_ZC/NCS))); @@ -495,7 +486,7 @@ void rx_nr_prach(PHY_VARS_gNB *gNB, preamble_index0 -= numshift; while (not_found) { // current root depending on rootSequenceIndex - int index = (rootSequenceIndex + preamble_offset) % N_ZC; + int index = (in->rootSequenceIndex + preamble_offset) % N_ZC; int u = nr_du[prach_root_sequence_map[index]]; uint16_t n_group_ra = 0; @@ -538,12 +529,12 @@ void rx_nr_prach(PHY_VARS_gNB *gNB, // Compute DFT of RX signal (conjugate input, results in conjugate output) for each new rootSequenceIndex if (LOG_DEBUGFLAG(DEBUG_PRACH)) { - int en = dB_fixed(signal_energy((int32_t *)rxsigF[0], 840)); + int en = dB_fixed(signal_energy((int32_t *)input[0], 840)); if (en>60) LOG_D(PHY, "frame %d, slot %d : preamble index %d, NCS %d, N_ZC/NCS %d: offset %d, preamble shift %d , en %d)\n", - frame, - slot, + in->frame, + in->slot, preamble_index, NCS, N_ZC / NCS, @@ -562,19 +553,19 @@ void rx_nr_prach(PHY_VARS_gNB *gNB, if (new_dft) { new_dft = false; - c16_t *Xu = (c16_t *)gNB->X_u[preamble_offset - first_nonzero_root_idx]; + c16_t *Xu = in->Xu[preamble_offset - first_nonzero_root_idx]; LOG_D(PHY,"PRACH RX new dft preamble_offset-first_nonzero_root_idx %d\n",preamble_offset-first_nonzero_root_idx); memset(prach_ifft, 0, sizeof(prach_ifft)); if (LOG_DUMPFLAG(DEBUG_PRACH)) { - LOG_M("prach_rxF0.m","prach_rxF0",rxsigF[0],N_ZC,1,1); - LOG_M("prach_rxF1.m","prach_rxF1",rxsigF[1],6144,1,1); + LOG_M("prach_rxF0.m", "prach_rxF0", input[0], N_ZC, 1, 1); + LOG_M("prach_rxF1.m", "prach_rxF1", input[1], 6144, 1, 1); } c16_t prachF[dft_sz] __attribute__((aligned(32))); for (int aa = 0; aa < nb_rx; aa++) { // Do componentwise product with Xu* on each antenna for (int offset = 0; offset < N_ZC; offset++) { - prachF[offset] = c16MulConjShift(Xu[offset], rxsigF[aa][offset], 15); + prachF[offset] = c16MulConjShift(Xu[offset], input[aa][offset], 15); } memset(prachF + N_ZC, 0, sizeof(*prachF) * (dft_sz - N_ZC)); // Now do IFFT of size 1024 (N_ZC=839) or 256 (N_ZC=139) @@ -613,11 +604,11 @@ void rx_nr_prach(PHY_VARS_gNB *gNB, for (int i = 0; i < NCS2; i++) { int lev = prach_ifft[preamble_shift2 + i]; int levdB = dB_fixed_times10(lev); - if (levdB > *max_preamble_energy || (levdB == *max_preamble_energy && *max_preamble_delay > i)) { - LOG_D(NR_PHY_RACH, "preamble_index %d, delay %d en %d dB > %d dB\n", preamble_index, i, levdB, *max_preamble_energy); - *max_preamble_energy = levdB; - *max_preamble_delay = i; // Note: This has to be normalized to the 30.72 Ms/s sampling rate - *max_preamble = preamble_index; + if (levdB > out.max_preamble_energy || (levdB == out.max_preamble_energy && out.max_preamble_delay > i)) { + LOG_D(NR_PHY_RACH, "preamble_index %d, delay %d en %d dB > %d dB\n", preamble_index, i, levdB, out.max_preamble_energy); + out.max_preamble_energy = levdB; + out.max_preamble_delay = i; // Note: This has to be normalized to the 30.72 Ms/s sampling rate + out.max_preamble = preamble_index; } } } // preamble_index @@ -637,16 +628,15 @@ void rx_nr_prach(PHY_VARS_gNB *gNB, // Format >3: 2048/2^mu samples @ 30.72 Ms/s, 2048/2^mu * 4 samples @ 122.88 Ms/s // By solving: // max_preamble_delay * ( (2048/2^mu*(fs/30.72M)) / 256 ) / fs = TA * 16 * 64 / 2^mu * Tc - uint16_t *TA = max_preamble_delay; - int mu = fp->numerology_index; - if (cfg->prach_sequence_length.value == 0) { + int mu = in->numerology_index; + if (in->prach_sequence_length == 0) { if (prach_fmt == 0 || prach_fmt == 1 || prach_fmt == 2) - *TA = *TA * 3 * (1 << mu) / 2; + out.max_preamble_delay *= 3 * (1 << mu) / 2; else if (prach_fmt == 3) - *TA = *TA * 3 * (1 << mu) / 8; - } - else *TA = *TA/2; - - stop_meas(&gNB->rx_prach); + out.max_preamble_delay *= 3 * (1 << mu) / 8; + } else + out.max_preamble_delay /= 2; + stop_meas(in->rx_prach); + return out; } diff --git a/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h b/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h index 2cbe1fde77..fd0a36536d 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h +++ b/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h @@ -202,24 +202,14 @@ void nr_fill_ulsch(PHY_VARS_gNB *gNB, prach_item_t *nr_fill_prach(PHY_VARS_gNB *gNB, int SFN, int Slot, nfapi_nr_prach_pdu_t *prach_pdu); -void rx_nr_prach(PHY_VARS_gNB *gNB, - nfapi_nr_prach_pdu_t *prach_pdu, - int frame, - int subframe, - uint16_t *max_preamble, - uint16_t *max_preamble_energy, - uint16_t *max_preamble_delay, - c16_t **rxsigF); +typedef struct rx_prach_out { + uint16_t max_preamble; + uint16_t max_preamble_energy; + uint16_t max_preamble_delay; +} rx_prach_out_t; +rx_prach_out_t rx_nr_prach(const prach_item_t *, int occasion); -void rx_nr_prach_ru(RU_t *ru, - int prach_fmt, - int numRA, - int beam, - int prachStartSymbol, - int prachStartSlot, - int prachOccasion, - int frame, - int subframe); +void rx_nr_prach_ru(prach_item_t *, int32_t **, NR_DL_FRAME_PARMS *frame_parms, int N_TA_offset); void nr_fill_prach_ru(RU_t *ru,prach_item_t * ); prach_item_t *find_nr_prach(prach_list_t *, int frame, int slot, find_type_t type); diff --git a/openair1/PHY/defs_common.h b/openair1/PHY/defs_common.h index b469555354..efaccf2bf7 100644 --- a/openair1/PHY/defs_common.h +++ b/openair1/PHY/defs_common.h @@ -1007,6 +1007,17 @@ typedef struct { int num_slots; // prach duration in slots int beams[NFAPI_MAX_NUM_BG_IF]; nfapi_nr_prach_pdu_t pdu; + int rootSequenceIndex; + int numrootSequenceIndex; + int msg1_frequencystart; + int mu; + int prach_sequence_length; + int restricted_set; + int numerology_index; + int nb_rx; + c16_t ***rxsigF; + c16_t (*Xu)[839]; + time_stats_t *rx_prach; } prach_item_t; typedef struct { diff --git a/openair1/SCHED_NR/fapi_nr_l1.c b/openair1/SCHED_NR/fapi_nr_l1.c index ad6f90e6e8..4ec87a1e5f 100644 --- a/openair1/SCHED_NR/fapi_nr_l1.c +++ b/openair1/SCHED_NR/fapi_nr_l1.c @@ -156,8 +156,12 @@ void nr_schedule_ul_tti_req(PHY_VARS_gNB *gNB, nfapi_nr_ul_tti_request_t *UL_tti nfapi_nr_prach_pdu_t *prach_pdu = &UL_tti_req->pdus_list[i].prach_pdu; LOG_D(NR_PHY_RACH, "Add prach decoding request for %d.%d\n", UL_tti_req->SFN, UL_tti_req->Slot); prach_item_t *prach = nr_fill_prach(gNB, UL_tti_req->SFN, UL_tti_req->Slot, prach_pdu); + if (!prach) + LOG_W(NR_PHY_RACH, "Error in scheduling rach\n"); + /* the present design is not supporting multiple gNB in one RU if (prach && (gNB->RU_list[0]->if_south == LOCAL_RF || gNB->RU_list[0]->if_south == REMOTE_IF5)) nr_fill_prach_ru(gNB->RU_list[0], prach); + */ break; case NFAPI_NR_UL_CONFIG_SRS_PDU_TYPE: LOG_D(NR_PHY, diff --git a/openair1/SCHED_NR/nr_prach_procedures.c b/openair1/SCHED_NR/nr_prach_procedures.c index caaa579ad0..e6cd15b4a9 100644 --- a/openair1/SCHED_NR/nr_prach_procedures.c +++ b/openair1/SCHED_NR/nr_prach_procedures.c @@ -49,16 +49,11 @@ int get_nr_prach_duration(uint8_t prach_format) void L1_nr_prach_procedures(PHY_VARS_gNB *gNB, int frame, int slot, nfapi_nr_rach_indication_t *rach_ind) { - uint16_t max_preamble[4]={0},max_preamble_energy[4]={0},max_preamble_delay[4]={0}; - - RU_t *ru; VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_PRACH_RX,1); rach_ind->sfn = frame; rach_ind->slot = slot; rach_ind->number_of_pdus = 0; - ru=gNB->RU_list[0]; - prach_item_t *prach_id = find_nr_prach(&gNB->prach_list, frame, slot, SEARCH_EXIST); if (!prach_id) { return; @@ -74,11 +69,7 @@ void L1_nr_prach_procedures(PHY_VARS_gNB *gNB, int frame, int slot, nfapi_nr_rac // comment FK: the standard 38.211 section 5.3.2 has one extra term +14*N_RA_slot. This is because there prachStartSymbol is // given wrt to start of the 15kHz slot or 60kHz slot. Here we work slot based, so this function is anyway only called in slots // where there is PRACH. Its up to the MAC to schedule another PRACH PDU in the case there are there N_RA_slot \in {0,1}. - - c16_t *rxsigF[ru->nb_rx]; - for (int i = 0; i < ru->nb_rx; ++i) - rxsigF[i] = (c16_t *)ru->prach_rxsigF[prach_oc][i]; - rx_nr_prach(gNB, prach_pdu, frame, slot, max_preamble, max_preamble_energy, max_preamble_delay, rxsigF); + rx_prach_out_t res = rx_nr_prach(prach_id, prach_oc); LOG_D(NR_PHY, "[RAPROC] Frame %d, slot %d, occasion %d (prachStartSymbol %d) : Most likely preamble %d, energy %d.%d dB delay %d " "(prach_energy counter %d)\n", @@ -86,26 +77,26 @@ void L1_nr_prach_procedures(PHY_VARS_gNB *gNB, int frame, int slot, nfapi_nr_rac slot, prach_oc, prachStartSymbol, - max_preamble[0], - max_preamble_energy[0] / 10, - max_preamble_energy[0] % 10, - max_preamble_delay[0], + res.max_preamble, + res.max_preamble_energy / 10, + res.max_preamble_energy % 10, + res.max_preamble_delay, gNB->prach_energy_counter); if ((gNB->prach_energy_counter == NUM_PRACH_RX_FOR_NOISE_ESTIMATE) - && (max_preamble_energy[0] > gNB->measurements.prach_I0 + gNB->prach_thres) + && (res.max_preamble_energy > gNB->measurements.prach_I0 + gNB->prach_thres) && (rach_ind->number_of_pdus < MAX_NUM_NR_RX_RACH_PDUS)) { LOG_A(NR_PHY, "[RAPROC] %d.%d Initiating RA procedure with preamble %d, energy %d.%d dB (I0 %d, thres %d), delay %d start symbol " "%u freq index %u\n", frame, prach_start_slot, - max_preamble[0], - max_preamble_energy[0] / 10, - max_preamble_energy[0] % 10, + res.max_preamble, + res.max_preamble_energy / 10, + res.max_preamble_energy % 10, gNB->measurements.prach_I0, gNB->prach_thres, - max_preamble_delay[0], + res.max_preamble_delay, prachStartSymbol, prach_pdu->num_ra); @@ -113,9 +104,9 @@ void L1_nr_prach_procedures(PHY_VARS_gNB *gNB, int frame, int slot, nfapi_nr_rac T_INT(gNB->Mod_id), T_INT(frame), T_INT(slot), - T_INT(max_preamble[0]), - T_INT(max_preamble_energy[0]), - T_INT(max_preamble_delay[0])); + T_INT(res.max_preamble), + T_INT(res.max_preamble_energy), + T_INT(res.max_preamble_delay)); nfapi_nr_prach_indication_pdu_t *ind = rach_ind->pdu_list + rach_ind->number_of_pdus; *ind = (nfapi_nr_prach_indication_pdu_t){ @@ -123,14 +114,14 @@ void L1_nr_prach_procedures(PHY_VARS_gNB *gNB, int frame, int slot, nfapi_nr_rac .symbol_index = prachStartSymbol, .slot_index = slot, .freq_index = prach_pdu->num_ra, - .avg_rssi = (max_preamble_energy[0] < 631) ? (128 + (max_preamble_energy[0] / 5)) : 254, + .avg_rssi = (res.max_preamble_energy < 631) ? (128 + (res.max_preamble_energy / 5)) : 254, .avg_snr = 0xff, // invalid for now .num_preamble = 1, .preamble_list = { - {.preamble_index = max_preamble[0], .timing_advance = max_preamble_delay[0], .preamble_pwr = 0xffffffff}}}; + {.preamble_index = res.max_preamble, .timing_advance = res.max_preamble_delay, .preamble_pwr = 0xffffffff}}}; rach_ind->number_of_pdus++; } - gNB->measurements.prach_I0 = ((gNB->measurements.prach_I0 * 900) >> 10) + ((max_preamble_energy[0] * 124) >> 10); + gNB->measurements.prach_I0 = ((gNB->measurements.prach_I0 * 900) >> 10) + ((res.max_preamble_energy * 124) >> 10); if (frame == 0) LOG_I(PHY, "prach_I0 = %d.%d dB\n", gNB->measurements.prach_I0 / 10, gNB->measurements.prach_I0 % 10); if (gNB->prach_energy_counter < NUM_PRACH_RX_FOR_NOISE_ESTIMATE) diff --git a/openair1/SIMULATION/NR_PHY/prachsim.c b/openair1/SIMULATION/NR_PHY/prachsim.c index e5f64fff5d..7d87ac54a7 100644 --- a/openair1/SIMULATION/NR_PHY/prachsim.c +++ b/openair1/SIMULATION/NR_PHY/prachsim.c @@ -135,10 +135,11 @@ int main(int argc, char **argv){ double **s_re, **s_im, **r_re, **r_im, iqim = 0.0, delay_avg = 0, ue_speed = 0, fs=-1, bw; int i, l, aa, aarx, trial, n_frames = 1, rx_prach_start; //, ntrials=1; c16_t **txdata; - int N_RB_UL = 106, delay = 0, NCS_config = 13, rootSequenceIndex = 1, threequarter_fs = 0, mu = 1, fd_occasion = 0, loglvl = OAILOG_INFO, numRA = 0, prachStartSymbol = 0; + int N_RB_UL = 106, delay = 0, NCS_config = 13, rootSequenceIndex = 1, threequarter_fs = 0, mu = 1, fd_occasion = 0, + loglvl = OAILOG_INFO; uint8_t snr1set = 0, ue_speed1set = 0, transmission_mode = 1, n_tx = 1, n_rx = 1, awgn_flag = 0, msg1_frequencystart = 0, num_prach_fd_occasions = 1, prach_format=0; uint8_t config_index = 98, prach_sequence_length = 1, restrictedSetConfig = 0; - uint16_t Nid_cell = 0, preamble_tx = 0, preamble_delay, format0, format1; + uint16_t Nid_cell = 0, preamble_tx = 0, format0, format1; uint32_t tx_lev = 10000, prach_errors = 0; //,tx_lev_dB; uint64_t SSB_positions = 0x01; uint16_t RA_sfn_index; @@ -714,9 +715,17 @@ int main(int argc, char **argv){ } rx_prach_start = subframe*frame_parms->samples_per_subframe; - if (n_frames==1) printf("slot %d, rx_prach_start %d\n",slot,rx_prach_start); - uint16_t preamble_rx, preamble_energy; + if (n_frames == 1) + printf("slot %d, rx_prach_start %d\n", slot, rx_prach_start); + c16_t **rxsigF[NUMBER_OF_NR_RU_PRACH_OCCASIONS_MAX]; + for (int j = 0; j < NUMBER_OF_NR_RU_PRACH_OCCASIONS_MAX; j++) { + rxsigF[j] = malloc(ru->nb_rx * sizeof(*rxsigF)); + for (int i = 0; i < ru->nb_rx; i++) { + // largest size for PRACH FFT is 4x98304 (16*24576) + rxsigF[j][i] = malloc16_clear(4 * 98304 * sizeof(**rxsigF)); + } + } for (SNR = snr0; SNR < snr1 && !stop; SNR += .1) { for (ue_speed = ue_speed0; ue_speed < ue_speed1 && !stop; ue_speed += 10) { @@ -727,8 +736,7 @@ int main(int argc, char **argv){ prach_errors=0; for (trial = 0; trial < n_frames && !stop; trial++) { - - if (input_fd==NULL) { + if (input_fd == NULL) { sigma2_dB = 10*log10((double)tx_lev) - SNR - 10*log10(N_RB_UL*12/N_ZC); if (n_frames==1) @@ -755,52 +763,72 @@ int main(int argc, char **argv){ tmp->i = (short)(.167 * (r_im[aa][i] + (iqim * r_re[aa][i]) + sqrt(sigma2 / 2) * gaussdouble(0.0, 1.0))); } } - } else { - n_bytes = fread(&ru->common.rxdata[0][rx_prach_start],sizeof(int32_t),frame_parms->samples_per_subframe,input_fd); - printf("fread %d bytes from file %s\n",n_bytes,input_file); - if (n_bytes!=frame_parms->samples_per_subframe) { - printf("expected %d bytes\n",frame_parms->samples_per_subframe); - exit(-1); - } - } + } else { + n_bytes = fread(&ru->common.rxdata[0][rx_prach_start], sizeof(int32_t), frame_parms->samples_per_subframe, input_fd); + printf("fread %d bytes from file %s\n", n_bytes, input_file); + if (n_bytes != frame_parms->samples_per_subframe) { + printf("expected %d bytes\n", frame_parms->samples_per_subframe); + exit(-1); + } + } - for (l = 0; l < frame_parms->symbols_per_slot; l++) { - for (aa = 0; aa < frame_parms->nb_antennas_rx; aa++) { - nr_slot_fep_ul(frame_parms, ru->common.rxdata[aa], ru->common.rxdataF[aa], l, slot, ru->N_TA_offset); - } - } - rx_nr_prach_ru(ru, prach_format, numRA, 0, prachStartSymbol, slot, prachOccasion, frame, slot); - c16_t *rxsigF[ru->nb_rx]; - for (int i = 0; i < ru->nb_rx; ++i) - rxsigF[i] = (c16_t *)ru->prach_rxsigF[prachOccasion][i]; - if (n_frames == 1) - LOG_I(PHY, - "ncs %d,num_seq %d\n", - prach_pdu->num_cs, - prach_config->num_prach_fd_occasions_list[fd_occasion].num_root_sequences.value); - rx_nr_prach(gNB, prach_pdu, frame, subframe, &preamble_rx, &preamble_energy, &preamble_delay, rxsigF); + for (l = 0; l < frame_parms->symbols_per_slot; l++) { + for (aa = 0; aa < frame_parms->nb_antennas_rx; aa++) { + nr_slot_fep_ul(frame_parms, ru->common.rxdata[aa], ru->common.rxdataF[aa], l, slot, ru->N_TA_offset); + } + } - // printf(" preamble_energy %d preamble_rx %d preamble_tx %d \n", preamble_energy, preamble_rx, preamble_tx); + nfapi_nr_prach_config_t *cfg = &gNB->gNB_config.prach_config; + nfapi_nr_num_prach_fd_occasions_t *occ = &cfg->num_prach_fd_occasions_list[prach_pdu->num_ra]; + prach_pdu->num_prach_ocas=1; + prach_item_t in = {.frame = frame, + .slot = slot, + .pdu = *prach_pdu, + .rootSequenceIndex = occ->prach_root_sequence_index.value, + .numrootSequenceIndex = occ->num_root_sequences.value, + .msg1_frequencystart = occ->k1.value, + .mu = cfg->prach_sub_c_spacing.value, + .prach_sequence_length = cfg->prach_sequence_length.value, + .restricted_set = cfg->restricted_set_config.value, + .numerology_index = gNB->frame_parms.numerology_index, + .nb_rx = gNB->gNB_config.carrier_config.num_rx_ant.value, + .rxsigF = rxsigF, + .Xu = gNB->X_u, + .rx_prach = &gNB->rx_prach}; + rx_nr_prach_ru(&in, ru->common.rxdata, ru->nr_frame_parms, ru->N_TA_offset); + if (n_frames == 1) + LOG_I(PHY, + "ncs %d,num_seq %d\n", + prach_pdu->num_cs, + prach_config->num_prach_fd_occasions_list[fd_occasion].num_root_sequences.value); + rx_prach_out_t out = rx_nr_prach(&in, prachOccasion); - if (preamble_rx != preamble_tx) - prach_errors++; - else - delay_avg += (double)preamble_delay; + // printf(" preamble_energy %d preamble_rx %d preamble_tx %d \n", out.max_preamble_energy, out.max_preamble, + // preamble_tx); - N_ZC = (prach_sequence_length) ? 139 : 839; + if (out.max_preamble != preamble_tx) + prach_errors++; + else + delay_avg += (double)out.max_preamble_delay; - if (n_frames == 1) { - printf("preamble %d (tx %d) : energy %d, delay %d\n", preamble_rx, preamble_tx, preamble_energy, preamble_delay); + N_ZC = (prach_sequence_length) ? 139 : 839; + + if (n_frames == 1) { + printf("preamble %d (tx %d) : energy %d, delay %d\n", + out.max_preamble, + preamble_tx, + out.max_preamble_energy, + out.max_preamble_delay); #ifdef NR_PRACH_DEBUG LOG_M("prach0.m","prach0", &txdata[0][prach_start], frame_parms->samples_per_subframe, 1, 1); LOG_M("rxsig0.m","rxs0", &ru->common.rxdata[0][subframe*frame_parms->samples_per_subframe], frame_parms->samples_per_subframe, 1, 1); LOG_M("ru_rxsig0.m","rxs0", &ru->common.rxdata[0][subframe*frame_parms->samples_per_subframe], frame_parms->samples_per_subframe, 1, 1); LOG_M("ru_rxsigF0.m","rxsF0", ru->common.rxdataF[0], frame_parms->ofdm_symbol_size*frame_parms->symbols_per_slot, 1, 1); - LOG_M("ru_prach_rxsigF0.m","rxsF0", ru->prach_rxsigF[0][0], N_ZC, 1, 1); + LOG_M("ru_prach_rxsigF0.m", "rxsF0", rxsigF[0][0], N_ZC, 1, 1); LOG_M("prach_preamble.m","prachp", &gNB->X_u[0], N_ZC, 1, 1); LOG_M("ue_prach_preamble.m","prachp", &UE->X_u[0], N_ZC, 1, 1); #endif - } + } } printf("SNR %f dB, UE Speed %f km/h: errors %u/%d (delay %f)\n", SNR, ue_speed, prach_errors, n_frames, delay_avg/(double)(n_frames-prach_errors)); @@ -817,7 +845,13 @@ int main(int argc, char **argv){ if (input_fd) break; } //SNR loop - + for (int j = 0; j < NUMBER_OF_NR_RU_PRACH_OCCASIONS_MAX; j++) { + for (int i = 0; i < ru->nb_rx; i++) { + // largest size for PRACH FFT is 4x98304 (16*24576) + free(rxsigF[j][i]); + } + free(rxsigF[j]); + } free_channel_desc_scm(UE2gNB); nr_phy_free_RU(ru); diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c index 88c9c875ea..198975f1ae 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c @@ -1430,7 +1430,12 @@ static void nr_generate_Msg2(module_id_t module_idP, scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.ra_ResponseWindow; const int n_slots_frame = nr_mac->frame_structure.numb_slots_frame; if (!msg2_in_response_window(ra->preamble_frame, ra->preamble_slot, n_slots_frame, rrc_ra_ResponseWindow, frameP, slotP)) { - LOG_E(NR_MAC, "UE RA-RNTI %04x TC-RNTI %04x: exceeded RA window, cannot schedule Msg2\n", ra->RA_rnti, UE->rnti); + LOG_E(NR_MAC, + "sfn: %d.%d UE RA-RNTI %04x TC-RNTI %04x: exceeded RA window, cannot schedule Msg2\n", + frameP, + slotP, + ra->RA_rnti, + UE->rnti); nr_release_ra_UE(nr_mac, UE->rnti); return; } From fff95cc07580d588cb7411d1f5f4fe51fff1d1a1 Mon Sep 17 00:00:00 2001 From: Laurent THOMAS Date: Wed, 29 Oct 2025 15:20:36 +0100 Subject: [PATCH 41/69] Refactor rx_nr_prach --- openair1/PHY/NR_TRANSPORT/nr_prach.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/openair1/PHY/NR_TRANSPORT/nr_prach.c b/openair1/PHY/NR_TRANSPORT/nr_prach.c index 0bdb538f20..101bd76463 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_prach.c +++ b/openair1/PHY/NR_TRANSPORT/nr_prach.c @@ -409,7 +409,6 @@ void rx_nr_prach_ru(prach_item_t *p, int32_t **rxdata, NR_DL_FRAME_PARMS *fp, in rx_prach_out_t rx_nr_prach(const prach_item_t *in, int occasion) { rx_prach_out_t out = {}; - c16_t **input = in->rxsigF[occasion]; uint16_t preamble_index0 = 0; uint16_t numshift = 0; int first_nonzero_root_idx = 0; @@ -453,7 +452,7 @@ rx_prach_out_t rx_nr_prach(const prach_item_t *in, int occasion) int32_t prach_ifft[dft_sz] __attribute__((aligned(32))); for (int preamble_index = 0; preamble_index < 64; preamble_index++) { if (LOG_DEBUGFLAG(DEBUG_PRACH)) { - int en = dB_fixed(signal_energy((int32_t *)input[0], N_ZC == 839 ? 840 : 140)); + int en = dB_fixed(signal_energy((int32_t *)in->rxsigF[occasion][0], N_ZC == 839 ? 840 : 140)); if (en > 60) LOG_D(PHY, "frame %d, slot %d : Trying preamble %d \n", in->frame, in->slot, preamble_index); } @@ -527,9 +526,9 @@ rx_prach_out_t rx_nr_prach(const prach_item_t *in, int occasion) first_nonzero_root_idx = preamble_offset; } - // Compute DFT of RX signal (conjugate input, results in conjugate output) for each new rootSequenceIndex + // Compute DFT of RX signal (conjugate in->rxsigF[occasion], results in conjugate output) for each new rootSequenceIndex if (LOG_DEBUGFLAG(DEBUG_PRACH)) { - int en = dB_fixed(signal_energy((int32_t *)input[0], 840)); + int en = dB_fixed(signal_energy((int32_t *)in->rxsigF[occasion][0], 840)); if (en>60) LOG_D(PHY, "frame %d, slot %d : preamble index %d, NCS %d, N_ZC/NCS %d: offset %d, preamble shift %d , en %d)\n", @@ -558,14 +557,14 @@ rx_prach_out_t rx_nr_prach(const prach_item_t *in, int occasion) memset(prach_ifft, 0, sizeof(prach_ifft)); if (LOG_DUMPFLAG(DEBUG_PRACH)) { - LOG_M("prach_rxF0.m", "prach_rxF0", input[0], N_ZC, 1, 1); - LOG_M("prach_rxF1.m", "prach_rxF1", input[1], 6144, 1, 1); + LOG_M("prach_rxF0.m", "prach_rxF0", in->rxsigF[occasion][0], N_ZC, 1, 1); + LOG_M("prach_rxF1.m", "prach_rxF1", in->rxsigF[occasion][1], 6144, 1, 1); } c16_t prachF[dft_sz] __attribute__((aligned(32))); for (int aa = 0; aa < nb_rx; aa++) { // Do componentwise product with Xu* on each antenna for (int offset = 0; offset < N_ZC; offset++) { - prachF[offset] = c16MulConjShift(Xu[offset], input[aa][offset], 15); + prachF[offset] = c16MulConjShift(Xu[offset], in->rxsigF[occasion][aa][offset], 15); } memset(prachF + N_ZC, 0, sizeof(*prachF) * (dft_sz - N_ZC)); // Now do IFFT of size 1024 (N_ZC=839) or 256 (N_ZC=139) From 32889870b3657a2a45e1a828d20231b68b0c9a97 Mon Sep 17 00:00:00 2001 From: Jaroslava Fiedlerova Date: Thu, 30 Oct 2025 13:37:15 +0100 Subject: [PATCH 42/69] CI: Adjust attenutation for HO setup --- ci-scripts/xml_files/container_sa_f1_ho_b210_quectel.xml | 4 ++-- ci-scripts/xml_files/container_sa_n2_ho_b210_quectel.xml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) 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 77b2312409..07a5c5f401 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 @@ -93,7 +93,7 @@ Custom_Command Set attenuator to 0 for DU0 and 17 for DU1 rocket - python3 %%workspace%%/ci-scripts/attenuatorctl.py -r 1,2 0 -r 3,4 17 -d 5 + python3 %%workspace%%/ci-scripts/attenuatorctl.py -s 1,2 0 -s 3,4 25 @@ -168,7 +168,7 @@ Custom_Command Attenuate DU1 by 17dB and remove attenuation on DU0 to trigger Handover rocket - python3 %%workspace%%/ci-scripts/attenuatorctl.py -r 1,2 0 -r 3,4 17 -d 5 + python3 %%workspace%%/ci-scripts/attenuatorctl.py -r 1,2 0 -r 3,4 25 -d 5 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 b67522b220..46707f70b4 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 @@ -87,7 +87,7 @@ Custom_Command Set initial attenuation on target gNB rocket - python3 %%workspace%%/ci-scripts/attenuatorctl.py -s 1,2 0 -s 3,4 15 + python3 %%workspace%%/ci-scripts/attenuatorctl.py -s 1,2 0 -s 3,4 25 @@ -154,7 +154,7 @@ Custom_Command Gradually attenuate gNB-PCI0 (ch1-2=0dB) and gNB-PCI1 (ch3-4=15dB) over 5s to trigger N2 Handover back to gNB-PCI0 rocket - python3 %%workspace%%/ci-scripts/attenuatorctl.py -r 1,2 0 -r 3,4 15 -d 5 + python3 %%workspace%%/ci-scripts/attenuatorctl.py -r 1,2 0 -r 3,4 25 -d 5 From 09e1e6c6fdb3bc4fa4b0d4cfdeb175b874e093cc Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Fri, 17 Oct 2025 11:53:20 +0200 Subject: [PATCH 43/69] Rewrite NR_MAC UE_iterator() to limit variable scope Especially in pf_dl()/pf_ul(), we use a first loop using UE_iterator(), then iterate over a subset of UEs. It has happened a couple of times that I was using variable "UE" (from the iterator), when it should only be used in the first UE_iterator() loop. Rewrite UE_iterator() to effectively limit the scope of the iterator variables to the body of the UE_iterator. This should also make it possible to reuse multiple UE_iterator()s with the same variables in sequence. --- openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h index 5bd786df90..f64b94fb47 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h +++ b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h @@ -819,7 +819,7 @@ typedef struct { nr_beam_mode_t beam_mode; } NR_beam_info_t; -#define UE_iterator(BaSe, VaR) NR_UE_info_t ** VaR##pptr=BaSe, *VaR; while ((VaR=*(VaR##pptr++))) +#define UE_iterator(BaSe, VaR) for (NR_UE_info_t **VaR##pptr=BaSe, *VaR=*VaR##pptr; VaR; VaR=*(++VaR##pptr)) typedef struct { /// current frame for DCI From 2f636037eec62b8217e6d2b2a60df48bfbacc0b6 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Wed, 15 Oct 2025 15:42:00 +0200 Subject: [PATCH 44/69] Fixup: compute_PDU_length() --- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c index 8a81d8ae4f..540e2c6291 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c @@ -747,10 +747,10 @@ static void other_sib_sched_control(module_id_t module_idP, // Data to be transmitted memcpy(tx_req->TLVs[0].value.direct, sib_bcch_pdu, sched_pdsch_otherSI.tb_size); - tx_req->PDU_length = sched_pdsch_otherSI.tb_size; tx_req->PDU_index = pdu_index; tx_req->num_TLV = 1; - tx_req->TLVs[0].length = sched_pdsch_otherSI.tb_size + 2; + tx_req->TLVs[0].length = sched_pdsch_otherSI.tb_size; + tx_req->PDU_length = compute_PDU_length(tx_req->num_TLV, tx_req->TLVs[0].length); TX_req->Number_of_PDUs++; TX_req->SFN = frame; TX_req->Slot = slot; From ce744fd24f8eb35f5a1fb1e3d51dc29f91fb0463 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 21 Aug 2025 19:23:29 +0200 Subject: [PATCH 45/69] Refactor DLSCH post processor into post_process_dlsch() Introduce a struct with information on FAPI structures to save resource and data allocation into. It's in nr_mac_gNB.h because the next commits will reuse this for all preprocessors. --- .../LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c | 731 +++++++++--------- openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h | 11 + 2 files changed, 383 insertions(+), 359 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c index 44c9072a15..7fe346ab7d 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c @@ -641,6 +641,11 @@ static void pf_dl(module_id_t module_id, const uint32_t b = UE->mac_stats.dl.current_bytes; UE->dl_thr_ue = (1 - a) * UE->dl_thr_ue + a * b; + /* Check if this UE should get TA (every 100 frames). If we add the CE, + * ta_apply will be reset */ + if (frame == ((sched_ctrl->ta_frame + 100) % 1024)) + sched_ctrl->ta_apply = true; + int total_rem_ues = 0; for (int i = 0; i < num_beams; i++) total_rem_ues += remainUEs[i]; @@ -1010,6 +1015,370 @@ nfapi_nr_dl_tti_pdsch_pdu_rel15_t *prepare_pdsch_pdu(nfapi_nr_dl_tti_request_pdu return pdsch_pdu; } +void post_process_dlsch(gNB_MAC_INST *nr_mac, post_process_pdsch_t *pdsch, NR_UE_info_t *UE, NR_sched_pdsch_t *sched_pdsch) +{ + int CC_id = 0; + int module_id = 0; + frame_t frame = pdsch->frame; + slot_t slot = pdsch->slot; + + const NR_ServingCellConfigCommon_t *scc = nr_mac->common_channels[CC_id].ServingCellConfigCommon; + NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; + NR_UE_DL_BWP_t *current_BWP = &UE->current_DL_BWP; + + const rnti_t rnti = UE->rnti; + + /* POST processing */ + const uint8_t nrOfLayers = sched_pdsch->nrOfLayers; + const uint32_t TBS = sched_pdsch->tb_size; + int8_t current_harq_pid = sched_pdsch->dl_harq_pid; + + if (current_harq_pid < 0) { + /* PP has not selected a specific HARQ Process, get a new one */ + current_harq_pid = sched_ctrl->available_dl_harq.head; + AssertFatal(current_harq_pid >= 0, + "no free HARQ process available for UE %04x\n", + UE->rnti); + remove_front_nr_list(&sched_ctrl->available_dl_harq); + sched_pdsch->dl_harq_pid = current_harq_pid; + } else { + /* PP selected a specific HARQ process. Check whether it will be a new + * transmission or a retransmission, and remove from the corresponding + * list */ + if (sched_ctrl->harq_processes[current_harq_pid].round == 0) + remove_nr_list(&sched_ctrl->available_dl_harq, current_harq_pid); + else + remove_nr_list(&sched_ctrl->retrans_dl_harq, current_harq_pid); + } + + NR_tda_info_t *tda_info = &sched_pdsch->tda_info; + NR_pdsch_dmrs_t *dmrs_parms = &sched_pdsch->dmrs_parms; + NR_UE_harq_t *harq = &sched_ctrl->harq_processes[current_harq_pid]; + NR_sched_pucch_t *pucch = NULL; + DevAssert(!harq->is_waiting); + if (sched_pdsch->pucch_allocation < 0) { + finish_nr_dl_harq(sched_ctrl, current_harq_pid); + } else { + pucch = &sched_ctrl->sched_pucch[sched_pdsch->pucch_allocation]; + add_tail_nr_list(&sched_ctrl->feedback_dl_harq, current_harq_pid); + harq->feedback_frame = pucch->frame; + harq->feedback_slot = pucch->ul_slot; + harq->is_waiting = true; + } + UE->mac_stats.dl.rounds[harq->round]++; + LOG_D(NR_MAC, + "%4d.%2d [DLSCH/PDSCH/PUCCH] RNTI %04x DCI L %d start %3d RBs %3d startSymbol %2d nb_symbol %2d dmrspos %x MCS %2d nrOfLayers %d TBS %4d HARQ PID %2d round %d RV %d NDI %d dl_data_to_ULACK %d (%d.%d) PUCCH allocation %d TPC %d\n", + frame, + slot, + rnti, + sched_ctrl->aggregation_level, + sched_pdsch->rbStart, + sched_pdsch->rbSize, + tda_info->startSymbolIndex, + tda_info->nrOfSymbols, + dmrs_parms->dl_dmrs_symb_pos, + sched_pdsch->mcs, + nrOfLayers, + TBS, + current_harq_pid, + harq->round, + nr_get_rv(harq->round % 4), + harq->ndi, + pucch ? pucch->timing_indicator : 0, + pucch ? pucch->frame : 0, + pucch ? pucch->ul_slot : 0, + sched_pdsch->pucch_allocation, + sched_ctrl->tpc1); + + const int bwp_id = current_BWP->bwp_id; + const int coresetid = sched_ctrl->coreset->controlResourceSetId; + + /* look up the PDCCH PDU for this CC, BWP, and CORESET. If it does not exist, create it */ + nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu = nr_mac->pdcch_pdu_idx[CC_id][coresetid]; + + if (!pdcch_pdu) { + LOG_D(NR_MAC, "creating pdcch pdu, pdcch_pdu = NULL. \n"); + nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdcch_pdu = &pdsch->dl_req->dl_tti_pdu_list[pdsch->dl_req->nPDUs]; + memset(dl_tti_pdcch_pdu, 0, sizeof(nfapi_nr_dl_tti_request_pdu_t)); + dl_tti_pdcch_pdu->PDUType = NFAPI_NR_DL_TTI_PDCCH_PDU_TYPE; + dl_tti_pdcch_pdu->PDUSize = (uint8_t)(2+sizeof(nfapi_nr_dl_tti_pdcch_pdu)); + pdsch->dl_req->nPDUs += 1; + pdcch_pdu = &dl_tti_pdcch_pdu->pdcch_pdu.pdcch_pdu_rel15; + LOG_D(NR_MAC,"Trying to configure DL pdcch for UE %04x, bwp %d, cs %d\n", UE->rnti, bwp_id, coresetid); + NR_ControlResourceSet_t *coreset = sched_ctrl->coreset; + nr_configure_pdcch(pdcch_pdu, coreset, &sched_ctrl->sched_pdcch); + nr_mac->pdcch_pdu_idx[CC_id][coresetid] = pdcch_pdu; + } + + nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdsch_pdu = &pdsch->dl_req->dl_tti_pdu_list[pdsch->dl_req->nPDUs]; + memset(dl_tti_pdsch_pdu, 0, sizeof(nfapi_nr_dl_tti_request_pdu_t)); + dl_tti_pdsch_pdu->PDUType = NFAPI_NR_DL_TTI_PDSCH_PDU_TYPE; + dl_tti_pdsch_pdu->PDUSize = (uint8_t)(2 + sizeof(nfapi_nr_dl_tti_pdsch_pdu)); + pdsch->dl_req->nPDUs += 1; + + /* SCF222: PDU index incremented for each PDSCH PDU sent in TX control + * message. This is used to associate control information to data and is + * reset every slot. */ + const int pduindex = nr_mac->pdu_index[CC_id]++; + // TODO: verify the case where maxMIMO_Layers is NULL, in which case + // in principle maxMIMO_layers should be given by the maximum number of layers + // for PDSCH supported by the UE for the serving cell (5.4.2.1 of 38.212) + long maxMIMO_Layers = UE->sc_info.maxMIMO_Layers_PDSCH ? *UE->sc_info.maxMIMO_Layers_PDSCH : 1; + const int nl_tbslbrm = min(maxMIMO_Layers, 4); + nfapi_nr_dl_tti_pdsch_pdu_rel15_t *pdsch_pdu = prepare_pdsch_pdu(dl_tti_pdsch_pdu, + nr_mac, + UE, + sched_pdsch, + current_BWP->pdsch_Config, + false, + harq->round, + rnti, + UE->UE_beam_index, + nl_tbslbrm, + pduindex); + + + LOG_D(NR_MAC,"Configuring DCI/PDCCH in %d.%d at CCE %d, rnti %x\n", frame,slot,sched_ctrl->cce_index,rnti); + /* Fill PDCCH DL DCI PDU */ + nfapi_nr_dl_dci_pdu_t *dci_pdu = prepare_dci_pdu(pdcch_pdu, + scc, + sched_ctrl->search_space, + sched_ctrl->coreset, + sched_ctrl->aggregation_level, + sched_ctrl->cce_index, + UE->UE_beam_index, + rnti); + pdcch_pdu->numDlDci++; + + /* DCI payload */ + const int rnti_type = TYPE_C_RNTI_; + dci_pdu_rel15_t dci_payload = prepare_dci_dl_payload(nr_mac, + UE, + rnti_type, + sched_ctrl->search_space->searchSpaceType->present, + pdsch_pdu, + sched_pdsch, + pucch, + current_harq_pid, + 0, + false); + + // Reset TPC to 0 dB to not request new gain multiple times before computing new value for SNR + sched_ctrl->tpc1 = 1; + NR_PDSCH_Config_t *pdsch_Config = current_BWP->pdsch_Config; + AssertFatal(pdsch_Config == NULL + || pdsch_Config->resourceAllocation == NR_PDSCH_Config__resourceAllocation_resourceAllocationType1, + "Only frequency resource allocation type 1 is currently supported\n"); + + LOG_D(NR_MAC, + "%4d.%2d DCI type 1 payload: freq_alloc %d (%d,%d,%d), " + "nrOfLayers %d, time_alloc %d, vrb to prb %d, mcs %d tb_scaling %d ndi %d rv %d tpc %d ti %d\n", + frame, + slot, + dci_payload.frequency_domain_assignment.val, + pdsch_pdu->rbStart, + pdsch_pdu->rbSize, + pdsch_pdu->BWPSize, + pdsch_pdu->nrOfLayers, + dci_payload.time_domain_assignment.val, + dci_payload.vrb_to_prb_mapping.val, + dci_payload.mcs, + dci_payload.tb_scaling, + dci_payload.ndi, + dci_payload.rv, + dci_payload.tpc, + pucch ? pucch->timing_indicator : 0); + + fill_dci_pdu_rel15(&UE->sc_info, + current_BWP, + &UE->current_UL_BWP, + dci_pdu, + &dci_payload, + current_BWP->dci_format, + rnti_type, + bwp_id, + sched_ctrl->search_space, + sched_ctrl->coreset, + UE->pdsch_HARQ_ACK_Codebook, + nr_mac->cset0_bwp_size); + + LOG_D(NR_MAC, + "coreset params: FreqDomainResource %llx, start_symbol %d n_symb %d\n", + (unsigned long long)pdcch_pdu->FreqDomainResource, + pdcch_pdu->StartSymbolIndex, + pdcch_pdu->DurationSymbols); + + if (harq->round != 0) { /* retransmission */ + /* we do not have to do anything, since we do not require to get data + * from RLC or encode MAC CEs. The TX_req structure is filled below + * or copy data to FAPI structures */ + LOG_D(NR_MAC, + "%d.%2d DL retransmission RNTI %04x HARQ PID %d round %d NDI %d\n", + frame, + slot, + rnti, + current_harq_pid, + harq->round, + harq->ndi); + if (!get_softmodem_params()->phy_test) + AssertFatal(harq->sched_pdsch.tb_size == TBS, + "UE %04x mismatch between scheduled TBS and buffered TB for HARQ PID %d\n", + UE->rnti, + current_harq_pid); + else if (harq->sched_pdsch.tb_size != TBS) + LOG_E(NR_MAC, + "Mismatch between scheduled TBS and buffered TB for HARQ PID %d. No RTX control in phy-test mode. " + "Possible causes: presence of CSI-RS or DLSCH scheduled in the mixed slot.\n", + current_harq_pid); + T(T_GNB_MAC_RETRANSMISSION_DL_PDU_WITH_DATA, T_INT(module_id), T_INT(CC_id), T_INT(rnti), + T_INT(frame), T_INT(slot), T_INT(current_harq_pid), T_INT(harq->round), T_BUFFER(harq->transportBlock.buf, TBS)); + UE->mac_stats.dl.total_rbs_retx += sched_pdsch->rbSize; + nr_mac->mac_stats.used_prb_aggregate += sched_pdsch->rbSize; + } else { /* initial transmission */ + LOG_D(NR_MAC, "Initial HARQ transmission in %d.%d\n", frame, slot); + uint8_t *buf = allocate_transportBlock_buffer(&harq->transportBlock, TBS); + /* first, write all CEs that might be there */ + int written = nr_write_ce_dlsch_pdu(module_id, + sched_ctrl, + (unsigned char *)buf, + 255, // no drx + NULL); // contention res id + buf += written; + uint8_t *bufEnd = buf + TBS - written; + DevAssert(TBS > written); + int dlsch_total_bytes = 0; + /* next, get RLC data */ + start_meas(&nr_mac->rlc_data_req); + int sdus = 0; + + if (sched_ctrl->num_total_bytes > 0) { + /* loop over all activated logical channels */ + for (int i = 0; i < seq_arr_size(&sched_ctrl->lc_config); ++i) { + const nr_lc_config_t *c = seq_arr_at(&sched_ctrl->lc_config, i); + const int lcid = c->lcid; + + if (sched_ctrl->rlc_status[lcid].bytes_in_buffer == 0) + continue; // no data for this LC tbs_size_t len = 0; + + int lcid_bytes=0; + while (bufEnd-buf > sizeof(NR_MAC_SUBHEADER_LONG) + 1 ) { + // we do not know how much data we will get from RLC, i.e., whether it + // will be longer than 256B or not. Therefore, reserve space for long header, then + // fetch data, then fill real length + NR_MAC_SUBHEADER_LONG *header = (NR_MAC_SUBHEADER_LONG *) buf; + /* limit requested number of bytes to what preprocessor specified, or + * such that TBS is full */ + const rlc_buffer_occupancy_t ndata = min(sched_ctrl->rlc_status[lcid].bytes_in_buffer, + bufEnd-buf-sizeof(NR_MAC_SUBHEADER_LONG)); + tbs_size_t len = nr_mac_rlc_data_req(module_id, + rnti, + true, + lcid, + ndata, + (char *)buf+sizeof(NR_MAC_SUBHEADER_LONG)); + LOG_D(NR_MAC, + "%4d.%2d RNTI %04x: %d bytes from %s %d (ndata %d, remaining size %ld)\n", + frame, + slot, + rnti, + len, + lcid < 4 ? "DCCH" : "DTCH", + lcid, + ndata, + bufEnd-buf-sizeof(NR_MAC_SUBHEADER_LONG)); + + if (len == 0) + break; + + T(T_GNB_MAC_LCID_DL, T_INT(rnti), T_INT(frame), T_INT(slot), T_INT(lcid), T_INT(len * 8), T_INT(nr_rlc_tx_list_occupancy(rnti, lcid))); + header->R = 0; + header->F = 1; + header->LCID = lcid; + header->L = htons(len); + buf += len+sizeof(NR_MAC_SUBHEADER_LONG); + dlsch_total_bytes += len; + lcid_bytes += len; + sdus += 1; + } + + UE->mac_stats.dl.lc_bytes[lcid] += lcid_bytes; + } + } else if (get_softmodem_params()->phy_test || get_softmodem_params()->do_ra) { + /* we will need the large header, phy-test typically allocates all + * resources and fills to the last byte below */ + LOG_D(NR_MAC, "Configuring DL_TX in %d.%d: TBS %d of random data\n", frame, slot, TBS); + + if (bufEnd-buf > sizeof(NR_MAC_SUBHEADER_LONG) ) { + NR_MAC_SUBHEADER_LONG *header = (NR_MAC_SUBHEADER_LONG *) buf; + // fill dlsch_buffer with random data + header->R = 0; + header->F = 1; + header->LCID = DL_SCH_LCID_PADDING; + buf += sizeof(NR_MAC_SUBHEADER_LONG); + header->L = htons(bufEnd-buf); + + for (; ((intptr_t)buf) % 4; buf++) + *buf = lrand48() & 0xff; + for (; buf < bufEnd - 3; buf += 4) { + uint32_t *buf32 = (uint32_t *)buf; + *buf32 = lrand48(); + } + for (; buf < bufEnd; buf++) + *buf = lrand48() & 0xff; + sdus +=1; + } + } + + stop_meas(&nr_mac->rlc_data_req); + + // Add padding header and zero rest out if there is space left + if (bufEnd-buf > 0) { + NR_MAC_SUBHEADER_FIXED *padding = (NR_MAC_SUBHEADER_FIXED *) buf; + padding->R = 0; + padding->LCID = DL_SCH_LCID_PADDING; + buf += 1; + memset(buf,0,bufEnd-buf); + buf=bufEnd; + } + + UE->mac_stats.dl.total_bytes += TBS; + UE->mac_stats.dl.current_bytes = TBS; + UE->mac_stats.dl.total_rbs += sched_pdsch->rbSize; + UE->mac_stats.dl.num_mac_sdu += sdus; + UE->mac_stats.dl.current_rbs = sched_pdsch->rbSize; + UE->mac_stats.dl.total_sdu_bytes += dlsch_total_bytes; + nr_mac->mac_stats.used_prb_aggregate += sched_pdsch->rbSize; + + /* save retransmission information */ + harq->sched_pdsch = *sched_pdsch; + /* save which time allocation has been used, to be used on + * retransmissions */ + harq->sched_pdsch.time_domain_allocation = sched_pdsch->time_domain_allocation; + + // ta command is sent, values are reset + if (sched_ctrl->ta_apply) { + sched_ctrl->ta_apply = false; + sched_ctrl->ta_frame = frame; + LOG_D(NR_MAC, "%d.%2d UE %04x TA scheduled, resetting TA frame\n", frame, slot, UE->rnti); + } + + T(T_GNB_MAC_DL_PDU_WITH_DATA, T_INT(module_id), T_INT(CC_id), T_INT(rnti), + T_INT(frame), T_INT(slot), T_INT(current_harq_pid), T_BUFFER(harq->transportBlock.buf, TBS)); + T(T_GNB_MAC_DL, T_INT(rnti), T_INT(frame), T_INT(slot), T_INT(sched_pdsch->mcs), T_INT(TBS)); + } + + const int ntx_req = pdsch->TX_req->Number_of_PDUs; + nfapi_nr_pdu_t *tx_req = &pdsch->TX_req->pdu_list[ntx_req]; + tx_req->PDU_index = pduindex; + tx_req->num_TLV = 1; + tx_req->TLVs[0].length = TBS; + tx_req->PDU_length = compute_PDU_length(tx_req->num_TLV, tx_req->TLVs[0].length); + memcpy(tx_req->TLVs[0].value.direct, harq->transportBlock.buf, TBS); + pdsch->TX_req->Number_of_PDUs++; + pdsch->TX_req->SFN = frame; + pdsch->TX_req->Slot = slot; +} + void nr_schedule_ue_spec(module_id_t module_id, frame_t frame, slot_t slot, @@ -1031,12 +1400,13 @@ void nr_schedule_ue_spec(module_id_t module_id, NR_UEs_t *UE_info = &gNB_mac->UE_info; nfapi_nr_dl_tti_request_body_t *dl_req = &DL_req->dl_tti_request_body; + post_process_pdsch_t pdsch = { frame, slot, dl_req, TX_req }; + const NR_BWP_t *initialDL = &scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters; gNB_mac->mac_stats.total_prb_aggregate += NRRIV2BW(initialDL->locationAndBandwidth, MAX_BWP_SIZE); UE_iterator(UE_info->connected_ue_list, UE) { NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; - NR_UE_DL_BWP_t *current_BWP = &UE->current_DL_BWP; if (!nr_mac_ue_is_active(UE) && !get_softmodem_params()->phy_test) continue; @@ -1045,368 +1415,11 @@ void nr_schedule_ue_spec(module_id_t module_id, UE->mac_stats.dl.current_bytes = 0; UE->mac_stats.dl.current_rbs = 0; - /* update TA and set ta_apply every 100 frames. - * Possible improvement: take the periodicity from input file. - * If such UE is not scheduled now, it will be by the preprocessor later. - * If we add the CE, ta_apply will be reset */ - if (frame == ((sched_ctrl->ta_frame + 100) % 1024) && !nr_timer_is_active(&sched_ctrl->transm_interrupt)) { - sched_ctrl->ta_apply = true; /* the timer is reset once TA CE is scheduled */ - LOG_D(NR_MAC, "[UE %04x][%d.%d] UL timing alignment procedures: setting flag for Timing Advance command\n", UE->rnti, frame, slot); - } - if (sched_pdsch->rbSize <= 0) continue; - const rnti_t rnti = UE->rnti; + post_process_dlsch(gNB_mac, &pdsch, UE, sched_pdsch); - /* POST processing */ - const uint8_t nrOfLayers = sched_pdsch->nrOfLayers; - const uint32_t TBS = sched_pdsch->tb_size; - int8_t current_harq_pid = sched_pdsch->dl_harq_pid; - - if (current_harq_pid < 0) { - /* PP has not selected a specific HARQ Process, get a new one */ - current_harq_pid = sched_ctrl->available_dl_harq.head; - AssertFatal(current_harq_pid >= 0, - "no free HARQ process available for UE %04x\n", - UE->rnti); - remove_front_nr_list(&sched_ctrl->available_dl_harq); - sched_pdsch->dl_harq_pid = current_harq_pid; - } else { - /* PP selected a specific HARQ process. Check whether it will be a new - * transmission or a retransmission, and remove from the corresponding - * list */ - if (sched_ctrl->harq_processes[current_harq_pid].round == 0) - remove_nr_list(&sched_ctrl->available_dl_harq, current_harq_pid); - else - remove_nr_list(&sched_ctrl->retrans_dl_harq, current_harq_pid); - } - - NR_tda_info_t *tda_info = &sched_pdsch->tda_info; - NR_pdsch_dmrs_t *dmrs_parms = &sched_pdsch->dmrs_parms; - NR_UE_harq_t *harq = &sched_ctrl->harq_processes[current_harq_pid]; - NR_sched_pucch_t *pucch = NULL; - DevAssert(!harq->is_waiting); - if (sched_pdsch->pucch_allocation < 0) { - finish_nr_dl_harq(sched_ctrl, current_harq_pid); - } else { - pucch = &sched_ctrl->sched_pucch[sched_pdsch->pucch_allocation]; - add_tail_nr_list(&sched_ctrl->feedback_dl_harq, current_harq_pid); - harq->feedback_frame = pucch->frame; - harq->feedback_slot = pucch->ul_slot; - harq->is_waiting = true; - } - UE->mac_stats.dl.rounds[harq->round]++; - LOG_D(NR_MAC, - "%4d.%2d [DLSCH/PDSCH/PUCCH] RNTI %04x DCI L %d start %3d RBs %3d startSymbol %2d nb_symbol %2d dmrspos %x MCS %2d nrOfLayers %d TBS %4d HARQ PID %2d round %d RV %d NDI %d dl_data_to_ULACK %d (%d.%d) PUCCH allocation %d TPC %d\n", - frame, - slot, - rnti, - sched_ctrl->aggregation_level, - sched_pdsch->rbStart, - sched_pdsch->rbSize, - tda_info->startSymbolIndex, - tda_info->nrOfSymbols, - dmrs_parms->dl_dmrs_symb_pos, - sched_pdsch->mcs, - nrOfLayers, - TBS, - current_harq_pid, - harq->round, - nr_get_rv(harq->round % 4), - harq->ndi, - pucch ? pucch->timing_indicator : 0, - pucch ? pucch->frame : 0, - pucch ? pucch->ul_slot : 0, - sched_pdsch->pucch_allocation, - sched_ctrl->tpc1); - - const int bwp_id = current_BWP->bwp_id; - const int coresetid = sched_ctrl->coreset->controlResourceSetId; - - /* look up the PDCCH PDU for this CC, BWP, and CORESET. If it does not exist, create it */ - nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu = gNB_mac->pdcch_pdu_idx[CC_id][coresetid]; - - if (!pdcch_pdu) { - LOG_D(NR_MAC, "creating pdcch pdu, pdcch_pdu = NULL. \n"); - nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdcch_pdu = &dl_req->dl_tti_pdu_list[dl_req->nPDUs]; - memset(dl_tti_pdcch_pdu, 0, sizeof(nfapi_nr_dl_tti_request_pdu_t)); - dl_tti_pdcch_pdu->PDUType = NFAPI_NR_DL_TTI_PDCCH_PDU_TYPE; - dl_tti_pdcch_pdu->PDUSize = (uint8_t)(2+sizeof(nfapi_nr_dl_tti_pdcch_pdu)); - dl_req->nPDUs += 1; - pdcch_pdu = &dl_tti_pdcch_pdu->pdcch_pdu.pdcch_pdu_rel15; - LOG_D(NR_MAC,"Trying to configure DL pdcch for UE %04x, bwp %d, cs %d\n", UE->rnti, bwp_id, coresetid); - NR_ControlResourceSet_t *coreset = sched_ctrl->coreset; - nr_configure_pdcch(pdcch_pdu, coreset, &sched_ctrl->sched_pdcch); - gNB_mac->pdcch_pdu_idx[CC_id][coresetid] = pdcch_pdu; - } - - nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdsch_pdu = &dl_req->dl_tti_pdu_list[dl_req->nPDUs]; - memset(dl_tti_pdsch_pdu, 0, sizeof(nfapi_nr_dl_tti_request_pdu_t)); - dl_tti_pdsch_pdu->PDUType = NFAPI_NR_DL_TTI_PDSCH_PDU_TYPE; - dl_tti_pdsch_pdu->PDUSize = (uint8_t)(2 + sizeof(nfapi_nr_dl_tti_pdsch_pdu)); - dl_req->nPDUs += 1; - /* SCF222: PDU index incremented for each PDSCH PDU sent in TX control - * message. This is used to associate control information to data and is - * reset every slot. */ - const int pduindex = gNB_mac->pdu_index[CC_id]++; - // TODO: verify the case where maxMIMO_Layers is NULL, in which case - // in principle maxMIMO_layers should be given by the maximum number of layers - // for PDSCH supported by the UE for the serving cell (5.4.2.1 of 38.212) - long maxMIMO_Layers = UE->sc_info.maxMIMO_Layers_PDSCH ? *UE->sc_info.maxMIMO_Layers_PDSCH : 1; - const int nl_tbslbrm = min(maxMIMO_Layers, 4); - nfapi_nr_dl_tti_pdsch_pdu_rel15_t *pdsch_pdu = prepare_pdsch_pdu(dl_tti_pdsch_pdu, - gNB_mac, - UE, - sched_pdsch, - current_BWP->pdsch_Config, - false, - harq->round, - rnti, - UE->UE_beam_index, - nl_tbslbrm, - pduindex); - - - LOG_D(NR_MAC,"Configuring DCI/PDCCH in %d.%d at CCE %d, rnti %x\n", frame,slot,sched_ctrl->cce_index,rnti); - /* Fill PDCCH DL DCI PDU */ - nfapi_nr_dl_dci_pdu_t *dci_pdu = prepare_dci_pdu(pdcch_pdu, - scc, - sched_ctrl->search_space, - sched_ctrl->coreset, - sched_ctrl->aggregation_level, - sched_ctrl->cce_index, - UE->UE_beam_index, - rnti); - pdcch_pdu->numDlDci++; - - /* DCI payload */ - const int rnti_type = TYPE_C_RNTI_; - dci_pdu_rel15_t dci_payload = prepare_dci_dl_payload(gNB_mac, - UE, - rnti_type, - sched_ctrl->search_space->searchSpaceType->present, - pdsch_pdu, - sched_pdsch, - pucch, - current_harq_pid, - 0, - false); - - // Reset TPC to 0 dB to not request new gain multiple times before computing new value for SNR - sched_ctrl->tpc1 = 1; - NR_PDSCH_Config_t *pdsch_Config = current_BWP->pdsch_Config; - AssertFatal(pdsch_Config == NULL - || pdsch_Config->resourceAllocation == NR_PDSCH_Config__resourceAllocation_resourceAllocationType1, - "Only frequency resource allocation type 1 is currently supported\n"); - - LOG_D(NR_MAC, - "%4d.%2d DCI type 1 payload: freq_alloc %d (%d,%d,%d), " - "nrOfLayers %d, time_alloc %d, vrb to prb %d, mcs %d tb_scaling %d ndi %d rv %d tpc %d ti %d\n", - frame, - slot, - dci_payload.frequency_domain_assignment.val, - pdsch_pdu->rbStart, - pdsch_pdu->rbSize, - pdsch_pdu->BWPSize, - pdsch_pdu->nrOfLayers, - dci_payload.time_domain_assignment.val, - dci_payload.vrb_to_prb_mapping.val, - dci_payload.mcs, - dci_payload.tb_scaling, - dci_payload.ndi, - dci_payload.rv, - dci_payload.tpc, - pucch ? pucch->timing_indicator : 0); - - fill_dci_pdu_rel15(&UE->sc_info, - current_BWP, - &UE->current_UL_BWP, - dci_pdu, - &dci_payload, - current_BWP->dci_format, - rnti_type, - bwp_id, - sched_ctrl->search_space, - sched_ctrl->coreset, - UE->pdsch_HARQ_ACK_Codebook, - gNB_mac->cset0_bwp_size); - - LOG_D(NR_MAC, - "coreset params: FreqDomainResource %llx, start_symbol %d n_symb %d\n", - (unsigned long long)pdcch_pdu->FreqDomainResource, - pdcch_pdu->StartSymbolIndex, - pdcch_pdu->DurationSymbols); - - if (harq->round != 0) { /* retransmission */ - /* we do not have to do anything, since we do not require to get data - * from RLC or encode MAC CEs. The TX_req structure is filled below - * or copy data to FAPI structures */ - LOG_D(NR_MAC, - "%d.%2d DL retransmission RNTI %04x HARQ PID %d round %d NDI %d\n", - frame, - slot, - rnti, - current_harq_pid, - harq->round, - harq->ndi); - if (!get_softmodem_params()->phy_test) - AssertFatal(harq->sched_pdsch.tb_size == TBS, - "UE %04x mismatch between scheduled TBS and buffered TB for HARQ PID %d\n", - UE->rnti, - current_harq_pid); - else if (harq->sched_pdsch.tb_size != TBS) - LOG_E(NR_MAC, - "Mismatch between scheduled TBS and buffered TB for HARQ PID %d. No RTX control in phy-test mode. " - "Possible causes: presence of CSI-RS or DLSCH scheduled in the mixed slot.\n", - current_harq_pid); - T(T_GNB_MAC_RETRANSMISSION_DL_PDU_WITH_DATA, T_INT(module_id), T_INT(CC_id), T_INT(rnti), - T_INT(frame), T_INT(slot), T_INT(current_harq_pid), T_INT(harq->round), T_BUFFER(harq->transportBlock.buf, TBS)); - UE->mac_stats.dl.total_rbs_retx += sched_pdsch->rbSize; - gNB_mac->mac_stats.used_prb_aggregate += sched_pdsch->rbSize; - } else { /* initial transmission */ - LOG_D(NR_MAC, "Initial HARQ transmission in %d.%d\n", frame, slot); - uint8_t *buf = allocate_transportBlock_buffer(&harq->transportBlock, TBS); - /* first, write all CEs that might be there */ - int written = nr_write_ce_dlsch_pdu(module_id, - sched_ctrl, - (unsigned char *)buf, - 255, // no drx - NULL); // contention res id - buf += written; - uint8_t *bufEnd = buf + TBS - written; - DevAssert(TBS > written); - int dlsch_total_bytes = 0; - /* next, get RLC data */ - start_meas(&gNB_mac->rlc_data_req); - int sdus = 0; - - if (sched_ctrl->num_total_bytes > 0) { - /* loop over all activated logical channels */ - for (int i = 0; i < seq_arr_size(&sched_ctrl->lc_config); ++i) { - const nr_lc_config_t *c = seq_arr_at(&sched_ctrl->lc_config, i); - const int lcid = c->lcid; - - if (sched_ctrl->rlc_status[lcid].bytes_in_buffer == 0) - continue; // no data for this LC tbs_size_t len = 0; - - int lcid_bytes=0; - while (bufEnd-buf > sizeof(NR_MAC_SUBHEADER_LONG) + 1 ) { - // we do not know how much data we will get from RLC, i.e., whether it - // will be longer than 256B or not. Therefore, reserve space for long header, then - // fetch data, then fill real length - NR_MAC_SUBHEADER_LONG *header = (NR_MAC_SUBHEADER_LONG *) buf; - /* limit requested number of bytes to what preprocessor specified, or - * such that TBS is full */ - const rlc_buffer_occupancy_t ndata = min(sched_ctrl->rlc_status[lcid].bytes_in_buffer, - bufEnd-buf-sizeof(NR_MAC_SUBHEADER_LONG)); - tbs_size_t len = nr_mac_rlc_data_req(module_id, - rnti, - true, - lcid, - ndata, - (char *)buf+sizeof(NR_MAC_SUBHEADER_LONG)); - LOG_D(NR_MAC, - "%4d.%2d RNTI %04x: %d bytes from %s %d (ndata %d, remaining size %ld)\n", - frame, - slot, - rnti, - len, - lcid < 4 ? "DCCH" : "DTCH", - lcid, - ndata, - bufEnd-buf-sizeof(NR_MAC_SUBHEADER_LONG)); - - if (len == 0) - break; - - T(T_GNB_MAC_LCID_DL, T_INT(rnti), T_INT(frame), T_INT(slot), T_INT(lcid), T_INT(len * 8), T_INT(nr_rlc_tx_list_occupancy(rnti, lcid))); - header->R = 0; - header->F = 1; - header->LCID = lcid; - header->L = htons(len); - buf += len+sizeof(NR_MAC_SUBHEADER_LONG); - dlsch_total_bytes += len; - lcid_bytes += len; - sdus += 1; - } - - UE->mac_stats.dl.lc_bytes[lcid] += lcid_bytes; - } - } else if (get_softmodem_params()->phy_test || get_softmodem_params()->do_ra) { - /* we will need the large header, phy-test typically allocates all - * resources and fills to the last byte below */ - LOG_D(NR_MAC, "Configuring DL_TX in %d.%d: TBS %d of random data\n", frame, slot, TBS); - - if (bufEnd-buf > sizeof(NR_MAC_SUBHEADER_LONG) ) { - NR_MAC_SUBHEADER_LONG *header = (NR_MAC_SUBHEADER_LONG *) buf; - // fill dlsch_buffer with random data - header->R = 0; - header->F = 1; - header->LCID = DL_SCH_LCID_PADDING; - buf += sizeof(NR_MAC_SUBHEADER_LONG); - header->L = htons(bufEnd-buf); - - for (; ((intptr_t)buf) % 4; buf++) - *buf = lrand48() & 0xff; - for (; buf < bufEnd - 3; buf += 4) { - uint32_t *buf32 = (uint32_t *)buf; - *buf32 = lrand48(); - } - for (; buf < bufEnd; buf++) - *buf = lrand48() & 0xff; - sdus +=1; - } - } - - stop_meas(&gNB_mac->rlc_data_req); - - // Add padding header and zero rest out if there is space left - if (bufEnd-buf > 0) { - NR_MAC_SUBHEADER_FIXED *padding = (NR_MAC_SUBHEADER_FIXED *) buf; - padding->R = 0; - padding->LCID = DL_SCH_LCID_PADDING; - buf += 1; - memset(buf,0,bufEnd-buf); - buf=bufEnd; - } - - UE->mac_stats.dl.total_bytes += TBS; - UE->mac_stats.dl.current_bytes = TBS; - UE->mac_stats.dl.total_rbs += sched_pdsch->rbSize; - UE->mac_stats.dl.num_mac_sdu += sdus; - UE->mac_stats.dl.current_rbs = sched_pdsch->rbSize; - UE->mac_stats.dl.total_sdu_bytes += dlsch_total_bytes; - gNB_mac->mac_stats.used_prb_aggregate += sched_pdsch->rbSize; - - /* save retransmission information */ - harq->sched_pdsch = *sched_pdsch; - /* save which time allocation has been used, to be used on - * retransmissions */ - harq->sched_pdsch.time_domain_allocation = sched_pdsch->time_domain_allocation; - - // ta command is sent, values are reset - if (sched_ctrl->ta_apply) { - sched_ctrl->ta_apply = false; - sched_ctrl->ta_frame = frame; - LOG_D(NR_MAC, "%d.%2d UE %04x TA scheduled, resetting TA frame\n", frame, slot, UE->rnti); - } - - T(T_GNB_MAC_DL_PDU_WITH_DATA, T_INT(module_id), T_INT(CC_id), T_INT(rnti), - T_INT(frame), T_INT(slot), T_INT(current_harq_pid), T_BUFFER(harq->transportBlock.buf, TBS)); - T(T_GNB_MAC_DL, T_INT(rnti), T_INT(frame), T_INT(slot), T_INT(sched_pdsch->mcs), T_INT(TBS)); - } - - const int ntx_req = TX_req->Number_of_PDUs; - nfapi_nr_pdu_t *tx_req = &TX_req->pdu_list[ntx_req]; - tx_req->PDU_index = pduindex; - tx_req->num_TLV = 1; - tx_req->TLVs[0].length = TBS; - tx_req->PDU_length = compute_PDU_length(tx_req->num_TLV, tx_req->TLVs[0].length); - memcpy(tx_req->TLVs[0].value.direct, harq->transportBlock.buf, TBS); - TX_req->Number_of_PDUs++; - TX_req->SFN = frame; - TX_req->Slot = slot; /* mark UE as scheduled */ sched_pdsch->rbSize = 0; } diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h index f64b94fb47..544e218e5b 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h +++ b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h @@ -821,6 +821,17 @@ typedef struct { #define UE_iterator(BaSe, VaR) for (NR_UE_info_t **VaR##pptr=BaSe, *VaR=*VaR##pptr; VaR; VaR=*(++VaR##pptr)) +typedef struct { + /// current frame + frame_t frame; + /// current slot + slot_t slot; + /// FAPI DL req in which allocations are made + nfapi_nr_dl_tti_request_body_t *dl_req; + /// TX_data request holds the actual data + nfapi_nr_tx_data_request_t *TX_req; +} post_process_pdsch_t; + typedef struct { /// current frame for DCI frame_t frame; From 1a752a8433a72bdae1ef78b06bb008301c928527 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Mon, 22 Sep 2025 10:18:13 +0200 Subject: [PATCH 46/69] Remove unused/write-only code --- .../LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c | 28 ++----------------- 1 file changed, 2 insertions(+), 26 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c index 7fe346ab7d..03abcbfd0c 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c @@ -587,7 +587,6 @@ static bool allocate_dl_retransmission(module_id_t module_id, return true; } -static uint32_t pf_tbs[3][29]; // pre-computed, approximate TBS values for PF coefficient typedef struct UEsched_s { float coef; NR_UE_info_t * UE; @@ -909,31 +908,8 @@ static void nr_dlsch_preprocessor(module_id_t module_id, frame_t frame, slot_t s pf_dl(module_id, frame, slot, UE_info->connected_ue_list, max_sched_ues, num_beams, n_rb_sched); } -nr_pp_impl_dl nr_init_dlsch_preprocessor(int CC_id) { - /* during initialization: no mutex needed */ - /* in the PF algorithm, we have to use the TBsize to compute the coefficient. - * This would include the number of DMRS symbols, which in turn depends on - * the time domain allocation. In case we are in a mixed slot, we do not want - * to recalculate all these values just, and therefore we provide a look-up - * table which should approximately give us the TBsize */ - for (int mcsTableIdx = 0; mcsTableIdx < 3; ++mcsTableIdx) { - for (int mcs = 0; mcs < 29; ++mcs) { - if (mcs > 27 && mcsTableIdx == 1) - continue; - - const uint8_t Qm = nr_get_Qm_dl(mcs, mcsTableIdx); - const uint16_t R = nr_get_code_rate_dl(mcs, mcsTableIdx); - pf_tbs[mcsTableIdx][mcs] = nr_compute_tbs(Qm, - R, - 1, /* rbSize */ - 10, /* hypothetical number of slots */ - 0, /* N_PRB_DMRS * N_DMRS_SLOT */ - 0 /* N_PRB_oh, 0 for initialBWP */, - 0 /* tb_scaling */, - 1 /* nrOfLayers */) >> 3; - } - } - +nr_pp_impl_dl nr_init_dlsch_preprocessor(int CC_id) +{ return nr_dlsch_preprocessor; } From 16227243843d6759491972c24196557358616c38 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Mon, 22 Sep 2025 11:53:44 +0200 Subject: [PATCH 47/69] Store selected MCS in UE iterator PF uses MCS and average throughput to decide which UE to schedule. Thus, the first loop decides on MCS, whereas the second does the "main UE allocation" after sorting by the PF metric. A follow-up commit will remove sched_pusch from NR_UE_sched_ctrl_t. Thus, we cannot rely on sched_ctrl to store the MCS in the first loop, and look it up from there in the second. Instead, store it as part of the UE iterator data, and take it from there. See also: f3068caa3774 ("Store selected MCS in UE iterator", for UL) --- .../LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c | 23 +++++++++++-------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c index 03abcbfd0c..7b39e0eabd 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c @@ -590,6 +590,7 @@ static bool allocate_dl_retransmission(module_id_t module_id, typedef struct UEsched_s { float coef; NR_UE_info_t * UE; + int selected_mcs; } UEsched_t; static int comparator(const void *p, const void *q) @@ -686,17 +687,16 @@ static void pf_dl(module_id_t module_id, const NR_bler_options_t *bo = &mac->dl_bler; const int max_mcs_table = current_BWP->mcsTableIdx == 1 ? 27 : 28; const int max_mcs = min(sched_ctrl->dl_max_mcs, max_mcs_table); + int selected_mcs; if (bo->harq_round_max == 1) { int new_mcs = min(bo->max_mcs, max_mcs); - sched_pdsch->mcs = max(bo->min_mcs, new_mcs); - sched_ctrl->dl_bler_stats.mcs = sched_pdsch->mcs; + selected_mcs = max(bo->min_mcs, new_mcs); + sched_ctrl->dl_bler_stats.mcs = selected_mcs; } else - sched_pdsch->mcs = get_mcs_from_bler(bo, stats, &sched_ctrl->dl_bler_stats, max_mcs, frame); - sched_pdsch->nrOfLayers = get_dl_nrOfLayers(sched_ctrl, current_BWP->dci_format); - sched_pdsch->pm_index = - get_pm_index(mac, UE, current_BWP->dci_format, sched_pdsch->nrOfLayers, mac->radio_config.pdsch_AntennaPorts.XP); - const uint8_t Qm = nr_get_Qm_dl(sched_pdsch->mcs, current_BWP->mcsTableIdx); - const uint16_t R = nr_get_code_rate_dl(sched_pdsch->mcs, current_BWP->mcsTableIdx); + selected_mcs = get_mcs_from_bler(bo, stats, &sched_ctrl->dl_bler_stats, max_mcs, frame); + int l = get_dl_nrOfLayers(sched_ctrl, current_BWP->dci_format); + const uint8_t Qm = nr_get_Qm_dl(selected_mcs, current_BWP->mcsTableIdx); + const uint16_t R = nr_get_code_rate_dl(selected_mcs, current_BWP->mcsTableIdx); uint32_t tbs = nr_compute_tbs(Qm, R, 1, /* rbSize */ @@ -704,7 +704,7 @@ static void pf_dl(module_id_t module_id, 0, /* N_PRB_DMRS * N_DMRS_SLOT */ 0 /* N_PRB_oh, 0 for initialBWP */, 0 /* tb_scaling */, - sched_pdsch->nrOfLayers) >> 3; + l) >> 3; float coeff_ue = (float) tbs / UE->dl_thr_ue; LOG_D(NR_MAC, "[UE %04x][%4d.%2d] b %d, thr_ue %f, tbs %d, coeff_ue %f\n", UE->rnti, @@ -717,6 +717,7 @@ static void pf_dl(module_id_t module_id, /* Create UE_sched list for UEs eligible for new transmission*/ UE_sched[numUE].coef = coeff_ue; UE_sched[numUE].UE = UE; + UE_sched[numUE].selected_mcs = selected_mcs; numUE++; } } @@ -843,6 +844,10 @@ static void pf_dl(module_id_t module_id, sched_ctrl->cce_index = CCEIndex; fill_pdcch_vrb_map(mac, CC_id, &sched_ctrl->sched_pdcch, CCEIndex, sched_ctrl->aggregation_level, beam.idx); + int l = get_dl_nrOfLayers(sched_ctrl, dl_bwp->dci_format); + sched_pdsch->nrOfLayers = l; + sched_pdsch->mcs = iterator->selected_mcs; + sched_pdsch->pm_index = get_pm_index(mac, iterator->UE, dl_bwp->dci_format, l, mac->radio_config.pdsch_AntennaPorts.XP); sched_pdsch->dmrs_parms = get_dl_dmrs_params(scc, dl_bwp, tda_info, sched_pdsch->nrOfLayers); sched_pdsch->Qm = nr_get_Qm_dl(sched_pdsch->mcs, dl_bwp->mcsTableIdx); sched_pdsch->R = nr_get_code_rate_dl(sched_pdsch->mcs, dl_bwp->mcsTableIdx); From a6d16a66d2fa2203197b6ddcd4b44ddf9a576b5c Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Mon, 22 Sep 2025 12:05:33 +0200 Subject: [PATCH 48/69] Reduce scope of NR_sched_pdsch in first DL sched loop We don't need NR_sched_pdsch here. Remove the use of it. --- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c index 7b39e0eabd..8d47b98924 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c @@ -632,9 +632,8 @@ static void pf_dl(module_id_t module_id, continue; const NR_mac_dir_stats_t *stats = &UE->mac_stats.dl; - NR_sched_pdsch_t *sched_pdsch = &sched_ctrl->sched_pdsch; /* get the PID of a HARQ process awaiting retrnasmission, or -1 otherwise */ - sched_pdsch->dl_harq_pid = sched_ctrl->retrans_dl_harq.head; + int harq_pid = sched_ctrl->retrans_dl_harq.head; /* Calculate Throughput */ const float a = 0.01f; @@ -653,12 +652,12 @@ static void pf_dl(module_id_t module_id, continue; /* retransmission */ - if (sched_pdsch->dl_harq_pid >= 0) { + if (harq_pid >= 0) { NR_beam_alloc_t beam = beam_allocation_procedure(&mac->beam_info, frame, slot, UE->UE_beam_index, slots_per_frame); bool sch_ret = beam.idx >= 0; /* Allocate retransmission */ if (sch_ret) - sch_ret = allocate_dl_retransmission(module_id, frame, slot, &n_rb_sched[beam.idx], UE, beam.idx, sched_pdsch->dl_harq_pid); + sch_ret = allocate_dl_retransmission(module_id, frame, slot, &n_rb_sched[beam.idx], UE, beam.idx, harq_pid); if (!sch_ret) { LOG_D(NR_MAC, "[UE %04x][%4d.%2d] DL retransmission could not be allocated\n", UE->rnti, frame, slot); reset_beam_status(&mac->beam_info, frame, slot, UE->UE_beam_index, slots_per_frame, beam.new_beam); From 761a70d199b7cd35e449924e38b4352ba3da1e16 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Mon, 22 Sep 2025 13:50:07 +0200 Subject: [PATCH 49/69] Remove use of curInfo in allocate_dl_retransmission() It seems to be assumed that curInfo actually has the currently active number of layers/PMI. However, I am not sure this would always be true (e.g., UE might not have been scheduled for some slots, but number of layers decreased as reported by CSI). Instead, recalculate the info from scratch when necessary. --- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c | 7 ++++--- 1 file changed, 4 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 8d47b98924..c763128d23 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c @@ -438,13 +438,14 @@ static bool allocate_dl_retransmission(module_id_t module_id, NR_UE_DL_BWP_t *dl_bwp = &UE->current_DL_BWP; NR_UE_UL_BWP_t *ul_bwp = &UE->current_UL_BWP; NR_sched_pdsch_t *retInfo = &sched_ctrl->harq_processes[current_harq_pid].sched_pdsch; - NR_sched_pdsch_t *curInfo = &sched_ctrl->sched_pdsch; + int layers = get_dl_nrOfLayers(sched_ctrl, dl_bwp->dci_format); + int pm_index = get_pm_index(nr_mac, UE, dl_bwp->dci_format, layers, nr_mac->radio_config.pdsch_AntennaPorts.XP); // If the RI changed between current rtx and a previous transmission // we need to verify if it is not decreased // othwise it wouldn't be possible to transmit the same TBS - int layers = (curInfo->nrOfLayers < retInfo->nrOfLayers) ? curInfo->nrOfLayers : retInfo->nrOfLayers; - int pm_index = (curInfo->nrOfLayers < retInfo->nrOfLayers) ? curInfo->pm_index : retInfo->pm_index; + layers = (layers < retInfo->nrOfLayers) ? layers : retInfo->nrOfLayers; + pm_index = (layers < retInfo->nrOfLayers) ? pm_index : retInfo->pm_index; const int coresetid = sched_ctrl->coreset->controlResourceSetId; const int tda = get_dl_tda(nr_mac, slot); From 2daa1dac185052c182074ec729f5d4ed208eaf83 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Mon, 22 Sep 2025 14:30:06 +0200 Subject: [PATCH 50/69] allocate_dl_retransmission(): refactor NR_sched_pdsch usage Assign NR_sched_pdsch to sched_ctrl->sched_pdsch in one place, where the post-processing functionality will be called in a follow-up commit. This should result in no functional change. --- .../LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c | 61 ++++++++++--------- 1 file changed, 31 insertions(+), 30 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c index c763128d23..befe95b525 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c @@ -437,15 +437,15 @@ static bool allocate_dl_retransmission(module_id_t module_id, NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; NR_UE_DL_BWP_t *dl_bwp = &UE->current_DL_BWP; NR_UE_UL_BWP_t *ul_bwp = &UE->current_UL_BWP; - NR_sched_pdsch_t *retInfo = &sched_ctrl->harq_processes[current_harq_pid].sched_pdsch; + NR_sched_pdsch_t new_sched = sched_ctrl->harq_processes[current_harq_pid].sched_pdsch; int layers = get_dl_nrOfLayers(sched_ctrl, dl_bwp->dci_format); int pm_index = get_pm_index(nr_mac, UE, dl_bwp->dci_format, layers, nr_mac->radio_config.pdsch_AntennaPorts.XP); // If the RI changed between current rtx and a previous transmission // we need to verify if it is not decreased // othwise it wouldn't be possible to transmit the same TBS - layers = (layers < retInfo->nrOfLayers) ? layers : retInfo->nrOfLayers; - pm_index = (layers < retInfo->nrOfLayers) ? pm_index : retInfo->pm_index; + layers = (layers < new_sched.nrOfLayers) ? layers : new_sched.nrOfLayers; + pm_index = (layers < new_sched.nrOfLayers) ? pm_index : new_sched.pm_index; const int coresetid = sched_ctrl->coreset->controlResourceSetId; const int tda = get_dl_tda(nr_mac, slot); @@ -464,11 +464,11 @@ static bool allocate_dl_retransmission(module_id_t module_id, if (!temp_tda.valid_tda) return false; - bool reuse_old_tda = (retInfo->tda_info.startSymbolIndex == temp_tda.startSymbolIndex) && (retInfo->tda_info.nrOfSymbols <= temp_tda.nrOfSymbols); + bool reuse_old_tda = (new_sched.tda_info.startSymbolIndex == temp_tda.startSymbolIndex) && (new_sched.tda_info.nrOfSymbols <= temp_tda.nrOfSymbols); LOG_D(NR_MAC, "[UE %x] %s old TDA, %s number of layers\n", UE->rnti, reuse_old_tda ? "reuse" : "do not reuse", - layers == retInfo->nrOfLayers ? "same" : "different"); + layers == new_sched.nrOfLayers ? "same" : "different"); uint16_t *rballoc_mask = nr_mac->common_channels[CC_id].vrb_map[beam_idx]; @@ -477,13 +477,13 @@ static bool allocate_dl_retransmission(module_id_t module_id, int rbStop = bwp_info.bwpStart + bwp_info.bwpSize - 1; int rbSize = 0; - if (reuse_old_tda && layers == retInfo->nrOfLayers) { + if (reuse_old_tda && layers == new_sched.nrOfLayers) { /* Check that there are enough resources for retransmission */ - while (rbSize < retInfo->rbSize) { + while (rbSize < new_sched.rbSize) { rbStart += rbSize; /* last iteration rbSize was not enough, skip it */ rbSize = 0; - const uint16_t slbitmap = SL_to_bitmap(retInfo->tda_info.startSymbolIndex, retInfo->tda_info.nrOfSymbols); + const uint16_t slbitmap = SL_to_bitmap(new_sched.tda_info.startSymbolIndex, new_sched.tda_info.nrOfSymbols); while (rbStart < rbStop && (rballoc_mask[rbStart] & slbitmap)) rbStart++; @@ -492,7 +492,7 @@ static bool allocate_dl_retransmission(module_id_t module_id, return false; } - while (rbStart + rbSize <= rbStop && !(rballoc_mask[rbStart + rbSize] & slbitmap) && rbSize < retInfo->rbSize) + while (rbStart + rbSize <= rbStop && !(rballoc_mask[rbStart + rbSize] & slbitmap) && rbSize < new_sched.rbSize) rbSize++; } } else { @@ -509,37 +509,37 @@ static bool allocate_dl_retransmission(module_id_t module_id, uint32_t new_tbs; uint16_t new_rbSize; - bool success = nr_find_nb_rb(retInfo->Qm, - retInfo->R, + bool success = nr_find_nb_rb(new_sched.Qm, + new_sched.R, 1, // no transform precoding for DL layers, temp_tda.nrOfSymbols, temp_dmrs.N_PRB_DMRS * temp_dmrs.N_DMRS_SLOT, - retInfo->tb_size, + new_sched.tb_size, 1, /* minimum of 1RB: need to find exact TBS, don't preclude any number */ rbSize, &new_tbs, &new_rbSize); - if (!success || new_tbs != retInfo->tb_size) { + if (!success || new_tbs != new_sched.tb_size) { LOG_D(NR_MAC, "[UE %04x][%4d.%2d] allocation of DL retransmission failed: new TBS %d of new TDA does not match old TBS %d\n", UE->rnti, frame, slot, new_tbs, - retInfo->tb_size); + new_sched.tb_size); return false; /* the maximum TBsize we might have is smaller than what we need */ } /* we can allocate it. Overwrite the time_domain_allocation, the number * of RBs, and the new TB size. The rest is done below */ - retInfo->tb_size = new_tbs; - retInfo->rbSize = new_rbSize; - retInfo->time_domain_allocation = tda; - retInfo->nrOfLayers = layers; - retInfo->pm_index = pm_index; - retInfo->dmrs_parms = temp_dmrs; - retInfo->tda_info = temp_tda; + new_sched.tb_size = new_tbs; + new_sched.rbSize = new_rbSize; + new_sched.time_domain_allocation = tda; + new_sched.nrOfLayers = layers; + new_sched.pm_index = pm_index; + new_sched.dmrs_parms = temp_dmrs; + new_sched.tda_info = temp_tda; } /* Find a free CCE */ @@ -574,16 +574,17 @@ static bool allocate_dl_retransmission(module_id_t module_id, sched_ctrl->cce_index = CCEIndex; fill_pdcch_vrb_map(nr_mac, CC_id, &sched_ctrl->sched_pdcch, CCEIndex, sched_ctrl->aggregation_level, beam_idx); - /* just reuse from previous scheduling opportunity, set new start RB */ - sched_ctrl->sched_pdsch = *retInfo; - sched_ctrl->sched_pdsch.rbStart = rbStart - bwp_info.bwpStart; - sched_ctrl->sched_pdsch.pucch_allocation = alloc; - sched_ctrl->sched_pdsch.bwp_info = bwp_info; - /* retransmissions: directly allocate */ - *n_rb_sched -= sched_ctrl->sched_pdsch.rbSize; - for (int rb = rbStart; rb < sched_ctrl->sched_pdsch.rbSize; rb++) - rballoc_mask[rb] |= SL_to_bitmap(retInfo->tda_info.startSymbolIndex, retInfo->tda_info.nrOfSymbols); + new_sched.rbStart = rbStart - bwp_info.bwpStart; + new_sched.pucch_allocation = alloc; + new_sched.bwp_info = bwp_info; + sched_ctrl->sched_pdsch = new_sched; + + /* retransmissions: directly allocate */ + *n_rb_sched -= new_sched.rbSize; + + for (int rb = rbStart; rb < new_sched.rbSize; rb++) + rballoc_mask[rb] |= SL_to_bitmap(new_sched.tda_info.startSymbolIndex, new_sched.tda_info.nrOfSymbols); return true; } From d4dc044d2dd3f556a132473cea1d71c33da00a98 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Mon, 22 Sep 2025 14:49:48 +0200 Subject: [PATCH 51/69] pf_dl(): refactor NR_pdsch_sched usage As in parent commit. --- .../LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c | 79 ++++++++++--------- 1 file changed, 41 insertions(+), 38 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c index befe95b525..4a39969be4 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c @@ -759,33 +759,28 @@ static void pf_dl(module_id_t module_id, continue; } - NR_sched_pdsch_t *sched_pdsch = &sched_ctrl->sched_pdsch; - sched_pdsch->dl_harq_pid = sched_ctrl->available_dl_harq.head; - /* MCS has been set above */ - sched_pdsch->time_domain_allocation = get_dl_tda(mac, slot); - AssertFatal(sched_pdsch->time_domain_allocation>=0,"Unable to find PDSCH time domain allocation in list\n"); + int tda = get_dl_tda(mac, slot); + AssertFatal(tda >= 0,"Unable to find PDSCH time domain allocation in list\n"); const int coresetid = sched_ctrl->coreset->controlResourceSetId; - sched_pdsch->tda_info = get_dl_tda_info(dl_bwp, + NR_tda_info_t tda_info = get_dl_tda_info(dl_bwp, sched_ctrl->search_space->searchSpaceType->present, - sched_pdsch->time_domain_allocation, + tda, scc->dmrs_TypeA_Position, 1, TYPE_C_RNTI_, coresetid, false); - AssertFatal(sched_pdsch->tda_info.valid_tda, "Invalid TDA from get_dl_tda_info\n"); + AssertFatal(tda_info.valid_tda, "Invalid TDA from get_dl_tda_info\n"); - NR_tda_info_t *tda_info = &sched_pdsch->tda_info; - - const uint16_t slbitmap = SL_to_bitmap(tda_info->startSymbolIndex, tda_info->nrOfSymbols); + const uint16_t slbitmap = SL_to_bitmap(tda_info.startSymbolIndex, tda_info.nrOfSymbols); uint16_t *rballoc_mask = mac->common_channels[CC_id].vrb_map[beam.idx]; - sched_pdsch->bwp_info = get_pdsch_bwp_start_size(mac, iterator->UE); + bwp_info_t bwp_info = get_pdsch_bwp_start_size(mac, iterator->UE); int rbStart = 0; // WRT BWP start - int rbStop = sched_pdsch->bwp_info.bwpSize - 1; - int bwp_start = sched_pdsch->bwp_info.bwpStart; + int rbStop = bwp_info.bwpSize - 1; + int bwp_start = bwp_info.bwpStart; // Freq-demain allocation while (rbStart < rbStop && (rballoc_mask[rbStart + bwp_start] & slbitmap)) rbStart++; @@ -831,7 +826,7 @@ static void pf_dl(module_id_t module_id, * allocation after CCE alloc fail would be more complex) */ int alloc = -1; - if (!get_FeedbackDisabled(iterator->UE->sc_info.downlinkHARQ_FeedbackDisabled_r17, sched_pdsch->dl_harq_pid)) { + if (!get_FeedbackDisabled(iterator->UE->sc_info.downlinkHARQ_FeedbackDisabled_r17, sched_ctrl->available_dl_harq.head)) { int r_pucch = nr_get_pucch_resource(sched_ctrl->coreset, ul_bwp->pucch_Config, CCEIndex); alloc = nr_acknack_scheduling(mac, iterator->UE, frame, slot, iterator->UE->UE_beam_index, r_pucch, 0); if (alloc < 0) { @@ -846,40 +841,48 @@ static void pf_dl(module_id_t module_id, fill_pdcch_vrb_map(mac, CC_id, &sched_ctrl->sched_pdcch, CCEIndex, sched_ctrl->aggregation_level, beam.idx); int l = get_dl_nrOfLayers(sched_ctrl, dl_bwp->dci_format); - sched_pdsch->nrOfLayers = l; - sched_pdsch->mcs = iterator->selected_mcs; - sched_pdsch->pm_index = get_pm_index(mac, iterator->UE, dl_bwp->dci_format, l, mac->radio_config.pdsch_AntennaPorts.XP); - sched_pdsch->dmrs_parms = get_dl_dmrs_params(scc, dl_bwp, tda_info, sched_pdsch->nrOfLayers); - sched_pdsch->Qm = nr_get_Qm_dl(sched_pdsch->mcs, dl_bwp->mcsTableIdx); - sched_pdsch->R = nr_get_code_rate_dl(sched_pdsch->mcs, dl_bwp->mcsTableIdx); - sched_pdsch->pucch_allocation = alloc; - uint32_t TBS = 0; - uint16_t rbSize; + NR_sched_pdsch_t sched_pdsch = { + // rbSize below + .rbStart = rbStart, + .mcs = iterator->selected_mcs, + .R = nr_get_code_rate_dl(iterator->selected_mcs, dl_bwp->mcsTableIdx), + .Qm = nr_get_Qm_dl(iterator->selected_mcs, dl_bwp->mcsTableIdx), + // tb_size below + .dl_harq_pid = sched_ctrl->available_dl_harq.head, + .pucch_allocation = alloc, + .pm_index = get_pm_index(mac, iterator->UE, dl_bwp->dci_format, l, mac->radio_config.pdsch_AntennaPorts.XP), + .nrOfLayers = l, + .bwp_info = bwp_info, + .dmrs_parms = get_dl_dmrs_params(scc, dl_bwp, &tda_info, l), + .time_domain_allocation = tda, + .tda_info = tda_info, + }; + // Fix me: currently, the RLC does not give us the total number of PDUs // awaiting. Therefore, for the time being, we put a fixed overhead of 12 // (for 4 PDUs) and optionally + 2 for TA. Once RLC gives the number of // PDUs, we replace with 3 * numPDUs const int oh = 3 * 4 + 2 * (frame == (sched_ctrl->ta_frame + 100) % 1024); //const int oh = 3 * sched_ctrl->dl_pdus_total + 2 * (frame == (sched_ctrl->ta_frame + 100) % 1024); - nr_find_nb_rb(sched_pdsch->Qm, - sched_pdsch->R, + nr_find_nb_rb(sched_pdsch.Qm, + sched_pdsch.R, 1, // no transform precoding for DL - sched_pdsch->nrOfLayers, - tda_info->nrOfSymbols, - sched_pdsch->dmrs_parms.N_PRB_DMRS * sched_pdsch->dmrs_parms.N_DMRS_SLOT, + sched_pdsch.nrOfLayers, + tda_info.nrOfSymbols, + sched_pdsch.dmrs_parms.N_PRB_DMRS * sched_pdsch.dmrs_parms.N_DMRS_SLOT, sched_ctrl->num_total_bytes + oh, min_rbSize, max_rbSize, - &TBS, - &rbSize); - sched_pdsch->rbSize = rbSize; - sched_pdsch->rbStart = rbStart; - sched_pdsch->tb_size = TBS; - /* transmissions: directly allocate */ - n_rb_sched[beam.idx] -= sched_pdsch->rbSize; + &sched_pdsch.tb_size, + &sched_pdsch.rbSize); - for (int rb = bwp_start; rb < sched_pdsch->rbSize; rb++) - rballoc_mask[rb + sched_pdsch->rbStart] |= slbitmap; + sched_ctrl->sched_pdsch = sched_pdsch; + + /* transmissions: directly allocate */ + n_rb_sched[beam.idx] -= sched_pdsch.rbSize; + + for (int rb = bwp_start; rb < sched_pdsch.rbSize; rb++) + rballoc_mask[rb + sched_pdsch.rbStart] |= slbitmap; remainUEs[beam.idx]--; iterator++; From 8205503496d373d08de30714de6f156a31396ad7 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Mon, 22 Sep 2025 15:58:40 +0200 Subject: [PATCH 52/69] nr_preprocessor_phytest(): Refactor NR_sched_pdsch usage As in parent commit(s). --- .../LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c | 72 +++++++++---------- 1 file changed, 32 insertions(+), 40 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c index 5ec7bf781d..10b38272e8 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c @@ -86,9 +86,6 @@ void nr_preprocessor_phytest(module_id_t module_id, frame_t frame, slot_t slot) if(!tda_info.valid_tda) return; - sched_ctrl->sched_pdsch.tda_info = tda_info; - sched_ctrl->sched_pdsch.time_domain_allocation = tda; - /* find largest unallocated chunk */ const int bwpSize = dl_bwp->BWPSize; const int BWPStart = dl_bwp->BWPStart; @@ -142,12 +139,11 @@ void nr_preprocessor_phytest(module_id_t module_id, frame_t frame, slot_t slot) 0); AssertFatal(CCEIndex >= 0, "Could not find CCE for UE %04x\n", UE->rnti); - NR_sched_pdsch_t *sched_pdsch = &sched_ctrl->sched_pdsch; - if (sched_pdsch->dl_harq_pid == -1) - sched_pdsch->dl_harq_pid = sched_ctrl->available_dl_harq.head; - int alloc = -1; - if (!get_FeedbackDisabled(UE->sc_info.downlinkHARQ_FeedbackDisabled_r17, sched_pdsch->dl_harq_pid)) { + int harq_pid = sched_ctrl->retrans_dl_harq.head; + if (harq_pid < 0) + harq_pid = sched_ctrl->available_dl_harq.head; + if (!get_FeedbackDisabled(UE->sc_info.downlinkHARQ_FeedbackDisabled_r17, harq_pid)) { int r_pucch = nr_get_pucch_resource(sched_ctrl->coreset, UE->current_UL_BWP.pucch_Config, CCEIndex); alloc = nr_acknack_scheduling(mac, UE, frame, slot, 0, r_pucch, 0); if (alloc < 0) { @@ -165,42 +161,38 @@ void nr_preprocessor_phytest(module_id_t module_id, frame_t frame, slot_t slot) sched_ctrl->aggregation_level, beam); - //AssertFatal(alloc, - // "could not find uplink slot for PUCCH (RNTI %04x@%d.%d)!\n", - // rnti, frame, slot); - - sched_pdsch->pucch_allocation = alloc; - sched_pdsch->rbStart = rbStart; - sched_pdsch->rbSize = rbSize; - sched_pdsch->bwp_info = get_pdsch_bwp_start_size(mac, UE); - sched_pdsch->dmrs_parms = get_dl_dmrs_params(scc, - dl_bwp, - &tda_info, - target_dl_Nl); - - sched_pdsch->mcs = target_dl_mcs; - sched_pdsch->nrOfLayers = target_dl_Nl; - sched_pdsch->Qm = nr_get_Qm_dl(sched_pdsch->mcs, dl_bwp->mcsTableIdx); - sched_pdsch->R = nr_get_code_rate_dl(sched_pdsch->mcs, dl_bwp->mcsTableIdx); + NR_sched_pdsch_t sched_pdsch = { + .rbSize = rbSize, + .rbStart = rbStart, + .mcs = target_dl_mcs, + .R = nr_get_code_rate_dl(target_dl_mcs, dl_bwp->mcsTableIdx), + .Qm = nr_get_Qm_dl(target_dl_mcs, dl_bwp->mcsTableIdx), + // tbSize further below + .dl_harq_pid = sched_ctrl->retrans_dl_harq.head, // PID of HARQ awaiting retransmission, or -1 otherwise + .pucch_allocation = alloc, + .pm_index = 0, + .nrOfLayers = target_dl_Nl, + .bwp_info = get_pdsch_bwp_start_size(mac, UE), + .dmrs_parms = get_dl_dmrs_params(scc, dl_bwp, &tda_info, target_dl_Nl), + .time_domain_allocation = tda, + .tda_info = tda_info, + }; sched_ctrl->dl_bler_stats.mcs = target_dl_mcs; /* for logging output */ - sched_pdsch->tb_size = nr_compute_tbs(sched_pdsch->Qm, - sched_pdsch->R, - sched_pdsch->rbSize, - tda_info.nrOfSymbols, - sched_pdsch->dmrs_parms.N_PRB_DMRS * sched_pdsch->dmrs_parms.N_DMRS_SLOT, - 0 /* N_PRB_oh, 0 for initialBWP */, - 0 /* tb_scaling */, - sched_pdsch->nrOfLayers) - >> 3; + sched_pdsch.tb_size = nr_compute_tbs(sched_pdsch.Qm, + sched_pdsch.R, + sched_pdsch.rbSize, + tda_info.nrOfSymbols, + sched_pdsch.dmrs_parms.N_PRB_DMRS * sched_pdsch.dmrs_parms.N_DMRS_SLOT, + 0 /* N_PRB_oh, 0 for initialBWP */, + 0 /* tb_scaling */, + target_dl_Nl) + >> 3; - /* get the PID of a HARQ process awaiting retransmission, or -1 otherwise */ - sched_pdsch->dl_harq_pid = sched_ctrl->retrans_dl_harq.head; + sched_ctrl->sched_pdsch = sched_pdsch; /* mark the corresponding RBs as used */ - for (int rb = 0; rb < sched_pdsch->rbSize; rb++) - vrb_map[rb + sched_pdsch->rbStart + BWPStart] = SL_to_bitmap(tda_info.startSymbolIndex, tda_info.nrOfSymbols); - - if ((frame&127) == 0) LOG_D(MAC,"phytest: %d.%d DL mcs %d, DL rbStart %d, DL rbSize %d\n", frame, slot, sched_pdsch->mcs, rbStart,rbSize); + for (int rb = 0; rb < sched_pdsch.rbSize; rb++) + vrb_map[rb + sched_pdsch.rbStart + BWPStart] = SL_to_bitmap(tda_info.startSymbolIndex, tda_info.nrOfSymbols); } uint32_t target_ul_mcs = 9; From 1900edb56d6f3b8c0b88c8947cbfd0c2268e5c6f Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Mon, 22 Sep 2025 16:33:29 +0200 Subject: [PATCH 53/69] schedule_control_sib1(): Refactor NR_sched_pdsch usage Similarly to parent commit(s), refactor the use of NR_sched_pdsch. Instead of using nr_mac->sched_ctrlCommon, put the NR_sched_pdsch_t on the stack. This also refactors update_rb_mcs_tbs() to update the existing NR_sched_pdsch instead of updating individual fields. This also reduces the extend to which sched_ctrlCommon is used. --- .../LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c | 120 ++++++++---------- 1 file changed, 53 insertions(+), 67 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c index 540e2c6291..1f6fb64181 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c @@ -274,35 +274,32 @@ void schedule_nr_mib(module_id_t module_idP, frame_t frameP, slot_t slotP, nfapi } } -static uint32_t get_tbs_bch(NR_sched_pdsch_t *pdsch, - uint32_t num_total_bytes, - uint16_t *vrb_map) +static void update_rb_mcs_tbs(NR_sched_pdsch_t *pdsch, uint32_t num_total_bytes, uint16_t *vrb_map) { - NR_tda_info_t *tda_info = &pdsch->tda_info; + const NR_tda_info_t *tda_info = &pdsch->tda_info; // Calculate number of PRB_DMRS uint8_t N_PRB_DMRS = pdsch->dmrs_parms.N_PRB_DMRS; LOG_D(MAC, "dlDmrsSymbPos %x\n", pdsch->dmrs_parms.dl_dmrs_symb_pos); int mcsTableIdx = 0; - uint32_t TBS = 0; const uint16_t slbitmap = SL_to_bitmap(tda_info->startSymbolIndex, tda_info->nrOfSymbols); int bwpSize = pdsch->bwp_info.bwpSize; int bwpStart = pdsch->bwp_info.bwpStart; int rbStop = bwpSize - 1; - int rbStart = 0; - uint16_t rbSize = 0; - while (rbStart < rbStop) { - if (vrb_map[rbStart + bwpStart] & slbitmap) - rbStart++; + while (pdsch->rbStart < rbStop) { + if (vrb_map[pdsch->rbStart + bwpStart] & slbitmap) + pdsch->rbStart++; else { int max_rbSize = 0; - while (rbStart + max_rbSize <= rbStop && !(vrb_map[rbStart + max_rbSize + bwpStart] & slbitmap)) + while (pdsch->rbStart + max_rbSize <= rbStop && !(vrb_map[pdsch->rbStart + max_rbSize + bwpStart] & slbitmap)) max_rbSize++; bool res = false; while (res == false && pdsch->mcs < 10) { - res = nr_find_nb_rb(nr_get_Qm_dl(pdsch->mcs, mcsTableIdx), - nr_get_code_rate_dl(pdsch->mcs, mcsTableIdx), + pdsch->Qm = nr_get_Qm_dl(pdsch->mcs, mcsTableIdx); + pdsch->R = nr_get_code_rate_dl(pdsch->mcs, mcsTableIdx); + res = nr_find_nb_rb(pdsch->Qm, + pdsch->R, 1, // no transform precoding for DL 1, // single layer tda_info->nrOfSymbols, @@ -310,59 +307,56 @@ static uint32_t get_tbs_bch(NR_sched_pdsch_t *pdsch, num_total_bytes, 1, // min_rbSize max_rbSize, - &TBS, - &rbSize); + &pdsch->tb_size, + &pdsch->rbSize); if (!res) pdsch->mcs++; } break; } } - AssertFatal(TBS >= num_total_bytes, + AssertFatal(pdsch->tb_size >= num_total_bytes, "Couldn't allocate enough resources for %d bytes in SIB PDSCH (rbStart %d, rbSize %d, bwpSize %d)\n", num_total_bytes, - rbStart, - rbSize, + pdsch->rbStart, + pdsch->rbSize, bwpSize); - pdsch->rbSize = rbSize; - pdsch->rbStart = rbStart; - LOG_D(NR_MAC, "mcs=%i, startSymbolIndex = %i, nrOfSymbols = %i, rbSize = %i, TBS = %i, dmrs_length %d, N_PRB_DMRS = %d, mappingtype = %d\n", pdsch->mcs, tda_info->startSymbolIndex, tda_info->nrOfSymbols, - rbSize, - TBS, + pdsch->rbSize, + pdsch->tb_size, pdsch->dmrs_parms.N_DMRS_SLOT, N_PRB_DMRS, tda_info->mapping_type); - return TBS; } -static uint32_t schedule_control_sib1(gNB_MAC_INST *gNB_mac, - int CC_id, - NR_sched_pdcch_t *pdcch, - NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config, - int time_domain_allocation, - NR_pdsch_dmrs_t *dmrs_parms, - NR_tda_info_t *tda_info, - uint8_t candidate_idx, - int beam, - uint16_t num_total_bytes) +static NR_sched_pdsch_t schedule_control_sib1(gNB_MAC_INST *gNB_mac, + int CC_id, + NR_sched_pdcch_t *pdcch, + NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config, + int time_domain_allocation, + NR_pdsch_dmrs_t *dmrs_parms, + NR_tda_info_t *tda_info, + uint8_t candidate_idx, + int beam, + uint16_t num_total_bytes) { AssertFatal(gNB_mac->sched_ctrlCommon, "sched_ctrlCommon is NULL\n"); NR_COMMON_channels_t *cc = &gNB_mac->common_channels[CC_id]; uint16_t *vrb_map = cc->vrb_map[beam]; - NR_sched_pdsch_t *pdsch = &gNB_mac->sched_ctrlCommon->sched_pdsch; - pdsch->bwp_info = get_pdsch_bwp_start_size(gNB_mac, NULL); - pdsch->time_domain_allocation = time_domain_allocation; - pdsch->dmrs_parms = *dmrs_parms; - pdsch->tda_info = *tda_info; - pdsch->nrOfLayers = 1; - pdsch->pm_index = 0; - pdsch->mcs = 0; // starting from mcs 0 + NR_sched_pdsch_t pdsch = { + .bwp_info = get_pdsch_bwp_start_size(gNB_mac, NULL), + .time_domain_allocation = time_domain_allocation, + .dmrs_parms = *dmrs_parms, + .tda_info = *tda_info, + .nrOfLayers = 1, + .pm_index = 0, + .mcs = 0, // starting from mcs 0 + }; gNB_mac->sched_ctrlCommon->num_total_bytes = num_total_bytes; uint8_t nr_of_candidates = 0; @@ -383,12 +377,7 @@ static uint32_t schedule_control_sib1(gNB_MAC_INST *gNB_mac, AssertFatal(gNB_mac->sched_ctrlCommon->cce_index >= 0, "Could not find CCE for coreset0\n"); - uint32_t TBS = get_tbs_bch(&gNB_mac->sched_ctrlCommon->sched_pdsch, - gNB_mac->sched_ctrlCommon->num_total_bytes, - vrb_map); - - pdsch->R = nr_get_code_rate_dl(pdsch->mcs, 0); - pdsch->Qm = nr_get_Qm_dl(pdsch->mcs, 0); + update_rb_mcs_tbs(&pdsch, gNB_mac->sched_ctrlCommon->num_total_bytes, vrb_map); // Mark the corresponding RBs as used fill_pdcch_vrb_map(gNB_mac, @@ -397,10 +386,10 @@ static uint32_t schedule_control_sib1(gNB_MAC_INST *gNB_mac, gNB_mac->sched_ctrlCommon->cce_index, gNB_mac->sched_ctrlCommon->aggregation_level, beam); - for (int rb = 0; rb < pdsch->rbSize; rb++) { + for (int rb = 0; rb < pdsch.rbSize; rb++) { vrb_map[rb + type0_PDCCH_CSS_config->cset_start_rb] |= SL_to_bitmap(tda_info->startSymbolIndex, tda_info->nrOfSymbols); } - return TBS; + return pdsch; } static void nr_fill_nfapi_dl_SIB_pdu(gNB_MAC_INST *gNB_mac, @@ -578,22 +567,21 @@ void schedule_nr_sib1(module_id_t module_idP, NR_COMMON_channels_t *cc = &gNB_mac->common_channels[0]; // Configure sched_ctrlCommon for SIB1 - uint32_t TBS = schedule_control_sib1(gNB_mac, - CC_id, - &sched_pdcch, - type0_PDCCH_CSS_config, - time_domain_allocation, - &dmrs_parms, - &tda_info, - candidate_idx, - beam.idx, - cc->sib1_bcch_length); + NR_sched_pdsch_t sched_pdsch = schedule_control_sib1(gNB_mac, + CC_id, + &sched_pdcch, + type0_PDCCH_CSS_config, + time_domain_allocation, + &dmrs_parms, + &tda_info, + candidate_idx, + beam.idx, + cc->sib1_bcch_length); - gNB_mac->sched_ctrlCommon->sched_pdsch.tb_size = TBS; nfapi_nr_dl_tti_request_body_t *dl_req = &DL_req->dl_tti_request_body; int pdu_index = gNB_mac->pdu_index[0]++; nr_fill_nfapi_dl_SIB_pdu(gNB_mac, - &gNB_mac->sched_ctrlCommon->sched_pdsch, + &sched_pdsch, &sched_pdcch, gNB_mac->sched_ctrlCommon->search_space, gNB_mac->sched_ctrlCommon->coreset, @@ -609,11 +597,11 @@ void schedule_nr_sib1(module_id_t module_idP, nfapi_nr_pdu_t *tx_req = &TX_req->pdu_list[ntx_req]; // Data to be transmitted - memcpy(tx_req->TLVs[0].value.direct, cc->sib1_bcch_pdu, TBS); + memcpy(tx_req->TLVs[0].value.direct, cc->sib1_bcch_pdu, sched_pdsch.tb_size); tx_req->PDU_index = pdu_index; tx_req->num_TLV = 1; - tx_req->TLVs[0].length = TBS; + tx_req->TLVs[0].length = sched_pdsch.tb_size; tx_req->PDU_length = compute_PDU_length(tx_req->num_TLV, tx_req->TLVs[0].length); TX_req->Number_of_PDUs++; TX_req->SFN = frameP; @@ -718,9 +706,7 @@ static void other_sib_sched_control(module_id_t module_idP, uint16_t *vrb_map = cc->vrb_map[beam.idx]; uint8_t *sib_bcch_pdu = cc->other_sib_bcch_pdu[payload_idx]; int num_total_bytes = cc->other_sib_bcch_length[payload_idx]; - sched_pdsch_otherSI.tb_size = get_tbs_bch(&sched_pdsch_otherSI, num_total_bytes, vrb_map); - sched_pdsch_otherSI.R = nr_get_code_rate_dl(sched_pdsch_otherSI.mcs, 0); - sched_pdsch_otherSI.Qm = nr_get_Qm_dl(sched_pdsch_otherSI.mcs, 0); + update_rb_mcs_tbs(&sched_pdsch_otherSI, num_total_bytes, vrb_map); for (int rb = 0; rb < sched_pdsch_otherSI.rbSize; rb++) { vrb_map[rb + type0_PDCCH_CSS_config->cset_start_rb] |= SL_to_bitmap(tda_info.startSymbolIndex, tda_info.nrOfSymbols); From 4eb43f2c45c3500e7b009d9f9dcf2416412fbcac Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Wed, 1 Oct 2025 22:02:33 +0200 Subject: [PATCH 54/69] nr_dlsim_preprocessor(): Refactor NR_sched_pdsch usage Similarly to parent commit(s), assign sched_pdsch in a single place instead of relying on sched_ctrl. In a follow-up commit, the post-processor will be called in a single place. --- openair1/SIMULATION/NR_PHY/dlsim.c | 55 ++++++++++++++++-------------- 1 file changed, 29 insertions(+), 26 deletions(-) diff --git a/openair1/SIMULATION/NR_PHY/dlsim.c b/openair1/SIMULATION/NR_PHY/dlsim.c index 6329d5849f..3a4df8d2fc 100644 --- a/openair1/SIMULATION/NR_PHY/dlsim.c +++ b/openair1/SIMULATION/NR_PHY/dlsim.c @@ -213,46 +213,47 @@ void nr_dlsim_preprocessor(module_id_t module_id, frame_t frame, slot_t slot) AssertFatal(CCEIndex>=0, "%4d.%2d could not find CCE for DL DCI UE %d/RNTI %04x\n", frame, slot, 0, UE_info->rnti); sched_ctrl->cce_index = CCEIndex; - NR_sched_pdsch_t *sched_pdsch = &sched_ctrl->sched_pdsch; - sched_pdsch->rbStart = g_rbStart; - sched_pdsch->rbSize = g_rbSize; - sched_pdsch->bwp_info = get_pdsch_bwp_start_size(RC.nrmac[module_id], UE_info); - sched_pdsch->mcs = g_mcsIndex; - sched_pdsch->nrOfLayers = g_nrOfLayers; - sched_pdsch->pm_index = g_pmi; + NR_sched_pdsch_t sched_pdsch = { + .rbStart = g_rbStart, + .rbSize = g_rbSize, + .bwp_info = get_pdsch_bwp_start_size(RC.nrmac[module_id], UE_info), + .mcs = g_mcsIndex, + .nrOfLayers = g_nrOfLayers, + .pm_index = g_pmi, + }; /* the following might override the table that is mandated by RRC * configuration */ current_BWP->mcsTableIdx = g_mcsTableIdx; - sched_pdsch->time_domain_allocation = get_dl_tda(RC.nrmac[module_id], slot); - AssertFatal(sched_pdsch->time_domain_allocation >= 0,"Unable to find PDSCH time domain allocation in list\n"); + sched_pdsch.time_domain_allocation = get_dl_tda(RC.nrmac[module_id], slot); + AssertFatal(sched_pdsch.time_domain_allocation >= 0,"Unable to find PDSCH time domain allocation in list\n"); - sched_pdsch->tda_info = get_dl_tda_info(current_BWP, + sched_pdsch.tda_info = get_dl_tda_info(current_BWP, sched_ctrl->search_space->searchSpaceType->present, - sched_pdsch->time_domain_allocation, + sched_pdsch.time_domain_allocation, NR_MIB__dmrs_TypeA_Position_pos2, 1, TYPE_C_RNTI_, sched_ctrl->coreset->controlResourceSetId, false); - sched_pdsch->dmrs_parms = get_dl_dmrs_params(scc, + sched_pdsch.dmrs_parms = get_dl_dmrs_params(scc, current_BWP, - &sched_pdsch->tda_info, - sched_pdsch->nrOfLayers); + &sched_pdsch.tda_info, + sched_pdsch.nrOfLayers); - sched_pdsch->Qm = nr_get_Qm_dl(sched_pdsch->mcs, current_BWP->mcsTableIdx); - sched_pdsch->R = nr_get_code_rate_dl(sched_pdsch->mcs, current_BWP->mcsTableIdx); - sched_pdsch->tb_size = nr_compute_tbs(sched_pdsch->Qm, - sched_pdsch->R, - sched_pdsch->rbSize, - sched_pdsch->tda_info.nrOfSymbols, - sched_pdsch->dmrs_parms.N_PRB_DMRS * sched_pdsch->dmrs_parms.N_DMRS_SLOT, + sched_pdsch.Qm = nr_get_Qm_dl(sched_pdsch.mcs, current_BWP->mcsTableIdx); + sched_pdsch.R = nr_get_code_rate_dl(sched_pdsch.mcs, current_BWP->mcsTableIdx); + sched_pdsch.tb_size = nr_compute_tbs(sched_pdsch.Qm, + sched_pdsch.R, + sched_pdsch.rbSize, + sched_pdsch.tda_info.nrOfSymbols, + sched_pdsch.dmrs_parms.N_PRB_DMRS * sched_pdsch.dmrs_parms.N_DMRS_SLOT, 0 /* N_PRB_oh, 0 for initialBWP */, 0 /* tb_scaling */, - sched_pdsch->nrOfLayers) >> 3; + sched_pdsch.nrOfLayers) >> 3; /* the simulator assumes the HARQ PID is equal to the slot number */ - sched_pdsch->dl_harq_pid = slot; + sched_pdsch.dl_harq_pid = slot; /* The scheduler uses lists to track whether a HARQ process is * free/busy/awaiting retransmission, and updates the HARQ process states. @@ -266,10 +267,12 @@ void nr_dlsim_preprocessor(module_id_t module_id, frame_t frame, slot_t slot) else add_front_nr_list(&sched_ctrl->retrans_dl_harq, slot); // ... make PID retransmission sched_ctrl->harq_processes[slot].is_waiting = false; - AssertFatal(sched_pdsch->rbStart >= 0, "invalid rbStart %d\n", sched_pdsch->rbStart); - AssertFatal(sched_pdsch->rbSize > 0, "invalid rbSize %d\n", sched_pdsch->rbSize); - AssertFatal(sched_pdsch->mcs >= 0, "invalid mcs %d\n", sched_pdsch->mcs); + AssertFatal(sched_pdsch.rbStart >= 0, "invalid rbStart %d\n", sched_pdsch.rbStart); + AssertFatal(sched_pdsch.rbSize > 0, "invalid rbSize %d\n", sched_pdsch.rbSize); + AssertFatal(sched_pdsch.mcs >= 0, "invalid mcs %d\n", sched_pdsch.mcs); AssertFatal(current_BWP->mcsTableIdx >= 0 && current_BWP->mcsTableIdx <= 2, "invalid mcsTableIdx %d\n", current_BWP->mcsTableIdx); + + sched_ctrl->sched_pdsch = sched_pdsch; } nrUE_params_t nrUE_params; From 924f28ed70492919ee7a3fc1df4c4eb3a0917879 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 21 Aug 2025 19:21:33 +0200 Subject: [PATCH 55/69] Refactor to call post-processor in place Call the post-processor when the allocation is "fixed" (i.e., nothing changes anymore), instead of having a final loop across all UEs that might potentially be costly. In order to calculate the PF metric, note that the statistics "reset" is moved into pf_dl() instead of the post-processing loop, as it has to be done on each slot. See also: dd9803020227 ("Refactor to call post-processor in place") --- openair1/SIMULATION/NR_PHY/dlsim.c | 35 +++++---- .../LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c | 73 ++++++++----------- .../LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c | 8 +- .../NR_MAC_gNB/gNB_scheduler_primitives.c | 3 - openair2/LAYER2/NR_MAC_gNB/mac_proto.h | 3 +- openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h | 4 +- 6 files changed, 58 insertions(+), 68 deletions(-) diff --git a/openair1/SIMULATION/NR_PHY/dlsim.c b/openair1/SIMULATION/NR_PHY/dlsim.c index 3a4df8d2fc..9b3d4ac21b 100644 --- a/openair1/SIMULATION/NR_PHY/dlsim.c +++ b/openair1/SIMULATION/NR_PHY/dlsim.c @@ -182,13 +182,13 @@ extern void fix_scd(NR_ServingCellConfig_t *scd);// forward declaration /* specific dlsim DL preprocessor: uses rbStart/rbSize/mcs/nrOfLayers from command line of dlsim */ int g_mcsIndex = -1, g_mcsTableIdx = 0, g_rbStart = -1, g_rbSize = -1, g_nrOfLayers = 1, g_pmi = 0; -void nr_dlsim_preprocessor(module_id_t module_id, frame_t frame, slot_t slot) +void nr_dlsim_preprocessor(gNB_MAC_INST *nr_mac, post_process_pdsch_t *pp_pdsch) { - NR_UE_info_t *UE_info = RC.nrmac[module_id]->UE_info.connected_ue_list[0]; - AssertFatal(RC.nrmac[module_id]->UE_info.connected_ue_list[1] == NULL, "Only single UE allowed in dlsim\n"); + NR_UE_info_t *UE_info = nr_mac->UE_info.connected_ue_list[0]; + AssertFatal(nr_mac->UE_info.connected_ue_list[1] == NULL, "Only single UE allowed in dlsim\n"); NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl; NR_UE_DL_BWP_t *current_BWP = &UE_info->current_DL_BWP; - NR_ServingCellConfigCommon_t *scc = RC.nrmac[0]->common_channels[0].ServingCellConfigCommon; + NR_ServingCellConfigCommon_t *scc = nr_mac->common_channels[0].ServingCellConfigCommon; uint8_t nr_of_candidates = 0; if (g_mcsIndex < 4) { @@ -201,8 +201,8 @@ void nr_dlsim_preprocessor(module_id_t module_id, frame_t frame, slot_t slot) &nr_of_candidates, sched_ctrl->search_space,4); } - uint32_t Y = get_Y(sched_ctrl->search_space, slot, UE_info->rnti); - int CCEIndex = find_pdcch_candidate(RC.nrmac[module_id], + uint32_t Y = get_Y(sched_ctrl->search_space, pp_pdsch->slot, UE_info->rnti); + int CCEIndex = find_pdcch_candidate(nr_mac, /* CC_id = */ 0, sched_ctrl->aggregation_level, nr_of_candidates, @@ -210,13 +210,18 @@ void nr_dlsim_preprocessor(module_id_t module_id, frame_t frame, slot_t slot) &sched_ctrl->sched_pdcch, sched_ctrl->coreset, Y); - AssertFatal(CCEIndex>=0, "%4d.%2d could not find CCE for DL DCI UE %d/RNTI %04x\n", frame, slot, 0, UE_info->rnti); + AssertFatal(CCEIndex >= 0, + "%4d.%2d could not find CCE for DL DCI UE %d/RNTI %04x\n", + pp_pdsch->frame, + pp_pdsch->slot, + 0, + UE_info->rnti); sched_ctrl->cce_index = CCEIndex; NR_sched_pdsch_t sched_pdsch = { .rbStart = g_rbStart, .rbSize = g_rbSize, - .bwp_info = get_pdsch_bwp_start_size(RC.nrmac[module_id], UE_info), + .bwp_info = get_pdsch_bwp_start_size(nr_mac, UE_info), .mcs = g_mcsIndex, .nrOfLayers = g_nrOfLayers, .pm_index = g_pmi, @@ -224,7 +229,7 @@ void nr_dlsim_preprocessor(module_id_t module_id, frame_t frame, slot_t slot) /* the following might override the table that is mandated by RRC * configuration */ current_BWP->mcsTableIdx = g_mcsTableIdx; - sched_pdsch.time_domain_allocation = get_dl_tda(RC.nrmac[module_id], slot); + sched_pdsch.time_domain_allocation = get_dl_tda(nr_mac, pp_pdsch->slot); AssertFatal(sched_pdsch.time_domain_allocation >= 0,"Unable to find PDSCH time domain allocation in list\n"); sched_pdsch.tda_info = get_dl_tda_info(current_BWP, @@ -253,7 +258,7 @@ void nr_dlsim_preprocessor(module_id_t module_id, frame_t frame, slot_t slot) sched_pdsch.nrOfLayers) >> 3; /* the simulator assumes the HARQ PID is equal to the slot number */ - sched_pdsch.dl_harq_pid = slot; + sched_pdsch.dl_harq_pid = pp_pdsch->slot; /* The scheduler uses lists to track whether a HARQ process is * free/busy/awaiting retransmission, and updates the HARQ process states. @@ -262,17 +267,17 @@ void nr_dlsim_preprocessor(module_id_t module_id, frame_t frame, slot_t slot) * Therefore, below lines just "repair" everything so that the scheduler * won't remark that there is no HARQ feedback */ sched_ctrl->feedback_dl_harq.head = -1; // always overwrite feedback HARQ process - if (sched_ctrl->harq_processes[slot].round == 0) // depending on round set in simulation ... - add_front_nr_list(&sched_ctrl->available_dl_harq, slot); // ... make PID available + if (sched_ctrl->harq_processes[pp_pdsch->slot].round == 0) // depending on round set in simulation ... + add_front_nr_list(&sched_ctrl->available_dl_harq, pp_pdsch->slot); // ... make PID available else - add_front_nr_list(&sched_ctrl->retrans_dl_harq, slot); // ... make PID retransmission - sched_ctrl->harq_processes[slot].is_waiting = false; + add_front_nr_list(&sched_ctrl->retrans_dl_harq, pp_pdsch->slot); // ... make PID retransmission + sched_ctrl->harq_processes[pp_pdsch->slot].is_waiting = false; AssertFatal(sched_pdsch.rbStart >= 0, "invalid rbStart %d\n", sched_pdsch.rbStart); AssertFatal(sched_pdsch.rbSize > 0, "invalid rbSize %d\n", sched_pdsch.rbSize); AssertFatal(sched_pdsch.mcs >= 0, "invalid mcs %d\n", sched_pdsch.mcs); AssertFatal(current_BWP->mcsTableIdx >= 0 && current_BWP->mcsTableIdx <= 2, "invalid mcsTableIdx %d\n", current_BWP->mcsTableIdx); - sched_ctrl->sched_pdsch = sched_pdsch; + post_process_dlsch(nr_mac, pp_pdsch, UE_info, &sched_pdsch); } nrUE_params_t nrUE_params; diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c index 4a39969be4..aa184d8f85 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c @@ -422,17 +422,17 @@ bwp_info_t get_pdsch_bwp_start_size(gNB_MAC_INST *nr_mac, NR_UE_info_t *UE) return bwp_info; } -static bool allocate_dl_retransmission(module_id_t module_id, - frame_t frame, - slot_t slot, +static bool allocate_dl_retransmission(gNB_MAC_INST *nr_mac, + post_process_pdsch_t *pp_pdsch, int *n_rb_sched, NR_UE_info_t *UE, int beam_idx, int current_harq_pid) { - + frame_t frame = pp_pdsch->frame; + slot_t slot = pp_pdsch->slot; int CC_id = 0; - gNB_MAC_INST *nr_mac = RC.nrmac[module_id]; + const NR_ServingCellConfigCommon_t *scc = nr_mac->common_channels->ServingCellConfigCommon; NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; NR_UE_DL_BWP_t *dl_bwp = &UE->current_DL_BWP; @@ -578,7 +578,8 @@ static bool allocate_dl_retransmission(module_id_t module_id, new_sched.rbStart = rbStart - bwp_info.bwpStart; new_sched.pucch_allocation = alloc; new_sched.bwp_info = bwp_info; - sched_ctrl->sched_pdsch = new_sched; + + post_process_dlsch(nr_mac, pp_pdsch, UE, &new_sched); /* retransmissions: directly allocate */ *n_rb_sched -= new_sched.rbSize; @@ -606,15 +607,16 @@ static int comparator(const void *p, const void *q) return 0; } -static void pf_dl(module_id_t module_id, - frame_t frame, - slot_t slot, +static void pf_dl(gNB_MAC_INST *mac, + post_process_pdsch_t *pp_pdsch, NR_UE_info_t **UE_list, int max_num_ue, int num_beams, int n_rb_sched[num_beams]) { - gNB_MAC_INST *mac = RC.nrmac[module_id]; + frame_t frame = pp_pdsch->frame; + slot_t slot = pp_pdsch->slot; + NR_ServingCellConfigCommon_t *scc=mac->common_channels[0].ServingCellConfigCommon; // UEs that could be scheduled UEsched_t UE_sched[MAX_MOBILES_PER_GNB + 1] = {0}; @@ -633,15 +635,18 @@ static void pf_dl(module_id_t module_id, if (!nr_mac_ue_is_active(UE)) continue; - const NR_mac_dir_stats_t *stats = &UE->mac_stats.dl; + NR_mac_dir_stats_t *stats = &UE->mac_stats.dl; /* get the PID of a HARQ process awaiting retrnasmission, or -1 otherwise */ int harq_pid = sched_ctrl->retrans_dl_harq.head; /* Calculate Throughput */ const float a = 0.01f; - const uint32_t b = UE->mac_stats.dl.current_bytes; + const uint32_t b = stats->current_bytes; UE->dl_thr_ue = (1 - a) * UE->dl_thr_ue + a * b; + stats->current_bytes = 0; + stats->current_rbs = 0; + /* Check if this UE should get TA (every 100 frames). If we add the CE, * ta_apply will be reset */ if (frame == ((sched_ctrl->ta_frame + 100) % 1024)) @@ -659,7 +664,7 @@ static void pf_dl(module_id_t module_id, bool sch_ret = beam.idx >= 0; /* Allocate retransmission */ if (sch_ret) - sch_ret = allocate_dl_retransmission(module_id, frame, slot, &n_rb_sched[beam.idx], UE, beam.idx, harq_pid); + sch_ret = allocate_dl_retransmission(mac, pp_pdsch, &n_rb_sched[beam.idx], UE, beam.idx, harq_pid); if (!sch_ret) { LOG_D(NR_MAC, "[UE %04x][%4d.%2d] DL retransmission could not be allocated\n", UE->rnti, frame, slot); reset_beam_status(&mac->beam_info, frame, slot, UE->UE_beam_index, slots_per_frame, beam.new_beam); @@ -876,7 +881,7 @@ static void pf_dl(module_id_t module_id, &sched_pdsch.tb_size, &sched_pdsch.rbSize); - sched_ctrl->sched_pdsch = sched_pdsch; + post_process_dlsch(mac, pp_pdsch, iterator->UE, &sched_pdsch); /* transmissions: directly allocate */ n_rb_sched[beam.idx] -= sched_pdsch.rbSize; @@ -889,9 +894,9 @@ static void pf_dl(module_id_t module_id, } } -static void nr_dlsch_preprocessor(module_id_t module_id, frame_t frame, slot_t slot) +static void nr_dlsch_preprocessor(gNB_MAC_INST *mac, post_process_pdsch_t *pp_pdsch) { - gNB_MAC_INST *mac = RC.nrmac[module_id]; + module_id_t module_id = 0; NR_UEs_t *UE_info = &mac->UE_info; if (UE_info->connected_ue_list[0] == NULL) @@ -905,7 +910,7 @@ static void nr_dlsch_preprocessor(module_id_t module_id, frame_t frame, slot_t s n_rb_sched[i] = bw; /* Retrieve amount of data to send for this UE */ - nr_store_dlsch_buffer(module_id, frame, slot); + nr_store_dlsch_buffer(module_id, pp_pdsch->frame, pp_pdsch->slot); int average_agg_level = 4; // TODO find a better estimation int max_sched_ues = bw / (average_agg_level * NR_NB_REG_PER_CCE); @@ -914,7 +919,7 @@ static void nr_dlsch_preprocessor(module_id_t module_id, frame_t frame, slot_t s max_sched_ues = min(max_sched_ues, MAX_DCI_CORESET); /* proportional fair scheduling algorithm */ - pf_dl(module_id, frame, slot, UE_info->connected_ue_list, max_sched_ues, num_beams, n_rb_sched); + pf_dl(mac, pp_pdsch, UE_info->connected_ue_list, max_sched_ues, num_beams, n_rb_sched); } nr_pp_impl_dl nr_init_dlsch_preprocessor(int CC_id) @@ -1003,7 +1008,7 @@ nfapi_nr_dl_tti_pdsch_pdu_rel15_t *prepare_pdsch_pdu(nfapi_nr_dl_tti_request_pdu void post_process_dlsch(gNB_MAC_INST *nr_mac, post_process_pdsch_t *pdsch, NR_UE_info_t *UE, NR_sched_pdsch_t *sched_pdsch) { int CC_id = 0; - int module_id = 0; + int module_id = nr_mac->Mod_id; frame_t frame = pdsch->frame; slot_t slot = pdsch->slot; @@ -1371,6 +1376,8 @@ void nr_schedule_ue_spec(module_id_t module_id, nfapi_nr_tx_data_request_t *TX_req) { gNB_MAC_INST *gNB_mac = RC.nrmac[module_id]; + int CC_id = 0; + /* already mutex protected: held in gNB_dlsch_ulsch_scheduler() */ AssertFatal(pthread_mutex_trylock(&gNB_mac->sched_lock) == EBUSY, "this function should be called with the scheduler mutex locked\n"); @@ -1378,34 +1385,14 @@ void nr_schedule_ue_spec(module_id_t module_id, if (!is_dl_slot(slot, &gNB_mac->frame_structure)) return; - /* PREPROCESSOR */ - gNB_mac->pre_processor_dl(module_id, frame, slot); - const int CC_id = 0; NR_ServingCellConfigCommon_t *scc = gNB_mac->common_channels[CC_id].ServingCellConfigCommon; - NR_UEs_t *UE_info = &gNB_mac->UE_info; - nfapi_nr_dl_tti_request_body_t *dl_req = &DL_req->dl_tti_request_body; - - post_process_pdsch_t pdsch = { frame, slot, dl_req, TX_req }; - const NR_BWP_t *initialDL = &scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters; gNB_mac->mac_stats.total_prb_aggregate += NRRIV2BW(initialDL->locationAndBandwidth, MAX_BWP_SIZE); - UE_iterator(UE_info->connected_ue_list, UE) { - NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; + nfapi_nr_dl_tti_request_body_t *dl_req = &DL_req->dl_tti_request_body; + post_process_pdsch_t pdsch = { frame, slot, dl_req, TX_req }; - if (!nr_mac_ue_is_active(UE) && !get_softmodem_params()->phy_test) - continue; + /* PREPROCESSOR */ + gNB_mac->pre_processor_dl(gNB_mac, &pdsch); - NR_sched_pdsch_t *sched_pdsch = &sched_ctrl->sched_pdsch; - UE->mac_stats.dl.current_bytes = 0; - UE->mac_stats.dl.current_rbs = 0; - - if (sched_pdsch->rbSize <= 0) - continue; - - post_process_dlsch(gNB_mac, &pdsch, UE, sched_pdsch); - - /* mark UE as scheduled */ - sched_pdsch->rbSize = 0; - } } diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c index 10b38272e8..f9121b3125 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c @@ -55,9 +55,11 @@ uint32_t target_dl_bw = 50; uint64_t dlsch_slot_bitmap = (1<<1); /* schedules whole bandwidth for first user, all the time */ -void nr_preprocessor_phytest(module_id_t module_id, frame_t frame, slot_t slot) +void nr_preprocessor_phytest(gNB_MAC_INST *mac, post_process_pdsch_t *pp_pdsch) { - gNB_MAC_INST *mac = RC.nrmac[module_id]; + frame_t frame = pp_pdsch->frame; + slot_t slot = pp_pdsch->slot; + /* already mutex protected: held in gNB_dlsch_ulsch_scheduler() */ int slot_period = slot % mac->frame_structure.numb_slots_period; if (!is_xlsch_in_slot(dlsch_slot_bitmap, slot_period)) @@ -188,7 +190,7 @@ void nr_preprocessor_phytest(module_id_t module_id, frame_t frame, slot_t slot) target_dl_Nl) >> 3; - sched_ctrl->sched_pdsch = sched_pdsch; + post_process_dlsch(mac, pp_pdsch, UE, &sched_pdsch); /* mark the corresponding RBs as used */ for (int rb = 0; rb < sched_pdsch.rbSize; rb++) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c index d5cda66b5b..a81841d9c0 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c @@ -2974,9 +2974,6 @@ NR_UE_info_t *get_new_nr_ue_inst(uid_allocator_t *uia, rnti_t rnti, NR_CellGroup NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; sched_ctrl->ta_update = 31; - /* set illegal time domain allocation to force recomputation of all fields */ - sched_ctrl->sched_pdsch.time_domain_allocation = -1; - /* Set default BWPs */ AssertFatal(UE->sc_info.n_ul_bwp <= NR_MAX_NUM_BWP, "uplinkBWP_ToAddModList has %d BWP!\n", UE->sc_info.n_ul_bwp); diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h index f04b28b8da..cfe02755b2 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h @@ -145,7 +145,7 @@ uint16_t nr_mac_compute_RIV(uint16_t N_RB_DL, uint16_t RBstart, uint16_t Lcrbs); /* \brief preprocessor for phytest: schedules UE_id 0 with fixed MCS on all * freq resources */ -void nr_preprocessor_phytest(module_id_t module_id, frame_t frame, slot_t slot); +void nr_preprocessor_phytest(gNB_MAC_INST *mac, post_process_pdsch_t *pp_pdsch); /* \brief UL preprocessor for phytest: schedules UE_id 0 with fixed MCS on a * fixed set of resources */ void nr_ul_preprocessor_phytest(gNB_MAC_INST *nr_mac, post_process_pusch_t *pp_pusch); @@ -504,5 +504,6 @@ void prepare_du_configuration_update(gNB_MAC_INST *mac, void nr_mac_clean_cellgroup(NR_CellGroupConfig_t *cell_group); +void post_process_dlsch(gNB_MAC_INST *nr_mac, post_process_pdsch_t *pdsch, NR_UE_info_t *UE, NR_sched_pdsch_t *sched_pdsch); void post_process_ulsch(gNB_MAC_INST *nr_mac, post_process_pusch_t *pusch, NR_UE_info_t *UE, NR_sched_pusch_t *sched_pusch); #endif /*__LAYER2_NR_MAC_PROTO_H__*/ diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h index 544e218e5b..035ab6ad83 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h +++ b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h @@ -633,8 +633,6 @@ typedef struct { /// PHR info: nominal UE transmit power levels (dBm) int pcmax; - /// Sched PDSCH: scheduling decisions, copied into HARQ and cleared every TTI - NR_sched_pdsch_t sched_pdsch; /// UE-estimated maximum MCS (from CSI-RS) uint8_t dl_max_mcs; @@ -847,7 +845,7 @@ typedef struct { struct gNB_MAC_INST_s; typedef struct gNB_MAC_INST_s gNB_MAC_INST; -typedef void (*nr_pp_impl_dl)(module_id_t mod_id, frame_t frame, slot_t slot); +typedef void (*nr_pp_impl_dl)(gNB_MAC_INST *nr_mac, post_process_pdsch_t *pp_pdsch); typedef void (*nr_pp_impl_ul)(gNB_MAC_INST *nr_mac, post_process_pusch_t *pp_pusch); typedef struct f1_config_t { From 67ba4f67417a3c5abcc2e9b1c23223035918e767 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 25 Sep 2025 18:43:15 +0200 Subject: [PATCH 56/69] evaluate_cqi_report(): Add LOG_D for reported CQI --- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c index f3de970683..ed5f3183c7 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c @@ -680,6 +680,8 @@ static void evaluate_cqi_report(uint8_t *payload, const int cqi_idx = sched_ctrl->CSI_report.cri_ri_li_pmi_cqi_report.wb_cqi_1tb; const int mcs_table = UE->current_DL_BWP.mcsTableIdx; sched_ctrl->dl_max_mcs = get_mcs_from_cqi(mcs_table, cqi_Table, cqi_idx); + + LOG_D(MAC, "Reported CQI = %d, dl_max_mcs %d\n", temp_cqi, sched_ctrl->dl_max_mcs); } static uint8_t evaluate_pmi_report(uint8_t *payload, From 1292cd68b7d0fe830d0c78285ba6df7bee252189 Mon Sep 17 00:00:00 2001 From: Laurent THOMAS Date: Wed, 29 Oct 2025 15:16:02 +0100 Subject: [PATCH 57/69] Remove the usage of global mem for rach rx process saves about 600MB of memory allocation Move the definition of PRACH items and the PRACH list to the defs_nr_commons.h file. Do not re-write the entire structure in nr_schedule_rx_prach(), as it is quite large now. --- executables/nr-gnb.c | 1 - executables/nr-ru.c | 3 +- openair1/PHY/INIT/nr_init_ru.c | 20 ----------- openair1/PHY/NR_TRANSPORT/nr_prach.c | 15 +++------ .../PHY/NR_TRANSPORT/nr_transport_proto.h | 1 - openair1/PHY/defs_RU.h | 2 -- openair1/PHY/defs_common.h | 33 ++----------------- openair1/PHY/defs_nr_common.h | 28 ++++++++++++++++ openair1/SIMULATION/NR_PHY/prachsim.c | 21 ++---------- radio/fhi_72/oaioran.c | 7 +++- radio/fhi_72/oran_isolate.c | 30 +++++++++-------- radio/fhi_72/oran_isolate.h | 5 +-- 12 files changed, 64 insertions(+), 102 deletions(-) diff --git a/executables/nr-gnb.c b/executables/nr-gnb.c index 0e4fba9812..b0509f158d 100644 --- a/executables/nr-gnb.c +++ b/executables/nr-gnb.c @@ -387,7 +387,6 @@ void init_eNB_afterRU(void) int aa = 0; for (int ru_id = 0; ru_id < gNB->num_RU; ru_id++) { AssertFatal(gNB->RU_list[ru_id]->common.rxdataF != NULL, "RU %d : common.rxdataF is NULL\n", gNB->RU_list[ru_id]->idx); - AssertFatal(gNB->RU_list[ru_id]->prach_rxsigF != NULL, "RU %d : prach_rxsigF is NULL\n", gNB->RU_list[ru_id]->idx); for (int i = 0; i < gNB->RU_list[ru_id]->nb_rx; aa++, i++) { LOG_I(PHY, "Attaching RU %d antenna %d to gNB antenna %d\n", gNB->RU_list[ru_id]->idx, i, aa); for (int b = 0; b < gNB->RU_list[ru_id]->num_beams_period; b++) { diff --git a/executables/nr-ru.c b/executables/nr-ru.c index 9e4e6a5384..ea43ecdff1 100644 --- a/executables/nr-ru.c +++ b/executables/nr-ru.c @@ -1216,8 +1216,7 @@ void *ru_thread(void *param) prach_item_t *p = find_nr_prach(&gNB->prach_list, proc->frame_rx, proc->tti_rx, SEARCH_EXIST); if (p) { VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_RU_PRACH_RX, 1 ); - // this fills ru->prach_rxsigF for processing by gNB - p->rxsigF = (c16_t ***)ru->prach_rxsigF; + // need to extract RACH data for lqter processing by rx_nr_prach() rx_nr_prach_ru(p, ru->common.rxdata, ru->nr_frame_parms, ru->N_TA_offset); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_RU_PRACH_RX, 0); } // end if (prach_id >= 0) diff --git a/openair1/PHY/INIT/nr_init_ru.c b/openair1/PHY/INIT/nr_init_ru.c index 30ec333c70..71418bb1e3 100644 --- a/openair1/PHY/INIT/nr_init_ru.c +++ b/openair1/PHY/INIT/nr_init_ru.c @@ -112,25 +112,10 @@ void nr_phy_init_RU(RU_t *ru) LOG_D(PHY, "rxdataF[%d] %p for RU %d\n", i, ru->common.rxdataF[i], ru->idx); } - /* number of elements of an array X is computed as sizeof(X) / sizeof(X[0]) */ - // AssertFatal(ru->nb_rx <= sizeof(ru->prach_rxsigF) / sizeof(ru->prach_rxsigF[0]), - // "nb_antennas_rx too large"); - for (int j = 0; j < NUMBER_OF_NR_RU_PRACH_OCCASIONS_MAX; j++) { - ru->prach_rxsigF[j] = malloc(nb_rx_streams * sizeof(*ru->prach_rxsigF)); - - for (int i = 0; i < nb_rx_streams; i++) { - // largest size for PRACH FFT is 4x98304 (16*24576) - ru->prach_rxsigF[j][i] = malloc16_clear(4 * 98304 * 2 * sizeof(**ru->prach_rxsigF)); - LOG_D(PHY, "[INIT] prach_vars->rxsigF[%d] = %p\n", i, ru->prach_rxsigF[j][i]); - } - } - AssertFatal(ru->num_gNB <= NUMBER_OF_gNB_MAX, "gNB instances %d > %d\n", ru->num_gNB,NUMBER_OF_gNB_MAX); LOG_D(PHY, "[INIT] %s() ru->num_gNB:%d \n", __FUNCTION__, ru->num_gNB); } // !=IF5 - - init_prach_list(&ru->prach_list); } void nr_phy_free_RU(RU_t *ru) @@ -172,11 +157,6 @@ void nr_phy_free_RU(RU_t *ru) free_and_zero(ru->common.rxdataF[i]); free_and_zero(ru->common.rxdataF); - for (int j = 0; j < NUMBER_OF_NR_RU_PRACH_OCCASIONS_MAX; j++) { - for (int i = 0; i < nb_rx_streams; i++) - free_and_zero(ru->prach_rxsigF[j][i]); - free_and_zero(ru->prach_rxsigF[j]); - } for(int i = 0; i < ru->num_beams_period; ++i) free_and_zero(ru->common.beam_id[i]); free_and_zero(ru->common.beam_id); diff --git a/openair1/PHY/NR_TRANSPORT/nr_prach.c b/openair1/PHY/NR_TRANSPORT/nr_prach.c index 101bd76463..0d6a4887ca 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_prach.c +++ b/openair1/PHY/NR_TRANSPORT/nr_prach.c @@ -88,7 +88,10 @@ prach_item_t *nr_fill_prach(PHY_VARS_gNB *gNB, int SFN, int Slot, nfapi_nr_prach } const int fmt = prach_pdu->prach_format; NR_DL_FRAME_PARMS *fp = &gNB->frame_parms; - *prach = (prach_item_t){.frame = SFN, .slot = Slot, .num_slots = (fmt < 4) ? get_long_prach_dur(fmt, fp->numerology_index) : 1}; + // we set only elements as the whole structure has been cleaned when we release it + prach->frame = SFN; + prach->slot = Slot; + prach->num_slots = fmt < 4 ? get_long_prach_dur(fmt, fp->numerology_index) : 1; if (gNB->common_vars.beam_id) { int n_symb = get_nr_prach_duration(prach_pdu->prach_format); AssertFatal(prach_pdu->beamforming.dig_bf_interface < NFAPI_MAX_NUM_BG_IF, @@ -123,16 +126,6 @@ prach_item_t *nr_fill_prach(PHY_VARS_gNB *gNB, int SFN, int Slot, nfapi_nr_prach return prach; } -void nr_fill_prach_ru(RU_t *ru, prach_item_t *gnb_prach) -{ - prach_item_t *prach = find_nr_prach(&ru->prach_list, gnb_prach->frame, gnb_prach->slot, SEARCH_EXIST_OR_FREE); - if (!prach) { - LOG_E(PHY, "no prach memory found\n"); - return; - } - *prach = *gnb_prach; -} - static void rx_nr_prach_ru_internal(prach_item_t *p, int beam_id, int prachStartSymbol, diff --git a/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h b/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h index fd0a36536d..31a89e823b 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h +++ b/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h @@ -211,7 +211,6 @@ rx_prach_out_t rx_nr_prach(const prach_item_t *, int occasion); void rx_nr_prach_ru(prach_item_t *, int32_t **, NR_DL_FRAME_PARMS *frame_parms, int N_TA_offset); -void nr_fill_prach_ru(RU_t *ru,prach_item_t * ); prach_item_t *find_nr_prach(prach_list_t *, int frame, int slot, find_type_t type); void nr_fill_pucch(PHY_VARS_gNB *gNB, int frame, diff --git a/openair1/PHY/defs_RU.h b/openair1/PHY/defs_RU.h index b94d0b1c56..0e21f37fde 100644 --- a/openair1/PHY/defs_RU.h +++ b/openair1/PHY/defs_RU.h @@ -190,7 +190,6 @@ typedef struct { task_ans_t *ans; } feptx_cmd_t; -#define NUMBER_OF_NR_RU_PRACH_OCCASIONS_MAX 12 #define RU_RX_SLOT_DEPTH 4 typedef struct RU_proc_t_s { /// Pointer to associated RU descriptor @@ -592,7 +591,6 @@ typedef struct RU_t_s { int32_t *bw_list[NUMBER_OF_eNB_MAX+1]; /// beamforming weight vectors int32_t **beam_weights[NUMBER_OF_eNB_MAX+1][15]; - prach_list_t prach_list; /// received frequency-domain signal for PRACH (IF4p5 RRU) int16_t **prach_rxsigF[NUMBER_OF_NR_RU_PRACH_OCCASIONS_MAX]; /// received frequency-domain signal for PRACH BR (IF4p5 RRU) diff --git a/openair1/PHY/defs_common.h b/openair1/PHY/defs_common.h index efaccf2bf7..dbb07a9bbb 100644 --- a/openair1/PHY/defs_common.h +++ b/openair1/PHY/defs_common.h @@ -993,41 +993,14 @@ extern int sync_var; #define MBSFN_FDD_SF6 0x10 #define MBSFN_FDD_SF7 0x08 #define MBSFN_FDD_SF8 0x04 + +#define NUMBER_OF_NR_RU_PRACH_OCCASIONS_MAX 12 + typedef struct { pthread_mutex_t mutex_failure; bool failed; } decode_abort_t; -// TODO will be removed in a late commit -#include "nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h" -#define NUMBER_OF_NR_PRACH_MAX 8 -typedef struct { - int frame; - int slot; - int num_slots; // prach duration in slots - int beams[NFAPI_MAX_NUM_BG_IF]; - nfapi_nr_prach_pdu_t pdu; - int rootSequenceIndex; - int numrootSequenceIndex; - int msg1_frequencystart; - int mu; - int prach_sequence_length; - int restricted_set; - int numerology_index; - int nb_rx; - c16_t ***rxsigF; - c16_t (*Xu)[839]; - time_stats_t *rx_prach; -} prach_item_t; - -typedef struct { - /// prach commands - prach_item_t list[NUMBER_OF_NR_PRACH_MAX]; - /// mutex for prach_list access - pthread_mutex_t prach_list_mutex; -} prach_list_t; -void init_prach_list(prach_list_t *); - static inline void init_abort(decode_abort_t *ab) { int ret = pthread_mutex_init(&ab->mutex_failure, NULL); diff --git a/openair1/PHY/defs_nr_common.h b/openair1/PHY/defs_nr_common.h index 0d1cab4045..f4681020eb 100644 --- a/openair1/PHY/defs_nr_common.h +++ b/openair1/PHY/defs_nr_common.h @@ -133,6 +133,34 @@ typedef struct { int resource_type; } nr_srs_info_t; +#define NUMBER_OF_NR_PRACH_MAX 8 +typedef struct { + int frame; + int slot; + int num_slots; // prach duration in slots + int beams[NFAPI_MAX_NUM_BG_IF]; + nfapi_nr_prach_pdu_t pdu; + int rootSequenceIndex; + int numrootSequenceIndex; + int msg1_frequencystart; + int mu; + int prach_sequence_length; + int restricted_set; + int numerology_index; + int nb_rx; + c16_t rxsigF[NUMBER_OF_NR_RU_PRACH_OCCASIONS_MAX][NB_ANTENNAS_RX][NR_PRACH_SEQ_LEN_L]; + c16_t (*Xu)[839]; + time_stats_t *rx_prach; +} prach_item_t; + +typedef struct { + /// prach commands + prach_item_t list[NUMBER_OF_NR_PRACH_MAX]; + /// mutex for prach_list access + pthread_mutex_t prach_list_mutex; +} prach_list_t; +void init_prach_list(prach_list_t *); + typedef struct NR_DL_FRAME_PARMS NR_DL_FRAME_PARMS; typedef uint32_t (*get_samples_per_slot_t)(int slot, const NR_DL_FRAME_PARMS *fp); diff --git a/openair1/SIMULATION/NR_PHY/prachsim.c b/openair1/SIMULATION/NR_PHY/prachsim.c index 7d87ac54a7..aba532a80d 100644 --- a/openair1/SIMULATION/NR_PHY/prachsim.c +++ b/openair1/SIMULATION/NR_PHY/prachsim.c @@ -718,15 +718,6 @@ int main(int argc, char **argv){ if (n_frames == 1) printf("slot %d, rx_prach_start %d\n", slot, rx_prach_start); - c16_t **rxsigF[NUMBER_OF_NR_RU_PRACH_OCCASIONS_MAX]; - for (int j = 0; j < NUMBER_OF_NR_RU_PRACH_OCCASIONS_MAX; j++) { - rxsigF[j] = malloc(ru->nb_rx * sizeof(*rxsigF)); - for (int i = 0; i < ru->nb_rx; i++) { - // largest size for PRACH FFT is 4x98304 (16*24576) - rxsigF[j][i] = malloc16_clear(4 * 98304 * sizeof(**rxsigF)); - } - } - for (SNR = snr0; SNR < snr1 && !stop; SNR += .1) { for (ue_speed = ue_speed0; ue_speed < ue_speed1 && !stop; ue_speed += 10) { delay_avg = 0.0; @@ -792,7 +783,6 @@ int main(int argc, char **argv){ .restricted_set = cfg->restricted_set_config.value, .numerology_index = gNB->frame_parms.numerology_index, .nb_rx = gNB->gNB_config.carrier_config.num_rx_ant.value, - .rxsigF = rxsigF, .Xu = gNB->X_u, .rx_prach = &gNB->rx_prach}; rx_nr_prach_ru(&in, ru->common.rxdata, ru->nr_frame_parms, ru->N_TA_offset); @@ -824,7 +814,7 @@ int main(int argc, char **argv){ LOG_M("rxsig0.m","rxs0", &ru->common.rxdata[0][subframe*frame_parms->samples_per_subframe], frame_parms->samples_per_subframe, 1, 1); LOG_M("ru_rxsig0.m","rxs0", &ru->common.rxdata[0][subframe*frame_parms->samples_per_subframe], frame_parms->samples_per_subframe, 1, 1); LOG_M("ru_rxsigF0.m","rxsF0", ru->common.rxdataF[0], frame_parms->ofdm_symbol_size*frame_parms->symbols_per_slot, 1, 1); - LOG_M("ru_prach_rxsigF0.m", "rxsF0", rxsigF[0][0], N_ZC, 1, 1); + LOG_M("ru_prach_rxsigF0.m", "rxsF0", in.rxsigF[0][0], N_ZC, 1, 1); LOG_M("prach_preamble.m","prachp", &gNB->X_u[0], N_ZC, 1, 1); LOG_M("ue_prach_preamble.m","prachp", &UE->X_u[0], N_ZC, 1, 1); #endif @@ -844,14 +834,7 @@ int main(int argc, char **argv){ } if (input_fd) break; - } //SNR loop - for (int j = 0; j < NUMBER_OF_NR_RU_PRACH_OCCASIONS_MAX; j++) { - for (int i = 0; i < ru->nb_rx; i++) { - // largest size for PRACH FFT is 4x98304 (16*24576) - free(rxsigF[j][i]); - } - free(rxsigF[j]); - } + } // SNR loop free_channel_desc_scm(UE2gNB); nr_phy_free_RU(ru); diff --git a/radio/fhi_72/oaioran.c b/radio/fhi_72/oaioran.c index 37661d7ad1..493221d6a9 100644 --- a/radio/fhi_72/oaioran.c +++ b/radio/fhi_72/oaioran.c @@ -184,12 +184,17 @@ static int read_prach_data(ru_info_t *ru, int frame, int slot) int nb_rx_per_ru = ru->nb_rx / fh_init->xran_ports; /* If it is PRACH slot, copy prach IQ from XRAN PRACH buffer to OAI PRACH buffer */ if (is_prach_slot) { + if (!ru->prach_buf) { + LOG_W(HW, "we get rach data from ru, but it is not scheduled %d.%d\n", frame, slot); + return -1; + } for (sym_idx = 0; sym_idx < prach_sym; sym_idx++) { for (int aa = 0; aa < ru->nb_rx; aa++) { int16_t *dst, *src; int idx = 0; oran_buf_list_t *bufs = get_xran_buffers(aa / nb_rx_per_ru); - dst = ru->prach_buf[aa]; // + (sym_idx*576)); + // hardcoded to use only first prach occasion + dst = (int16_t *)ru->prach_buf[0][aa]; src = (int16_t *)bufs->prachdstdecomp[aa % nb_rx_per_ru][tti % XRAN_N_FE_BUF_LEN].pBuffers[sym_idx].pData; /* convert Network order to host order */ if (ru_conf->compMeth_PRACH == XRAN_COMPMETHOD_NONE) { diff --git a/radio/fhi_72/oran_isolate.c b/radio/fhi_72/oran_isolate.c index 48e95e7344..9158e468d4 100644 --- a/radio/fhi_72/oran_isolate.c +++ b/radio/fhi_72/oran_isolate.c @@ -31,6 +31,7 @@ #include "common/utils/LOG/log.h" #include "common/utils/LOG/vcd_signal_dumper.h" #include "openair1/PHY/defs_gNB.h" +#include "openair1/PHY/NR_TRANSPORT/nr_transport_proto.h" #include "oaioran.h" #include "oran-config.h" @@ -212,13 +213,15 @@ int trx_oran_ctlrecv(openair0_device *device, void *msg, ssize_t msg_len) void oran_fh_if4p5_south_in(RU_t *ru, int *frame, int *slot) { - ru_info_t ru_info; - ru_info.nb_rx = ru->nb_rx * ru->num_beams_period; - ru_info.nb_tx = ru->nb_tx * ru->num_beams_period; - ru_info.rxdataF = ru->common.rxdataF; - ru_info.beam_id = ru->common.beam_id; - ru_info.num_beams_period = ru->num_beams_period; - ru_info.prach_buf = ru->prach_rxsigF[0]; // index: [prach_oca][ant_id] + prach_item_t *prach_id = find_nr_prach(&ru->gNB_list[0]->prach_list, *frame, *slot, SEARCH_EXIST); + ru_info_t ru_info = { + .nb_rx = ru->nb_rx * ru->num_beams_period, + .nb_tx = ru->nb_tx * ru->num_beams_period, + .rxdataF = ru->common.rxdataF, + .beam_id = ru->common.beam_id, + .num_beams_period = ru->num_beams_period, + .prach_buf = prach_id ? prach_id->rxsigF : NULL, + }; RU_proc_t *proc = &ru->proc; int f, sl; @@ -269,12 +272,13 @@ void oran_fh_if4p5_south_in(RU_t *ru, int *frame, int *slot) void oran_fh_if4p5_south_out(RU_t *ru, int frame, int slot, uint64_t timestamp) { start_meas(&ru->tx_fhaul); - ru_info_t ru_info; - ru_info.nb_rx = ru->nb_rx * ru->num_beams_period; - ru_info.nb_tx = ru->nb_tx * ru->num_beams_period; - ru_info.txdataF_BF = ru->common.txdataF_BF; - ru_info.beam_id = ru->common.beam_id; - ru_info.num_beams_period = ru->num_beams_period; + ru_info_t ru_info = { + .nb_rx = ru->nb_rx * ru->num_beams_period, + .nb_tx = ru->nb_tx * ru->num_beams_period, + .txdataF_BF = ru->common.txdataF_BF, + .beam_id = ru->common.beam_id, + .num_beams_period = ru->num_beams_period, + }; // printf("south_out:\tframe=%d\tslot=%d\ttimestamp=%ld\n",frame,slot,timestamp); diff --git a/radio/fhi_72/oran_isolate.h b/radio/fhi_72/oran_isolate.h index 7dd61ad739..6ec011a24b 100644 --- a/radio/fhi_72/oran_isolate.h +++ b/radio/fhi_72/oran_isolate.h @@ -28,7 +28,8 @@ #include #include "xran_fh_o_du.h" - +#include "openair1/PHY/impl_defs_nr.h" +#include "openair1/PHY/TOOLS/tools_defs.h" /* * Structure added to bear the information needed from OAI RU */ @@ -50,7 +51,7 @@ typedef struct ru_info_s { int num_beams_period; // Needed for Prach - int16_t **prach_buf; + c16_t (*prach_buf)[NB_ANTENNAS_RX][NR_PRACH_SEQ_LEN_L]; } ru_info_t; /** @brief Reads RX data (PRACH/PUSCH) of next slot. From 80223d36d532e04bf05e250ea00a793963715cdf Mon Sep 17 00:00:00 2001 From: Laurent THOMAS Date: Wed, 29 Oct 2025 15:20:09 +0100 Subject: [PATCH 58/69] Rename nr_fill_prach to nr_schedule_rx_prach() --- doc/SW-archi-graph.md | 2 +- openair1/PHY/NR_TRANSPORT/nr_prach.c | 2 +- openair1/PHY/NR_TRANSPORT/nr_transport_proto.h | 2 +- openair1/SCHED/nfapi_lte_dummy.c | 10 ++++------ openair1/SCHED/nfapi_nr_dummy.c | 2 +- openair1/SCHED_NR/fapi_nr_l1.c | 2 +- 6 files changed, 9 insertions(+), 11 deletions(-) diff --git a/doc/SW-archi-graph.md b/doc/SW-archi-graph.md index a3397ed297..cf826e6e43 100644 --- a/doc/SW-archi-graph.md +++ b/doc/SW-archi-graph.md @@ -39,7 +39,7 @@ rx_func_implem[rx_func] --> handle_nr_nfapi_xxx_pdu --> sendTxFilled((L1_tx_filled)) --> nr_fill_ul_xxx - --> nr_fill_prach + --> nr_schedule_rx_prach() end gNB_dlsch_ulsch_scheduler --> NR_Schedule_response end diff --git a/openair1/PHY/NR_TRANSPORT/nr_prach.c b/openair1/PHY/NR_TRANSPORT/nr_prach.c index 0d6a4887ca..823af815d3 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_prach.c +++ b/openair1/PHY/NR_TRANSPORT/nr_prach.c @@ -79,7 +79,7 @@ prach_item_t *find_nr_prach(prach_list_t *l, int frame, int slot, find_type_t ty return p; } -prach_item_t *nr_fill_prach(PHY_VARS_gNB *gNB, int SFN, int Slot, nfapi_nr_prach_pdu_t *prach_pdu) +prach_item_t *nr_schedule_rx_prach(PHY_VARS_gNB *gNB, int SFN, int Slot, nfapi_nr_prach_pdu_t *prach_pdu) { prach_item_t *prach = find_nr_prach(&gNB->prach_list, SFN, Slot, SEARCH_EXIST_OR_FREE); if (!prach) { diff --git a/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h b/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h index 31a89e823b..0714f3dde3 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h +++ b/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h @@ -200,7 +200,7 @@ void nr_fill_ulsch(PHY_VARS_gNB *gNB, int slot, nfapi_nr_pusch_pdu_t *ulsch_pdu); -prach_item_t *nr_fill_prach(PHY_VARS_gNB *gNB, int SFN, int Slot, nfapi_nr_prach_pdu_t *prach_pdu); +prach_item_t *nr_schedule_rx_prach(PHY_VARS_gNB *gNB, int SFN, int Slot, nfapi_nr_prach_pdu_t *prach_pdu); typedef struct rx_prach_out { uint16_t max_preamble; diff --git a/openair1/SCHED/nfapi_lte_dummy.c b/openair1/SCHED/nfapi_lte_dummy.c index 5d9b5b7a76..be532a0c54 100644 --- a/openair1/SCHED/nfapi_lte_dummy.c +++ b/openair1/SCHED/nfapi_lte_dummy.c @@ -41,12 +41,10 @@ void nr_fill_pucch(PHY_VARS_gNB *gNB, int frame, int slot, nfapi_nr_pucch_pdu_t *pucch_pdu){} -void nr_fill_prach(PHY_VARS_gNB *gNB, - int SFN, - int Slot, - nfapi_nr_prach_pdu_t *prach_pdu){} -void nr_fill_prach_ru(RU_t *ru,prach_item_t *gnb_prach){} - +void nr_schedule_rx_prach(PHY_VARS_gNB *gNB, int SFN, int Slot, nfapi_nr_prach_pdu_t *prach_pdu) +{ +} + void nr_phy_config_request(NR_PHY_Config_t *gNB){} void install_nr_schedule_handlers(NR_IF_Module_t *if_inst){} diff --git a/openair1/SCHED/nfapi_nr_dummy.c b/openair1/SCHED/nfapi_nr_dummy.c index 87c1ea576f..7377a455dd 100644 --- a/openair1/SCHED/nfapi_nr_dummy.c +++ b/openair1/SCHED/nfapi_nr_dummy.c @@ -37,7 +37,7 @@ void nr_fill_pucch(PHY_VARS_gNB *gNB, int frame, int slot, nfapi_nr_pucch_pdu_t *pucch_pdu){} -void nr_fill_prach(PHY_VARS_gNB *gNB, int SFN, int Slot, nfapi_nr_prach_pdu_t *prach_pdu) +void nr_schedule_rx_prach(PHY_VARS_gNB *gNB, int SFN, int Slot, nfapi_nr_prach_pdu_t *prach_pdu) { } diff --git a/openair1/SCHED_NR/fapi_nr_l1.c b/openair1/SCHED_NR/fapi_nr_l1.c index 4ec87a1e5f..448af8c0e3 100644 --- a/openair1/SCHED_NR/fapi_nr_l1.c +++ b/openair1/SCHED_NR/fapi_nr_l1.c @@ -155,7 +155,7 @@ void nr_schedule_ul_tti_req(PHY_VARS_gNB *gNB, nfapi_nr_ul_tti_request_t *UL_tti UL_tti_req->Slot); nfapi_nr_prach_pdu_t *prach_pdu = &UL_tti_req->pdus_list[i].prach_pdu; LOG_D(NR_PHY_RACH, "Add prach decoding request for %d.%d\n", UL_tti_req->SFN, UL_tti_req->Slot); - prach_item_t *prach = nr_fill_prach(gNB, UL_tti_req->SFN, UL_tti_req->Slot, prach_pdu); + prach_item_t *prach = nr_schedule_rx_prach(gNB, UL_tti_req->SFN, UL_tti_req->Slot, prach_pdu); if (!prach) LOG_W(NR_PHY_RACH, "Error in scheduling rach\n"); /* the present design is not supporting multiple gNB in one RU From 0d083d83fcbf2b86170522f169e2309194e4045c Mon Sep 17 00:00:00 2001 From: Laurent THOMAS Date: Wed, 29 Oct 2025 15:18:46 +0100 Subject: [PATCH 59/69] Simplify code through lookup of PDU name, delete commented code --- .../nfapi/public_inc/nfapi_nr_interface_scf.h | 5 ++- openair1/SCHED_NR/fapi_nr_l1.c | 43 +++++-------------- 2 files changed, 15 insertions(+), 33 deletions(-) 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 754ef60e55..12cf081fdc 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 @@ -1481,7 +1481,10 @@ typedef enum { NFAPI_NR_UL_CONFIG_PUCCH_PDU_TYPE, NFAPI_NR_UL_CONFIG_SRS_PDU_TYPE, } nfapi_nr_ul_config_pdu_type_e; - +static const char* const txt_nfapi_nr_ul_config_pdu_type[] = {"NFAPI_NR_UL_CONFIG_PRACH_PDU_TYPE", + "NFAPI_NR_UL_CONFIG_PUSCH_PDU_TYPE", + "NFAPI_NR_UL_CONFIG_PUCCH_PDU_TYPE", + "NFAPI_NR_UL_CONFIG_SRS_PDU_TYPE"}; typedef struct { uint16_t pdu_type;//0: PRACH PDU, 1: PUSCH PDU, 2: PUCCH PDU, 3: SRS PDU diff --git a/openair1/SCHED_NR/fapi_nr_l1.c b/openair1/SCHED_NR/fapi_nr_l1.c index 448af8c0e3..9e4ab67efc 100644 --- a/openair1/SCHED_NR/fapi_nr_l1.c +++ b/openair1/SCHED_NR/fapi_nr_l1.c @@ -127,49 +127,28 @@ void nr_schedule_ul_tti_req(PHY_VARS_gNB *gNB, nfapi_nr_ul_tti_request_t *UL_tti int slot = UL_tti_req->Slot; for (int i = 0; i < UL_tti_req->n_pdus; i++) { - switch (UL_tti_req->pdus_list[i].pdu_type) { + int type = UL_tti_req->pdus_list[i].pdu_type; + LOG_D(NR_PHY, + "frame %d, slot %d got %s for %d.%d\n", + frame, + slot, + txt_nfapi_nr_ul_config_pdu_type[type], + UL_tti_req->SFN, + UL_tti_req->Slot); + switch (type) { case NFAPI_NR_UL_CONFIG_PUSCH_PDU_TYPE: - LOG_D(NR_PHY, - "frame %d, slot %d, Got NFAPI_NR_UL_TTI_PUSCH_PDU_TYPE for %d.%d\n", - frame, - slot, - UL_tti_req->SFN, - UL_tti_req->Slot); nr_fill_ulsch(gNB, UL_tti_req->SFN, UL_tti_req->Slot, &UL_tti_req->pdus_list[i].pusch_pdu); break; case NFAPI_NR_UL_CONFIG_PUCCH_PDU_TYPE: - LOG_D(NR_PHY, - "frame %d, slot %d, Got NFAPI_NR_UL_TTI_PUCCH_PDU_TYPE for %d.%d\n", - frame, - slot, - UL_tti_req->SFN, - UL_tti_req->Slot); nr_fill_pucch(gNB, UL_tti_req->SFN, UL_tti_req->Slot, &UL_tti_req->pdus_list[i].pucch_pdu); break; - case NFAPI_NR_UL_CONFIG_PRACH_PDU_TYPE: - LOG_D(NR_PHY, - "frame %d, slot %d, Got NFAPI_NR_UL_TTI_PRACH_PDU_TYPE for %d.%d\n", - frame, - slot, - UL_tti_req->SFN, - UL_tti_req->Slot); + case NFAPI_NR_UL_CONFIG_PRACH_PDU_TYPE: { nfapi_nr_prach_pdu_t *prach_pdu = &UL_tti_req->pdus_list[i].prach_pdu; - LOG_D(NR_PHY_RACH, "Add prach decoding request for %d.%d\n", UL_tti_req->SFN, UL_tti_req->Slot); prach_item_t *prach = nr_schedule_rx_prach(gNB, UL_tti_req->SFN, UL_tti_req->Slot, prach_pdu); if (!prach) LOG_W(NR_PHY_RACH, "Error in scheduling rach\n"); - /* the present design is not supporting multiple gNB in one RU - if (prach && (gNB->RU_list[0]->if_south == LOCAL_RF || gNB->RU_list[0]->if_south == REMOTE_IF5)) - nr_fill_prach_ru(gNB->RU_list[0], prach); - */ - break; + } break; case NFAPI_NR_UL_CONFIG_SRS_PDU_TYPE: - LOG_D(NR_PHY, - "frame %d, slot %d, Got NFAPI_NR_UL_CONFIG_SRS_PDU_TYPE for %d.%d\n", - frame, - slot, - UL_tti_req->SFN, - UL_tti_req->Slot); nr_fill_srs(gNB, UL_tti_req->SFN, UL_tti_req->Slot, &UL_tti_req->pdus_list[i].srs_pdu); break; } From d8d15205805735c6d3c0c9f81b0098bfdc9c97ae Mon Sep 17 00:00:00 2001 From: Laurent THOMAS Date: Tue, 21 Oct 2025 21:56:58 +0200 Subject: [PATCH 60/69] reduce sl_ahead to catch the RACH Msg1 in time in 24PRB test a bit difficult to understand: sl_ahead=6 => we systematically miss the rach detection in the scheduler because the scheduler runs more than 6 slots ahead the rx slot processing (here > 11 slots because 6 (DL and UL slots) + 4 (RU_RX_SLOT_DEPTH, so UL only)) so, reducing sl_ahead works better than large sl_ahead because the idea behind is: the scheduler of slot+sl_ahead will never create work to do in a UL slot before slot+sl_ahead+X (as minimum k2 is X, in the 24PRB CI test: 6) --- ci-scripts/conf_files/gnb.sa.band78.24prb.rfsim.conf | 1 + 1 file changed, 1 insertion(+) diff --git a/ci-scripts/conf_files/gnb.sa.band78.24prb.rfsim.conf b/ci-scripts/conf_files/gnb.sa.band78.24prb.rfsim.conf index 4a3d2852c4..afe40c733c 100644 --- a/ci-scripts/conf_files/gnb.sa.band78.24prb.rfsim.conf +++ b/ci-scripts/conf_files/gnb.sa.band78.24prb.rfsim.conf @@ -196,6 +196,7 @@ RUs = ( att_tx = 0 att_rx = 0; bands = [78]; + sl_ahead=3; max_pdschReferenceSignalPower = -27; max_rxgain = 114; sf_extension = 0; From 9ce9c16e368fcca70152c9d712e4cc3f82cc24f5 Mon Sep 17 00:00:00 2001 From: Laurent THOMAS Date: Wed, 29 Oct 2025 16:25:42 +0100 Subject: [PATCH 61/69] Add documentation on PRACH processing --- doc/rach_processing_in_gNB.md | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 doc/rach_processing_in_gNB.md diff --git a/doc/rach_processing_in_gNB.md b/doc/rach_processing_in_gNB.md new file mode 100644 index 0000000000..5c15cf0812 --- /dev/null +++ b/doc/rach_processing_in_gNB.md @@ -0,0 +1,24 @@ +The gNB RACH processing + +1. Collect I/Q samples +The gNB/ru main loop, in ru_thread() +If there is rach occasions in this slot +this main loop calls rx_nr_prach_ru() that stores the I/Q samples in the prach_item_t context + +2.process the samples +L1_rx_thread() has received slot indication by msg on queue resp_L1, it calls rx_func() => L1_nr_prach_procedures() +L1_nr_prach_procedures() fills nfapi_nr_rach_indication_t structure from result of rx_nr_prach() that process the content of rxsigF[prachOccasion][aa] +rx_func() sends the decoded rach to upper processing by call to NR_UL_indication() that calls handle_nr_rach() => nr_initiate_ra_proc() + +nr_initiate_ra_proc() creates a UE context if it needs, then sets UE.ra.ra_state to what it should do + +3. send the RACH DL +tx_func() that is launched by L1_tx_thread() as it gets L1_tx_out msg (from main loop in 1.) +tx_func()=>run_scheduler_monolithic()=>gNB_dlsch_ulsch_scheduler()=>nr_scheduler_RA() +nr_scheduler_RA() process all existing UE contexts, to see it it has to schedule a RACH DL + +4. global synchronisation +resp_L1 msg for (2.) is created in tx_func() that is launched by L1_tx_thread() (see3.) when it receives slot indication as it gets L1_tx_out msg +this msg is sent by the main loop (see 1.) +tx_func()=>run_scheduler_monolithic()=>nr_schedule_response ()=>nr_schedule_ul_tti_req ()=> nr_schedule_rx_prach() +writes in the triggering structure to (1.) that it will have to run rx_nr_prach_ru() in a given future slot From 27a022d6f86950d6b624b4380efb46854c1383a8 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 30 Oct 2025 23:13:46 +0100 Subject: [PATCH 62/69] Fix: avoid retransmission with 0 RBs Check and return, if necessary, that we have enough resources to make retransmissions. Without, we can asserts in L1, such as Assertion (NPRB>0 && (NPRB + RBstart <= BWPsize)) failed! In PRBalloc_to_locationandbandwidth0() openairinterface5g/common/utils/nr/nr_common.c:506 Illegal NPRB/RBstart Configuration (0,51) for BWPsize 51 which indicates that the scheduler requested a transmission with 0 PRBs, which does not make sense. --- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c | 8 ++++++++ openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c | 4 ++++ 2 files changed, 12 insertions(+) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c index aa184d8f85..b04e0029dd 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c @@ -494,6 +494,7 @@ static bool allocate_dl_retransmission(gNB_MAC_INST *nr_mac, while (rbStart + rbSize <= rbStop && !(rballoc_mask[rbStart + rbSize] & slbitmap) && rbSize < new_sched.rbSize) rbSize++; + DevAssert(rbSize > 0); } } else { /* the retransmission will use a different time domain allocation, check @@ -504,8 +505,14 @@ static bool allocate_dl_retransmission(gNB_MAC_INST *nr_mac, while (rbStart < rbStop && (rballoc_mask[rbStart] & slbitmap)) rbStart++; + if (rbStart >= rbStop) { + LOG_D(NR_MAC, "[UE %04x][%4d.%2d] could not allocate DL retransmission: no resources\n", UE->rnti, frame, slot); + return false; + } + while (rbStart + rbSize <= rbStop && !(rballoc_mask[rbStart + rbSize] & slbitmap)) rbSize++; + DevAssert(rbSize > 0); uint32_t new_tbs; uint16_t new_rbSize; @@ -1079,6 +1086,7 @@ void post_process_dlsch(gNB_MAC_INST *nr_mac, post_process_pdsch_t *pdsch, NR_UE pucch ? pucch->ul_slot : 0, sched_pdsch->pucch_allocation, sched_ctrl->tpc1); + DevAssert(sched_pdsch->rbSize > 0); const int bwp_id = current_BWP->bwp_id; const int coresetid = sched_ctrl->coreset->controlResourceSetId; diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c index f923a2c9ec..5974edf1f8 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c @@ -1834,6 +1834,10 @@ static bool allocate_ul_retransmission(gNB_MAC_INST *nrmac, const uint16_t slbitmap = SL_to_bitmap(tda_info->startSymbolIndex, tda_info->nrOfSymbols); while (rbStart < bwpSize && (rballoc_mask[rbStart + bwpStart] & slbitmap)) rbStart++; + if (rbStart >= bwpSize) { + LOG_D(NR_MAC, "[UE %04x][%4d.%2d] could not allocate UL retransmission: no resources\n", UE->rnti, frame, slot); + return false; + } int rbSize = 0; while (rbStart + rbSize < bwpSize && !(rballoc_mask[rbStart + bwpStart + rbSize] & slbitmap)) rbSize++; From 24399eac2d4126ba4eb55fc00082be85b4915193 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 9 Oct 2025 19:53:26 +0200 Subject: [PATCH 63/69] update_dlsch_buffer() for individual UEs --- .../LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c | 70 +++++++++---------- 1 file changed, 33 insertions(+), 37 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c index b04e0029dd..7a52198240 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c @@ -321,46 +321,41 @@ int nr_write_ce_dlsch_pdu(module_id_t module_idP, return offset; } -static void nr_store_dlsch_buffer(module_id_t module_id, frame_t frame, slot_t slot) +static uint32_t update_dlsch_buffer(frame_t frame, slot_t slot, NR_UE_info_t *UE) { - UE_iterator(RC.nrmac[module_id]->UE_info.connected_ue_list, UE) { - NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; - sched_ctrl->num_total_bytes = 0; - sched_ctrl->dl_pdus_total = 0; + NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; + sched_ctrl->num_total_bytes = 0; + sched_ctrl->dl_pdus_total = 0; - /* loop over all activated logical channels */ - // Note: DL_SCH_LCID_DCCH, DL_SCH_LCID_DCCH1, DL_SCH_LCID_DTCH - for (int i = 0; i < seq_arr_size(&sched_ctrl->lc_config); ++i) { - const nr_lc_config_t *c = seq_arr_at(&sched_ctrl->lc_config, i); - const int lcid = c->lcid; - const uint16_t rnti = UE->rnti; - LOG_D(NR_MAC, "In %s: UE %x: LCID %d\n", __FUNCTION__, rnti, lcid); - memset(&sched_ctrl->rlc_status[lcid], 0, sizeof(sched_ctrl->rlc_status[lcid])); - if (c->suspended) - continue; - if (lcid == DL_SCH_LCID_DTCH && nr_timer_is_active(&sched_ctrl->transm_interrupt)) - continue; - sched_ctrl->rlc_status[lcid] = nr_mac_rlc_status_ind(rnti, frame, lcid); + /* loop over all activated logical channels */ + for (int i = 0; i < seq_arr_size(&sched_ctrl->lc_config); ++i) { + const nr_lc_config_t *c = seq_arr_at(&sched_ctrl->lc_config, i); + const int lcid = c->lcid; + const uint16_t rnti = UE->rnti; + LOG_D(NR_MAC, "UE %x: LCID %d\n", rnti, lcid); + memset(&sched_ctrl->rlc_status[lcid], 0, sizeof(sched_ctrl->rlc_status[lcid])); + if (c->suspended) + continue; + if (lcid == DL_SCH_LCID_DTCH && nr_timer_is_active(&sched_ctrl->transm_interrupt)) + continue; + sched_ctrl->rlc_status[lcid] = nr_mac_rlc_status_ind(rnti, frame, lcid); - if (sched_ctrl->rlc_status[lcid].bytes_in_buffer == 0) - continue; + if (sched_ctrl->rlc_status[lcid].bytes_in_buffer == 0) + continue; - sched_ctrl->dl_pdus_total += sched_ctrl->rlc_status[lcid].pdus_in_buffer; - sched_ctrl->num_total_bytes += sched_ctrl->rlc_status[lcid].bytes_in_buffer; - LOG_D(MAC, - "[gNB %d][%4d.%2d] %s%d->DLSCH, RLC status for UE %d: %d bytes in buffer, total DL buffer size = %d bytes, %d total PDU bytes, %s TA command\n", - module_id, - frame, - slot, - lcid < 4 ? "DCCH":"DTCH", - lcid, - UE->rnti, - sched_ctrl->rlc_status[lcid].bytes_in_buffer, - sched_ctrl->num_total_bytes, - sched_ctrl->dl_pdus_total, - sched_ctrl->ta_apply ? "send":"do not send"); - } + sched_ctrl->dl_pdus_total += sched_ctrl->rlc_status[lcid].pdus_in_buffer; + sched_ctrl->num_total_bytes += sched_ctrl->rlc_status[lcid].bytes_in_buffer; + LOG_D(MAC, + "%4d.%2d UE %04x LCID %d status: %d bytes, total buffer %d bytes %d PDUs\n", + frame, + slot, + UE->rnti, + lcid, + sched_ctrl->rlc_status[lcid].bytes_in_buffer, + sched_ctrl->num_total_bytes, + sched_ctrl->dl_pdus_total); } + return sched_ctrl->num_total_bytes; } void finish_nr_dl_harq(NR_UE_sched_ctrl_t *sched_ctrl, int harq_pid) @@ -903,7 +898,6 @@ static void pf_dl(gNB_MAC_INST *mac, static void nr_dlsch_preprocessor(gNB_MAC_INST *mac, post_process_pdsch_t *pp_pdsch) { - module_id_t module_id = 0; NR_UEs_t *UE_info = &mac->UE_info; if (UE_info->connected_ue_list[0] == NULL) @@ -917,7 +911,9 @@ static void nr_dlsch_preprocessor(gNB_MAC_INST *mac, post_process_pdsch_t *pp_pd n_rb_sched[i] = bw; /* Retrieve amount of data to send for this UE */ - nr_store_dlsch_buffer(module_id, pp_pdsch->frame, pp_pdsch->slot); + UE_iterator(mac->UE_info.connected_ue_list, UE) { + update_dlsch_buffer(pp_pdsch->frame, pp_pdsch->slot, UE); + } int average_agg_level = 4; // TODO find a better estimation int max_sched_ues = bw / (average_agg_level * NR_NB_REG_PER_CCE); From 916455f0279a2189b2580371c1bd51e71d0621eb Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 9 Oct 2025 19:55:06 +0200 Subject: [PATCH 64/69] Move update_dlsch_buffer() into pf_dl() This slightly speeds up the scheduler (it e.g., does not need to check for UEs that have retransmissions), and harmonizes with pf_ul(), which evaluates (UL) BSR at a similar place within the scheduler. --- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c index 7a52198240..d848cf99c8 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c @@ -687,6 +687,8 @@ static void pf_dl(gNB_MAC_INST *mac, continue; } + update_dlsch_buffer(pp_pdsch->frame, pp_pdsch->slot, UE); + /* Check DL buffer and skip this UE if no bytes and no TA necessary */ if (sched_ctrl->num_total_bytes == 0 && frame != (sched_ctrl->ta_frame + 100) % 1024) continue; @@ -910,11 +912,6 @@ static void nr_dlsch_preprocessor(gNB_MAC_INST *mac, post_process_pdsch_t *pp_pd for (int i = 0; i < num_beams; i++) n_rb_sched[i] = bw; - /* Retrieve amount of data to send for this UE */ - UE_iterator(mac->UE_info.connected_ue_list, UE) { - update_dlsch_buffer(pp_pdsch->frame, pp_pdsch->slot, UE); - } - int average_agg_level = 4; // TODO find a better estimation int max_sched_ues = bw / (average_agg_level * NR_NB_REG_PER_CCE); From 9449f777ccd273b6ab4ecba61ab64c0b7ac2d689 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Tue, 28 Oct 2025 19:16:46 +0100 Subject: [PATCH 65/69] Remove TBS table and recompute on demand --- .../LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c | 41 ++++++------------- 1 file changed, 12 insertions(+), 29 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c index 5974edf1f8..94325bf26b 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c @@ -1913,7 +1913,6 @@ static bool allocate_ul_retransmission(gNB_MAC_INST *nrmac, return true; } -static uint32_t ul_pf_tbs[5][29]; // pre-computed, approximate TBS values for PF coefficient typedef struct UEsched_s { float coef; bool sched_inactive; @@ -2069,8 +2068,8 @@ static int pf_ul(gNB_MAC_INST *nrmac, const int max_mcs_table = (current_BWP->mcs_table == 0 || current_BWP->mcs_table == 2) ? 28 : 27; const int max_mcs = min(bo->max_mcs, max_mcs_table); /* no per-user maximum MCS yet */ int selected_mcs; + int nrOfLayers = get_ul_nrOfLayers(sched_ctrl, current_BWP->dci_format); if (bo->harq_round_max == 1) { - int nrOfLayers = get_ul_nrOfLayers(sched_ctrl, current_BWP->dci_format); selected_mcs = get_mcs_from_SINRx10(current_BWP->mcs_table, sched_ctrl->pusch_snrx10, nrOfLayers); selected_mcs = min(max_mcs, selected_mcs); selected_mcs = max(bo->min_mcs, selected_mcs); @@ -2082,7 +2081,17 @@ static int pf_ul(gNB_MAC_INST *nrmac, /* Create UE_sched for UEs eligibale for new data transmission*/ /* Calculate coefficient*/ - const uint32_t tbs = ul_pf_tbs[current_BWP->mcs_table][selected_mcs]; + const uint8_t Qm = nr_get_Qm_dl(selected_mcs, current_BWP->mcs_table); + const uint16_t R = nr_get_code_rate_dl(selected_mcs, current_BWP->mcs_table); + const uint32_t tbs = nr_compute_tbs(Qm, + R, + 1, /* rbSize */ + 10, /* hypothetical number of slots */ + 0, /* N_PRB_DMRS * N_DMRS_SLOT */ + 0 /* N_PRB_oh, 0 for initialBWP */, + 0 /* tb_scaling */, + nrOfLayers) + >> 3; float coeff_ue = (float) tbs / UE->ul_thr_ue; bool sched_inactive = B == 0 && do_sched; LOG_D(NR_MAC, "[UE %04x][%4d.%2d] b %d, ul_thr_ue %f, tbs %d, coeff_ue %f, sched_inactive %d\n", @@ -2707,32 +2716,6 @@ static void nr_ulsch_preprocessor(gNB_MAC_INST *nr_mac, post_process_pusch_t *pp nr_pp_impl_ul nr_init_ulsch_preprocessor(int CC_id) { - /* during initialization: no mutex needed */ - /* in the PF algorithm, we have to use the TBsize to compute the coefficient. - * This would include the number of DMRS symbols, which in turn depends on - * the time domain allocation. In case we are in a mixed slot, we do not want - * to recalculate all these values, and therefore we provide a look-up table - * which should approximately(!) give us the TBsize. In particular, the - * number of symbols, the number of DMRS symbols, and the exact Qm and R, are - * not correct*/ - for (int mcsTableIdx = 0; mcsTableIdx < 5; ++mcsTableIdx) { - for (int mcs = 0; mcs < 29; ++mcs) { - if (mcs > 27 && (mcsTableIdx == 1 || mcsTableIdx == 3 || mcsTableIdx == 4)) - continue; - const uint8_t Qm = nr_get_Qm_ul(mcs, mcsTableIdx); - const uint16_t R = nr_get_code_rate_ul(mcs, mcsTableIdx); - /* note: we do not update R/Qm based on low MCS or pi2BPSK */ - ul_pf_tbs[mcsTableIdx][mcs] = nr_compute_tbs(Qm, - R, - 1, /* rbSize */ - 10, /* hypothetical number of slots */ - 0, /* N_PRB_DMRS * N_DMRS_SLOT */ - 0 /* N_PRB_oh, 0 for initialBWP */, - 0 /* tb_scaling */, - 1 /* nrOfLayers */) - >> 3; - } - } return nr_ulsch_preprocessor; } From e6b307bf6e928f9dbf311b05431c5dede1b7e23d Mon Sep 17 00:00:00 2001 From: Nick Hedberg Date: Wed, 29 Oct 2025 20:19:02 +0000 Subject: [PATCH 66/69] Indent correctly --- radio/USRP/usrp_lib.cpp | 53 +++++++++++++++++++++-------------------- 1 file changed, 27 insertions(+), 26 deletions(-) diff --git a/radio/USRP/usrp_lib.cpp b/radio/USRP/usrp_lib.cpp index 79c58b59f4..923e938869 100644 --- a/radio/USRP/usrp_lib.cpp +++ b/radio/USRP/usrp_lib.cpp @@ -488,38 +488,39 @@ static int trx_usrp_write(openair0_device *device, buff_tx[i][j] = simde_mm256_slli_epi16(tmp, 4); } } - } + } - s->tx_md.has_time_spec = true; - s->tx_md.start_of_burst = (s->tx_count==0) ? true : first_packet_state; - s->tx_md.end_of_burst = last_packet_state; - s->tx_md.time_spec = uhd::time_spec_t::from_ticks(timestamp, s->sample_rate); - s->tx_count++; + s->tx_md.has_time_spec = true; + s->tx_md.start_of_burst = (s->tx_count == 0) ? true : first_packet_state; + s->tx_md.end_of_burst = last_packet_state; + s->tx_md.time_spec = uhd::time_spec_t::from_ticks(timestamp, s->sample_rate); + s->tx_count++; -VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_BEAM_SWITCHING_GPIO,1); - // bit 13 enables gpio - if ((flags_gpio & TX_GPIO_CHANGE) != 0) { - // push GPIO bits - s->usrp->set_command_time(s->tx_md.time_spec); - s->usrp->set_gpio_attr(s->gpio_bank, "OUT", flags_gpio, MAN_MASK); - s->usrp->clear_command_time(); - } -VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_BEAM_SWITCHING_GPIO,0); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_BEAM_SWITCHING_GPIO, 1); + // bit 13 enables gpio + if ((flags_gpio & TX_GPIO_CHANGE) != 0) { + // push GPIO bits + s->usrp->set_command_time(s->tx_md.time_spec); + s->usrp->set_gpio_attr(s->gpio_bank, "OUT", flags_gpio, MAN_MASK); + s->usrp->clear_command_time(); + } + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_BEAM_SWITCHING_GPIO, 0); - if (cc>1) { - std::vector buff_ptrs; + if (cc > 1) { + std::vector buff_ptrs; - for (int i=0; itx_stream->send(buff_ptrs, nsamps, s->tx_md); - } - else { - ret = (int)s->tx_stream->send(&(((int16_t *)buff_tx[0])[0]), nsamps, s->tx_md); - } + ret = (int)s->tx_stream->send(buff_ptrs, nsamps, s->tx_md); + } else { + ret = (int)s->tx_stream->send(&(((int16_t *)buff_tx[0])[0]), nsamps, s->tx_md); + } - if (ret != nsamps) LOG_E(HW,"[xmit] tx samples %d != %d\n",ret,nsamps); - return ret; + if (ret != nsamps) { + LOG_E(HW, "[xmit] tx samples %d != %d\n", ret, nsamps); + } + return ret; } else { pthread_mutex_lock(&write_thread->mutex_write); From 330c4fce5d84d3d7fc6a0fbdc67ed74189537e41 Mon Sep 17 00:00:00 2001 From: Nick Hedberg Date: Wed, 29 Oct 2025 20:19:34 +0000 Subject: [PATCH 67/69] Fix capitalization --- openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c index 23cd60b25f..0939b52c7a 100644 --- a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c +++ b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c @@ -82,7 +82,7 @@ void print_ue_mac_stats(const module_id_t mod, const int frame_rx, const int slo for (int i = 1; i < nb + 1; i++) cur += snprintf(cur, end - cur, "/%lu", mac->stats.dl.rounds[i]); - cur += snprintf(cur, end - cur, "\n Ul harq: %lu", mac->stats.ul.rounds[0]); + cur += snprintf(cur, end - cur, "\n UL harq: %lu", mac->stats.ul.rounds[0]); for (nb = NR_MAX_HARQ_ROUNDS_FOR_STATS - 1; nb > 1; nb--) if (mac->stats.ul.rounds[nb]) break; From e4812c3d8ecf6adc43124ed81ca5d7d339cfa9e4 Mon Sep 17 00:00:00 2001 From: Nick Hedberg Date: Wed, 15 Oct 2025 10:49:50 +0000 Subject: [PATCH 68/69] Allow for null-string REGISTRY names --- .../4g_l2sim_fdd/docker-compose.yml | 6 ++--- .../docker-compose.yml | 4 ++-- .../docker-compose.yml | 4 ++-- .../docker-compose.yml | 4 ++-- .../docker-compose.yml | 4 ++-- .../4g_rfsimulator_fembms/docker-compose.yml | 4 ++-- .../4g_rfsimulator_mbms/docker-compose.yml | 4 ++-- .../docker-compose.yml | 4 ++-- .../5g_f1_rfsimulator/docker-compose.yaml | 8 +++---- .../5g_fdd_rfsimulator/docker-compose.yaml | 4 ++-- .../5g_rfsimulator/docker-compose.yaml | 22 +++++++++---------- .../5g_rfsimulator_24prb/docker-compose.yaml | 4 ++-- .../5g_rfsimulator_2x2/docker-compose.yaml | 4 ++-- .../5g_rfsimulator_e1/docker-compose.yaml | 20 ++++++++--------- .../docker-compose.yaml | 4 ++-- .../5g_rfsimulator_flexric/docker-compose.yml | 16 +++++++------- .../docker-compose.yaml | 4 ++-- .../docker-compose.yaml | 4 ++-- .../5g_rfsimulator_n2_ho/docker-compose.yaml | 14 ++++++------ .../docker-compose.yaml | 4 ++-- .../docker-compose.yaml | 4 ++-- .../docker-compose.yaml | 4 ++-- .../docker-compose.yaml | 4 ++-- .../docker-compose.yaml | 6 ++--- .../5g_sa_f1_b210_ho/docker-compose.yml | 6 ++--- .../5g_sa_n2_ho_b210/docker-compose.yml | 4 ++-- .../5g_sa_n310_2x2_100MHz/docker-compose.yml | 2 +- .../5g_sa_n310_2x2_60MHz/docker-compose.yml | 2 +- .../5g_sa_n310_4x4_60MHz/docker-compose.yml | 4 ++-- .../5g_sa_n310_gnb/docker-compose.yml | 2 +- .../5g_sa_n310_nrue/docker-compose.yml | 2 +- .../fr1_enb_mono_fdd_tim/docker-compose.yml | 2 +- .../docker-compose.yml | 4 ++-- .../lte_b200_fdd_05Mhz_tm1/docker-compose.yml | 2 +- .../docker-compose.yml | 2 +- .../docker-compose.yml | 2 +- .../lte_b200_fdd_10Mhz_tm1/docker-compose.yml | 2 +- .../docker-compose.yml | 2 +- .../docker-compose.yml | 2 +- .../lte_b200_fdd_20Mhz_tm1/docker-compose.yml | 2 +- .../docker-compose.yml | 4 ++-- .../lte_b200_tdd_05Mhz_tm1/docker-compose.yml | 2 +- .../lte_b200_tdd_05Mhz_tm2/docker-compose.yml | 2 +- .../lte_b200_tdd_10Mhz_tm1/docker-compose.yml | 2 +- .../lte_b200_tdd_20Mhz_tm1/docker-compose.yml | 2 +- .../docker-compose.yml | 2 +- .../lte_n3xx_tdd_2x2_tm1/docker-compose.yml | 2 +- .../lte_n3xx_tdd_2x2_tm2/docker-compose.yml | 2 +- .../nsa_b200_enb/docker-compose.yml | 2 +- .../nsa_b200_gnb/docker-compose.yml | 2 +- .../sa_aw2s_2x2_gnb/docker-compose.yml | 2 +- .../yaml_files/sa_aw2s_gnb/docker-compose.yml | 2 +- .../yaml_files/sa_b200_gnb/docker-compose.yml | 2 +- .../sa_e1_b200_gnb/docker-compose.yml | 6 ++--- .../sa_f1_b200_gnb/docker-compose.yml | 4 ++-- .../docker-compose.yml | 2 +- .../docker-compose.yml | 2 +- .../sa_fhi_7.2_vvdn_gnb/docker-compose.yml | 2 +- .../sa_gnb_aerial/docker-compose.yaml | 2 +- .../sa_gnb_aerial_ul/docker-compose.yaml | 2 +- .../sa_sc_b200_gnb/docker-compose.yml | 2 +- 61 files changed, 126 insertions(+), 126 deletions(-) diff --git a/ci-scripts/yaml_files/4g_l2sim_fdd/docker-compose.yml b/ci-scripts/yaml_files/4g_l2sim_fdd/docker-compose.yml index 0d810a1d4b..4ae1f78aa6 100644 --- a/ci-scripts/yaml_files/4g_l2sim_fdd/docker-compose.yml +++ b/ci-scripts/yaml_files/4g_l2sim_fdd/docker-compose.yml @@ -178,7 +178,7 @@ services: retries: 5 oai_enb: - image: ${REGISTRY:-oaisoftwarealliance}/${ENB_IMG:-oai-enb}:${TAG:-develop} + image: ${REGISTRY-oaisoftwarealliance/}${ENB_IMG:-oai-enb}:${TAG:-develop} privileged: true container_name: l2sim4g-oai-enb network_mode: "host" @@ -210,7 +210,7 @@ services: retries: 5 oai_ue1: - image: ${REGISTRY:-oaisoftwarealliance}/${LTEUE_IMG:-oai-lte-ue}:${TAG:-develop} + image: ${REGISTRY-oaisoftwarealliance/}${LTEUE_IMG:-oai-lte-ue}:${TAG:-develop} privileged: true container_name: l2sim4g-oai-lte-ue1 network_mode: "host" @@ -229,7 +229,7 @@ services: retries: 5 oai_ue2: - image: ${REGISTRY:-oaisoftwarealliance}/${LTEUE_IMG:-oai-lte-ue}:${TAG:-develop} + image: ${REGISTRY-oaisoftwarealliance/}${LTEUE_IMG:-oai-lte-ue}:${TAG:-develop} privileged: true container_name: l2sim4g-oai-lte-ue2 network_mode: "host" diff --git a/ci-scripts/yaml_files/4g_rfsimulator_fdd_05MHz/docker-compose.yml b/ci-scripts/yaml_files/4g_rfsimulator_fdd_05MHz/docker-compose.yml index 4b110abf74..5461f37a10 100644 --- a/ci-scripts/yaml_files/4g_rfsimulator_fdd_05MHz/docker-compose.yml +++ b/ci-scripts/yaml_files/4g_rfsimulator_fdd_05MHz/docker-compose.yml @@ -178,7 +178,7 @@ services: retries: 5 oai_enb0: - image: ${REGISTRY:-oaisoftwarealliance}/${ENB_IMG:-oai-enb}:${TAG:-develop} + image: ${REGISTRY-oaisoftwarealliance/}${ENB_IMG:-oai-enb}:${TAG:-develop} privileged: true container_name: rfsim4g-oai-enb networks: @@ -197,7 +197,7 @@ services: retries: 5 oai_ue0: - image: ${REGISTRY:-oaisoftwarealliance}/${LTEUE_IMG:-oai-lte-ue}:${TAG:-develop} + image: ${REGISTRY-oaisoftwarealliance/}${LTEUE_IMG:-oai-lte-ue}:${TAG:-develop} privileged: true container_name: rfsim4g-oai-lte-ue0 networks: diff --git a/ci-scripts/yaml_files/4g_rfsimulator_fdd_05MHz_noS1/docker-compose.yml b/ci-scripts/yaml_files/4g_rfsimulator_fdd_05MHz_noS1/docker-compose.yml index 9de0f448c3..ab07314c91 100644 --- a/ci-scripts/yaml_files/4g_rfsimulator_fdd_05MHz_noS1/docker-compose.yml +++ b/ci-scripts/yaml_files/4g_rfsimulator_fdd_05MHz_noS1/docker-compose.yml @@ -1,6 +1,6 @@ services: oai_enb0: - image: ${REGISTRY:-oaisoftwarealliance}/${ENB_IMG:-oai-enb}:${TAG:-develop} + image: ${REGISTRY-oaisoftwarealliance/}${ENB_IMG:-oai-enb}:${TAG:-develop} privileged: true container_name: rfsim4g-oai-enb networks: @@ -19,7 +19,7 @@ services: retries: 5 oai_ue0: - image: ${REGISTRY:-oaisoftwarealliance}/${LTEUE_IMG:-oai-lte-ue}:${TAG:-develop} + image: ${REGISTRY-oaisoftwarealliance/}${LTEUE_IMG:-oai-lte-ue}:${TAG:-develop} privileged: true container_name: rfsim4g-oai-lte-ue0 networks: diff --git a/ci-scripts/yaml_files/4g_rfsimulator_fdd_10MHz/docker-compose.yml b/ci-scripts/yaml_files/4g_rfsimulator_fdd_10MHz/docker-compose.yml index 1cb0150465..856428f728 100644 --- a/ci-scripts/yaml_files/4g_rfsimulator_fdd_10MHz/docker-compose.yml +++ b/ci-scripts/yaml_files/4g_rfsimulator_fdd_10MHz/docker-compose.yml @@ -178,7 +178,7 @@ services: retries: 5 oai_enb0: - image: ${REGISTRY:-oaisoftwarealliance}/${ENB_IMG:-oai-enb}:${TAG:-develop} + image: ${REGISTRY-oaisoftwarealliance/}${ENB_IMG:-oai-enb}:${TAG:-develop} privileged: true container_name: rfsim4g-oai-enb networks: @@ -197,7 +197,7 @@ services: retries: 5 oai_ue0: - image: ${REGISTRY:-oaisoftwarealliance}/${LTEUE_IMG:-oai-lte-ue}:${TAG:-develop} + image: ${REGISTRY-oaisoftwarealliance/}${LTEUE_IMG:-oai-lte-ue}:${TAG:-develop} privileged: true container_name: rfsim4g-oai-lte-ue0 networks: diff --git a/ci-scripts/yaml_files/4g_rfsimulator_fdd_20MHz/docker-compose.yml b/ci-scripts/yaml_files/4g_rfsimulator_fdd_20MHz/docker-compose.yml index a0e43a27d2..3458c4f11b 100644 --- a/ci-scripts/yaml_files/4g_rfsimulator_fdd_20MHz/docker-compose.yml +++ b/ci-scripts/yaml_files/4g_rfsimulator_fdd_20MHz/docker-compose.yml @@ -178,7 +178,7 @@ services: retries: 5 oai_enb0: - image: ${REGISTRY:-oaisoftwarealliance}/${ENB_IMG:-oai-enb}:${TAG:-develop} + image: ${REGISTRY-oaisoftwarealliance/}${ENB_IMG:-oai-enb}:${TAG:-develop} privileged: true container_name: rfsim4g-oai-enb networks: @@ -197,7 +197,7 @@ services: retries: 5 oai_ue0: - image: ${REGISTRY:-oaisoftwarealliance}/${LTEUE_IMG:-oai-lte-ue}:${TAG:-develop} + image: ${REGISTRY-oaisoftwarealliance/}${LTEUE_IMG:-oai-lte-ue}:${TAG:-develop} privileged: true container_name: rfsim4g-oai-lte-ue0 networks: diff --git a/ci-scripts/yaml_files/4g_rfsimulator_fembms/docker-compose.yml b/ci-scripts/yaml_files/4g_rfsimulator_fembms/docker-compose.yml index 5c7f267074..cadb22236a 100644 --- a/ci-scripts/yaml_files/4g_rfsimulator_fembms/docker-compose.yml +++ b/ci-scripts/yaml_files/4g_rfsimulator_fembms/docker-compose.yml @@ -1,6 +1,6 @@ services: oai_enb0: - image: ${REGISTRY:-oaisoftwarealliance}/${ENB_IMG:-oai-enb}:${TAG:-develop} + image: ${REGISTRY-oaisoftwarealliance/}${ENB_IMG:-oai-enb}:${TAG:-develop} privileged: true container_name: rfsim4g-oai-enb networks: @@ -19,7 +19,7 @@ services: retries: 5 oai_ue0: - image: ${REGISTRY:-oaisoftwarealliance}/${LTEUE_IMG:-oai-lte-ue}:${TAG:-develop} + image: ${REGISTRY-oaisoftwarealliance/}${LTEUE_IMG:-oai-lte-ue}:${TAG:-develop} privileged: true container_name: rfsim4g-oai-lte-ue0 networks: diff --git a/ci-scripts/yaml_files/4g_rfsimulator_mbms/docker-compose.yml b/ci-scripts/yaml_files/4g_rfsimulator_mbms/docker-compose.yml index af913ead24..027644d9a1 100644 --- a/ci-scripts/yaml_files/4g_rfsimulator_mbms/docker-compose.yml +++ b/ci-scripts/yaml_files/4g_rfsimulator_mbms/docker-compose.yml @@ -1,6 +1,6 @@ services: oai_enb0: - image: ${REGISTRY:-oaisoftwarealliance}/${ENB_IMG:-oai-enb}:${TAG:-develop} + image: ${REGISTRY-oaisoftwarealliance/}${ENB_IMG:-oai-enb}:${TAG:-develop} privileged: true container_name: rfsim4g-oai-enb networks: @@ -19,7 +19,7 @@ services: retries: 5 oai_ue0: - image: ${REGISTRY:-oaisoftwarealliance}/${LTEUE_IMG:-oai-lte-ue}:${TAG:-develop} + image: ${REGISTRY-oaisoftwarealliance/}${LTEUE_IMG:-oai-lte-ue}:${TAG:-develop} privileged: true container_name: rfsim4g-oai-lte-ue0 networks: diff --git a/ci-scripts/yaml_files/4g_rfsimulator_tdd_05MHz/docker-compose.yml b/ci-scripts/yaml_files/4g_rfsimulator_tdd_05MHz/docker-compose.yml index 7ebbed861f..24acd9c676 100644 --- a/ci-scripts/yaml_files/4g_rfsimulator_tdd_05MHz/docker-compose.yml +++ b/ci-scripts/yaml_files/4g_rfsimulator_tdd_05MHz/docker-compose.yml @@ -178,7 +178,7 @@ services: retries: 5 oai_enb0: - image: ${REGISTRY:-oaisoftwarealliance}/${ENB_IMG:-oai-enb}:${TAG:-develop} + image: ${REGISTRY-oaisoftwarealliance/}${ENB_IMG:-oai-enb}:${TAG:-develop} privileged: true container_name: rfsim4g-oai-enb networks: @@ -197,7 +197,7 @@ services: retries: 5 oai_ue0: - image: ${REGISTRY:-oaisoftwarealliance}/${LTEUE_IMG:-oai-lte-ue}:${TAG:-develop} + image: ${REGISTRY-oaisoftwarealliance/}${LTEUE_IMG:-oai-lte-ue}:${TAG:-develop} privileged: true container_name: rfsim4g-oai-lte-ue0 networks: 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 73d2505e92..49dcf0e450 100644 --- a/ci-scripts/yaml_files/5g_f1_rfsimulator/docker-compose.yaml +++ b/ci-scripts/yaml_files/5g_f1_rfsimulator/docker-compose.yaml @@ -92,7 +92,7 @@ services: retries: 5 oai-cu: - image: ${REGISTRY:-oaisoftwarealliance}/${GNB_IMG:-oai-gnb}:${TAG:-develop} + image: ${REGISTRY-oaisoftwarealliance/}${GNB_IMG:-oai-gnb}:${TAG:-develop} container_name: rfsim5g-oai-cu cap_drop: - ALL @@ -121,7 +121,7 @@ services: retries: 5 oai-du-pci0: - image: ${REGISTRY:-oaisoftwarealliance}/${GNB_IMG:-oai-gnb}:${TAG:-develop} + image: ${REGISTRY-oaisoftwarealliance/}${GNB_IMG:-oai-gnb}:${TAG:-develop} container_name: rfsim5g-oai-du-pci0 cap_drop: - ALL @@ -152,7 +152,7 @@ services: retries: 5 oai-du-pci1: - image: ${REGISTRY:-oaisoftwarealliance}/${GNB_IMG:-oai-gnb}:${TAG:-develop} + image: ${REGISTRY-oaisoftwarealliance/}${GNB_IMG:-oai-gnb}:${TAG:-develop} container_name: rfsim5g-oai-du-pci1 cap_drop: - ALL @@ -187,7 +187,7 @@ services: retries: 5 oai-nr-ue: - image: ${REGISTRY:-oaisoftwarealliance}/${NRUE_IMG:-oai-nr-ue}:${TAG:-develop} + image: ${REGISTRY-oaisoftwarealliance/}${NRUE_IMG:-oai-nr-ue}:${TAG:-develop} container_name: rfsim5g-oai-nr-ue cap_drop: - ALL diff --git a/ci-scripts/yaml_files/5g_fdd_rfsimulator/docker-compose.yaml b/ci-scripts/yaml_files/5g_fdd_rfsimulator/docker-compose.yaml index 9eec82a98b..8bcb771967 100644 --- a/ci-scripts/yaml_files/5g_fdd_rfsimulator/docker-compose.yaml +++ b/ci-scripts/yaml_files/5g_fdd_rfsimulator/docker-compose.yaml @@ -90,7 +90,7 @@ services: start_period: 10s start_interval: 500ms oai-gnb: - image: ${REGISTRY:-oaisoftwarealliance}/${GNB_IMG:-oai-gnb}:${TAG:-develop} + image: ${REGISTRY-oaisoftwarealliance/}${GNB_IMG:-oai-gnb}:${TAG:-develop} container_name: rfsim5g-oai-gnb cap_drop: - ALL @@ -113,7 +113,7 @@ services: retries: 5 ipc: host oai-nr-ue: - image: ${REGISTRY:-oaisoftwarealliance}/${NRUE_IMG:-oai-nr-ue}:${TAG:-develop} + image: ${REGISTRY-oaisoftwarealliance/}${NRUE_IMG:-oai-nr-ue}:${TAG:-develop} container_name: rfsim5g-oai-nr-ue cap_drop: - ALL diff --git a/ci-scripts/yaml_files/5g_rfsimulator/docker-compose.yaml b/ci-scripts/yaml_files/5g_rfsimulator/docker-compose.yaml index ecdf79872b..97dcce4d49 100644 --- a/ci-scripts/yaml_files/5g_rfsimulator/docker-compose.yaml +++ b/ci-scripts/yaml_files/5g_rfsimulator/docker-compose.yaml @@ -90,7 +90,7 @@ services: timeout: 5s retries: 5 oai-gnb: - image: ${REGISTRY:-oaisoftwarealliance}/${GNB_IMG:-oai-gnb}:${TAG:-develop} + image: ${REGISTRY-oaisoftwarealliance/}${GNB_IMG:-oai-gnb}:${TAG:-develop} container_name: rfsim5g-oai-gnb cap_add: - SYS_NICE @@ -114,7 +114,7 @@ services: timeout: 5s retries: 5 oai-nr-ue: - image: ${REGISTRY:-oaisoftwarealliance}/${NRUE_IMG:-oai-nr-ue}:${TAG:-develop} + image: ${REGISTRY-oaisoftwarealliance/}${NRUE_IMG:-oai-nr-ue}:${TAG:-develop} container_name: rfsim5g-oai-nr-ue cap_drop: - ALL @@ -141,7 +141,7 @@ services: timeout: 5s retries: 5 oai-nr-ue2: - image: ${REGISTRY:-oaisoftwarealliance}/${NRUE_IMG:-oai-nr-ue}:${TAG:-develop} + image: ${REGISTRY-oaisoftwarealliance/}${NRUE_IMG:-oai-nr-ue}:${TAG:-develop} container_name: rfsim5g-oai-nr-ue2 cap_drop: - ALL @@ -168,7 +168,7 @@ services: timeout: 5s retries: 5 oai-nr-ue3: - image: ${REGISTRY:-oaisoftwarealliance}/${NRUE_IMG:-oai-nr-ue}:${TAG:-develop} + image: ${REGISTRY-oaisoftwarealliance/}${NRUE_IMG:-oai-nr-ue}:${TAG:-develop} container_name: rfsim5g-oai-nr-ue3 cap_drop: - ALL @@ -195,7 +195,7 @@ services: timeout: 5s retries: 5 oai-nr-ue4: - image: ${REGISTRY:-oaisoftwarealliance}/${NRUE_IMG:-oai-nr-ue}:${TAG:-develop} + image: ${REGISTRY-oaisoftwarealliance/}${NRUE_IMG:-oai-nr-ue}:${TAG:-develop} container_name: rfsim5g-oai-nr-ue4 cap_drop: - ALL @@ -222,7 +222,7 @@ services: timeout: 5s retries: 5 oai-nr-ue5: - image: ${REGISTRY:-oaisoftwarealliance}/${NRUE_IMG:-oai-nr-ue}:${TAG:-develop} + image: ${REGISTRY-oaisoftwarealliance/}${NRUE_IMG:-oai-nr-ue}:${TAG:-develop} container_name: rfsim5g-oai-nr-ue5 cap_drop: - ALL @@ -249,7 +249,7 @@ services: timeout: 5s retries: 5 oai-nr-ue6: - image: ${REGISTRY:-oaisoftwarealliance}/${NRUE_IMG:-oai-nr-ue}:${TAG:-develop} + image: ${REGISTRY-oaisoftwarealliance/}${NRUE_IMG:-oai-nr-ue}:${TAG:-develop} container_name: rfsim5g-oai-nr-ue6 cap_drop: - ALL @@ -276,7 +276,7 @@ services: timeout: 5s retries: 5 oai-nr-ue7: - image: ${REGISTRY:-oaisoftwarealliance}/${NRUE_IMG:-oai-nr-ue}:${TAG:-develop} + image: ${REGISTRY-oaisoftwarealliance/}${NRUE_IMG:-oai-nr-ue}:${TAG:-develop} container_name: rfsim5g-oai-nr-ue7 cap_drop: - ALL @@ -303,7 +303,7 @@ services: timeout: 5s retries: 5 oai-nr-ue8: - image: ${REGISTRY:-oaisoftwarealliance}/${NRUE_IMG:-oai-nr-ue}:${TAG:-develop} + image: ${REGISTRY-oaisoftwarealliance/}${NRUE_IMG:-oai-nr-ue}:${TAG:-develop} container_name: rfsim5g-oai-nr-ue8 cap_drop: - ALL @@ -330,7 +330,7 @@ services: timeout: 5s retries: 5 oai-nr-ue9: - image: ${REGISTRY:-oaisoftwarealliance}/${NRUE_IMG:-oai-nr-ue}:${TAG:-develop} + image: ${REGISTRY-oaisoftwarealliance/}${NRUE_IMG:-oai-nr-ue}:${TAG:-develop} container_name: rfsim5g-oai-nr-ue9 cap_drop: - ALL @@ -357,7 +357,7 @@ services: timeout: 5s retries: 5 oai-nr-ue10: - image: ${REGISTRY:-oaisoftwarealliance}/${NRUE_IMG:-oai-nr-ue}:${TAG:-develop} + image: ${REGISTRY-oaisoftwarealliance/}${NRUE_IMG:-oai-nr-ue}:${TAG:-develop} container_name: rfsim5g-oai-nr-ue10 cap_drop: - ALL diff --git a/ci-scripts/yaml_files/5g_rfsimulator_24prb/docker-compose.yaml b/ci-scripts/yaml_files/5g_rfsimulator_24prb/docker-compose.yaml index 9cab11ea9e..b5b9684626 100644 --- a/ci-scripts/yaml_files/5g_rfsimulator_24prb/docker-compose.yaml +++ b/ci-scripts/yaml_files/5g_rfsimulator_24prb/docker-compose.yaml @@ -90,7 +90,7 @@ services: timeout: 5s retries: 5 oai-gnb: - image: ${REGISTRY:-oaisoftwarealliance}/${GNB_IMG:-oai-gnb}:${TAG:-develop} + image: ${REGISTRY-oaisoftwarealliance/}${GNB_IMG:-oai-gnb}:${TAG:-develop} container_name: rfsim5g-oai-gnb cap_drop: - ALL @@ -112,7 +112,7 @@ services: timeout: 5s retries: 5 oai-nr-ue: - image: ${REGISTRY:-oaisoftwarealliance}/${NRUE_IMG:-oai-nr-ue}:${TAG:-develop} + image: ${REGISTRY-oaisoftwarealliance/}${NRUE_IMG:-oai-nr-ue}:${TAG:-develop} container_name: rfsim5g-oai-nr-ue cap_drop: - ALL diff --git a/ci-scripts/yaml_files/5g_rfsimulator_2x2/docker-compose.yaml b/ci-scripts/yaml_files/5g_rfsimulator_2x2/docker-compose.yaml index 778754fd58..f3482280bd 100644 --- a/ci-scripts/yaml_files/5g_rfsimulator_2x2/docker-compose.yaml +++ b/ci-scripts/yaml_files/5g_rfsimulator_2x2/docker-compose.yaml @@ -90,7 +90,7 @@ services: timeout: 5s retries: 5 oai-gnb: - image: ${REGISTRY:-oaisoftwarealliance}/${GNB_IMG:-oai-gnb}:${TAG:-develop} + image: ${REGISTRY-oaisoftwarealliance/}${GNB_IMG:-oai-gnb}:${TAG:-develop} container_name: rfsim5g-oai-gnb cap_drop: - ALL @@ -115,7 +115,7 @@ services: retries: 5 oai-nr-ue: - image: ${REGISTRY:-oaisoftwarealliance}/${NRUE_IMG:-oai-nr-ue}:${TAG:-develop} + image: ${REGISTRY-oaisoftwarealliance/}${NRUE_IMG:-oai-nr-ue}:${TAG:-develop} container_name: rfsim5g-oai-nr-ue cap_drop: - ALL diff --git a/ci-scripts/yaml_files/5g_rfsimulator_e1/docker-compose.yaml b/ci-scripts/yaml_files/5g_rfsimulator_e1/docker-compose.yaml index 9ccce2a8e1..200a1b6e3a 100644 --- a/ci-scripts/yaml_files/5g_rfsimulator_e1/docker-compose.yaml +++ b/ci-scripts/yaml_files/5g_rfsimulator_e1/docker-compose.yaml @@ -71,7 +71,7 @@ services: interface_name: eth1 oai-cucp: - image: ${REGISTRY:-oaisoftwarealliance}/${GNB_IMG:-oai-gnb}:${TAG:-develop} + image: ${REGISTRY-oaisoftwarealliance/}${GNB_IMG:-oai-gnb}:${TAG:-develop} container_name: rfsim5g-oai-cucp cap_drop: - ALL @@ -100,7 +100,7 @@ services: retries: 5 oai-cuup: - image: ${REGISTRY:-oaisoftwarealliance}/${NRCUUP_IMG:-oai-nr-cuup}:${TAG:-develop} + image: ${REGISTRY-oaisoftwarealliance/}${NRCUUP_IMG:-oai-nr-cuup}:${TAG:-develop} container_name: rfsim5g-oai-cuup cap_drop: - ALL @@ -131,7 +131,7 @@ services: retries: 5 oai-cuup2: - image: ${REGISTRY:-oaisoftwarealliance}/${NRCUUP_IMG:-oai-nr-cuup}:${TAG:-develop} + image: ${REGISTRY-oaisoftwarealliance/}${NRCUUP_IMG:-oai-nr-cuup}:${TAG:-develop} container_name: rfsim5g-oai-cuup2 cap_drop: - ALL @@ -165,7 +165,7 @@ services: retries: 5 oai-cuup3: - image: ${REGISTRY:-oaisoftwarealliance}/${NRCUUP_IMG:-oai-nr-cuup}:${TAG:-develop} + image: ${REGISTRY-oaisoftwarealliance/}${NRCUUP_IMG:-oai-nr-cuup}:${TAG:-develop} container_name: rfsim5g-oai-cuup3 cap_drop: - ALL @@ -199,7 +199,7 @@ services: retries: 5 oai-du: - image: ${REGISTRY:-oaisoftwarealliance}/${GNB_IMG:-oai-gnb}:${TAG:-develop} + image: ${REGISTRY-oaisoftwarealliance/}${GNB_IMG:-oai-gnb}:${TAG:-develop} container_name: rfsim5g-oai-du cap_drop: - ALL @@ -230,7 +230,7 @@ services: retries: 5 oai-du2: - image: ${REGISTRY:-oaisoftwarealliance}/${GNB_IMG:-oai-gnb}:${TAG:-develop} + image: ${REGISTRY-oaisoftwarealliance/}${GNB_IMG:-oai-gnb}:${TAG:-develop} container_name: rfsim5g-oai-du2 cap_drop: - ALL @@ -264,7 +264,7 @@ services: retries: 5 oai-du3: - image: ${REGISTRY:-oaisoftwarealliance}/${GNB_IMG:-oai-gnb}:${TAG:-develop} + image: ${REGISTRY-oaisoftwarealliance/}${GNB_IMG:-oai-gnb}:${TAG:-develop} container_name: rfsim5g-oai-du3 cap_drop: - ALL @@ -298,7 +298,7 @@ services: retries: 5 oai-nr-ue: - image: ${REGISTRY:-oaisoftwarealliance}/${NRUE_IMG:-oai-nr-ue}:${TAG:-develop} + image: ${REGISTRY-oaisoftwarealliance/}${NRUE_IMG:-oai-nr-ue}:${TAG:-develop} container_name: rfsim5g-oai-nr-ue cap_drop: - ALL @@ -328,7 +328,7 @@ services: retries: 5 oai-nr-ue2: - image: ${REGISTRY:-oaisoftwarealliance}/${NRUE_IMG:-oai-nr-ue}:${TAG:-develop} + image: ${REGISTRY-oaisoftwarealliance/}${NRUE_IMG:-oai-nr-ue}:${TAG:-develop} container_name: rfsim5g-oai-nr-ue2 cap_drop: - ALL @@ -358,7 +358,7 @@ services: retries: 5 oai-nr-ue3: - image: ${REGISTRY:-oaisoftwarealliance}/${NRUE_IMG:-oai-nr-ue}:${TAG:-develop} + image: ${REGISTRY-oaisoftwarealliance/}${NRUE_IMG:-oai-nr-ue}:${TAG:-develop} container_name: rfsim5g-oai-nr-ue3 cap_drop: - ALL diff --git a/ci-scripts/yaml_files/5g_rfsimulator_fdd_phytest/docker-compose.yaml b/ci-scripts/yaml_files/5g_rfsimulator_fdd_phytest/docker-compose.yaml index 1dec021ffc..533c5d576c 100644 --- a/ci-scripts/yaml_files/5g_rfsimulator_fdd_phytest/docker-compose.yaml +++ b/ci-scripts/yaml_files/5g_rfsimulator_fdd_phytest/docker-compose.yaml @@ -1,6 +1,6 @@ services: oai-gnb: - image: ${REGISTRY:-oaisoftwarealliance}/${GNB_IMG:-oai-gnb}:${TAG:-develop} + image: ${REGISTRY-oaisoftwarealliance/}${GNB_IMG:-oai-gnb}:${TAG:-develop} container_name: rfsim5g-oai-gnb cap_drop: - ALL @@ -25,7 +25,7 @@ services: retries: 5 oai-nr-ue: - image: ${REGISTRY:-oaisoftwarealliance}/${NRUE_IMG:-oai-nr-ue}:${TAG:-develop} + image: ${REGISTRY-oaisoftwarealliance/}${NRUE_IMG:-oai-nr-ue}:${TAG:-develop} container_name: rfsim5g-oai-nr-ue cap_drop: - ALL diff --git a/ci-scripts/yaml_files/5g_rfsimulator_flexric/docker-compose.yml b/ci-scripts/yaml_files/5g_rfsimulator_flexric/docker-compose.yml index 6b9771e1c1..8e1688dff3 100644 --- a/ci-scripts/yaml_files/5g_rfsimulator_flexric/docker-compose.yml +++ b/ci-scripts/yaml_files/5g_rfsimulator_flexric/docker-compose.yml @@ -1,6 +1,6 @@ services: oai-flexric: - image: ${REGISTRY:-oaisoftwarealliance}/oai-flexric:${FLEXRIC_TAG:-develop} + image: ${REGISTRY-oaisoftwarealliance/}oai-flexric:${FLEXRIC_TAG:-develop} container_name: oai-flexric networks: public_net: @@ -13,7 +13,7 @@ services: timeout: 5s xapp-rc-moni: - image: ${REGISTRY:-oaisoftwarealliance}/oai-flexric:${FLEXRIC_TAG:-develop} + image: ${REGISTRY-oaisoftwarealliance/}oai-flexric:${FLEXRIC_TAG:-develop} command: "stdbuf -o0 /usr/local/flexric/xApp/c/monitor/xapp_rc_moni" container_name: xapp-rc-moni depends_on: @@ -30,7 +30,7 @@ services: timeout: 5s xapp-kpm-moni: - image: ${REGISTRY:-oaisoftwarealliance}/oai-flexric:${FLEXRIC_TAG:-develop} + image: ${REGISTRY-oaisoftwarealliance/}oai-flexric:${FLEXRIC_TAG:-develop} command: "stdbuf -o0 /usr/local/flexric/xApp/c/monitor/xapp_kpm_moni" container_name: xapp-kpm-moni depends_on: @@ -47,7 +47,7 @@ services: timeout: 5s xapp-kpm-rc: - image: ${REGISTRY:-oaisoftwarealliance}/oai-flexric:${FLEXRIC_TAG:-develop} + image: ${REGISTRY-oaisoftwarealliance/}oai-flexric:${FLEXRIC_TAG:-develop} command: "stdbuf -o0 /usr/local/flexric/xApp/c/kpm_rc/xapp_kpm_rc" container_name: xapp-kpm-rc depends_on: @@ -64,7 +64,7 @@ services: timeout: 5s xapp-gtp-mac-rlc-pdcp-moni: - image: ${REGISTRY:-oaisoftwarealliance}/oai-flexric:${FLEXRIC_TAG:-develop} + image: ${REGISTRY-oaisoftwarealliance/}oai-flexric:${FLEXRIC_TAG:-develop} command: "stdbuf -o0 /usr/local/flexric/xApp/c/monitor/xapp_gtp_mac_rlc_pdcp_moni" container_name: xapp-gtp-mac-rlc-pdcp-moni depends_on: @@ -81,7 +81,7 @@ services: timeout: 5s oai-gnb: - image: ${REGISTRY:-oaisoftwarealliance}/${GNB_IMG:-oai-gnb}:${TAG:-develop} + image: ${REGISTRY-oaisoftwarealliance/}${GNB_IMG:-oai-gnb}:${TAG:-develop} privileged: true container_name: rfsim5g-oai-gnb environment: @@ -101,7 +101,7 @@ services: retries: 5 oai-nr-ue: - image: ${REGISTRY:-oaisoftwarealliance}/${NRUE_IMG:-oai-nr-ue}:${TAG:-develop} + image: ${REGISTRY-oaisoftwarealliance/}${NRUE_IMG:-oai-nr-ue}:${TAG:-develop} privileged: true container_name: rfsim5g-oai-nr-ue environment: @@ -120,7 +120,7 @@ services: retries: 5 oai-nr-ue2: - image: ${REGISTRY:-oaisoftwarealliance}/${NRUE_IMG:-oai-nr-ue}:${TAG:-develop} + image: ${REGISTRY-oaisoftwarealliance/}${NRUE_IMG:-oai-nr-ue}:${TAG:-develop} privileged: true container_name: rfsim5g-oai-nr-ue2 environment: diff --git a/ci-scripts/yaml_files/5g_rfsimulator_fr2_32prb/docker-compose.yaml b/ci-scripts/yaml_files/5g_rfsimulator_fr2_32prb/docker-compose.yaml index 13d91d9090..7ae33004f5 100644 --- a/ci-scripts/yaml_files/5g_rfsimulator_fr2_32prb/docker-compose.yaml +++ b/ci-scripts/yaml_files/5g_rfsimulator_fr2_32prb/docker-compose.yaml @@ -91,7 +91,7 @@ services: retries: 5 oai-gnb: - image: ${REGISTRY:-oaisoftwarealliance}/${GNB_IMG:-oai-gnb}:${TAG:-develop} + image: ${REGISTRY-oaisoftwarealliance/}${GNB_IMG:-oai-gnb}:${TAG:-develop} container_name: rfsim5g-oai-gnb cap_drop: - ALL @@ -112,7 +112,7 @@ services: retries: 5 oai-nr-ue: - image: ${REGISTRY:-oaisoftwarealliance}/${NRUE_IMG:-oai-nr-ue}:${TAG:-develop} + image: ${REGISTRY-oaisoftwarealliance/}${NRUE_IMG:-oai-nr-ue}:${TAG:-develop} container_name: rfsim5g-oai-nr-ue cap_drop: - ALL diff --git a/ci-scripts/yaml_files/5g_rfsimulator_multiue/docker-compose.yaml b/ci-scripts/yaml_files/5g_rfsimulator_multiue/docker-compose.yaml index 9d660e0c3b..b44178a3f5 100644 --- a/ci-scripts/yaml_files/5g_rfsimulator_multiue/docker-compose.yaml +++ b/ci-scripts/yaml_files/5g_rfsimulator_multiue/docker-compose.yaml @@ -83,7 +83,7 @@ services: timeout: 5s retries: 5 oai-gnb: - image: ${REGISTRY:-oaisoftwarealliance}/${GNB_IMG:-oai-gnb}:${TAG:-develop} + image: ${REGISTRY-oaisoftwarealliance/}${GNB_IMG:-oai-gnb}:${TAG:-develop} container_name: rfsim5g-oai-gnb cap_drop: - ALL @@ -103,7 +103,7 @@ services: timeout: 5s retries: 5 oai-nr-ue: - image: ${REGISTRY:-oaisoftwarealliance}/${NRUE_IMG:-oai-nr-ue}:${TAG:-develop} + image: ${REGISTRY-oaisoftwarealliance/}${NRUE_IMG:-oai-nr-ue}:${TAG:-develop} container_name: rfsim5g-oai-nr-ue cap_drop: - ALL 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 f3b75c1471..ad171109c7 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 @@ -84,7 +84,7 @@ services: retries: 5 oai-cucp-0: - image: ${REGISTRY:-oaisoftwarealliance}/${GNB_IMG:-oai-gnb}:${TAG:-develop} + image: ${REGISTRY-oaisoftwarealliance/}${GNB_IMG:-oai-gnb}:${TAG:-develop} container_name: rfsim5g-oai-cucp-0 cap_drop: - ALL @@ -111,7 +111,7 @@ services: retries: 5 oai-cuup-0: - image: ${REGISTRY:-oaisoftwarealliance}/${NRCUUP_IMG:-oai-nr-cuup}:${TAG:-develop} + image: ${REGISTRY-oaisoftwarealliance/}${NRCUUP_IMG:-oai-nr-cuup}:${TAG:-develop} container_name: rfsim5g-oai-cuup-0 cap_drop: - ALL @@ -139,7 +139,7 @@ services: oai-du-0: - image: ${REGISTRY:-oaisoftwarealliance}/${GNB_IMG:-oai-gnb}:${TAG:-develop} + image: ${REGISTRY-oaisoftwarealliance/}${GNB_IMG:-oai-gnb}:${TAG:-develop} container_name: rfsim5g-oai-du-0 cap_drop: - ALL @@ -168,7 +168,7 @@ services: retries: 5 oai-nr-ue: - image: ${REGISTRY:-oaisoftwarealliance}/${NRUE_IMG:-oai-nr-ue}:${TAG:-develop} + image: ${REGISTRY-oaisoftwarealliance/}${NRUE_IMG:-oai-nr-ue}:${TAG:-develop} container_name: rfsim5g-oai-nr-ue cap_drop: - ALL @@ -194,7 +194,7 @@ services: retries: 5 oai-cucp-1: - image: ${REGISTRY:-oaisoftwarealliance}/${GNB_IMG:-oai-gnb}:${TAG:-develop} + image: ${REGISTRY-oaisoftwarealliance/}${GNB_IMG:-oai-gnb}:${TAG:-develop} container_name: rfsim5g-oai-cucp-1 cap_drop: - ALL @@ -226,7 +226,7 @@ services: retries: 5 oai-cuup-1: - image: ${REGISTRY:-oaisoftwarealliance}/${NRCUUP_IMG:-oai-nr-cuup}:${TAG:-develop} + image: ${REGISTRY-oaisoftwarealliance/}${NRCUUP_IMG:-oai-nr-cuup}:${TAG:-develop} container_name: rfsim5g-oai-cuup-1 cap_drop: - ALL @@ -253,7 +253,7 @@ services: retries: 5 oai-du-1: - image: ${REGISTRY:-oaisoftwarealliance}/${GNB_IMG:-oai-gnb}:${TAG:-develop} + image: ${REGISTRY-oaisoftwarealliance/}${GNB_IMG:-oai-gnb}:${TAG:-develop} container_name: rfsim5g-oai-du-1 cap_drop: - ALL diff --git a/ci-scripts/yaml_files/5g_rfsimulator_ntn_geo/docker-compose.yaml b/ci-scripts/yaml_files/5g_rfsimulator_ntn_geo/docker-compose.yaml index c83060b713..731b833f08 100644 --- a/ci-scripts/yaml_files/5g_rfsimulator_ntn_geo/docker-compose.yaml +++ b/ci-scripts/yaml_files/5g_rfsimulator_ntn_geo/docker-compose.yaml @@ -90,7 +90,7 @@ services: timeout: 5s retries: 5 oai-gnb: - image: ${REGISTRY:-oaisoftwarealliance}/${GNB_IMG:-oai-gnb}:${TAG:-develop} + image: ${REGISTRY-oaisoftwarealliance/}${GNB_IMG:-oai-gnb}:${TAG:-develop} container_name: rfsim5g-oai-gnb cap_drop: - ALL @@ -115,7 +115,7 @@ services: retries: 5 oai-nr-ue: - image: ${REGISTRY:-oaisoftwarealliance}/${NRUE_IMG:-oai-nr-ue}:${TAG:-develop} + image: ${REGISTRY-oaisoftwarealliance/}${NRUE_IMG:-oai-nr-ue}:${TAG:-develop} container_name: rfsim5g-oai-nr-ue cap_drop: - ALL diff --git a/ci-scripts/yaml_files/5g_rfsimulator_ntn_leo/docker-compose.yaml b/ci-scripts/yaml_files/5g_rfsimulator_ntn_leo/docker-compose.yaml index 5469b0b247..4e209e09d1 100644 --- a/ci-scripts/yaml_files/5g_rfsimulator_ntn_leo/docker-compose.yaml +++ b/ci-scripts/yaml_files/5g_rfsimulator_ntn_leo/docker-compose.yaml @@ -87,7 +87,7 @@ services: timeout: 5s retries: 5 oai-gnb: - image: ${REGISTRY:-oaisoftwarealliance}/${GNB_IMG:-oai-gnb}:${TAG:-develop} + image: ${REGISTRY-oaisoftwarealliance/}${GNB_IMG:-oai-gnb}:${TAG:-develop} container_name: rfsim5g-oai-gnb cap_drop: - ALL @@ -110,7 +110,7 @@ services: retries: 5 oai-nr-ue: - image: ${REGISTRY:-oaisoftwarealliance}/${NRUE_IMG:-oai-nr-ue}:${TAG:-develop} + image: ${REGISTRY-oaisoftwarealliance/}${NRUE_IMG:-oai-nr-ue}:${TAG:-develop} container_name: rfsim5g-oai-nr-ue cap_drop: - ALL diff --git a/ci-scripts/yaml_files/5g_rfsimulator_sidelink/docker-compose.yaml b/ci-scripts/yaml_files/5g_rfsimulator_sidelink/docker-compose.yaml index c04e634ca2..5d8de35ac8 100644 --- a/ci-scripts/yaml_files/5g_rfsimulator_sidelink/docker-compose.yaml +++ b/ci-scripts/yaml_files/5g_rfsimulator_sidelink/docker-compose.yaml @@ -1,6 +1,6 @@ services: oai-nr-ue-1: - image: ${REGISTRY:-oaisoftwarealliance}/${NRUE_IMG:-oai-nr-ue}:${TAG:-develop} + image: ${REGISTRY-oaisoftwarealliance/}${NRUE_IMG:-oai-nr-ue}:${TAG:-develop} container_name: rfsim5g-oai-nr-ue-1 cap_drop: - ALL @@ -25,7 +25,7 @@ services: retries: 5 oai-nr-ue-2: - image: ${REGISTRY:-oaisoftwarealliance}/${NRUE_IMG:-oai-nr-ue}:${TAG:-develop} + image: ${REGISTRY-oaisoftwarealliance/}${NRUE_IMG:-oai-nr-ue}:${TAG:-develop} container_name: rfsim5g-oai-nr-ue-2 cap_drop: - ALL diff --git a/ci-scripts/yaml_files/5g_rfsimulator_tdd_dora/docker-compose.yaml b/ci-scripts/yaml_files/5g_rfsimulator_tdd_dora/docker-compose.yaml index 89f6562697..60484914a6 100644 --- a/ci-scripts/yaml_files/5g_rfsimulator_tdd_dora/docker-compose.yaml +++ b/ci-scripts/yaml_files/5g_rfsimulator_tdd_dora/docker-compose.yaml @@ -1,6 +1,6 @@ services: oai-gnb: - image: ${REGISTRY:-oaisoftwarealliance}/${GNB_IMG:-oai-gnb}:${TAG:-develop} + image: ${REGISTRY-oaisoftwarealliance/}${GNB_IMG:-oai-gnb}:${TAG:-develop} container_name: rfsim5g-oai-gnb cap_drop: - ALL @@ -25,7 +25,7 @@ services: retries: 5 oai-nr-ue: - image: ${REGISTRY:-oaisoftwarealliance}/${NRUE_IMG:-oai-nr-ue}:${TAG:-develop} + image: ${REGISTRY-oaisoftwarealliance/}${NRUE_IMG:-oai-nr-ue}:${TAG:-develop} container_name: rfsim5g-oai-nr-ue cap_drop: - ALL diff --git a/ci-scripts/yaml_files/5g_rfsimulator_u0_25prb/docker-compose.yaml b/ci-scripts/yaml_files/5g_rfsimulator_u0_25prb/docker-compose.yaml index ed1701ef86..722290aa38 100644 --- a/ci-scripts/yaml_files/5g_rfsimulator_u0_25prb/docker-compose.yaml +++ b/ci-scripts/yaml_files/5g_rfsimulator_u0_25prb/docker-compose.yaml @@ -91,7 +91,7 @@ services: retries: 5 oai-vnf: - image: ${REGISTRY:-oaisoftwarealliance}/${GNB_IMG:-oai-gnb}:${TAG:-develop} + image: ${REGISTRY-oaisoftwarealliance/}${GNB_IMG:-oai-gnb}:${TAG:-develop} container_name: rfsim5g-oai-vnf cap_drop: - ALL @@ -115,7 +115,7 @@ services: retries: 5 oai-pnf: - image: ${REGISTRY:-oaisoftwarealliance}/${GNB_IMG:-oai-gnb}:${TAG:-develop} + image: ${REGISTRY-oaisoftwarealliance/}${GNB_IMG:-oai-gnb}:${TAG:-develop} container_name: rfsim5g-oai-pnf cap_drop: - ALL @@ -139,7 +139,7 @@ services: retries: 5 oai-nr-ue: - image: ${REGISTRY:-oaisoftwarealliance}/${NRUE_IMG:-oai-nr-ue}:${TAG:-develop} + image: ${REGISTRY-oaisoftwarealliance/}${NRUE_IMG:-oai-nr-ue}:${TAG:-develop} container_name: rfsim5g-oai-nr-ue cap_drop: - ALL diff --git a/ci-scripts/yaml_files/5g_sa_f1_b210_ho/docker-compose.yml b/ci-scripts/yaml_files/5g_sa_f1_b210_ho/docker-compose.yml index c1c3db1607..937f7d5d65 100644 --- a/ci-scripts/yaml_files/5g_sa_f1_b210_ho/docker-compose.yml +++ b/ci-scripts/yaml_files/5g_sa_f1_b210_ho/docker-compose.yml @@ -1,6 +1,6 @@ services: oai-cu: - image: ${REGISTRY:-oaisoftwarealliance}/${GNB_IMG:-oai-gnb}:${TAG:-develop} + image: ${REGISTRY-oaisoftwarealliance/}${GNB_IMG:-oai-gnb}:${TAG:-develop} container_name: oai-cu cap_drop: - ALL @@ -26,7 +26,7 @@ services: retries: 5 oai-du0: - image: ${REGISTRY:-oaisoftwarealliance}/${GNB_IMG:-oai-gnb}:${TAG:-develop} + image: ${REGISTRY-oaisoftwarealliance/}${GNB_IMG:-oai-gnb}:${TAG:-develop} container_name: oai-du0 cap_drop: - ALL @@ -58,7 +58,7 @@ services: retries: 5 oai-du1: - image: ${REGISTRY:-oaisoftwarealliance}/${GNB_IMG:-oai-gnb}:${TAG:-develop} + image: ${REGISTRY-oaisoftwarealliance/}${GNB_IMG:-oai-gnb}:${TAG:-develop} container_name: oai-du1 cap_drop: - ALL diff --git a/ci-scripts/yaml_files/5g_sa_n2_ho_b210/docker-compose.yml b/ci-scripts/yaml_files/5g_sa_n2_ho_b210/docker-compose.yml index 6704b434db..e02afae7cc 100644 --- a/ci-scripts/yaml_files/5g_sa_n2_ho_b210/docker-compose.yml +++ b/ci-scripts/yaml_files/5g_sa_n2_ho_b210/docker-compose.yml @@ -1,6 +1,6 @@ services: oai-gnb-pci0: - image: ${REGISTRY:-oaisoftwarealliance}/${GNB_IMG:-oai-gnb}:${TAG:-develop} + image: ${REGISTRY-oaisoftwarealliance/}${GNB_IMG:-oai-gnb}:${TAG:-develop} container_name: oai-gnb-pci0 cap_drop: - ALL @@ -28,7 +28,7 @@ services: retries: 5 oai-gnb-pci1: - image: ${REGISTRY:-oaisoftwarealliance}/${GNB_IMG:-oai-gnb}:${TAG:-develop} + image: ${REGISTRY-oaisoftwarealliance/}${GNB_IMG:-oai-gnb}:${TAG:-develop} container_name: oai-gnb-pci1 cap_drop: - ALL diff --git a/ci-scripts/yaml_files/5g_sa_n310_2x2_100MHz/docker-compose.yml b/ci-scripts/yaml_files/5g_sa_n310_2x2_100MHz/docker-compose.yml index 11ecb20f08..879f86ce90 100644 --- a/ci-scripts/yaml_files/5g_sa_n310_2x2_100MHz/docker-compose.yml +++ b/ci-scripts/yaml_files/5g_sa_n310_2x2_100MHz/docker-compose.yml @@ -1,6 +1,6 @@ services: oai-gnb: - image: ${REGISTRY:-oaisoftwarealliance}/${GNB_IMG:-oai-gnb}:${TAG:-develop} + image: ${REGISTRY-oaisoftwarealliance/}${GNB_IMG:-oai-gnb}:${TAG:-develop} network_mode: "host" container_name: oai-gnb cap_drop: diff --git a/ci-scripts/yaml_files/5g_sa_n310_2x2_60MHz/docker-compose.yml b/ci-scripts/yaml_files/5g_sa_n310_2x2_60MHz/docker-compose.yml index 332fb23503..b5eb5dd441 100644 --- a/ci-scripts/yaml_files/5g_sa_n310_2x2_60MHz/docker-compose.yml +++ b/ci-scripts/yaml_files/5g_sa_n310_2x2_60MHz/docker-compose.yml @@ -1,6 +1,6 @@ services: oai-gnb: - image: ${REGISTRY:-oaisoftwarealliance}/${GNB_IMG:-oai-gnb}:${TAG:-develop} + image: ${REGISTRY-oaisoftwarealliance/}${GNB_IMG:-oai-gnb}:${TAG:-develop} network_mode: "host" container_name: oai-gnb cap_drop: 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 d3d2ddf582..487672ae1f 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 @@ -1,6 +1,6 @@ services: oai-vnf: - image: ${REGISTRY:-oaisoftwarealliance}/${GNB_IMG:-oai-gnb}:${TAG:-develop} + image: ${REGISTRY-oaisoftwarealliance/}${GNB_IMG:-oai-gnb}:${TAG:-develop} network_mode: "host" container_name: oai-vnf cap_drop: @@ -20,7 +20,7 @@ services: timeout: 5s retries: 5 oai-pnf: - image: ${REGISTRY:-oaisoftwarealliance}/${GNB_IMG:-oai-gnb}:${TAG:-develop} + image: ${REGISTRY-oaisoftwarealliance/}${GNB_IMG:-oai-gnb}:${TAG:-develop} network_mode: "host" container_name: oai-pnf cap_drop: diff --git a/ci-scripts/yaml_files/5g_sa_n310_gnb/docker-compose.yml b/ci-scripts/yaml_files/5g_sa_n310_gnb/docker-compose.yml index 562b72561a..e1cd519d22 100644 --- a/ci-scripts/yaml_files/5g_sa_n310_gnb/docker-compose.yml +++ b/ci-scripts/yaml_files/5g_sa_n310_gnb/docker-compose.yml @@ -1,6 +1,6 @@ services: oai-gnb: - image: ${REGISTRY:-oaisoftwarealliance}/${GNB_IMG:-oai-gnb}:${TAG:-develop} + image: ${REGISTRY-oaisoftwarealliance/}${GNB_IMG:-oai-gnb}:${TAG:-develop} network_mode: "host" container_name: oai-gnb cap_drop: diff --git a/ci-scripts/yaml_files/5g_sa_n310_nrue/docker-compose.yml b/ci-scripts/yaml_files/5g_sa_n310_nrue/docker-compose.yml index 9fb80ad065..5db92f6ee2 100644 --- a/ci-scripts/yaml_files/5g_sa_n310_nrue/docker-compose.yml +++ b/ci-scripts/yaml_files/5g_sa_n310_nrue/docker-compose.yml @@ -1,6 +1,6 @@ services: oai-nr-ue: - image: ${REGISTRY:-oaisoftwarealliance}/${NRUE_IMG:-oai-nr-ue}:${TAG:-develop} + image: ${REGISTRY-oaisoftwarealliance/}${NRUE_IMG:-oai-nr-ue}:${TAG:-develop} network_mode: host container_name: oai-nr-ue cap_drop: 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 index 4c40d738a4..7963f823b1 100644 --- 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 @@ -1,6 +1,6 @@ services: enb_mono_fdd: - image: ${REGISTRY:-oaisoftwarealliance}/oai-enb:${TAG:-develop} + image: ${REGISTRY-oaisoftwarealliance/}oai-enb:${TAG:-develop} privileged: true container_name: prod-enb-mono-fdd environment: diff --git a/ci-scripts/yaml_files/lte_b200_fdd_05Mhz_if4.5/docker-compose.yml b/ci-scripts/yaml_files/lte_b200_fdd_05Mhz_if4.5/docker-compose.yml index d15a9df172..290edf23b1 100644 --- a/ci-scripts/yaml_files/lte_b200_fdd_05Mhz_if4.5/docker-compose.yml +++ b/ci-scripts/yaml_files/lte_b200_fdd_05Mhz_if4.5/docker-compose.yml @@ -1,6 +1,6 @@ services: rru_fdd: - image: ${REGISTRY:-oaisoftwarealliance}/oai-enb:${TAG:-develop} + image: ${REGISTRY-oaisoftwarealliance/}oai-enb:${TAG:-develop} privileged: true container_name: lte-b200-rru-fdd-05Mhz-tm1 network_mode: "host" @@ -17,7 +17,7 @@ services: timeout: 5s retries: 5 rcc_fdd: - image: ${REGISTRY:-oaisoftwarealliance}/oai-enb:${TAG:-develop} + image: ${REGISTRY-oaisoftwarealliance/}oai-enb:${TAG:-develop} privileged: true container_name: lte-b200-rcc-fdd-05Mhz-tm1 network_mode: "host" diff --git a/ci-scripts/yaml_files/lte_b200_fdd_05Mhz_tm1/docker-compose.yml b/ci-scripts/yaml_files/lte_b200_fdd_05Mhz_tm1/docker-compose.yml index 2a6e7bb51a..d3f6897534 100644 --- a/ci-scripts/yaml_files/lte_b200_fdd_05Mhz_tm1/docker-compose.yml +++ b/ci-scripts/yaml_files/lte_b200_fdd_05Mhz_tm1/docker-compose.yml @@ -1,6 +1,6 @@ services: enb_mono_fdd: - image: ${REGISTRY:-oaisoftwarealliance}/oai-enb:${TAG:-develop} + image: ${REGISTRY-oaisoftwarealliance/}oai-enb:${TAG:-develop} privileged: true container_name: lte-b200-enb-fdd-05Mhz-tm1 environment: diff --git a/ci-scripts/yaml_files/lte_b200_fdd_05Mhz_tm1_no_rrc_activity/docker-compose.yml b/ci-scripts/yaml_files/lte_b200_fdd_05Mhz_tm1_no_rrc_activity/docker-compose.yml index 7cdc585d34..6bf2f4606f 100644 --- a/ci-scripts/yaml_files/lte_b200_fdd_05Mhz_tm1_no_rrc_activity/docker-compose.yml +++ b/ci-scripts/yaml_files/lte_b200_fdd_05Mhz_tm1_no_rrc_activity/docker-compose.yml @@ -1,6 +1,6 @@ services: enb_mono_fdd: - image: ${REGISTRY:-oaisoftwarealliance}/oai-enb:${TAG:-develop} + image: ${REGISTRY-oaisoftwarealliance/}oai-enb:${TAG:-develop} privileged: true container_name: lte-b200-enb-fdd-05Mhz-tm1 environment: diff --git a/ci-scripts/yaml_files/lte_b200_fdd_10Mhz_oai_ue_magma/docker-compose.yml b/ci-scripts/yaml_files/lte_b200_fdd_10Mhz_oai_ue_magma/docker-compose.yml index c6d64cc028..a213d1900b 100644 --- a/ci-scripts/yaml_files/lte_b200_fdd_10Mhz_oai_ue_magma/docker-compose.yml +++ b/ci-scripts/yaml_files/lte_b200_fdd_10Mhz_oai_ue_magma/docker-compose.yml @@ -1,6 +1,6 @@ services: lte_ue0: - image: ${REGISTRY:-oaisoftwarealliance}/oai-lte-ue:${TAG:-develop} + image: ${REGISTRY-oaisoftwarealliance/}oai-lte-ue:${TAG:-develop} privileged: true container_name: lte-b200-ue-fdd-10Mhz-tm1 environment: diff --git a/ci-scripts/yaml_files/lte_b200_fdd_10Mhz_tm1/docker-compose.yml b/ci-scripts/yaml_files/lte_b200_fdd_10Mhz_tm1/docker-compose.yml index 14d1045de8..3cbf927f8e 100644 --- a/ci-scripts/yaml_files/lte_b200_fdd_10Mhz_tm1/docker-compose.yml +++ b/ci-scripts/yaml_files/lte_b200_fdd_10Mhz_tm1/docker-compose.yml @@ -1,6 +1,6 @@ services: enb_mono_fdd: - image: ${REGISTRY:-oaisoftwarealliance}/oai-enb:${TAG:-develop} + image: ${REGISTRY-oaisoftwarealliance/}oai-enb:${TAG:-develop} privileged: true container_name: lte-b200-enb-fdd-10Mhz-tm1 environment: diff --git a/ci-scripts/yaml_files/lte_b200_fdd_10Mhz_tm1_cdrx/docker-compose.yml b/ci-scripts/yaml_files/lte_b200_fdd_10Mhz_tm1_cdrx/docker-compose.yml index d1fcd91850..38c14472b6 100644 --- a/ci-scripts/yaml_files/lte_b200_fdd_10Mhz_tm1_cdrx/docker-compose.yml +++ b/ci-scripts/yaml_files/lte_b200_fdd_10Mhz_tm1_cdrx/docker-compose.yml @@ -1,6 +1,6 @@ services: enb_mono_fdd: - image: ${REGISTRY:-oaisoftwarealliance}/oai-enb:${TAG:-develop} + image: ${REGISTRY-oaisoftwarealliance/}oai-enb:${TAG:-develop} privileged: true container_name: lte-b200-enb-fdd-10Mhz-tm1 environment: diff --git a/ci-scripts/yaml_files/lte_b200_fdd_10Mhz_tm1_magma/docker-compose.yml b/ci-scripts/yaml_files/lte_b200_fdd_10Mhz_tm1_magma/docker-compose.yml index 6b1b583863..c1c9c4b531 100644 --- a/ci-scripts/yaml_files/lte_b200_fdd_10Mhz_tm1_magma/docker-compose.yml +++ b/ci-scripts/yaml_files/lte_b200_fdd_10Mhz_tm1_magma/docker-compose.yml @@ -1,6 +1,6 @@ services: enb_mono_fdd: - image: ${REGISTRY:-oaisoftwarealliance}/oai-enb:${TAG:-develop} + image: ${REGISTRY-oaisoftwarealliance/}oai-enb:${TAG:-develop} privileged: true container_name: lte-b200-enb-fdd-10Mhz-tm1 environment: diff --git a/ci-scripts/yaml_files/lte_b200_fdd_20Mhz_tm1/docker-compose.yml b/ci-scripts/yaml_files/lte_b200_fdd_20Mhz_tm1/docker-compose.yml index a36afb957e..e027c521d7 100644 --- a/ci-scripts/yaml_files/lte_b200_fdd_20Mhz_tm1/docker-compose.yml +++ b/ci-scripts/yaml_files/lte_b200_fdd_20Mhz_tm1/docker-compose.yml @@ -1,6 +1,6 @@ services: enb_mono_fdd: - image: ${REGISTRY:-oaisoftwarealliance}/oai-enb:${TAG:-develop} + image: ${REGISTRY-oaisoftwarealliance/}oai-enb:${TAG:-develop} privileged: true container_name: lte-b200-enb-fdd-20Mhz-tm1 environment: diff --git a/ci-scripts/yaml_files/lte_b200_tdd_05Mhz_if4.5/docker-compose.yml b/ci-scripts/yaml_files/lte_b200_tdd_05Mhz_if4.5/docker-compose.yml index 0311390ab7..56c730083a 100644 --- a/ci-scripts/yaml_files/lte_b200_tdd_05Mhz_if4.5/docker-compose.yml +++ b/ci-scripts/yaml_files/lte_b200_tdd_05Mhz_if4.5/docker-compose.yml @@ -1,6 +1,6 @@ services: rru_tdd: - image: ${REGISTRY:-oaisoftwarealliance}/oai-enb:${TAG:-develop} + image: ${REGISTRY-oaisoftwarealliance/}oai-enb:${TAG:-develop} privileged: true container_name: lte-b200-rru-tdd-05Mhz-tm1 network_mode: "host" @@ -17,7 +17,7 @@ services: timeout: 5s retries: 5 rcc_tdd: - image: ${REGISTRY:-oaisoftwarealliance}/oai-enb:${TAG:-develop} + image: ${REGISTRY-oaisoftwarealliance/}oai-enb:${TAG:-develop} privileged: true container_name: lte-b200-rcc-tdd-05Mhz-tm1 network_mode: "host" diff --git a/ci-scripts/yaml_files/lte_b200_tdd_05Mhz_tm1/docker-compose.yml b/ci-scripts/yaml_files/lte_b200_tdd_05Mhz_tm1/docker-compose.yml index 68f48d7087..9ce6bf3609 100644 --- a/ci-scripts/yaml_files/lte_b200_tdd_05Mhz_tm1/docker-compose.yml +++ b/ci-scripts/yaml_files/lte_b200_tdd_05Mhz_tm1/docker-compose.yml @@ -1,6 +1,6 @@ services: enb_mono_tdd: - image: ${REGISTRY:-oaisoftwarealliance}/oai-enb:${TAG:-develop} + image: ${REGISTRY-oaisoftwarealliance/}oai-enb:${TAG:-develop} privileged: true container_name: lte-b200-enb-tdd-05Mhz-tm1 environment: diff --git a/ci-scripts/yaml_files/lte_b200_tdd_05Mhz_tm2/docker-compose.yml b/ci-scripts/yaml_files/lte_b200_tdd_05Mhz_tm2/docker-compose.yml index b11b268129..d462baac14 100644 --- a/ci-scripts/yaml_files/lte_b200_tdd_05Mhz_tm2/docker-compose.yml +++ b/ci-scripts/yaml_files/lte_b200_tdd_05Mhz_tm2/docker-compose.yml @@ -1,6 +1,6 @@ services: enb_mono_tdd: - image: ${REGISTRY:-oaisoftwarealliance}/oai-enb:${TAG:-develop} + image: ${REGISTRY-oaisoftwarealliance/}oai-enb:${TAG:-develop} privileged: true container_name: lte-b200-enb-tdd-05Mhz-tm2 environment: diff --git a/ci-scripts/yaml_files/lte_b200_tdd_10Mhz_tm1/docker-compose.yml b/ci-scripts/yaml_files/lte_b200_tdd_10Mhz_tm1/docker-compose.yml index 7934784cdc..025c5ad26b 100644 --- a/ci-scripts/yaml_files/lte_b200_tdd_10Mhz_tm1/docker-compose.yml +++ b/ci-scripts/yaml_files/lte_b200_tdd_10Mhz_tm1/docker-compose.yml @@ -1,6 +1,6 @@ services: enb_mono_tdd: - image: ${REGISTRY:-oaisoftwarealliance}/oai-enb:${TAG:-develop} + image: ${REGISTRY-oaisoftwarealliance/}oai-enb:${TAG:-develop} privileged: true container_name: lte-b200-enb-tdd-10Mhz-tm1 environment: diff --git a/ci-scripts/yaml_files/lte_b200_tdd_20Mhz_tm1/docker-compose.yml b/ci-scripts/yaml_files/lte_b200_tdd_20Mhz_tm1/docker-compose.yml index 0bca3bc43a..748525aa82 100644 --- a/ci-scripts/yaml_files/lte_b200_tdd_20Mhz_tm1/docker-compose.yml +++ b/ci-scripts/yaml_files/lte_b200_tdd_20Mhz_tm1/docker-compose.yml @@ -1,6 +1,6 @@ services: enb_mono_tdd: - image: ${REGISTRY:-oaisoftwarealliance}/oai-enb:${TAG:-develop} + image: ${REGISTRY-oaisoftwarealliance/}oai-enb:${TAG:-develop} privileged: true container_name: lte-b200-enb-tdd-20Mhz-tm1 environment: diff --git a/ci-scripts/yaml_files/lte_b200_tdd_20Mhz_tm1_default_scheduler/docker-compose.yml b/ci-scripts/yaml_files/lte_b200_tdd_20Mhz_tm1_default_scheduler/docker-compose.yml index 953cce7ffc..dfdd4ed877 100644 --- a/ci-scripts/yaml_files/lte_b200_tdd_20Mhz_tm1_default_scheduler/docker-compose.yml +++ b/ci-scripts/yaml_files/lte_b200_tdd_20Mhz_tm1_default_scheduler/docker-compose.yml @@ -1,6 +1,6 @@ services: enb_mono_tdd: - image: ${REGISTRY:-oaisoftwarealliance}/oai-enb:${TAG:-develop} + image: ${REGISTRY-oaisoftwarealliance/}oai-enb:${TAG:-develop} privileged: true container_name: lte-b200-enb-tdd-20Mhz-tm1 environment: 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 5ac5b93d14..0aefaf5ef0 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 @@ -1,6 +1,6 @@ services: oai-enb: - image: ${REGISTRY:-oaisoftwarealliance}/oai-enb:${TAG:-develop} + image: ${REGISTRY-oaisoftwarealliance/}oai-enb:${TAG:-develop} privileged: true container_name: oai-enb environment: 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 929c9633c7..db6215a148 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 @@ -1,6 +1,6 @@ services: oai-enb: - image: ${REGISTRY:-oaisoftwarealliance}/oai-enb:${TAG:-develop} + image: ${REGISTRY-oaisoftwarealliance/}oai-enb:${TAG:-develop} privileged: true container_name: oai-enb environment: diff --git a/ci-scripts/yaml_files/nsa_b200_enb/docker-compose.yml b/ci-scripts/yaml_files/nsa_b200_enb/docker-compose.yml index 76790c44f9..6dfe229265 100644 --- a/ci-scripts/yaml_files/nsa_b200_enb/docker-compose.yml +++ b/ci-scripts/yaml_files/nsa_b200_enb/docker-compose.yml @@ -1,6 +1,6 @@ services: enb_mono_fdd: - image: ${REGISTRY:-oaisoftwarealliance}/oai-enb:${TAG:-develop} + image: ${REGISTRY-oaisoftwarealliance/}oai-enb:${TAG:-develop} privileged: true container_name: nsa-b200-enb ulimits: diff --git a/ci-scripts/yaml_files/nsa_b200_gnb/docker-compose.yml b/ci-scripts/yaml_files/nsa_b200_gnb/docker-compose.yml index bb6576054e..f104735fa0 100644 --- a/ci-scripts/yaml_files/nsa_b200_gnb/docker-compose.yml +++ b/ci-scripts/yaml_files/nsa_b200_gnb/docker-compose.yml @@ -1,6 +1,6 @@ services: gnb_mono_tdd: - image: ${REGISTRY:-oaisoftwarealliance}/${GNB_IMG:-oai-gnb}:${TAG:-develop} + image: ${REGISTRY-oaisoftwarealliance/}${GNB_IMG:-oai-gnb}:${TAG:-develop} container_name: nsa-b200-gnb cap_drop: - ALL diff --git a/ci-scripts/yaml_files/sa_aw2s_2x2_gnb/docker-compose.yml b/ci-scripts/yaml_files/sa_aw2s_2x2_gnb/docker-compose.yml index a1baef974a..fadeea96ef 100644 --- a/ci-scripts/yaml_files/sa_aw2s_2x2_gnb/docker-compose.yml +++ b/ci-scripts/yaml_files/sa_aw2s_2x2_gnb/docker-compose.yml @@ -1,6 +1,6 @@ services: oai-gnb: - image: ${REGISTRY:-oaisoftwarealliance}/oai-gnb-aw2s:${TAG:-develop} + image: ${REGISTRY-oaisoftwarealliance/}oai-gnb-aw2s:${TAG:-develop} network_mode: "host" container_name: oai-gnb-aw2s cap_drop: 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 9530b3cd5c..54bf6cec00 100644 --- a/ci-scripts/yaml_files/sa_aw2s_gnb/docker-compose.yml +++ b/ci-scripts/yaml_files/sa_aw2s_gnb/docker-compose.yml @@ -1,6 +1,6 @@ services: oai-gnb: - image: ${REGISTRY:-oaisoftwarealliance}/oai-gnb-aw2s:${TAG:-develop} + image: ${REGISTRY-oaisoftwarealliance/}oai-gnb-aw2s:${TAG:-develop} network_mode: "host" container_name: oai-gnb-aw2s cap_drop: diff --git a/ci-scripts/yaml_files/sa_b200_gnb/docker-compose.yml b/ci-scripts/yaml_files/sa_b200_gnb/docker-compose.yml index 7fe7db5317..d57ec4b5bd 100644 --- a/ci-scripts/yaml_files/sa_b200_gnb/docker-compose.yml +++ b/ci-scripts/yaml_files/sa_b200_gnb/docker-compose.yml @@ -1,6 +1,6 @@ services: gnb_mono_tdd: - image: ${REGISTRY:-oaisoftwarealliance}/${GNB_IMG:-oai-gnb}:${TAG:-develop} + image: ${REGISTRY-oaisoftwarealliance/}${GNB_IMG:-oai-gnb}:${TAG:-develop} container_name: sa-b200-gnb cap_drop: - ALL diff --git a/ci-scripts/yaml_files/sa_e1_b200_gnb/docker-compose.yml b/ci-scripts/yaml_files/sa_e1_b200_gnb/docker-compose.yml index c20a43c0e1..bbcd04238c 100644 --- a/ci-scripts/yaml_files/sa_e1_b200_gnb/docker-compose.yml +++ b/ci-scripts/yaml_files/sa_e1_b200_gnb/docker-compose.yml @@ -1,6 +1,6 @@ services: gnb_cucp: - image: ${REGISTRY:-oaisoftwarealliance}/${GNB_IMG:-oai-gnb}:${TAG:-develop} + image: ${REGISTRY-oaisoftwarealliance/}${GNB_IMG:-oai-gnb}:${TAG:-develop} container_name: sa-cucp-gnb cap_drop: - ALL @@ -25,7 +25,7 @@ services: retries: 5 gnb_cuup: - image: ${REGISTRY:-oaisoftwarealliance}/${NRCUUP_IMG:-oai-nr-cuup}:${TAG:-develop} + image: ${REGISTRY-oaisoftwarealliance/}${NRCUUP_IMG:-oai-nr-cuup}:${TAG:-develop} container_name: sa-cuup-gnb cap_drop: - ALL @@ -51,7 +51,7 @@ services: retries: 5 gnb_du_tdd: - image: ${REGISTRY:-oaisoftwarealliance}/${GNB_IMG:-oai-gnb}:${TAG:-develop} + image: ${REGISTRY-oaisoftwarealliance/}${GNB_IMG:-oai-gnb}:${TAG:-develop} container_name: sa-du-b200-gnb cap_drop: - ALL diff --git a/ci-scripts/yaml_files/sa_f1_b200_gnb/docker-compose.yml b/ci-scripts/yaml_files/sa_f1_b200_gnb/docker-compose.yml index 2c1ab75e92..740b0eff1a 100644 --- a/ci-scripts/yaml_files/sa_f1_b200_gnb/docker-compose.yml +++ b/ci-scripts/yaml_files/sa_f1_b200_gnb/docker-compose.yml @@ -1,6 +1,6 @@ services: gnb_cu: - image: ${REGISTRY:-oaisoftwarealliance}/${GNB_IMG:-oai-gnb}:${TAG:-develop} + image: ${REGISTRY-oaisoftwarealliance/}${GNB_IMG:-oai-gnb}:${TAG:-develop} container_name: sa-cu-gnb cap_drop: - ALL @@ -25,7 +25,7 @@ services: retries: 5 gnb_du_fdd: - image: ${REGISTRY:-oaisoftwarealliance}/${GNB_IMG:-oai-gnb}:${TAG:-develop} + image: ${REGISTRY-oaisoftwarealliance/}${GNB_IMG:-oai-gnb}:${TAG:-develop} container_name: sa-du-b200-gnb cap_drop: - ALL diff --git a/ci-scripts/yaml_files/sa_fhi_7.2_benetel550_gnb/docker-compose.yml b/ci-scripts/yaml_files/sa_fhi_7.2_benetel550_gnb/docker-compose.yml index b70229ac94..8c38739994 100644 --- a/ci-scripts/yaml_files/sa_fhi_7.2_benetel550_gnb/docker-compose.yml +++ b/ci-scripts/yaml_files/sa_fhi_7.2_benetel550_gnb/docker-compose.yml @@ -1,6 +1,6 @@ services: oai-gnb: - image: ${REGISTRY:-oaisoftwarealliance}/oai-gnb-fhi72:${TAG:-develop} + image: ${REGISTRY-oaisoftwarealliance/}oai-gnb-fhi72:${TAG:-develop} cap_add: - SYS_ADMIN - IPC_LOCK diff --git a/ci-scripts/yaml_files/sa_fhi_7.2_metanoia_2x2_gnb/docker-compose.yml b/ci-scripts/yaml_files/sa_fhi_7.2_metanoia_2x2_gnb/docker-compose.yml index f08859a516..3e29c33ff9 100644 --- a/ci-scripts/yaml_files/sa_fhi_7.2_metanoia_2x2_gnb/docker-compose.yml +++ b/ci-scripts/yaml_files/sa_fhi_7.2_metanoia_2x2_gnb/docker-compose.yml @@ -1,6 +1,6 @@ services: oai-gnb: - image: ${REGISTRY:-oaisoftwarealliance}/oai-gnb-fhi72:${TAG:-develop} + image: ${REGISTRY-oaisoftwarealliance/}oai-gnb-fhi72:${TAG:-develop} cap_add: - IPC_LOCK - SYS_NICE diff --git a/ci-scripts/yaml_files/sa_fhi_7.2_vvdn_gnb/docker-compose.yml b/ci-scripts/yaml_files/sa_fhi_7.2_vvdn_gnb/docker-compose.yml index ff06893fa0..2e6c044fcb 100644 --- a/ci-scripts/yaml_files/sa_fhi_7.2_vvdn_gnb/docker-compose.yml +++ b/ci-scripts/yaml_files/sa_fhi_7.2_vvdn_gnb/docker-compose.yml @@ -1,6 +1,6 @@ services: oai-gnb: - image: ${REGISTRY:-oaisoftwarealliance}/oai-gnb-fhi72:${TAG:-develop} + image: ${REGISTRY-oaisoftwarealliance/}oai-gnb-fhi72:${TAG:-develop} cap_add: - IPC_LOCK - SYS_NICE 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 c9f3d90131..f04beeb6c2 100644 --- a/ci-scripts/yaml_files/sa_gnb_aerial/docker-compose.yaml +++ b/ci-scripts/yaml_files/sa_gnb_aerial/docker-compose.yaml @@ -34,7 +34,7 @@ services: retries: 5 oai-gnb-aerial: cpuset: "13-14" - image: ${REGISTRY:-oaisoftwarealliance}/oai-gnb-aerial:${TAG:-develop} + image: ${REGISTRY-oaisoftwarealliance/}${GNB_IMG:-oai-gnb-aerial}:${TAG:-develop} depends_on: nv-cubb: condition: service_healthy diff --git a/ci-scripts/yaml_files/sa_gnb_aerial_ul/docker-compose.yaml b/ci-scripts/yaml_files/sa_gnb_aerial_ul/docker-compose.yaml index 077c58c67c..c0b3e6f81d 100644 --- a/ci-scripts/yaml_files/sa_gnb_aerial_ul/docker-compose.yaml +++ b/ci-scripts/yaml_files/sa_gnb_aerial_ul/docker-compose.yaml @@ -34,7 +34,7 @@ services: retries: 5 oai-gnb-aerial: cpuset: "13-16" - image: ${REGISTRY:-oaisoftwarealliance}/oai-gnb-aerial:${TAG:-develop} + image: ${REGISTRY-oaisoftwarealliance/}${GNB_IMG:-oai-gnb-aerial}:${TAG:-develop} depends_on: nv-cubb: condition: service_healthy diff --git a/ci-scripts/yaml_files/sa_sc_b200_gnb/docker-compose.yml b/ci-scripts/yaml_files/sa_sc_b200_gnb/docker-compose.yml index f0b86f4c33..51571332bd 100644 --- a/ci-scripts/yaml_files/sa_sc_b200_gnb/docker-compose.yml +++ b/ci-scripts/yaml_files/sa_sc_b200_gnb/docker-compose.yml @@ -1,6 +1,6 @@ services: gnb_mono_tdd: - image: ${REGISTRY:-oaisoftwarealliance}/${GNB_IMG:-oai-gnb}:${TAG:-develop} + image: ${REGISTRY-oaisoftwarealliance/}${GNB_IMG:-oai-gnb}:${TAG:-develop} container_name: sa-b200-gnb cap_drop: - ALL From aff3c9872faca1a5671a42200bef228f16335cc9 Mon Sep 17 00:00:00 2001 From: Jaroslava Fiedlerova Date: Thu, 30 Oct 2025 10:11:12 +0100 Subject: [PATCH 69/69] CI: align REGISTRY env var with updated image path format Following the change to use: image: ${REGISTRY-oaisoftwarealliance/}${GNB_IMG:-oai-gnb}:${TAG:-develop} the REGISTRY variable must now include the trailing slash. --- ci-scripts/cls_containerize.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/ci-scripts/cls_containerize.py b/ci-scripts/cls_containerize.py index c97bb8d4d1..3cebcb24d7 100644 --- a/ci-scripts/cls_containerize.py +++ b/ci-scripts/cls_containerize.py @@ -119,7 +119,7 @@ def ExistEnvFilePrint(ssh, wd, prompt='env vars in existing'): def WriteEnvFile(ssh, services, wd, tag, flexric_tag): ret = ssh.run(f'cat {wd}/.env', silent=True, reportNonZero=False) - registry = "oai-ci" # pull_images() gives us this registry path + registry = "oai-ci/" # pull_images() gives us this registry path envs = {"REGISTRY":registry, "TAG": tag, "FLEXRIC_TAG": flexric_tag} if ret.returncode == 0: # it exists, we have to update # transforms env file to dictionary @@ -134,7 +134,8 @@ def WriteEnvFile(ssh, services, wd, tag, flexric_tag): # or -asan images. We need to detect which kind we did pull. fullImageName = GetImageName(ssh, svc, f"{wd}/docker-compose.y*ml") image = fullImageName.split("/")[-1].split(":")[0] - checkimg = f"{registry}/{image}-asan:{tag}" + # registry now includes the trailing slash ("oai-ci/") + checkimg = f"{registry}{image}-asan:{tag}" ret = ssh.run(f'docker image inspect {checkimg}', reportNonZero=False) if ret.returncode == 0: logging.info(f"detected pulled image {checkimg}")