From b4bc7c96bad8ddc5fef3416d2820706f539b4137 Mon Sep 17 00:00:00 2001 From: Laurent THOMAS Date: Tue, 29 Oct 2024 14:42:38 +0100 Subject: [PATCH] Move UL_INFO structure allocation local to a rx slot processing Use UL_INFO on the stack, to simplify the code. move in the same struct the associated rach, pdu, crc, srs arrays that where pointed from directly in gNB structure Keep in nfapi the existing logic that make malloc for theses rach, pdu, crc, srs array lists Pass only relevant fields, where appropriate. Co-authored-by: Robert Schmidt --- executables/nr-gnb.c | 22 +-- nfapi/open-nFAPI/vnf/src/vnf_p7_interface.c | 33 ++-- openair1/PHY/INIT/nr_init.c | 4 - openair1/PHY/defs_gNB.h | 20 +-- openair1/SCHED_NR/fapi_nr_l1.h | 11 +- openair1/SCHED_NR/nr_prach_procedures.c | 22 +-- openair1/SCHED_NR/phy_procedures_nr_gNB.c | 176 +++++++++----------- openair1/SCHED_NR/sched_nr.h | 4 +- openair1/SIMULATION/NR_PHY/ulschsim.c | 1 - openair1/SIMULATION/NR_PHY/ulsim.c | 18 +- openair2/NR_PHY_INTERFACE/NR_IF_Module.c | 73 ++++---- openair2/NR_PHY_INTERFACE/NR_IF_Module.h | 17 +- 12 files changed, 184 insertions(+), 217 deletions(-) diff --git a/executables/nr-gnb.c b/executables/nr-gnb.c index 8098b75a56..5734efc5d0 100644 --- a/executables/nr-gnb.c +++ b/executables/nr-gnb.c @@ -220,10 +220,10 @@ static void rx_func(processingData_L1_t *info) LOG_D(NR_PHY, "%d.%d Starting RX processing\n", frame_rx, slot_rx); // UE-specific RX processing for subframe n - // TODO: check if this is correct for PARALLEL_RU_L1_TRX_SPLIT - + NR_UL_IND_t UL_INFO = {.frame = frame_rx, .slot = slot_rx, .module_id = gNB->Mod_id, .CC_id = gNB->CC_id}; // Do PRACH RU processing - L1_nr_prach_procedures(gNB,frame_rx,slot_rx); + UL_INFO.rach_ind.pdu_list = UL_INFO.prach_pdu_indication_list; + L1_nr_prach_procedures(gNB, frame_rx, slot_rx, &UL_INFO.rach_ind); //WA: comment rotation in tx/rx if (gNB->phase_comp) { @@ -242,15 +242,11 @@ static void rx_func(processingData_L1_t *info) } } } - phy_procedures_gNB_uespec_RX(gNB, frame_rx, slot_rx); + phy_procedures_gNB_uespec_RX(gNB, frame_rx, slot_rx, &UL_INFO); // Call the scheduler start_meas(&gNB->ul_indication_stats); - gNB->UL_INFO.frame = frame_rx; - gNB->UL_INFO.slot = slot_rx; - gNB->UL_INFO.module_id = gNB->Mod_id; - gNB->UL_INFO.CC_id = gNB->CC_id; - gNB->if_inst->NR_UL_indication(&gNB->UL_INFO); + gNB->if_inst->NR_UL_indication(&UL_INFO); stop_meas(&gNB->ul_indication_stats); #ifndef OAI_FHI72 @@ -462,17 +458,11 @@ void init_gNB() // Register MAC interface module AssertFatal((gNB->if_inst = NR_IF_Module_init(inst)) != NULL, "Cannot register interface"); - LOG_I(NR_PHY, "Registered with MAC interface module (%p)\n", gNB->if_inst); - // Set function pointers in MAC IF module + LOG_I(NR_PHY, "Registered with MAC interface module (%p)\n", gNB->if_inst); gNB->if_inst->NR_Schedule_response = nr_schedule_response; gNB->if_inst->NR_PHY_config_req = nr_phy_config_request; - // Clear UL_INFO and set rx/crc indication lists - memset((void *)&gNB->UL_INFO, 0, sizeof(gNB->UL_INFO)); - gNB->UL_INFO.rx_ind.pdu_list = gNB->rx_pdu_list; - gNB->UL_INFO.crc_ind.crc_list = gNB->crc_pdu_list; - gNB->prach_energy_counter = 0; gNB->chest_time = get_softmodem_params()->chest_time; gNB->chest_freq = get_softmodem_params()->chest_freq; diff --git a/nfapi/open-nFAPI/vnf/src/vnf_p7_interface.c b/nfapi/open-nFAPI/vnf/src/vnf_p7_interface.c index 6bba112c50..a883ccf4a2 100644 --- a/nfapi/open-nFAPI/vnf/src/vnf_p7_interface.c +++ b/nfapi/open-nFAPI/vnf/src/vnf_p7_interface.c @@ -182,24 +182,25 @@ int nfapi_nr_vnf_p7_start(nfapi_vnf_p7_config_t* config) NFAPI_TRACE(NFAPI_TRACE_DEBUG, "This is the slot_ind queue size %ld in %s():%d\n", gnb_slot_ind_queue.num_items, __FUNCTION__, __LINE__); if (slot_ind) { - gNB->UL_INFO.frame = slot_ind->sfn; - gNB->UL_INFO.slot = slot_ind->slot; + NR_UL_IND_t UL_INFO = {.frame = slot_ind->sfn, .slot = slot_ind->slot}; - NFAPI_TRACE(NFAPI_TRACE_DEBUG, "gNB->UL_INFO.frame = %d and slot %d, prev_slot = %d\n", - gNB->UL_INFO.frame, gNB->UL_INFO.slot, prev_slot); - if (setup_done && prev_slot != gNB->UL_INFO.slot) { //Give the VNF sufficient time to setup before starting scheduling && prev_slot != gNB->UL_INFO.slot + NFAPI_TRACE(NFAPI_TRACE_DEBUG, "UL_INFO.frame = %d and slot %d, prev_slot = %d\n", UL_INFO.frame, UL_INFO.slot, prev_slot); + if (setup_done && prev_slot != UL_INFO.slot) { // Give the VNF sufficient time to setup before starting scheduling && + // prev_slot != UL_INFO.slot - //Call the scheduler - gNB->UL_INFO.module_id = gNB->Mod_id; - gNB->UL_INFO.CC_id = gNB->CC_id; - NFAPI_TRACE(NFAPI_TRACE_DEBUG, "Calling NR_UL_indication for gNB->UL_INFO.frame = %d and slot %d\n", - gNB->UL_INFO.frame, gNB->UL_INFO.slot); - gNB->if_inst->NR_UL_indication(&gNB->UL_INFO); - prev_slot = gNB->UL_INFO.slot; - } - free(slot_ind); - slot_ind = NULL; - } + // Call the scheduler + UL_INFO.module_id = gNB->Mod_id; + UL_INFO.CC_id = gNB->CC_id; + NFAPI_TRACE(NFAPI_TRACE_DEBUG, + "Calling NR_UL_indication for UL_INFO.frame = %d and slot %d\n", + UL_INFO.frame, + UL_INFO.slot); + gNB->if_inst->NR_UL_indication(&UL_INFO); + prev_slot = UL_INFO.slot; + } + free(slot_ind); + slot_ind = NULL; + } selectRetval = pselect(maxSock+1, &rfds, NULL, NULL, &pselect_timeout, NULL); diff --git a/openair1/PHY/INIT/nr_init.c b/openair1/PHY/INIT/nr_init.c index 07cdca7692..ca14ca99be 100644 --- a/openair1/PHY/INIT/nr_init.c +++ b/openair1/PHY/INIT/nr_init.c @@ -136,8 +136,6 @@ void phy_init_nr_gNB(PHY_VARS_gNB *gNB) int ret_loader = load_nrLDPC_coding_interface(NULL, &gNB->nrLDPC_coding_interface); AssertFatal(ret_loader == 0, "error loading LDPC library\n"); - pthread_mutex_init(&gNB->UL_INFO.crc_rx_mutex, NULL); - gNB->max_nb_pdsch = MAX_MOBILES_PER_GNB; init_delay_table(fp->ofdm_symbol_size, MAX_DELAY_COMP, NR_MAX_OFDM_SYMBOL_SIZE, fp->delay_table); @@ -231,8 +229,6 @@ void phy_free_nr_gNB(PHY_VARS_gNB *gNB) const int max_ul_mimo_layers = 4; // taken from phy_init_nr_gNB() const int n_buf = Prx * max_ul_mimo_layers; - pthread_mutex_destroy(&gNB->UL_INFO.crc_rx_mutex); - PHY_MEASUREMENTS_gNB *meas = &gNB->measurements; free_and_zero(meas->n0_subband_power); free_and_zero(meas->n0_subband_power_dB); diff --git a/openair1/PHY/defs_gNB.h b/openair1/PHY/defs_gNB.h index e8fdfd4dda..154cc7a989 100644 --- a/openair1/PHY/defs_gNB.h +++ b/openair1/PHY/defs_gNB.h @@ -45,6 +45,7 @@ #include "PHY/CODING/nrLDPC_decoder/nrLDPC_types.h" #include "executables/rt_profiling.h" #include "nfapi_nr_interface_scf.h" +#include "openair2/NR_PHY_INTERFACE/NR_IF_Module.h" #define MAX_NUM_RU_PER_gNB 8 #define MAX_PUCCH0_NID 8 @@ -415,10 +416,6 @@ typedef struct { int prach_I0; } PHY_MEASUREMENTS_gNB; - -#define MAX_NUM_NR_RX_RACH_PDUS 4 -#define MAX_UL_PDUS_PER_SLOT 8 -#define MAX_NUM_NR_SRS_PDUS 8 // the current RRC resource allocation is that each UE gets its // "own" PUCCH resource (for F0) in a dedicated PRB in each slot // therefore, we can have up to "number of UE" UCI PDUs @@ -443,22 +440,9 @@ typedef struct PHY_VARS_gNB_s { NR_DL_FRAME_PARMS frame_parms; PHY_MEASUREMENTS_gNB measurements; NR_IF_Module_t *if_inst; - NR_UL_IND_t UL_INFO; - - /// NFAPI RX ULSCH information - nfapi_nr_rx_data_pdu_t rx_pdu_list[MAX_UL_PDUS_PER_SLOT]; - /// NFAPI RX ULSCH CRC information - nfapi_nr_crc_t crc_pdu_list[MAX_UL_PDUS_PER_SLOT]; - /// NFAPI SRS information - nfapi_nr_srs_indication_pdu_t srs_pdu_list[MAX_NUM_NR_SRS_PDUS]; - /// NFAPI UCI information - nfapi_nr_uci_t uci_pdu_list[MAX_NUM_NR_UCI_PDUS]; - /// NFAPI PRACH information - nfapi_nr_prach_indication_pdu_t prach_pdu_indication_list[MAX_NUM_NR_RX_RACH_PDUS]; nfapi_nr_ul_tti_request_t UL_tti_req; - nfapi_nr_uci_indication_t uci_indication; - + int max_nb_pucch; int max_nb_srs; int max_nb_pdsch; diff --git a/openair1/SCHED_NR/fapi_nr_l1.h b/openair1/SCHED_NR/fapi_nr_l1.h index 28a6d84b9f..59df4fb30d 100644 --- a/openair1/SCHED_NR/fapi_nr_l1.h +++ b/openair1/SCHED_NR/fapi_nr_l1.h @@ -53,8 +53,15 @@ void handle_nr_nfapi_pdsch_pdu(processingData_L1tx_t *msgTx, nfapi_nr_dl_tti_pdsch_pdu *pdsch_pdu, uint8_t *sdu); - -void nr_fill_indication(PHY_VARS_gNB *gNB, int frame, int slot_rx, int UE_id, uint8_t harq_pid, uint8_t crc_flag,int dtx_flag); +void nr_fill_indication(PHY_VARS_gNB *gNB, + int frame, + int slot_rx, + int UE_id, + uint8_t harq_pid, + uint8_t crc_flag, + int dtx_flag, + nfapi_nr_crc_t *crc, + nfapi_nr_rx_data_pdu_t *pdu); //added void handle_nfapi_nr_ul_dci_pdu(PHY_VARS_gNB *gNB, diff --git a/openair1/SCHED_NR/nr_prach_procedures.c b/openair1/SCHED_NR/nr_prach_procedures.c index 280a39c371..75c8ae56c9 100644 --- a/openair1/SCHED_NR/nr_prach_procedures.c +++ b/openair1/SCHED_NR/nr_prach_procedures.c @@ -98,22 +98,19 @@ uint8_t get_nr_prach_duration(uint8_t prach_format){ } } -void L1_nr_prach_procedures(PHY_VARS_gNB *gNB,int frame,int slot) { - +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}; - - uint8_t pdu_index = 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); - gNB->UL_INFO.rach_ind.sfn = frame; - gNB->UL_INFO.rach_ind.slot = slot; - gNB->UL_INFO.rach_ind.pdu_list = gNB->prach_pdu_indication_list; - gNB->UL_INFO.rach_ind.number_of_pdus = 0; + rach_ind->sfn = frame; + rach_ind->slot = slot; + rach_ind->number_of_pdus = 0; ru=gNB->RU_list[0]; @@ -152,7 +149,7 @@ void L1_nr_prach_procedures(PHY_VARS_gNB *gNB,int frame,int slot) { gNB->prach_energy_counter); if ((gNB->prach_energy_counter == 100) && (max_preamble_energy[0] > gNB->measurements.prach_I0 + gNB->prach_thres) - && (pdu_index < MAX_NUM_NR_RX_RACH_PDUS)) { + && (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", @@ -175,9 +172,7 @@ void L1_nr_prach_procedures(PHY_VARS_gNB *gNB,int frame,int slot) { T_INT(max_preamble_energy[0]), T_INT(max_preamble_delay[0])); - gNB->UL_INFO.rach_ind.number_of_pdus += 1; - - nfapi_nr_prach_indication_pdu_t *ind = &gNB->prach_pdu_indication_list[pdu_index]; + 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; @@ -189,7 +184,7 @@ void L1_nr_prach_procedures(PHY_VARS_gNB *gNB,int frame,int slot) { 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; - pdu_index++; + 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); @@ -198,4 +193,3 @@ void L1_nr_prach_procedures(PHY_VARS_gNB *gNB,int frame,int slot) { } //for NUMBER_OF_NR_PRACH_OCCASION_MAX VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_PRACH_RX,0); } - diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c index 26251506c7..8b78cd579b 100644 --- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c +++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c @@ -305,7 +305,7 @@ void phy_procedures_gNB_TX(processingData_L1tx_t *msgTx, VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_gNB_TX + gNB->CC_id, 0); } -static int nr_ulsch_procedures(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, bool *ulsch_to_decode) +static int nr_ulsch_procedures(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, bool *ulsch_to_decode, NR_UL_IND_t *UL_INFO) { NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms; @@ -374,8 +374,7 @@ static int nr_ulsch_procedures(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, boo //--------------------- ULSCH decoding --------------------- //---------------------------------------------------------- - int ret_nr_ulsch_decoding = - nr_ulsch_decoding(gNB, frame_parms, frame_rx, slot_rx, G, ULSCH_ids, nb_pusch); + int ret_nr_ulsch_decoding = nr_ulsch_decoding(gNB, frame_parms, frame_rx, slot_rx, G, ULSCH_ids, nb_pusch); // CRC check per uplink shared channel for (pusch_id = 0; pusch_id < nb_pusch; pusch_id++) { @@ -398,6 +397,8 @@ static int nr_ulsch_procedures(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, boo } } + nfapi_nr_crc_t *crc = &UL_INFO->crc_ind.crc_list[UL_INFO->crc_ind.number_crcs++]; + nfapi_nr_rx_data_pdu_t *pdu = &UL_INFO->rx_ind.pdu_list[UL_INFO->rx_ind.number_of_pdus++]; if (crc_valid && !check_abort(&ulsch_harq->abort_decode) && !pusch->DTX) { LOG_D(NR_PHY, "[gNB %d] ULSCH %d: Setting ACK for SFN/SF %d.%d (rnti %x, pid %d, ndi %d, status %d, round %d, TBS %d, Max interation " @@ -413,7 +414,7 @@ static int nr_ulsch_procedures(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, boo ulsch_harq->round, ulsch_harq->TBS, ulsch->max_ldpc_iterations); - nr_fill_indication(gNB, ulsch->frame, ulsch->slot, ULSCH_id, ulsch->harq_pid, 0, 0); + nr_fill_indication(gNB, ulsch->frame, ulsch->slot, ULSCH_id, ulsch->harq_pid, 0, 0, crc, pdu); LOG_D(PHY, "ULSCH received ok \n"); ulsch->active = false; ulsch_harq->round = 0; @@ -433,7 +434,7 @@ static int nr_ulsch_procedures(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, boo ulsch_harq->ulsch_pdu.rb_start, ulsch_harq->ulsch_pdu.rb_size, ulsch_harq->TBS); - nr_fill_indication(gNB, ulsch->frame, ulsch->slot, ULSCH_id, ulsch->harq_pid, 1, 0); + nr_fill_indication(gNB, ulsch->frame, ulsch->slot, ULSCH_id, ulsch->harq_pid, 1, 0, crc, pdu); ulsch->handled = 1; LOG_D(PHY, "ULSCH %d in error\n",ULSCH_id); ulsch->last_iteration_cnt = ulsch->max_ldpc_iterations + 1; // Setting to max_ldpc_iterations + 1 is sufficient given that this variable is only used for checking for failure @@ -443,7 +444,15 @@ static int nr_ulsch_procedures(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, boo return ret_nr_ulsch_decoding; } -void nr_fill_indication(PHY_VARS_gNB *gNB, int frame, int slot_rx, int ULSCH_id, uint8_t harq_pid, uint8_t crc_flag, int dtx_flag) +void nr_fill_indication(PHY_VARS_gNB *gNB, + int frame, + int slot_rx, + int ULSCH_id, + uint8_t harq_pid, + uint8_t crc_flag, + int dtx_flag, + nfapi_nr_crc_t *crc, + nfapi_nr_rx_data_pdu_t *pdu) { NR_gNB_ULSCH_t *ulsch = &gNB->ulsch[ULSCH_id]; NR_UL_gNB_HARQ_t *harq_process = ulsch->harq_process; @@ -499,54 +508,29 @@ void nr_fill_indication(PHY_VARS_gNB *gNB, int frame, int slot_rx, int ULSCH_id, else if (SNRtimes10 > 635) cqi=255; else cqi=(640+SNRtimes10)/5; - // multiple threads might call this function at the same time, or while the - // L2 reads the messages. Hence, if not protected, crc and rx indications - // might not appear pairwise (in the same order) in the same slot, or even in - // separate slots. The L2 does not support this; hence, use the crc_rx_mutex - // to ensure that messages are pairwise. - int rc = pthread_mutex_lock(&gNB->UL_INFO.crc_rx_mutex); - DevAssert(rc == 0); - - // crc indication - uint16_t num_crc = gNB->UL_INFO.crc_ind.number_crcs; - gNB->UL_INFO.crc_ind.crc_list = &gNB->crc_pdu_list[0]; - gNB->UL_INFO.crc_ind.sfn = frame; - gNB->UL_INFO.crc_ind.slot = slot_rx; - - gNB->crc_pdu_list[num_crc].handle = pusch_pdu->handle; - gNB->crc_pdu_list[num_crc].rnti = pusch_pdu->rnti; - gNB->crc_pdu_list[num_crc].harq_id = harq_pid; - gNB->crc_pdu_list[num_crc].tb_crc_status = crc_flag; - gNB->crc_pdu_list[num_crc].num_cb = pusch_pdu->pusch_data.num_cb; - gNB->crc_pdu_list[num_crc].ul_cqi = cqi; - gNB->crc_pdu_list[num_crc].timing_advance = timing_advance_update; + crc->handle = pusch_pdu->handle; + crc->rnti = pusch_pdu->rnti; + crc->harq_id = harq_pid; + crc->tb_crc_status = crc_flag; + crc->num_cb = pusch_pdu->pusch_data.num_cb; + crc->ul_cqi = cqi; + crc->timing_advance = timing_advance_update; // in terms of dBFS range -128 to 0 with 0.1 step - gNB->crc_pdu_list[num_crc].rssi = + crc->rssi = (dtx_flag == 0) ? 1280 - (10 * dB_fixed(32767 * 32767) - dB_fixed_times10(gNB->pusch_vars[ULSCH_id].ulsch_power[0])) : 0; - gNB->UL_INFO.crc_ind.number_crcs++; - - // rx indication - uint16_t num_rx = gNB->UL_INFO.rx_ind.number_of_pdus; - gNB->UL_INFO.rx_ind.pdu_list = &gNB->rx_pdu_list[0]; - gNB->UL_INFO.rx_ind.sfn = frame; - gNB->UL_INFO.rx_ind.slot = slot_rx; - gNB->rx_pdu_list[num_rx].handle = pusch_pdu->handle; - gNB->rx_pdu_list[num_rx].rnti = pusch_pdu->rnti; - gNB->rx_pdu_list[num_rx].harq_id = harq_pid; - gNB->rx_pdu_list[num_rx].ul_cqi = cqi; - gNB->rx_pdu_list[num_rx].timing_advance = timing_advance_update; - gNB->rx_pdu_list[num_rx].rssi = gNB->crc_pdu_list[num_crc].rssi; + pdu->handle = pusch_pdu->handle; + pdu->rnti = pusch_pdu->rnti; + pdu->harq_id = harq_pid; + pdu->ul_cqi = cqi; + pdu->timing_advance = timing_advance_update; + pdu->rssi = crc->rssi; if (crc_flag) - gNB->rx_pdu_list[num_rx].pdu_length = 0; + pdu->pdu_length = 0; else { - gNB->rx_pdu_list[num_rx].pdu_length = harq_process->TBS; - gNB->rx_pdu_list[num_rx].pdu = harq_process->b; + pdu->pdu_length = harq_process->TBS; + pdu->pdu = harq_process->b; } - gNB->UL_INFO.rx_ind.number_of_pdus++; - - rc = pthread_mutex_unlock(&gNB->UL_INFO.crc_rx_mutex); - DevAssert(rc == 0); } // Function to fill UL RB mask to be used for N0 measurements @@ -715,7 +699,7 @@ int check_srs_pdu(const nfapi_nr_srs_pdu_t *srs_pdu, nfapi_nr_srs_pdu_t *saved_s return 0; } -int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) +int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, NR_UL_IND_t *UL_INFO) { /* those variables to log T_GNB_PHY_PUCCH_PUSCH_IQ only when we try to decode */ int pucch_decode_done = 0; @@ -752,51 +736,55 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) c16_t **rxdataF = gNB->common_vars.rxdataF[pucch->beam_nb]; pucch_decode_done = 1; nfapi_nr_pucch_pdu_t *pucch_pdu = &pucch->pucch_pdu; - uint16_t num_ucis; + UL_INFO->uci_ind.uci_list = UL_INFO->uci_pdu_list; + nfapi_nr_uci_t *uci = UL_INFO->uci_ind.uci_list + UL_INFO->uci_ind.num_ucis; switch (pucch_pdu->format_type) { - case 0: - num_ucis = gNB->UL_INFO.uci_ind.num_ucis; - gNB->UL_INFO.uci_ind.uci_list = &gNB->uci_pdu_list[0]; - gNB->UL_INFO.uci_ind.sfn = frame_rx; - gNB->UL_INFO.uci_ind.slot = slot_rx; - gNB->uci_pdu_list[num_ucis].pdu_type = NFAPI_NR_UCI_FORMAT_0_1_PDU_TYPE; - gNB->uci_pdu_list[num_ucis].pdu_size = sizeof(nfapi_nr_uci_pucch_pdu_format_0_1_t); - nfapi_nr_uci_pucch_pdu_format_0_1_t *uci_pdu_format0 = &gNB->uci_pdu_list[num_ucis].pucch_pdu_format_0_1; + case 0: + UL_INFO->uci_ind.sfn = frame_rx; + UL_INFO->uci_ind.slot = slot_rx; + uci->pdu_type = NFAPI_NR_UCI_FORMAT_0_1_PDU_TYPE; + uci->pdu_size = sizeof(nfapi_nr_uci_pucch_pdu_format_0_1_t); + nfapi_nr_uci_pucch_pdu_format_0_1_t *uci_pdu_format0 = &uci->pucch_pdu_format_0_1; - int offset = pucch_pdu->start_symbol_index*gNB->frame_parms.ofdm_symbol_size + (gNB->frame_parms.first_carrier_offset+pucch_pdu->prb_start*12); - LOG_D(NR_PHY, - "frame %d, slot %d: PUCCH signal energy %d\n", - frame_rx, - slot_rx, - signal_energy_nodc(&rxdataF[0][soffset + offset], 12)); + int offset = pucch_pdu->start_symbol_index * gNB->frame_parms.ofdm_symbol_size + + (gNB->frame_parms.first_carrier_offset + pucch_pdu->prb_start * 12); + LOG_D(NR_PHY, + "frame %d, slot %d: PUCCH signal energy %d\n", + frame_rx, + slot_rx, + signal_energy_nodc(&rxdataF[0][soffset + offset], 12)); - nr_decode_pucch0(gNB, rxdataF, frame_rx, slot_rx, uci_pdu_format0, pucch_pdu); + nr_decode_pucch0(gNB, rxdataF, frame_rx, slot_rx, uci_pdu_format0, pucch_pdu); - gNB->UL_INFO.uci_ind.num_ucis += 1; - pucch->active = false; - break; - case 2: - num_ucis = gNB->UL_INFO.uci_ind.num_ucis; - gNB->UL_INFO.uci_ind.uci_list = &gNB->uci_pdu_list[0]; - gNB->UL_INFO.uci_ind.sfn = frame_rx; - gNB->UL_INFO.uci_ind.slot = slot_rx; - gNB->uci_pdu_list[num_ucis].pdu_type = NFAPI_NR_UCI_FORMAT_2_3_4_PDU_TYPE; - gNB->uci_pdu_list[num_ucis].pdu_size = sizeof(nfapi_nr_uci_pucch_pdu_format_2_3_4_t); - nfapi_nr_uci_pucch_pdu_format_2_3_4_t *uci_pdu_format2 = &gNB->uci_pdu_list[num_ucis].pucch_pdu_format_2_3_4; + UL_INFO->uci_ind.num_ucis += 1; + pucch->active = false; + break; + case 2: + UL_INFO->uci_ind.sfn = frame_rx; + UL_INFO->uci_ind.slot = slot_rx; + uci->pdu_type = NFAPI_NR_UCI_FORMAT_2_3_4_PDU_TYPE; + uci->pdu_size = sizeof(nfapi_nr_uci_pucch_pdu_format_2_3_4_t); + nfapi_nr_uci_pucch_pdu_format_2_3_4_t *uci_pdu_format2 = &uci->pucch_pdu_format_2_3_4; - LOG_D(PHY, "%d.%d Calling nr_decode_pucch2\n", frame_rx, slot_rx); - nr_decode_pucch2(gNB, rxdataF, frame_rx, slot_rx, uci_pdu_format2, pucch_pdu); + LOG_D(PHY, "%d.%d Calling nr_decode_pucch2\n", frame_rx, slot_rx); + nr_decode_pucch2(gNB, rxdataF, frame_rx, slot_rx, uci_pdu_format2, pucch_pdu); - gNB->UL_INFO.uci_ind.num_ucis += 1; - pucch->active = false; - break; - default: - AssertFatal(1 == 0, "Only PUCCH formats 0 and 2 are currently supported\n"); + UL_INFO->uci_ind.num_ucis += 1; + pucch->active = false; + break; + default: + AssertFatal(1 == 0, "Only PUCCH formats 0 and 2 are currently supported\n"); } } } } + UL_INFO->crc_ind.sfn = frame_rx; + UL_INFO->crc_ind.slot = slot_rx; + UL_INFO->crc_ind.crc_list = UL_INFO->crc_pdu_list; + UL_INFO->rx_ind.sfn = frame_rx; + UL_INFO->rx_ind.slot = slot_rx; + UL_INFO->rx_ind.pdu_list = UL_INFO->rx_pdu_list; bool ulsch_to_decode[gNB->max_nb_pusch]; bzero((void *)ulsch_to_decode, sizeof(ulsch_to_decode)); for (int ULSCH_id = 0; ULSCH_id < gNB->max_nb_pusch; ULSCH_id++) { @@ -875,7 +863,9 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) if (!get_softmodem_params()->phy_test) { /* in case of phy_test mode, we still want to decode to measure execution time. Therefore, we don't yet call nr_fill_indication, it will be called later */ - nr_fill_indication(gNB, frame_rx, slot_rx, ULSCH_id, ulsch->harq_pid, 1, 1); + nfapi_nr_crc_t *crc = &UL_INFO->crc_ind.crc_list[UL_INFO->crc_ind.number_crcs++]; + nfapi_nr_rx_data_pdu_t *pdu = &UL_INFO->rx_ind.pdu_list[UL_INFO->rx_ind.number_of_pdus++]; + nr_fill_indication(gNB, frame_rx, slot_rx, ULSCH_id, ulsch->harq_pid, 1, 1, crc, pdu); pusch_DTX++; continue; } @@ -905,7 +895,7 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) if (gNB->max_nb_pusch == 1) start_meas(&gNB->ulsch_decoding_stats); - int const ret_nr_ulsch_procedures = nr_ulsch_procedures(gNB, frame_rx, slot_rx, ulsch_to_decode); + int const ret_nr_ulsch_procedures = nr_ulsch_procedures(gNB, frame_rx, slot_rx, ulsch_to_decode, UL_INFO); if (ret_nr_ulsch_procedures != 0) { LOG_E(PHY,"Error in nr_ulsch_procedures, returned %d\n",ret_nr_ulsch_procedures); } @@ -980,11 +970,12 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) T_INT(0), T_BUFFER(srs_estimated_channel_time_shifted[0][0], frame_parms->ofdm_symbol_size * sizeof(int32_t))); - gNB->UL_INFO.srs_ind.pdu_list = &gNB->srs_pdu_list[0]; - gNB->UL_INFO.srs_ind.sfn = frame_rx; - gNB->UL_INFO.srs_ind.slot = slot_rx; + UL_INFO->srs_ind.sfn = frame_rx; + UL_INFO->srs_ind.slot = slot_rx; - nfapi_nr_srs_indication_pdu_t *srs_indication = &gNB->srs_pdu_list[gNB->UL_INFO.srs_ind.number_of_pdus]; + // data model difficult to understand, nfapi do malloc for this pointer + UL_INFO->srs_ind.pdu_list = UL_INFO->srs_pdu_list; + nfapi_nr_srs_indication_pdu_t *srs_indication = UL_INFO->srs_pdu_list + UL_INFO->srs_ind.number_of_pdus++; srs_indication->handle = srs_pdu->handle; srs_indication->rnti = srs_pdu->rnti; start_meas(&gNB->srs_timing_advance_stats); @@ -1013,8 +1004,8 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) srs_indication->report_type = srs_pdu->srs_parameters_v4.report_type[0]; #ifdef SRS_IND_DEBUG - LOG_I(NR_PHY, "gNB->UL_INFO.srs_ind.sfn = %i\n", gNB->UL_INFO.srs_ind.sfn); - LOG_I(NR_PHY, "gNB->UL_INFO.srs_ind.slot = %i\n", gNB->UL_INFO.srs_ind.slot); + LOG_I(NR_PHY, "UL_INFO->srs_ind.sfn = %i\n", UL_INFO->srs_ind.sfn); + LOG_I(NR_PHY, "UL_INFO->srs_ind.slot = %i\n", UL_INFO->srs_ind.slot); LOG_I(NR_PHY, "srs_indication->rnti = %04x\n", srs_indication->rnti); LOG_I(NR_PHY, "srs_indication->timing_advance = %i\n", srs_indication->timing_advance_offset); LOG_I(NR_PHY, "srs_indication->timing_advance_offset_nsec = %i\n", srs_indication->timing_advance_offset_nsec); @@ -1124,10 +1115,7 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) LOG_I(NR_PHY, "value[%i] = 0x%02x\n", b, value[b] & 0xFF); } #endif - - gNB->UL_INFO.srs_ind.number_of_pdus += 1; srs->active = false; - stop_meas(&gNB->rx_srs_stats); } } diff --git a/openair1/SCHED_NR/sched_nr.h b/openair1/SCHED_NR/sched_nr.h index 20028cea9f..bf5a1eda3f 100644 --- a/openair1/SCHED_NR/sched_nr.h +++ b/openair1/SCHED_NR/sched_nr.h @@ -34,8 +34,8 @@ void nr_set_ssb_first_subcarrier(nfapi_nr_config_request_scf_t *cfg, NR_DL_FRAME_PARMS *fp); void phy_procedures_gNB_TX(processingData_L1tx_t *msgTx, int frame_tx, int slot_tx, int do_meas); -int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx); -void L1_nr_prach_procedures(PHY_VARS_gNB *gNB,int frame,int slot); +int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, NR_UL_IND_t *UL_INFO); +void L1_nr_prach_procedures(PHY_VARS_gNB *gNB, int frame, int slot, nfapi_nr_rach_indication_t *rach_ind); void nr_common_signal_procedures (PHY_VARS_gNB *gNB,int frame,int slot,nfapi_nr_dl_tti_ssb_pdu ssb_pdu); void nr_feptx_ofdm(RU_t *ru,int frame_tx,int tti_tx); void nr_feptx0(RU_t *ru,int tti_tx,int first_symbol, int num_symbols, int aa); diff --git a/openair1/SIMULATION/NR_PHY/ulschsim.c b/openair1/SIMULATION/NR_PHY/ulschsim.c index e2802feffd..3c717a68c4 100644 --- a/openair1/SIMULATION/NR_PHY/ulschsim.c +++ b/openair1/SIMULATION/NR_PHY/ulschsim.c @@ -575,7 +575,6 @@ int main(int argc, char **argv) printf("\n"); exit(-1); #endif - nr_ulsch_decoding(gNB, frame_parms, frame, subframe, &G, &UE_id, 1); bool crc_valid = check_crc(harq_process_gNB->b, lenWithCrc(1, (harq_process_gNB->TBS) << 3), crcType(1, (harq_process_gNB->TBS) << 3)); if (!crc_valid) { diff --git a/openair1/SIMULATION/NR_PHY/ulsim.c b/openair1/SIMULATION/NR_PHY/ulsim.c index bdeab5a139..c704e26fb6 100644 --- a/openair1/SIMULATION/NR_PHY/ulsim.c +++ b/openair1/SIMULATION/NR_PHY/ulsim.c @@ -602,11 +602,11 @@ int main(int argc, char *argv[]) gNB->msgDataTx = msgDataTx; //gNB_config = &gNB->gNB_config; - //memset((void *)&gNB->UL_INFO,0,sizeof(gNB->UL_INFO)); - gNB->UL_INFO.rx_ind.pdu_list = (nfapi_nr_rx_data_pdu_t *)malloc(NB_UE_INST*sizeof(nfapi_nr_rx_data_pdu_t)); - gNB->UL_INFO.crc_ind.crc_list = (nfapi_nr_crc_t *)malloc(NB_UE_INST*sizeof(nfapi_nr_crc_t)); - gNB->UL_INFO.rx_ind.number_of_pdus = 0; - gNB->UL_INFO.crc_ind.number_crcs = 0; + NR_UL_IND_t UL_INFO = {0}; + UL_INFO.crc_ind.crc_list = UL_INFO.crc_pdu_list; + UL_INFO.rx_ind.pdu_list = UL_INFO.rx_pdu_list; + UL_INFO.rx_ind.number_of_pdus = 0; + UL_INFO.crc_ind.number_crcs = 0; gNB->max_ldpc_iterations = max_ldpc_iterations; gNB->pusch_thres = -20; frame_parms = &gNB->frame_parms; //to be initialized I suppose (maybe not necessary for PBCH) @@ -1256,9 +1256,9 @@ int main(int argc, char *argv[]) //---------------------------------------------------------- //------------------- gNB phy procedures ------------------- //---------------------------------------------------------- - gNB->UL_INFO.rx_ind.number_of_pdus = 0; - gNB->UL_INFO.crc_ind.number_crcs = 0; - gNB->UL_INFO.srs_ind.number_of_pdus = 0; + UL_INFO.rx_ind.number_of_pdus = 0; + UL_INFO.crc_ind.number_crcs = 0; + UL_INFO.srs_ind.number_of_pdus = 0; for(uint8_t symbol = 0; symbol < (gNB->frame_parms.Ncp == EXTENDED ? 12 : 14); symbol++) { for (int aa = 0; aa < gNB->frame_parms.nb_antennas_rx; aa++) @@ -1281,7 +1281,7 @@ int main(int argc, char *argv[]) gNB->frame_parms.Ncp == EXTENDED ? 12 : 14); } - ul_proc_error = phy_procedures_gNB_uespec_RX(gNB, frame, slot); + ul_proc_error = phy_procedures_gNB_uespec_RX(gNB, frame, slot, &UL_INFO); if (n_trials == 1 && round == 0) { LOG_M("rxsig0.m", "rx0", &rxdata[0][slot_offset], slot_length, 1, 1); diff --git a/openair2/NR_PHY_INTERFACE/NR_IF_Module.c b/openair2/NR_PHY_INTERFACE/NR_IF_Module.c index 507e4191d0..19d1bb37ec 100644 --- a/openair2/NR_PHY_INTERFACE/NR_IF_Module.c +++ b/openair2/NR_PHY_INTERFACE/NR_IF_Module.c @@ -62,8 +62,7 @@ extern int oai_nfapi_nr_uci_indication(nfapi_nr_uci_indication_t *ind); extern int oai_nfapi_nr_rach_indication(nfapi_nr_rach_indication_t *ind); extern uint8_t nfapi_mode; - -void handle_nr_rach(NR_UL_IND_t *UL_info) +static void handle_nr_rach(NR_UL_IND_t *UL_info) { if (NFAPI_MODE == NFAPI_MODE_PNF) { if (UL_info->rach_ind.number_of_pdus > 0) { @@ -73,34 +72,39 @@ void handle_nr_rach(NR_UL_IND_t *UL_info) } return; } + if (UL_info->rach_ind.number_of_pdus) { + int frame_diff = UL_info->frame - UL_info->rach_ind.sfn; + if (frame_diff < 0) { + frame_diff += 1024; + } + bool in_timewindow = frame_diff == 0 || (frame_diff == 1 && UL_info->slot < 7); - int frame_diff = UL_info->frame - UL_info->rach_ind.sfn; - if (frame_diff < 0) { - frame_diff += 1024; - } - bool in_timewindow = frame_diff == 0 || (frame_diff == 1 && UL_info->slot < 7); - - if (UL_info->rach_ind.number_of_pdus > 0 && in_timewindow) { - LOG_D(MAC,"UL_info[Frame %d, Slot %d] Calling initiate_ra_proc RACH:SFN/SLOT:%d/%d\n", - UL_info->frame, UL_info->slot, UL_info->rach_ind.sfn, UL_info->rach_ind.slot); - for (int i = 0; i < UL_info->rach_ind.number_of_pdus; i++) { - if (UL_info->rach_ind.pdu_list[i].num_preamble > 1) { - LOG_E(MAC, "Not more than 1 preamble per RACH PDU supported, ignoring the rest\n"); + if (in_timewindow) { + LOG_D(MAC, + "UL_info[Frame %d, Slot %d] Calling initiate_ra_proc RACH:SFN/SLOT:%d/%d\n", + UL_info->frame, + UL_info->slot, + UL_info->rach_ind.sfn, + UL_info->rach_ind.slot); + for (int i = 0; i < UL_info->rach_ind.number_of_pdus; i++) { + nfapi_nr_prach_indication_pdu_t *rach = UL_info->rach_ind.pdu_list + i; + if (rach->num_preamble > 1) { + LOG_E(MAC, "Not more than 1 preamble per RACH PDU supported, ignoring the rest\n"); + } + nr_initiate_ra_proc(UL_info->module_id, + UL_info->CC_id, + UL_info->rach_ind.sfn, + UL_info->rach_ind.slot, + rach->preamble_list[0].preamble_index, + rach->freq_index, + rach->symbol_index, + rach->preamble_list[0].timing_advance); } - nr_initiate_ra_proc(UL_info->module_id, - UL_info->CC_id, - UL_info->rach_ind.sfn, - UL_info->rach_ind.slot, - UL_info->rach_ind.pdu_list[i].preamble_list[0].preamble_index, - UL_info->rach_ind.pdu_list[i].freq_index, - UL_info->rach_ind.pdu_list[i].symbol_index, - UL_info->rach_ind.pdu_list[i].preamble_list[0].timing_advance); } } } - -void handle_nr_uci(NR_UL_IND_t *UL_info) +static void handle_nr_uci(NR_UL_IND_t *UL_info) { if(NFAPI_MODE == NFAPI_MODE_PNF) { if (UL_info->uci_ind.num_ucis > 0) { @@ -161,7 +165,7 @@ static bool crc_sfn_slot_matcher(void *wanted, void *candidate) return false; } -void handle_nr_ulsch(NR_UL_IND_t *UL_info) +static void handle_nr_ulsch(NR_UL_IND_t *UL_info) { if(NFAPI_MODE == NFAPI_MODE_PNF) { if (UL_info->crc_ind.number_crcs > 0) { @@ -179,9 +183,6 @@ void handle_nr_ulsch(NR_UL_IND_t *UL_info) } if (UL_info->rx_ind.number_of_pdus > 0 && UL_info->crc_ind.number_crcs > 0) { - // see nr_fill_indication about why this mutex is necessary - int rc = pthread_mutex_lock(&UL_info->crc_rx_mutex); - DevAssert(rc == 0); AssertFatal(UL_info->rx_ind.number_of_pdus == UL_info->crc_ind.number_crcs, "number_of_pdus %d, number_crcs %d\n", UL_info->rx_ind.number_of_pdus, UL_info->crc_ind.number_crcs); @@ -191,12 +192,12 @@ void handle_nr_ulsch(NR_UL_IND_t *UL_info) LOG_D(NR_PHY, "UL_info->crc_ind.pdu_list[%d].rnti:%04x " "UL_info->rx_ind.pdu_list[%d].rnti:%04x\n", i, crc->rnti, i, rx->rnti); + AssertFatal(crc->rnti == rx->rnti, "mis-match between CRC RNTI %04x and RX RNTI %04x\n", crc->rnti, rx->rnti); - AssertFatal(crc->rnti == rx->rnti, "mis-match between CRC RNTI %04x and RX RNTI %04x\n", - crc->rnti, rx->rnti); - - AssertFatal(crc->harq_id == rx->harq_id, "mis-match between CRC HARQ ID %04x and RX HARQ ID %04x\n", - crc->harq_id, rx->harq_id); + AssertFatal(crc->harq_id == rx->harq_id, + "mis-match between CRC HARQ ID %04x and RX HARQ ID %04x\n", + crc->harq_id, + rx->harq_id); LOG_D(NR_MAC, "%4d.%2d Calling rx_sdu (CRC %s/tb_crc_status %d)\n", @@ -221,13 +222,11 @@ void handle_nr_ulsch(NR_UL_IND_t *UL_info) } UL_info->rx_ind.number_of_pdus = 0; UL_info->crc_ind.number_crcs = 0; - rc = pthread_mutex_unlock(&UL_info->crc_rx_mutex); - DevAssert(rc == 0); } } -void handle_nr_srs(NR_UL_IND_t *UL_info) { - +static void handle_nr_srs(NR_UL_IND_t *UL_info) +{ if(NFAPI_MODE == NFAPI_MODE_PNF) { if (UL_info->srs_ind.number_of_pdus > 0) { LOG_D(PHY,"PNF Sending UL_info->srs_ind.number_of_pdus: %d, SFN/SF:%d.%d \n", diff --git a/openair2/NR_PHY_INTERFACE/NR_IF_Module.h b/openair2/NR_PHY_INTERFACE/NR_IF_Module.h index 261ead1ba0..ce6acffc2c 100644 --- a/openair2/NR_PHY_INTERFACE/NR_IF_Module.h +++ b/openair2/NR_PHY_INTERFACE/NR_IF_Module.h @@ -37,6 +37,9 @@ #include #include "assertions.h" #include "nfapi_nr_interface_scf.h" +#include "common/platform_constants.h" +#include "common/platform_types.h" +#include "common/openairinterface5g_limits.h" #define MAX_NUM_DL_PDU 100 #define MAX_NUM_UL_PDU 100 @@ -50,6 +53,10 @@ #define MAX_NUM_RACH_IND 100 #define MAX_NUM_SRS_IND 100 +#define MAX_NUM_NR_RX_RACH_PDUS 4 +#define MAX_UL_PDUS_PER_SLOT 8 +#define MAX_NUM_NR_SRS_PDUS 8 +#define MAX_NUM_NR_UCI_PDUS MAX_MOBILES_PER_GNB typedef struct { /// Module ID module_id_t module_id; @@ -64,10 +71,6 @@ typedef struct { nfapi_nr_crc_indication_t crc_ind; /// RX indication nfapi_nr_rx_data_indication_t rx_ind; - /// mutex to protect concurrent access to crc_ind and rx_ind, which the L2 - /// needs to be pairwise - pthread_mutex_t crc_rx_mutex; - /// RACH indication list nfapi_nr_rach_indication_t rach_ind; @@ -76,6 +79,12 @@ typedef struct { /// UCI indication nfapi_nr_uci_indication_t uci_ind; + nfapi_nr_crc_t crc_pdu_list[MAX_UL_PDUS_PER_SLOT]; + nfapi_nr_rx_data_pdu_t rx_pdu_list[MAX_UL_PDUS_PER_SLOT]; + nfapi_nr_srs_indication_pdu_t srs_pdu_list[MAX_NUM_NR_SRS_PDUS]; + nfapi_nr_uci_t uci_pdu_list[MAX_NUM_NR_UCI_PDUS]; + /// NFAPI PRACH information + nfapi_nr_prach_indication_pdu_t prach_pdu_indication_list[MAX_NUM_NR_RX_RACH_PDUS]; } NR_UL_IND_t;