From db2bcf0eee1b283792d4c14abd30a9e7e72fb7fe Mon Sep 17 00:00:00 2001 From: francescomani Date: Fri, 23 Jan 2026 13:48:52 +0100 Subject: [PATCH 01/11] preventing include of log.h in nr_common.h by moving function in nr_common.c --- common/utils/nr/nr_common.c | 13 +++++++++++++ common/utils/nr/nr_common.h | 14 +------------- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/common/utils/nr/nr_common.c b/common/utils/nr/nr_common.c index a3a8520c86..8d61498f9e 100644 --- a/common/utils/nr/nr_common.c +++ b/common/utils/nr/nr_common.c @@ -796,6 +796,19 @@ int get_subband_size(int NPRB,int size) { } +void warn_higher_threequarter_fs(const int n_rb, const int mu) +{ + LOG_W(NR_PHY, + "3/4 sampling is not possible for current PRB size: %d and numerology: %d.\n " + "So 6/4 sampling is chosen to support x3xx type USRPs.\n " + "Note that this sampling rate increases fronthaul traffic, FFT buffer size and processing time by a factor of two compared " + "to 3/4 sampling rate.\n " + "Some PRACH configuration might not be supported with 6/4 FFT size.\n " + "Consider reducing the PRB size that would fit within the FFT size of 3/4 sampling\n", + n_rb, + mu); +} + void get_samplerate_and_bw(int mu, int n_rb, int8_t threequarter_fs, diff --git a/common/utils/nr/nr_common.h b/common/utils/nr/nr_common.h index ca867fa694..f1a48766a9 100644 --- a/common/utils/nr/nr_common.h +++ b/common/utils/nr/nr_common.h @@ -37,7 +37,6 @@ #include #include "assertions.h" #include "common/utils/utils.h" -#include "common/utils/LOG/log.h" #define MAX_SI_GROUPS 3 #define NR_MAX_PDSCH_TBS 3824 @@ -273,18 +272,7 @@ static __attribute__((always_inline)) inline int count_bits64_with_mask(uint64_t return count_bits64(v & mask); } -static inline void warn_higher_threequarter_fs(const int n_rb, const int mu) -{ - LOG_W(PHY, - "3/4 sampling is not possible for current PRB size: %d and numerology: %d.\n " - "So 6/4 sampling is chosen to support x3xx type USRPs.\n " - "Note that this sampling rate increases fronthaul traffic, FFT buffer size and processing time by a factor of two compared " - "to 3/4 sampling rate.\n " - "Some PRACH configuration might not be supported with 6/4 FFT size.\n " - "Consider reducing the PRB size that would fit within the FFT size of 3/4 sampling\n", - n_rb, - mu); -} +void warn_higher_threequarter_fs(const int n_rb, const int mu); uint64_t from_nrarfcn(int nr_bandP, uint8_t scs_index, uint32_t dl_nrarfcn); uint32_t to_nrarfcn(int nr_bandP, uint64_t dl_CarrierFreq, uint8_t scs_index, uint32_t bw); From b53f4a6e377f0e28750ca57edbd321522716e64f Mon Sep 17 00:00:00 2001 From: francescomani Date: Thu, 21 Nov 2024 17:04:04 +0100 Subject: [PATCH 02/11] using constants for FAPI precoding weigths instead of hardcoded values --- common/utils/nr/nr_common.h | 1 + nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h | 3 ++- openair1/PHY/INIT/nr_init_ue.c | 6 +++--- openair1/PHY/defs_nr_common.h | 2 -- openair2/GNB_APP/gnb_config.c | 3 +++ 5 files changed, 9 insertions(+), 6 deletions(-) diff --git a/common/utils/nr/nr_common.h b/common/utils/nr/nr_common.h index f1a48766a9..d2b78725c9 100644 --- a/common/utils/nr/nr_common.h +++ b/common/utils/nr/nr_common.h @@ -87,6 +87,7 @@ static inline const char *rnti_types(nr_rnti_type_t rr) #define NR_NUMBER_OF_SYMBOLS_PER_SLOT 14 #define NR_NUMBER_OF_SYMBOLS_PER_SLOT_EXTENDED_CP 12 #define NR_MAX_NB_LAYERS 4 // 8 +#define NR_MAX_CSI_PORTS 4 // Since the IQ samples are represented by SQ15 R+I (see https://en.wikipedia.org/wiki/Q_(number_format)) we need to compensate when // calcualting signal energy. Instead of shifting each sample right by 15, we can normalize the result in dB scale once its diff --git a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h index fcd1968c25..3485c6430d 100644 --- a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h +++ b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h @@ -11,6 +11,7 @@ #include "stddef.h" #include "common/platform_types.h" +#include "common/utils/nr/nr_common.h" #include "nfapi_interface.h" #include "nfapi_nr_interface.h" @@ -495,7 +496,7 @@ typedef struct { uint16_t pm_idx; uint16_t numLayers; uint16_t num_ant_ports; - nfapi_nr_pm_weights_t weights[4][4]; // TODO temporary hardcoding + nfapi_nr_pm_weights_t weights[NR_MAX_NB_LAYERS][NR_MAX_CSI_PORTS]; } nfapi_nr_pm_pdu_t; diff --git a/openair1/PHY/INIT/nr_init_ue.c b/openair1/PHY/INIT/nr_init_ue.c index 7b21102bbf..c40d8b1096 100644 --- a/openair1/PHY/INIT/nr_init_ue.c +++ b/openair1/PHY/INIT/nr_init_ue.c @@ -262,8 +262,8 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB) // ceil((NB_RB*8(max allocation per RB)*2(QPSK))/32) ue->nr_csi_info = malloc16_clear(sizeof(nr_csi_info_t)); - ue->nr_csi_info->csi_rs_generated_signal = malloc16(NR_MAX_NB_PORTS * sizeof(*ue->nr_csi_info->csi_rs_generated_signal)); - for (int i = 0; i < NR_MAX_NB_PORTS; i++) { + ue->nr_csi_info->csi_rs_generated_signal = malloc16(NR_MAX_CSI_PORTS * sizeof(*ue->nr_csi_info->csi_rs_generated_signal)); + for (int i = 0; i < NR_MAX_CSI_PORTS; i++) { ue->nr_csi_info->csi_rs_generated_signal[i] = malloc16_clear(fp->samples_per_frame_wCP * sizeof(**ue->nr_csi_info->csi_rs_generated_signal)); } @@ -311,7 +311,7 @@ void term_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB) for (int gNB_id = 0; gNB_id < ue->n_connected_gNB; gNB_id++) { - for (int i=0; inr_csi_info->csi_rs_generated_signal[i]); } free_and_zero(ue->nr_csi_info->csi_rs_generated_signal); diff --git a/openair1/PHY/defs_nr_common.h b/openair1/PHY/defs_nr_common.h index dc2630348c..01677594cd 100644 --- a/openair1/PHY/defs_nr_common.h +++ b/openair1/PHY/defs_nr_common.h @@ -68,8 +68,6 @@ #define NR_MAX_PDCCH_AGG_LEVEL 16 // 3GPP TS 38.211 V15.8 Section 7.3.2 Table 7.3.2.1-1: Supported PDCCH aggregation levels -#define NR_MAX_NB_PORTS 32 - #define MAX_NUM_NR_DLSCH_SEGMENTS_PER_LAYER 36 #define MAX_NUM_NR_ULSCH_SEGMENTS_PER_LAYER 34 diff --git a/openair2/GNB_APP/gnb_config.c b/openair2/GNB_APP/gnb_config.c index f9e8261c0f..667ab25093 100644 --- a/openair2/GNB_APP/gnb_config.c +++ b/openair2/GNB_APP/gnb_config.c @@ -879,6 +879,9 @@ void RCconfig_NR_L1(void) // Antenna ports set_antenna_ports(&GNBParamList, &gNB->ap_N1, &gNB->ap_N2, &gNB->ap_XP); + AssertFatal(gNB->ap_N1 * gNB->ap_N2 * gNB->ap_XP <= NR_MAX_CSI_PORTS, + "Number of antenna ports set in config file exceeds the supported value of %d\n", + NR_MAX_CSI_PORTS); } // L1 params From 7a59f28ae314f5b16f2c517f82f34f8facc7f4f6 Mon Sep 17 00:00:00 2001 From: francescomani Date: Thu, 21 Nov 2024 18:10:46 +0100 Subject: [PATCH 03/11] RRC CSI-RS config for 8 and 12 ports --- common/utils/nr/nr_common.h | 2 +- openair2/LAYER2/NR_MAC_gNB/nr_radio_config.c | 20 +++++++++++++++++++- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/common/utils/nr/nr_common.h b/common/utils/nr/nr_common.h index d2b78725c9..b6e7a474bb 100644 --- a/common/utils/nr/nr_common.h +++ b/common/utils/nr/nr_common.h @@ -87,7 +87,7 @@ static inline const char *rnti_types(nr_rnti_type_t rr) #define NR_NUMBER_OF_SYMBOLS_PER_SLOT 14 #define NR_NUMBER_OF_SYMBOLS_PER_SLOT_EXTENDED_CP 12 #define NR_MAX_NB_LAYERS 4 // 8 -#define NR_MAX_CSI_PORTS 4 +#define NR_MAX_CSI_PORTS 12 // Since the IQ samples are represented by SQ15 R+I (see https://en.wikipedia.org/wiki/Q_(number_format)) we need to compensate when // calcualting signal energy. Instead of shifting each sample right by 15, we can normalize the result in dB scale once its diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_radio_config.c b/openair2/LAYER2/NR_MAC_gNB/nr_radio_config.c index fe4a64da2b..a7376d69ec 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_radio_config.c +++ b/openair2/LAYER2/NR_MAC_gNB/nr_radio_config.c @@ -479,8 +479,26 @@ static void config_csirs(const NR_ServingCellConfigCommon_t *servingcellconfigco resourceMapping.nrofPorts = NR_CSI_RS_ResourceMapping__nrofPorts_p4; resourceMapping.cdm_Type = NR_CSI_RS_ResourceMapping__cdm_Type_fd_CDM2; break; + case 8: + resourceMapping.frequencyDomainAllocation.present = NR_CSI_RS_ResourceMapping__frequencyDomainAllocation_PR_other; + resourceMapping.frequencyDomainAllocation.choice.other.buf = calloc(1, sizeof(uint8_t)); + resourceMapping.frequencyDomainAllocation.choice.other.size = 1; + resourceMapping.frequencyDomainAllocation.choice.other.bits_unused = 2; + resourceMapping.frequencyDomainAllocation.choice.other.buf[0] = 60; + resourceMapping.nrofPorts = NR_CSI_RS_ResourceMapping__nrofPorts_p8; + resourceMapping.cdm_Type = NR_CSI_RS_ResourceMapping__cdm_Type_fd_CDM2; + break; + case 12: + resourceMapping.frequencyDomainAllocation.present = NR_CSI_RS_ResourceMapping__frequencyDomainAllocation_PR_other; + resourceMapping.frequencyDomainAllocation.choice.other.buf = calloc(1, sizeof(uint8_t)); + resourceMapping.frequencyDomainAllocation.choice.other.size = 1; + resourceMapping.frequencyDomainAllocation.choice.other.bits_unused = 2; + resourceMapping.frequencyDomainAllocation.choice.other.buf[0] = 252; + resourceMapping.nrofPorts = NR_CSI_RS_ResourceMapping__nrofPorts_p12; + resourceMapping.cdm_Type = NR_CSI_RS_ResourceMapping__cdm_Type_fd_CDM2; + break; default: - AssertFatal(1==0,"Number of ports not yet supported\n"); + AssertFatal(false, "Number of ports not yet supported\n"); } resourceMapping.firstOFDMSymbolInTimeDomain = 13; // last symbol of slot resourceMapping.firstOFDMSymbolInTimeDomain2 = NULL; From 0a79dce24b946c8a72e91164b5452f9306391a76 Mon Sep 17 00:00:00 2001 From: francescomani Date: Thu, 23 Jan 2025 10:23:30 +0100 Subject: [PATCH 04/11] configuration of PUCCH2 PRB number depending on antenna ports --- openair2/LAYER2/NR_MAC_gNB/nr_radio_config.c | 72 ++++++++++++-------- 1 file changed, 44 insertions(+), 28 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_radio_config.c b/openair2/LAYER2/NR_MAC_gNB/nr_radio_config.c index a7376d69ec..8f3944ee44 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_radio_config.c +++ b/openair2/LAYER2/NR_MAC_gNB/nr_radio_config.c @@ -56,7 +56,6 @@ #define DEFAULT_MGTA NR_GapConfig__mgta_ms0dot5 #define DEFAULT_MGL NR_GapConfig__mgl_ms6 -#define PUCCH2_SIZE 8 const uint8_t slotsperframe[5] = {10, 20, 40, 80, 160}; static NR_BWP_t clone_generic_parameters(const NR_BWP_t *gp) @@ -216,7 +215,14 @@ static NR_SetupRelease_PDSCH_ConfigCommon_t *clone_pdsch_configcommon(const NR_S return clone; } -static int get_nb_pucch2_per_slot(const NR_ServingCellConfigCommon_t *scc, int bwp_size) +static int get_pucch2_size(const int num_ant_ports) +{ + // TODO the logic to set the number of PRBs needs to be improved + // it should involve the code rate parameter and the max number of bits to be transmitted + return (num_ant_ports <= 4 ? 8 : 16); +} + +static int get_nb_pucch2_per_slot(const NR_ServingCellConfigCommon_t *scc, int bwp_size, const nr_pdsch_AntennaPorts_t *ap) { const NR_TDD_UL_DL_Pattern_t *tdd = scc->tdd_UL_DL_ConfigurationCommon ? &scc->tdd_UL_DL_ConfigurationCommon->pattern1 : NULL; const int n_slots_frame = slotsperframe[*scc->ssbSubcarrierSpacing]; @@ -226,12 +232,14 @@ static int get_nb_pucch2_per_slot(const NR_ServingCellConfigCommon_t *scc, int b int max_csi_reports = MAX_MOBILES_PER_GNB << 1; // 2 reports per UE (RSRP and RI-PMI-CQI) int available_report_occasions = max_meas_report_period * ul_slots_period / n_slots_period; int nb_pucch2 = (max_csi_reports / (available_report_occasions + 1)) + 1; - // in current implementation we need (nb_pucch2 * PUCCH2_SIZE) prbs for PUCCH2 + int pucch2_size = get_pucch2_size(ap->N1 * ap->N2 * ap->XP); + // in current implementation we need (nb_pucch2 * pucch2_size) prbs for PUCCH2 // and MAX_MOBILES_PER_GNB prbs for PUCCH1 // checked for validity in verify_radio_configuration - AssertFatal((nb_pucch2 * PUCCH2_SIZE) + MAX_MOBILES_PER_GNB <= bwp_size, + AssertFatal((nb_pucch2 * pucch2_size) + MAX_MOBILES_PER_GNB <= bwp_size, "Cannot allocate all required PUCCH resources for max number of %d UEs in BWP with %d PRBs\n", - MAX_MOBILES_PER_GNB, bwp_size); + MAX_MOBILES_PER_GNB, + bwp_size); return nb_pucch2; } @@ -1206,11 +1214,12 @@ static void set_dl_DataToUL_ACK(NR_PUCCH_Config_t *pucch_Config, int min_feedbac } // PUCCH resource set 0 for configuration with O_uci <= 2 bits and/or a positive or negative SR (section 9.2.1 of 38.213) -static void config_pucch_resset0(NR_PUCCH_Config_t *pucch_Config, +static void config_pucch_resset0(const NR_ServingCellConfigCommon_t *scc, + NR_PUCCH_Config_t *pucch_Config, int uid, int curr_bwp, - int num_pucch2, - const NR_UE_NR_Capability_t *uecap) + const NR_UE_NR_Capability_t *uecap, + const nr_pdsch_AntennaPorts_t *ap) { NR_PUCCH_ResourceSet_t *pucchresset = calloc(1,sizeof(*pucchresset)); pucchresset->pucch_ResourceSetId = 0; @@ -1224,9 +1233,11 @@ static void config_pucch_resset0(NR_PUCCH_Config_t *pucch_Config, AssertFatal(pucch_F0_2WithoutFH == NULL,"UE does not support PUCCH F0 without frequency hopping. Current configuration is without FH\n"); } + int pucch2_size = get_pucch2_size(ap->N1 * ap->N2 * ap->XP); NR_PUCCH_Resource_t *pucchres0 = calloc(1,sizeof(*pucchres0)); pucchres0->pucch_ResourceId = *pucchid; - pucchres0->startingPRB = (PUCCH2_SIZE * num_pucch2) + uid; + int num_pucch2 = get_nb_pucch2_per_slot(scc, curr_bwp, ap); + pucchres0->startingPRB = (pucch2_size * num_pucch2) + uid; // checked for validity in verify_radio_configuration AssertFatal(pucchres0->startingPRB < curr_bwp, "Not enough resources in current BWP (size %d) to allocate uid %d\n", curr_bwp, uid); pucchres0->intraSlotFrequencyHopping = NULL; @@ -1243,10 +1254,12 @@ static void config_pucch_resset0(NR_PUCCH_Config_t *pucch_Config, // PUCCH resource set 1 for configuration with O_uci > 2 bits (currently format2) -static void config_pucch_resset1(NR_PUCCH_Config_t *pucch_Config, +static void config_pucch_resset1(const NR_ServingCellConfigCommon_t *scc, + NR_PUCCH_Config_t *pucch_Config, int uid, - int num_pucch2, - const NR_UE_NR_Capability_t *uecap) + int curr_bwp, + const NR_UE_NR_Capability_t *uecap, + const nr_pdsch_AntennaPorts_t *ap) { NR_PUCCH_ResourceSet_t *pucchresset=calloc(1,sizeof(*pucchresset)); pucchresset->pucch_ResourceSetId = 1; @@ -1260,14 +1273,16 @@ static void config_pucch_resset1(NR_PUCCH_Config_t *pucch_Config, AssertFatal(pucch_F0_2WithoutFH == NULL,"UE does not support PUCCH F2 without frequency hopping. Current configuration is without FH\n"); } + int pucch2_size = get_pucch2_size(ap->N1 * ap->N2 * ap->XP); NR_PUCCH_Resource_t *pucchres2 = calloc(1,sizeof(*pucchres2)); pucchres2->pucch_ResourceId = *pucchressetid; - pucchres2->startingPRB = PUCCH2_SIZE * (uid % num_pucch2); + int num_pucch2 = get_nb_pucch2_per_slot(scc, curr_bwp, ap); + pucchres2->startingPRB = pucch2_size * (uid % num_pucch2); pucchres2->intraSlotFrequencyHopping = NULL; pucchres2->secondHopPRB = NULL; pucchres2->format.present = NR_PUCCH_Resource__format_PR_format2; pucchres2->format.choice.format2 = calloc(1,sizeof(*pucchres2->format.choice.format2)); - pucchres2->format.choice.format2->nrofPRBs = PUCCH2_SIZE; + pucchres2->format.choice.format2->nrofPRBs = pucch2_size; pucchres2->format.choice.format2->nrofSymbols = 1; pucchres2->format.choice.format2->startingSymbolIndex = 13; asn1cSeqAdd(&pucch_Config->resourceToAddModList->list,pucchres2); @@ -1898,9 +1913,8 @@ static NR_BWP_Uplink_t *config_uplinkBWP(bool is_SA, pucch_Config->resourceSetToReleaseList = NULL; pucch_Config->resourceToAddModList = calloc(1,sizeof(*pucch_Config->resourceToAddModList)); pucch_Config->resourceToReleaseList = NULL; - int num_pucch2 = get_nb_pucch2_per_slot(scc, curr_bwp); - config_pucch_resset0(pucch_Config, uid, curr_bwp, num_pucch2, uecap); - config_pucch_resset1(pucch_Config, uid, num_pucch2, uecap); + config_pucch_resset0(scc, pucch_Config, uid, curr_bwp, uecap, &configuration->pdsch_AntennaPorts); + config_pucch_resset1(scc, pucch_Config, uid, curr_bwp, uecap, &configuration->pdsch_AntennaPorts); set_pucch_power_config(pucch_Config, configuration->do_CSIRS); scheduling_request_config(scc, pucch_Config, ubwp->bwp_Common->genericParameters.subcarrierSpacing); set_dl_DataToUL_ACK(pucch_Config, configuration->minRXTXTIME, ubwp->bwp_Common->genericParameters.subcarrierSpacing); @@ -1935,10 +1949,11 @@ static void set_csi_meas_periodicity(const NR_ServingCellConfigCommon_t *scc, NR_CSI_ReportConfig_t *csirep, int uid, int curr_bwp, + const nr_pdsch_AntennaPorts_t *antennaports, bool is_rsrp) { const int ideal_period = set_ideal_period(true); - const int num_pucch2 = get_nb_pucch2_per_slot(scc, curr_bwp); + const int num_pucch2 = get_nb_pucch2_per_slot(scc, curr_bwp, antennaports); const int idx = (uid * 2 / num_pucch2) + is_rsrp; frame_structure_t *fs = &RC.nrmac[0]->frame_structure; int offset = get_ul_slot_offset(fs, idx, true); @@ -2121,7 +2136,7 @@ static void config_csi_meas_report(NR_CSI_MeasConfig_t *csi_MeasConfig, csirep->nzp_CSI_RS_ResourcesForInterference = NULL; csirep->reportConfigType.present = NR_CSI_ReportConfig__reportConfigType_PR_periodic; csirep->reportConfigType.choice.periodic = calloc(1, sizeof(*csirep->reportConfigType.choice.periodic)); - set_csi_meas_periodicity(servingcellconfigcommon, csirep, uid, curr_bwp, false); + set_csi_meas_periodicity(servingcellconfigcommon, csirep, uid, curr_bwp, antennaports, false); asn1cSeqAdd(&csirep->reportConfigType.choice.periodic->pucch_CSI_ResourceList.list, pucchcsires); csirep->reportQuantity.present = NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_PMI_CQI; csirep->reportQuantity.choice.cri_RI_PMI_CQI = (NULL_t)0; @@ -2188,10 +2203,11 @@ static void config_rsrp_meas_report(NR_CSI_MeasConfig_t *csi_MeasConfig, int rep_id, int uid, int curr_bwp, - int num_antenna_ports, uint64_t ssb_bitmap) { int resource_id = -1; + const nr_pdsch_AntennaPorts_t *pdschap = &configuration->pdsch_AntennaPorts; + const int num_antenna_ports = pdschap->N1 * pdschap->N2 * pdschap->XP; for (int csi_list = 0; csi_list < csi_MeasConfig->csi_ResourceConfigToAddModList->list.count; csi_list++) { NR_CSI_ResourceConfig_t *csires = csi_MeasConfig->csi_ResourceConfigToAddModList->list.array[csi_list]; if (csires->csi_RS_ResourceSetList.present == NR_CSI_ResourceConfig__csi_RS_ResourceSetList_PR_nzp_CSI_RS_SSB) { @@ -2215,7 +2231,7 @@ static void config_rsrp_meas_report(NR_CSI_MeasConfig_t *csi_MeasConfig, csirep->nzp_CSI_RS_ResourcesForInterference = NULL; csirep->reportConfigType.present = NR_CSI_ReportConfig__reportConfigType_PR_periodic; csirep->reportConfigType.choice.periodic = calloc(1, sizeof(*csirep->reportConfigType.choice.periodic)); - set_csi_meas_periodicity(servingcellconfigcommon, csirep, uid, curr_bwp, true); + set_csi_meas_periodicity(servingcellconfigcommon, csirep, uid, curr_bwp, pdschap, true); asn1cSeqAdd(&csirep->reportConfigType.choice.periodic->pucch_CSI_ResourceList.list, pucchcsires); if (configuration->report_type == SSB_SINR) { csirep->reportQuantity.present = NR_CSI_ReportConfig__reportQuantity_PR_none; @@ -3344,9 +3360,8 @@ static NR_BWP_UplinkDedicated_t *configure_initial_ul_bwp(const NR_ServingCellCo pucch_Config->resourceSetToReleaseList = NULL; pucch_Config->resourceToAddModList = calloc(1, sizeof(*pucch_Config->resourceToAddModList)); pucch_Config->resourceToReleaseList = NULL; - int num_pucch2 = get_nb_pucch2_per_slot(scc, curr_bwp); - config_pucch_resset0(pucch_Config, id, curr_bwp, num_pucch2, uecap); - config_pucch_resset1(pucch_Config, id, num_pucch2, uecap); + config_pucch_resset0(scc, pucch_Config, id, curr_bwp, uecap, &configuration->pdsch_AntennaPorts); + config_pucch_resset1(scc, pucch_Config, id, curr_bwp, uecap, &configuration->pdsch_AntennaPorts); set_pucch_power_config(pucch_Config, configuration->do_CSIRS); initialUplinkBWP->pusch_Config = config_pusch(configuration, scc, uecap); @@ -3520,7 +3535,6 @@ static NR_CSI_MeasConfig_t *get_csiMeasConfig(const NR_ServingCellConfig_t *conf bwp_id + 10, uid, curr_bwp, - pdsch_AntennaPorts, bitmap); return csi_MeasConfig; } @@ -3742,16 +3756,18 @@ static bool verify_radio_configuration(int uid, const NR_ServingCellConfigCommon return false; // cannot allocate resources for CSI-RS } + const nr_pdsch_AntennaPorts_t *ap = &configuration->pdsch_AntennaPorts; + int pucch2_size = get_pucch2_size(ap->N1 * ap->N2 * ap->XP); int curr_bwp = NRRIV2BW(scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); - int num_pucch2 = get_nb_pucch2_per_slot(scc, curr_bwp); - int pucchres0_startingPRB = (PUCCH2_SIZE * num_pucch2) + uid; + int num_pucch2 = get_nb_pucch2_per_slot(scc, curr_bwp, ap); + int pucchres0_startingPRB = (pucch2_size * num_pucch2) + uid; // see config_pucch_resset0 if (pucchres0_startingPRB >= curr_bwp) { LOG_E(NR_RRC, "UID %d, cannot allocate resources for PUCCH0, rejecting UE\n", uid); return false; // cannot allocate resources for PUCCH0 } // see get_nb_pucch2_per_slot - if ((num_pucch2 * PUCCH2_SIZE) + MAX_MOBILES_PER_GNB > curr_bwp) { + if ((num_pucch2 * pucch2_size) + MAX_MOBILES_PER_GNB > curr_bwp) { LOG_E(NR_RRC, "UID %d, cannot allocate resources for PUCCH2, rejecting UE\n", uid); return false; // cannot allocate resources for PUCCH2 } From 448f27324812a31c14df895ca5c8cdf3c5d57881 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Fri, 20 Feb 2026 19:14:28 +0100 Subject: [PATCH 05/11] Write NB_ANTENNAS_RX/TX to header file and use in stack Prior to this commit, constants NB_ANTENNAS_RX/TX are provided on the command line to each compiler invocation. This has the drawback (1) that also files that don't need that get the constants, and (2) it is not easy to find them using ctags or similar, as the only definition is in CMakeLists.txt (where it is not found). In this commit, use cmake configure_file() to write a header file with these constants. The file will be generated during cmake invocation, and written to /common/cmake_defs.h. The relevant files that need this definition will pick it from the header. This has been used previously also in a commit to write git information. See-also: 8bffd1666df6 ("Avoid complete rebuild on cmake run with git info change") --- CMakeLists.txt | 6 +++-- cmake_targets/macros.cmake | 13 ----------- common/CMakeLists.txt | 1 + common/cmake_defs.h.in | 30 +++++++++++++++++++++++++ openair1/PHY/defs_UE.h | 1 + openair1/PHY/defs_nr_UE.h | 1 + openair1/PHY/impl_defs_top_NB_IoT.h | 1 + openair1/SIMULATION/LTE_PHY/dlsim.c | 1 + openair1/SIMULATION/LTE_PHY/syncsim.c | 1 + openair1/SIMULATION/LTE_PHY/ulsim.c | 1 + openair1/SIMULATION/TOOLS/channel_sim.c | 1 + radio/COMMON/common_lib.h | 1 + radio/fhi_72/oran_isolate.h | 1 + 13 files changed, 44 insertions(+), 15 deletions(-) create mode 100644 common/cmake_defs.h.in diff --git a/CMakeLists.txt b/CMakeLists.txt index 46016431aa..d0b9f17a02 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -549,8 +549,10 @@ endif() # Hardware dependant options ################################### -add_list1_option(NB_ANTENNAS_RX "4" "Number of antennas in reception" "1" "2" "4") -add_list1_option(NB_ANTENNAS_TX "4" "Number of antennas in transmission" "1" "2" "4") +set(NB_ANTENNAS_RX "4" CACHE STRING "Number of antennas in reception") +set_property(CACHE NB_ANTENNAS_RX PROPERTY STRINGS "1" "2" "4" "8") +set(NB_ANTENNAS_TX "4" CACHE STRING "Number of antennas in transmission") +set_property(CACHE NB_ANTENNAS_TX PROPERTY STRINGS "1" "2" "4" "8") set (CONFIG_ROOTDIR ${OPENAIR_DIR}/common/config) add_library(config_internals OBJECT diff --git a/cmake_targets/macros.cmake b/cmake_targets/macros.cmake index eafee3a0c1..cc59e12a90 100644 --- a/cmake_targets/macros.cmake +++ b/cmake_targets/macros.cmake @@ -34,19 +34,6 @@ macro(add_integer_option name val helpstr) add_definitions("-D${name}=${value}") endmacro(add_integer_option) -macro(add_list1_option name val helpstr) - if(DEFINED ${name}) - set(value ${${name}}) - else(DEFINED ${name}) - set(value ${val}) - endif() - set(${name} ${value} CACHE STRING "${helpstr}") - set_property(CACHE ${name} PROPERTY STRINGS ${ARGN}) - if(NOT "${value}" STREQUAL "False") - add_definitions("-D${name}=${value}") - endif() -endmacro(add_list1_option) - macro(add_list2_option name val helpstr) if(DEFINED ${name}) set(value ${${name}}) diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index f58880b04a..be079b874d 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -1,6 +1,7 @@ add_subdirectory(utils) add_subdirectory(config/yaml) +configure_file(cmake_defs.h.in cmake_defs.h @ONLY) configure_file(oai_version.h.in oai_version.h @ONLY) add_library(instrumentation INTERFACE) diff --git a/common/cmake_defs.h.in b/common/cmake_defs.h.in new file mode 100644 index 0000000000..c2221bf5e5 --- /dev/null +++ b/common/cmake_defs.h.in @@ -0,0 +1,30 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#ifndef CMAKE_DEFS_H_ +#define CMAKE_DEFS_H_ + +// Note: this file is automatically generated from common/cmake_defs.h.in +// please don't modify and change defines such as NB_ANTENNAS_RX/TX in cmake +#define NB_ANTENNAS_RX @NB_ANTENNAS_RX@ +#define NB_ANTENNAS_TX @NB_ANTENNAS_TX@ + +#endif /* CMAKE_DEFS_H_ */ diff --git a/openair1/PHY/defs_UE.h b/openair1/PHY/defs_UE.h index cd8ce75906..82cc747581 100644 --- a/openair1/PHY/defs_UE.h +++ b/openair1/PHY/defs_UE.h @@ -56,6 +56,7 @@ #include #include "common_lib.h" +#include "common/cmake_defs.h" #include "defs_common.h" #include "impl_defs_top.h" diff --git a/openair1/PHY/defs_nr_UE.h b/openair1/PHY/defs_nr_UE.h index 5511d8ed0d..c14751a050 100644 --- a/openair1/PHY/defs_nr_UE.h +++ b/openair1/PHY/defs_nr_UE.h @@ -39,6 +39,7 @@ #endif #endif +#include "common/cmake_defs.h" #include "defs_nr_common.h" #include "CODING/nrPolar_tools/nr_polar_pbch_defs.h" #include "PHY/defs_nr_sl_UE.h" diff --git a/openair1/PHY/impl_defs_top_NB_IoT.h b/openair1/PHY/impl_defs_top_NB_IoT.h index a6409839a4..8d05e9a05e 100644 --- a/openair1/PHY/impl_defs_top_NB_IoT.h +++ b/openair1/PHY/impl_defs_top_NB_IoT.h @@ -34,6 +34,7 @@ #define __PHY_IMPLEMENTATION_DEFS_NB_IOT_H__ #include "common/openairinterface5g_limits.h" +#include "common/cmake_defs.h" #define NUMBER_OF_SUBBANDS_MAX_NB_IoT 13 typedef enum {no_relay_NB_IoT=1,unicast_relay_type1_NB_IoT,unicast_relay_type2_NB_IoT, multicast_relay_NB_IoT} relaying_type_t_NB_IoT; diff --git a/openair1/SIMULATION/LTE_PHY/dlsim.c b/openair1/SIMULATION/LTE_PHY/dlsim.c index d6e8482919..a09b3558cb 100644 --- a/openair1/SIMULATION/LTE_PHY/dlsim.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim.c @@ -35,6 +35,7 @@ #include #include #include +#include "common/cmake_defs.h" #include "common/config/config_load_configmodule.h" #include "common/utils/LOG/log.h" #include "common/utils/var_array.h" diff --git a/openair1/SIMULATION/LTE_PHY/syncsim.c b/openair1/SIMULATION/LTE_PHY/syncsim.c index 456bc53a2c..c29b16e041 100644 --- a/openair1/SIMULATION/LTE_PHY/syncsim.c +++ b/openair1/SIMULATION/LTE_PHY/syncsim.c @@ -30,6 +30,7 @@ #include #include +#include "common/cmake_defs.h" #include "SIMULATION/TOOLS/defs.h" #include "SIMULATION/RF/defs.h" #include "PHY/types.h" diff --git a/openair1/SIMULATION/LTE_PHY/ulsim.c b/openair1/SIMULATION/LTE_PHY/ulsim.c index 7a442a4082..92b9d58f48 100644 --- a/openair1/SIMULATION/LTE_PHY/ulsim.c +++ b/openair1/SIMULATION/LTE_PHY/ulsim.c @@ -33,6 +33,7 @@ #include #include #include +#include "common/cmake_defs.h" #include "common/utils/var_array.h" #include "PHY/types.h" #include "PHY/defs_common.h" diff --git a/openair1/SIMULATION/TOOLS/channel_sim.c b/openair1/SIMULATION/TOOLS/channel_sim.c index 9f196b02ec..5115587bfc 100644 --- a/openair1/SIMULATION/TOOLS/channel_sim.c +++ b/openair1/SIMULATION/TOOLS/channel_sim.c @@ -24,6 +24,7 @@ #include #include +#include "common/cmake_defs.h" #include "SIMULATION/TOOLS/sim.h" #include "SIMULATION/RF/rf.h" #include "PHY/phy_extern_ue.h" diff --git a/radio/COMMON/common_lib.h b/radio/COMMON/common_lib.h index f21a1ffff4..693ca0e3c7 100644 --- a/radio/COMMON/common_lib.h +++ b/radio/COMMON/common_lib.h @@ -35,6 +35,7 @@ #include #include #include +#include "common/cmake_defs.h" #include #include "record_player.h" #include "common/utils/threadPool/notified_fifo.h" diff --git a/radio/fhi_72/oran_isolate.h b/radio/fhi_72/oran_isolate.h index 4f62ff5340..44c9bee51d 100644 --- a/radio/fhi_72/oran_isolate.h +++ b/radio/fhi_72/oran_isolate.h @@ -27,6 +27,7 @@ #include #include +#include "common/cmake_defs.h" #include "xran_fh_o_du.h" #include "openair1/PHY/impl_defs_nr.h" #include "openair1/PHY/TOOLS/tools_defs.h" From 0ea119ec39a44a61197fa6d60bf6d768bbb6533a Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Fri, 20 Feb 2026 19:14:38 +0100 Subject: [PATCH 06/11] Align t_nrPolar_params allocation to 32 bytes --- openair1/PHY/CODING/nrPolar_tools/nr_polar_init.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openair1/PHY/CODING/nrPolar_tools/nr_polar_init.c b/openair1/PHY/CODING/nrPolar_tools/nr_polar_init.c index 609f4b4a8f..462e2bfe08 100644 --- a/openair1/PHY/CODING/nrPolar_tools/nr_polar_init.c +++ b/openair1/PHY/CODING/nrPolar_tools/nr_polar_init.c @@ -97,7 +97,7 @@ t_nrPolar_params *nr_polar_params(int8_t messageType, uint16_t messageLength, ui // printf("currentPtr %p (polarParams %p)\n",currentPtr,polarParams); // Else, initialize and add node to the end of the linked list. - t_nrPolar_params *newPolarInitNode = malloc(sizeof(t_nrPolar_params)); + t_nrPolar_params *newPolarInitNode = memalign(32, sizeof(t_nrPolar_params)); AssertFatal(newPolarInitNode, "[nr_polar_init] New t_nrPolar_params * could not be created"); *newPolarInitNode = (t_nrPolar_params){.busy = true, .nextPtr = PolarList, .tree_linearization.is_initialized = false}; From 5b9d4550bac5ed61dec0b8f32d36b142ac1dc1ff Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 19 Feb 2026 16:55:34 +0100 Subject: [PATCH 07/11] Remove unused defines --- openair1/PHY/NR_REFSIG/pss_nr.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/openair1/PHY/NR_REFSIG/pss_nr.h b/openair1/PHY/NR_REFSIG/pss_nr.h index 8034d7f362..07ab520e90 100644 --- a/openair1/PHY/NR_REFSIG/pss_nr.h +++ b/openair1/PHY/NR_REFSIG/pss_nr.h @@ -72,9 +72,6 @@ #define SYNCHRO_RATE_CHANGE_FACTOR (1) #endif -#define SYNC_TMP_SIZE (NB_ANTENNAS_RX*SYNCHRO_FFT_SIZE_MAX*IQ_SIZE) /* to be aligned with existing lte synchro */ -#define SYNCF_TMP_SIZE (SYNCHRO_FFT_SIZE_MAX*IQ_SIZE) - void init_context_synchro_nr(NR_DL_FRAME_PARMS *frame_parms_ue); int pss_synchro_nr(const c16_t **rxdata, const NR_DL_FRAME_PARMS *frame_parms, From 1b619bed03cf68d6abf365830360fcf7ede9be29 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 19 Feb 2026 16:56:05 +0100 Subject: [PATCH 08/11] Remove unused sched_response_id --- openair1/SIMULATION/NR_PHY/dlsim.c | 1 - openair1/SIMULATION/NR_PHY/ulsim.c | 1 - openair2/NR_PHY_INTERFACE/NR_IF_Module.h | 2 -- 3 files changed, 4 deletions(-) diff --git a/openair1/SIMULATION/NR_PHY/dlsim.c b/openair1/SIMULATION/NR_PHY/dlsim.c index f1461bc25d..44feb23c40 100644 --- a/openair1/SIMULATION/NR_PHY/dlsim.c +++ b/openair1/SIMULATION/NR_PHY/dlsim.c @@ -1054,7 +1054,6 @@ int main(int argc, char **argv) NR_gNB_DLSCH_t *gNB_dlsch = &gNB->dlsch[0]; memset(Sched_INFO, 0, sizeof(*Sched_INFO)); - Sched_INFO->sched_response_id = -1; nfapi_nr_dl_tti_request_body_t *dl_req = &Sched_INFO->DL_req.dl_tti_request_body; // scheduler will place PDSCH second (after PDCCH), verification below nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdsch_pdu = &dl_req->dl_tti_pdu_list[1]; diff --git a/openair1/SIMULATION/NR_PHY/ulsim.c b/openair1/SIMULATION/NR_PHY/ulsim.c index e545d6cba2..80ea9cf31b 100644 --- a/openair1/SIMULATION/NR_PHY/ulsim.c +++ b/openair1/SIMULATION/NR_PHY/ulsim.c @@ -915,7 +915,6 @@ int main(int argc, char *argv[]) NR_Sched_Rsp_t *Sched_INFO = malloc16_clear(sizeof(*Sched_INFO)); memset((void*)Sched_INFO,0,sizeof(*Sched_INFO)); nfapi_nr_ul_tti_request_t *UL_tti_req = &Sched_INFO->UL_tti_req; - Sched_INFO->sched_response_id = -1; nr_phy_data_tx_t phy_data = {0}; diff --git a/openair2/NR_PHY_INTERFACE/NR_IF_Module.h b/openair2/NR_PHY_INTERFACE/NR_IF_Module.h index e53f04d859..e52f4ad678 100644 --- a/openair2/NR_PHY_INTERFACE/NR_IF_Module.h +++ b/openair2/NR_PHY_INTERFACE/NR_IF_Module.h @@ -85,8 +85,6 @@ typedef struct { typedef struct NR_Sched_Rsp { - /// the ID of this sched_response - used by sched_reponse memory management - int sched_response_id; /// Module ID module_id_t module_id; /// CC ID From bb72c4d057b63df4d823d35c6980d92bc8525391 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 19 Feb 2026 17:50:58 +0100 Subject: [PATCH 09/11] Fix alignment problem in nr_dlsim Fix error openair1/SIMULATION/NR_PHY/dlsim.c:1057:37: runtime error: member access within misaligned address 0x7f8a67e01010 for type 'struct NR_Sched_Rsp_t', which requires 32 byte alignment --- openair1/SIMULATION/NR_PHY/dlsim.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openair1/SIMULATION/NR_PHY/dlsim.c b/openair1/SIMULATION/NR_PHY/dlsim.c index 44feb23c40..5072b7bd9d 100644 --- a/openair1/SIMULATION/NR_PHY/dlsim.c +++ b/openair1/SIMULATION/NR_PHY/dlsim.c @@ -1012,7 +1012,7 @@ int main(int argc, char **argv) } //--------------- - Sched_INFO = malloc(sizeof(*Sched_INFO)); + Sched_INFO = memalign(32, sizeof(*Sched_INFO)); if (Sched_INFO == NULL) { LOG_E(PHY, "out of memory\n"); exit(1); From cdfe069c34258c419bb38eefa558dc92e522aa2f Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 19 Feb 2026 17:55:24 +0100 Subject: [PATCH 10/11] Remove unused cmake macros --- cmake_targets/at_commands/CMakeLists.txt | 10 ---------- cmake_targets/macros.cmake | 23 ----------------------- 2 files changed, 33 deletions(-) diff --git a/cmake_targets/at_commands/CMakeLists.txt b/cmake_targets/at_commands/CMakeLists.txt index c912bf9602..b450c087c2 100755 --- a/cmake_targets/at_commands/CMakeLists.txt +++ b/cmake_targets/at_commands/CMakeLists.txt @@ -51,16 +51,6 @@ set(OPENAIR_NAS_DIR ${OPENAIR_DIR}/openair3/NAS) set(CMAKE_MODULE_PATH "${OPENAIR_DIR}/cmake_targets/tools/MODULES" "${CMAKE_MODULE_PATH}") -macro(add_option name val helpstr) - if(DEFINED ${name}) - set(value ${${name}}) - else(DEFINED ${name}) - set(value ${val}) - endif() - set(${name} ${value} CACHE STRING "${helpstr}") - add_definitions("-D${name}=${value}") -endmacro(add_option) - macro(add_boolean_option name val helpstr) if(DEFINED ${name}) set(value ${${name}}) diff --git a/cmake_targets/macros.cmake b/cmake_targets/macros.cmake index cc59e12a90..4b1797db40 100644 --- a/cmake_targets/macros.cmake +++ b/cmake_targets/macros.cmake @@ -1,16 +1,6 @@ ########################################### # macros to define options as there is numerous options in oai ################################################ -macro(add_option name val helpstr) - if(DEFINED ${name}) - set(value ${${name}}) - else(DEFINED ${name}) - set(value ${val}) - endif() - set(${name} ${value} CACHE STRING "${helpstr}") - add_definitions("-D${name}=${value}") -endmacro(add_option) - macro(add_boolean_option name val helpstr adddef) if(DEFINED ${name}) set(value ${${name}}) @@ -34,19 +24,6 @@ macro(add_integer_option name val helpstr) add_definitions("-D${name}=${value}") endmacro(add_integer_option) -macro(add_list2_option name val helpstr) - if(DEFINED ${name}) - set(value ${${name}}) - else(DEFINED ${name}) - set(value ${val}) - endif() - set(${name} ${value} CACHE STRING "${helpstr}") - set_property(CACHE ${name} PROPERTY STRINGS ${ARGN}) - if(NOT "${value}" STREQUAL "None") - add_definitions("-D${value}=1") - endif() -endmacro(add_list2_option) - macro(add_list_string_option name val helpstr) if(DEFINED ${name}) set(value ${${name}}) From 2bd3685d6bc3c4a8e9295cb0716d600716e3851e Mon Sep 17 00:00:00 2001 From: francescomani Date: Fri, 20 Feb 2026 12:44:03 +0100 Subject: [PATCH 11/11] add check for input number of antennas to be compliant with NB_ANTENNAS_TX and NB_ANTENNAS_RX --- executables/nr-ru.c | 6 ++++++ executables/nr-ue-ru.c | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/executables/nr-ru.c b/executables/nr-ru.c index 397f940745..c6a2d30c07 100644 --- a/executables/nr-ru.c +++ b/executables/nr-ru.c @@ -1737,7 +1737,13 @@ static void NRRCconfig_RU(configmodule_interface_t *cfg) } /* strcmp(local_rf, "yes") != 0 */ ru->nb_tx = *param[RU_NB_TX_IDX].uptr; + AssertFatal(ru->nb_tx <= NB_ANTENNAS_TX, + "Config file has %d TX antennas set, but the compile time max value in NB_ANTENNAS_TX\n", + ru->nb_tx); ru->nb_rx = *param[RU_NB_RX_IDX].uptr; + AssertFatal(ru->nb_rx <= NB_ANTENNAS_RX, + "Config file has %d RX antennas set, but the compile time max value in NB_ANTENNAS_RX\n", + ru->nb_rx); ru->att_tx = *param[RU_ATT_TX_IDX].uptr; ru->att_rx = *param[RU_ATT_RX_IDX].uptr; ru->if_frequency = *param[RU_IF_FREQUENCY].u64ptr; diff --git a/executables/nr-ue-ru.c b/executables/nr-ue-ru.c index 7235ae5c9f..748a4fd731 100644 --- a/executables/nr-ue-ru.c +++ b/executables/nr-ue-ru.c @@ -205,6 +205,12 @@ void nrue_set_ru_params(configmodule_interface_t *cfg) if (RUParamList.numelt <= 0) { nrue_ru_count = 1; nrue_rus = calloc_or_fail(nrue_ru_count, sizeof(nrUE_RU_params_t)); + AssertFatal(get_nrUE_params()->nb_antennas_tx <= NB_ANTENNAS_TX, + "Config file has %d TX antennas set, but the compile time max value in NB_ANTENNAS_TX\n", + get_nrUE_params()->nb_antennas_tx); + AssertFatal(get_nrUE_params()->nb_antennas_rx <= NB_ANTENNAS_RX, + "Config file has %d RX antennas set, but the compile time max value in NB_ANTENNAS_RX\n", + get_nrUE_params()->nb_antennas_tx); nrue_rus[0] = (nrUE_RU_params_t){.nb_tx = get_nrUE_params()->nb_antennas_tx, .nb_rx = get_nrUE_params()->nb_antennas_rx, .att_tx = get_nrUE_params()->tx_gain,