From dea42f7e4aef7951e7c22b449d9a4e5d8e52e5a4 Mon Sep 17 00:00:00 2001 From: francescomani Date: Fri, 20 Feb 2026 09:49:11 +0100 Subject: [PATCH 01/44] remove some unnecessary use of NB_ANTENNAS_RX at UE --- executables/nr-ue.c | 2 +- openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h | 2 +- openair1/PHY/NR_UE_TRANSPORT/sss_nr.c | 29 +++++++++---------- 3 files changed, 16 insertions(+), 17 deletions(-) diff --git a/executables/nr-ue.c b/executables/nr-ue.c index 88a8ff84c8..4c5a480386 100644 --- a/executables/nr-ue.c +++ b/executables/nr-ue.c @@ -726,7 +726,6 @@ void *UE_thread(void *arg) PHY_VARS_NR_UE *UE = (PHY_VARS_NR_UE *)arg; const NR_DL_FRAME_PARMS *fp = &UE->frame_parms; // int tx_enabled = 0; - c16_t *rxp[fp->nb_antennas_rx]; enum stream_status_e stream_status = STREAM_STATUS_UNSYNC; fapi_nr_config_request_t *cfg = &UE->nrUE_config; sl_nr_phy_config_request_t *sl_cfg = NULL; @@ -780,6 +779,7 @@ void *UE_thread(void *arg) readFrame(UE, &tmp, duration_rx_to_tx, true); } + c16_t *rxp[fp->nb_antennas_rx]; while (!oai_exit) { if (syncRunning) { notifiedFIFO_elt_t *res = pollNotifiedFIFO(&nf); diff --git a/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h b/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h index 4a67f2956e..3f7bd0d63e 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h +++ b/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h @@ -122,7 +122,7 @@ void nr_ue_ssb_rsrp_measurements(PHY_VARS_NR_UE *ue, typedef struct { UE_nr_rxtx_proc_t proc; PHY_VARS_NR_UE *ue; - c16_t *rxdata[NB_ANTENNAS_RX]; + c16_t **rxdata; uint32_t rxdata_size; c16_t rxdata_ant[]; } nr_meas_task_args_t; diff --git a/openair1/PHY/NR_UE_TRANSPORT/sss_nr.c b/openair1/PHY/NR_UE_TRANSPORT/sss_nr.c index da27ca8603..0c0173b64d 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/sss_nr.c +++ b/openair1/PHY/NR_UE_TRANSPORT/sss_nr.c @@ -189,8 +189,8 @@ void insert_sss_nr(int16_t *sss_time, static int pss_ch_est_nr(const NR_DL_FRAME_PARMS *frame_parms, int nid2, - c16_t pss_ext[NB_ANTENNAS_RX][LENGTH_PSS_NR], - c16_t sss_ext[NB_ANTENNAS_RX][LENGTH_SSS_NR]) + c16_t pss_ext[frame_parms->nb_antennas_rx][LENGTH_PSS_NR], + c16_t sss_ext[frame_parms->nb_antennas_rx][LENGTH_SSS_NR]) { int16_t *pss = get_primary_synchro_nr2(nid2); @@ -250,15 +250,14 @@ static int pss_ch_est_nr(const NR_DL_FRAME_PARMS *frame_parms, * *********************************************************************/ -static int do_pss_sss_extract_nr( - const NR_DL_FRAME_PARMS *frame_parms, - c16_t pss_ext[NB_ANTENNAS_RX][LENGTH_PSS_NR], - c16_t sss_ext[NB_ANTENNAS_RX][LENGTH_SSS_NR], - uint8_t doPss, - uint8_t doSss, - uint8_t subframe, - int ssb_start_subcarrier, - c16_t rxdataF[][frame_parms->samples_per_slot_wCP]) // add flag to indicate extracting only PSS, only SSS, or both +static int do_pss_sss_extract_nr(const NR_DL_FRAME_PARMS *frame_parms, + c16_t pss_ext[frame_parms->nb_antennas_rx][LENGTH_PSS_NR], + c16_t sss_ext[frame_parms->nb_antennas_rx][LENGTH_SSS_NR], + uint8_t doPss, + uint8_t doSss, + uint8_t subframe, + int ssb_start_subcarrier, + c16_t rxdataF[][frame_parms->samples_per_slot_wCP]) // add flag to indicate extracting only PSS, only SSS, or both { AssertFatal(frame_parms->nb_antennas_rx > 0, "UB as sss_ext is not set to any value\n"); @@ -331,8 +330,8 @@ static int do_pss_sss_extract_nr( *********************************************************************/ static int pss_sss_extract_nr(const NR_DL_FRAME_PARMS *frame_parms, - c16_t pss_ext[NB_ANTENNAS_RX][LENGTH_PSS_NR], - c16_t sss_ext[NB_ANTENNAS_RX][LENGTH_SSS_NR], + c16_t pss_ext[frame_parms->nb_antennas_rx][LENGTH_PSS_NR], + c16_t sss_ext[frame_parms->nb_antennas_rx][LENGTH_SSS_NR], uint8_t subframe, int ssb_start_subcarrier, c16_t rxdataF[][frame_parms->samples_per_slot_wCP]) @@ -371,8 +370,8 @@ bool rx_sss_nr(const NR_DL_FRAME_PARMS *frame_parms, c16_t rxdataF[][frame_parms->samples_per_slot_wCP]) { uint8_t i; - c16_t pss_ext[NB_ANTENNAS_RX][LENGTH_PSS_NR] = {0}; - c16_t sss_ext[NB_ANTENNAS_RX][LENGTH_SSS_NR] = {0}; + c16_t pss_ext[frame_parms->nb_antennas_rx][LENGTH_PSS_NR]; + c16_t sss_ext[frame_parms->nb_antennas_rx][LENGTH_SSS_NR]; uint8_t Nid2 = GET_NID2(nid2); uint16_t Nid1; uint8_t phase; From c57a112aaef2f701ceb3f1e26aa47a6af0b64dfc Mon Sep 17 00:00:00 2001 From: francescomani Date: Fri, 20 Feb 2026 10:11:56 +0100 Subject: [PATCH 02/44] cleanup of PHY_NR_MEASUREMENTS structure to remove unused fields and dependence from NB_ANTENNAS_RX --- .../PHY/NR_UE_ESTIMATION/nr_ue_measurements.c | 39 +++++---------- .../NR_UE_TRANSPORT/nr_dlsch_demodulation.c | 27 ++--------- openair1/PHY/defs_nr_UE.h | 48 +++---------------- 3 files changed, 23 insertions(+), 91 deletions(-) diff --git a/openair1/PHY/NR_UE_ESTIMATION/nr_ue_measurements.c b/openair1/PHY/NR_UE_ESTIMATION/nr_ue_measurements.c index 8a59470cbf..6cb24dd426 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/nr_ue_measurements.c +++ b/openair1/PHY/NR_UE_ESTIMATION/nr_ue_measurements.c @@ -81,32 +81,21 @@ void nr_ue_measurements(PHY_VARS_NR_UE *ue, false); // signal measurements - for (gNB_id = 0; gNB_id < ue->n_connected_gNB; gNB_id++){ - + for (gNB_id = 0; gNB_id < ue->n_connected_gNB; gNB_id++) { ue->measurements.rx_power_tot[gNB_id] = 0; - - for (aarx = 0; aarx < frame_parms->nb_antennas_rx; aarx++){ - - ue->measurements.rx_power[gNB_id][aarx] = 0; - - for (aatx = 0; aatx < frame_parms->nb_antenna_ports_gNB; aatx++){ + for (aarx = 0; aarx < frame_parms->nb_antennas_rx; aarx++) { + int rx_power = 0; + for (aatx = 0; aatx < frame_parms->nb_antenna_ports_gNB; aatx++) { const int z = signal_energy_nodc((c16_t*)&dl_ch_estimates[gNB_id][ch_offset], number_rbs * NR_NB_SC_PER_RB); rx_spatial_power[gNB_id][aatx][aarx] = z; - if (rx_spatial_power[gNB_id][aatx][aarx] < 0) rx_spatial_power[gNB_id][aatx][aarx] = 0; - rx_spatial_power_dB[gNB_id][aatx][aarx] = (unsigned short)dB_fixed(rx_spatial_power[gNB_id][aatx][aarx]); - ue->measurements.rx_power[gNB_id][aarx] += rx_spatial_power[gNB_id][aatx][aarx]; + rx_power += rx_spatial_power[gNB_id][aatx][aarx]; } - - ue->measurements.rx_power_dB[gNB_id][aarx] = (unsigned short) dB_fixed(ue->measurements.rx_power[gNB_id][aarx]); - ue->measurements.rx_power_tot[gNB_id] += ue->measurements.rx_power[gNB_id][aarx]; - + ue->measurements.rx_power_tot[gNB_id] += rx_power; } - ue->measurements.rx_power_tot_dB[gNB_id] = (unsigned short) dB_fixed(ue->measurements.rx_power_tot[gNB_id]); - } // filter to remove jitter @@ -533,9 +522,9 @@ void nr_ue_rrc_measurements(PHY_VARS_NR_UE *ue, LOG_D(PHY, "In %s doing measurements for ssb_offset %d l_sss %d \n", __FUNCTION__, ssb_offset, l_sss); - for (aarx = 0; aarxframe_parms.nb_antennas_rx; aarx++) { + for (aarx = 0; aarx < ue->frame_parms.nb_antennas_rx; aarx++) { - ue->measurements.n0_power[aarx] = 0; + uint32_t n0_power = 0; rxF_sss = (int16_t *)&rxdataF[aarx][l_sss*ue->frame_parms.ofdm_symbol_size]; //-ve spectrum from SSS @@ -547,8 +536,7 @@ void nr_ue_rrc_measurements(PHY_VARS_NR_UE *ue, LOG_I(PHY, "In %s -rxF_sss %d %d\n", __FUNCTION__, rxF_sss[re*2], rxF_sss[re*2 + 1]); #endif - ue->measurements.n0_power[aarx] += (((int32_t)rxF_sss[re*2]*rxF_sss[re*2]) + ((int32_t)rxF_sss[re*2 + 1]*rxF_sss[re*2 + 1])); - + n0_power += (((int32_t)rxF_sss[re * 2] * rxF_sss[re * 2]) + ((int32_t)rxF_sss[re * 2 + 1] * rxF_sss[re * 2 + 1])); } //+ve spectrum from SSS @@ -560,14 +548,11 @@ void nr_ue_rrc_measurements(PHY_VARS_NR_UE *ue, LOG_I(PHY, "In %s +rxF_sss %d %d\n", __FUNCTION__, rxF_sss[re*2], rxF_sss[re*2 + 1]); #endif - ue->measurements.n0_power[aarx] += (((int32_t)rxF_sss[re*2]*rxF_sss[re*2]) + ((int32_t)rxF_sss[re*2 + 1]*rxF_sss[re*2 + 1])); - + n0_power += (((int32_t)rxF_sss[re * 2]*rxF_sss[re * 2]) + ((int32_t)rxF_sss[re * 2 + 1] * rxF_sss[re * 2 + 1])); } - ue->measurements.n0_power[aarx] /= 2*k_length; - ue->measurements.n0_power_dB[aarx] = (unsigned short) dB_fixed(ue->measurements.n0_power[aarx]); - ue->measurements.n0_power_tot += ue->measurements.n0_power[aarx]; - + n0_power /= 2 * k_length; + ue->measurements.n0_power_tot += n0_power; } ue->measurements.n0_power_tot_dB = (unsigned short) dB_fixed(ue->measurements.n0_power_tot); diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c index 73bcbfab46..2ce37b6dcd 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c @@ -141,7 +141,6 @@ static void nr_dlsch_channel_level_median(uint32_t rx_size_symbol, @param rho Cross-correlation between two spatial channels on each RX antenna @param frame_parms Pointer to frame descriptor @param symbol Symbol on which to operate - @param first_symbol_flag set to 1 on first DLSCH symbol @param mod_order Modulation order of allocation @param nb_rb Number of RBs in allocation @param output_shift Rescaling for compensated output (should be energy-normalizing) @@ -161,7 +160,6 @@ static void nr_dlsch_channel_compensation(uint32_t rx_size_symbol, uint8_t n_layers, unsigned char symbol, int length, - bool first_symbol_flag, unsigned char mod_order, unsigned short nb_rb, unsigned char output_shift, @@ -555,7 +553,6 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, nl, symbol, nb_re_pdsch, - first_symbol_flag, dlsch_config->qamModOrder, nb_rb_pdsch, *log2_maxh, @@ -769,7 +766,6 @@ static void nr_dlsch_channel_compensation(uint32_t rx_size_symbol, uint8_t n_layers, unsigned char symbol, int length, - bool first_symbol_flag, unsigned char mod_order, unsigned short nb_rb, unsigned char output_shift, @@ -868,24 +864,11 @@ static void nr_dlsch_channel_compensation(uint32_t rx_size_symbol, for (int aarx = 0; aarx < frame_parms->nb_antennas_rx; aarx++) { for (int l = 0; l < n_layers; l++) { for (int atx = 0; atx < n_layers; atx++) { - rho128 = (simde__m128i *)&rho[aarx][l * n_layers + atx][symbol * nb_rb * 12]; - dl_ch128 = (simde__m128i *)dl_ch_estimates_ext[l * frame_parms->nb_antennas_rx + aarx]; - dl_ch128_2 = (simde__m128i *)dl_ch_estimates_ext[atx * frame_parms->nb_antennas_rx + aarx]; - - // multiply by conjugated channel - mult_cpx_conj_vector((c16_t *)dl_ch128, (c16_t *)dl_ch128_2, (c16_t *)rho128, 12 * nb_rb_0, output_shift); - - if (first_symbol_flag) { - // rho_nm = H_arx_n.conj(H_arx_m) - // rho_rx_corr[arx][nm] = |H_arx_n|^2.|H_arx_m|^2 &rho[aarx][l*n_layers+atx][symbol*nb_rb*12] - measurements->rx_correlation[0][aarx][l * n_layers + atx] = - signal_energy(&rho[aarx][l * n_layers + atx][symbol * nb_rb * 12], length); - // avg_rho_re[aarx][l*n_layers+atx] = 16*avg_rho_re[aarx][l*n_layers+atx]/length; - // avg_rho_im[aarx][l*n_layers+atx] = 16*avg_rho_im[aarx][l*n_layers+atx]/length; - // printf("rho[rx]%d tx%d tx%d = Re: %d Im: %d\n",aarx, l,atx, avg_rho_re[aarx][l*n_layers+atx], - // avg_rho_im[aarx][l*n_layers+atx]); printf("rho_corr[rx]%d tx%d tx%d = %d ...\n",aarx, l,atx, - // measurements->rx_correlation[0][aarx][l*n_layers+atx]); - } + rho128 = (simde__m128i *)&rho[aarx][l * n_layers + atx][symbol * nb_rb * 12]; + dl_ch128 = (simde__m128i *)dl_ch_estimates_ext[l * frame_parms->nb_antennas_rx + aarx]; + dl_ch128_2 = (simde__m128i *)dl_ch_estimates_ext[atx * frame_parms->nb_antennas_rx + aarx]; + // multiply by conjugated channel + mult_cpx_conj_vector((c16_t *)dl_ch128, (c16_t *)dl_ch128_2, (c16_t *)rho128, 12 * nb_rb_0, output_shift); } } } diff --git a/openair1/PHY/defs_nr_UE.h b/openair1/PHY/defs_nr_UE.h index c14751a050..2eca4fbbd1 100644 --- a/openair1/PHY/defs_nr_UE.h +++ b/openair1/PHY/defs_nr_UE.h @@ -144,10 +144,6 @@ typedef struct { int ssb_rsrp_dBm[64]; float ssb_sinr_dB[64]; // common measurements - //! estimated noise power (linear) - unsigned int n0_power[NB_ANTENNAS_RX]; - //! estimated noise power (dB) - unsigned short n0_power_dB[NB_ANTENNAS_RX]; //! total estimated noise power (linear) unsigned int n0_power_tot; //! total estimated noise power (dB) @@ -165,59 +161,27 @@ typedef struct { //! estimated received spatial signal power (dB) fourDimArray_t *rx_spatial_power_dB; - /// estimated received signal power (sum over all TX antennas) - int rx_power[NUMBER_OF_CONNECTED_gNB_MAX][NB_ANTENNAS_RX]; - /// estimated received signal power (sum over all TX antennas) - unsigned short rx_power_dB[NUMBER_OF_CONNECTED_gNB_MAX][NB_ANTENNAS_RX]; - /// estimated received signal power (sum over all TX/RX antennas) - int rx_power_tot[NUMBER_OF_CONNECTED_gNB_MAX]; //NEW + int rx_power_tot[NUMBER_OF_CONNECTED_gNB_MAX]; //NEW /// estimated received signal power (sum over all TX/RX antennas) unsigned short rx_power_tot_dB[NUMBER_OF_CONNECTED_gNB_MAX]; //NEW //! estimated received signal power (sum of all TX/RX antennas, time average) - int rx_power_avg[NUMBER_OF_CONNECTED_gNB_MAX]; + int rx_power_avg[NUMBER_OF_CONNECTED_gNB_MAX]; //! estimated received signal power (sum of all TX/RX antennas, time average, in dB) unsigned short rx_power_avg_dB[NUMBER_OF_CONNECTED_gNB_MAX]; /// SINR (sum of all TX/RX antennas, in dB) - int wideband_cqi_tot[NUMBER_OF_CONNECTED_gNB_MAX]; + int wideband_cqi_tot[NUMBER_OF_CONNECTED_gNB_MAX]; /// SINR (sum of all TX/RX antennas, time average, in dB) - int wideband_cqi_avg[NUMBER_OF_CONNECTED_gNB_MAX]; + int wideband_cqi_avg[NUMBER_OF_CONNECTED_gNB_MAX]; //! estimated rssi (dBm) - short rx_rssi_dBm[NUMBER_OF_CONNECTED_gNB_MAX]; - //! estimated correlation (wideband linear) between spatial channels (computed in dlsch_demodulation) - int rx_correlation[NUMBER_OF_CONNECTED_gNB_MAX][NB_ANTENNAS_RX][NR_MAX_NB_LAYERS*NR_MAX_NB_LAYERS];// - //! estimated correlation (wideband dB) between spatial channels (computed in dlsch_demodulation) - int rx_correlation_dB[NUMBER_OF_CONNECTED_gNB_MAX][2]; + short rx_rssi_dBm[NUMBER_OF_CONNECTED_gNB_MAX]; - /// Wideband CQI (sum of all RX antennas, in dB, for precoded transmission modes (3,4,5,6), up to 4 spatial streams) - int precoded_cqi_dB[NUMBER_OF_CONNECTED_gNB_MAX+1][4]; - /// Subband CQI per RX antenna (= SINR) - int subband_cqi[NUMBER_OF_CONNECTED_gNB_MAX][NB_ANTENNAS_RX][NUMBER_OF_SUBBANDS_MAX]; - /// Total Subband CQI (= SINR) - int subband_cqi_tot[NUMBER_OF_CONNECTED_gNB_MAX][NUMBER_OF_SUBBANDS_MAX]; - /// Subband CQI in dB (= SINR dB) - int subband_cqi_dB[NUMBER_OF_CONNECTED_gNB_MAX][NB_ANTENNAS_RX][NUMBER_OF_SUBBANDS_MAX]; - /// Total Subband CQI - int subband_cqi_tot_dB[NUMBER_OF_CONNECTED_gNB_MAX][NUMBER_OF_SUBBANDS_MAX]; - /// Wideband PMI for each RX antenna - int wideband_pmi_re[NUMBER_OF_CONNECTED_gNB_MAX][NB_ANTENNAS_RX]; - /// Wideband PMI for each RX antenna - int wideband_pmi_im[NUMBER_OF_CONNECTED_gNB_MAX][NB_ANTENNAS_RX]; - ///Subband PMI for each RX antenna - int subband_pmi_re[NUMBER_OF_CONNECTED_gNB_MAX][NUMBER_OF_SUBBANDS_MAX][NB_ANTENNAS_RX]; - ///Subband PMI for each RX antenna - int subband_pmi_im[NUMBER_OF_CONNECTED_gNB_MAX][NUMBER_OF_SUBBANDS_MAX][NB_ANTENNAS_RX]; - /// chosen RX antennas (1=Rx antenna 1, 2=Rx antenna 2, 3=both Rx antennas) - unsigned char selected_rx_antennas[NUMBER_OF_CONNECTED_gNB_MAX][NUMBER_OF_SUBBANDS_MAX]; - /// Wideband Rank indication - unsigned char rank[NUMBER_OF_CONNECTED_gNB_MAX]; /// Number of RX Antennas unsigned char nb_antennas_rx; - /// DLSCH error counter - // short dlsch_errors; + /// Info about neighboring cells to perform the measurements neighboring_cell_info_t neighboring_cell_info[NUMBER_OF_NEIGHBORING_CELLS_MAX]; bool meas_request_pending; From a0a0f2104f2322b806b66b54e5b60839f055bafa Mon Sep 17 00:00:00 2001 From: francescomani Date: Fri, 20 Feb 2026 10:39:53 +0100 Subject: [PATCH 03/44] further cleanup in defs_nr_UE.h --- openair1/PHY/CODING/nr_segmentation.c | 6 +-- openair1/PHY/MODULATION/slot_fep_nr.c | 2 - openair1/PHY/NR_REFSIG/dmrs_nr.h | 13 ------ openair1/PHY/NR_REFSIG/pss_nr.h | 3 +- openair1/PHY/NR_REFSIG/ptrs_nr.h | 18 +------- openair1/PHY/NR_REFSIG/sss_nr.h | 2 - openair1/PHY/NR_REFSIG/ul_ref_seq_nr.h | 3 -- openair1/PHY/NR_TRANSPORT/nr_dlsch.c | 1 + openair1/PHY/defs_nr_UE.h | 57 ++------------------------ 9 files changed, 10 insertions(+), 95 deletions(-) diff --git a/openair1/PHY/CODING/nr_segmentation.c b/openair1/PHY/CODING/nr_segmentation.c index 57c21a5980..8312471b34 100644 --- a/openair1/PHY/CODING/nr_segmentation.c +++ b/openair1/PHY/CODING/nr_segmentation.c @@ -24,9 +24,9 @@ author: Hongzhi WANG (TCL) date: 12.09.2017 */ -#include "PHY/defs_nr_UE.h" -//#include "SCHED/extern.h" +#include "common/utils/LOG/log.h" +#include "openair1/PHY/CODING/coding_defs.h" //#define DEBUG_SEGMENTATION int32_t nr_segmentation(unsigned char *input_buffer, @@ -174,8 +174,6 @@ else return Kb; } - - #ifdef MAIN main() { diff --git a/openair1/PHY/MODULATION/slot_fep_nr.c b/openair1/PHY/MODULATION/slot_fep_nr.c index c534ed7eea..99cbf1c652 100644 --- a/openair1/PHY/MODULATION/slot_fep_nr.c +++ b/openair1/PHY/MODULATION/slot_fep_nr.c @@ -19,12 +19,10 @@ * contact@openairinterface.org */ -#include "PHY/defs_nr_UE.h" #include "PHY/defs_gNB.h" #include "PHY/defs_nr_common.h" #include "modulation_UE.h" #include "nr_modulation.h" -#include "PHY/LTE_ESTIMATION/lte_estimation.h" #include "PHY/NR_UE_ESTIMATION/nr_estimation.h" #include "PHY/nr_phy_common/inc/nr_phy_common.h" #include diff --git a/openair1/PHY/NR_REFSIG/dmrs_nr.h b/openair1/PHY/NR_REFSIG/dmrs_nr.h index 5f17478874..8e275568e3 100644 --- a/openair1/PHY/NR_REFSIG/dmrs_nr.h +++ b/openair1/PHY/NR_REFSIG/dmrs_nr.h @@ -33,24 +33,11 @@ #ifndef DMRS_NR_H #define DMRS_NR_H -#include "PHY/defs_nr_UE.h" #include "PHY/types.h" #include "PHY/NR_REFSIG/ss_pbch_nr.h" #include "PHY/NR_REFSIG/pss_nr.h" #include "PHY/NR_REFSIG/sss_nr.h" -/************** CODE GENERATION ***********************************/ - -/************** DEFINE ********************************************/ - - -/************* STRUCTURES *****************************************/ - - -/************** VARIABLES *****************************************/ - -/************** FUNCTION ******************************************/ - int pseudo_random_sequence(int M_PN, uint32_t *c, uint32_t cinit); void lte_gold_new(LTE_DL_FRAME_PARMS *frame_parms, uint32_t lte_gold_table[20][2][14], uint16_t Nid_cell); uint16_t get_dmrs_freq_idx_ul(uint16_t n, uint8_t k_prime, uint8_t delta, uint8_t dmrs_type); diff --git a/openair1/PHY/NR_REFSIG/pss_nr.h b/openair1/PHY/NR_REFSIG/pss_nr.h index 07ab520e90..15ae316d74 100644 --- a/openair1/PHY/NR_REFSIG/pss_nr.h +++ b/openair1/PHY/NR_REFSIG/pss_nr.h @@ -32,9 +32,8 @@ #ifndef PSS_NR_H #define PSS_NR_H -#include "PHY/defs_nr_UE.h" +#include "PHY/defs_nr_common.h" #include "PHY/types.h" - #include "PHY/NR_REFSIG/ss_pbch_nr.h" /************** CODE GENERATION ***********************************/ diff --git a/openair1/PHY/NR_REFSIG/ptrs_nr.h b/openair1/PHY/NR_REFSIG/ptrs_nr.h index 75f526dad5..dad093f712 100644 --- a/openair1/PHY/NR_REFSIG/ptrs_nr.h +++ b/openair1/PHY/NR_REFSIG/ptrs_nr.h @@ -33,20 +33,6 @@ #ifndef PTRS_NR_H #define PTRS_NR_H -#include "PHY/defs_nr_UE.h" - -/************** CODE GENERATION ***********************************/ - -/************** DEFINE ********************************************/ - - -/************* STRUCTURES *****************************************/ - - -/************** VARIABLES *****************************************/ - -/************** FUNCTION ******************************************/ - void set_ptrs_symb_idx(uint16_t *ptrs_symbols, uint8_t duration_in_symbols, uint8_t start_symbol, @@ -86,8 +72,8 @@ int8_t nr_ptrs_process_slot(uint16_t dmrsSymbPos, uint16_t ptrsSymbPos, int16_t *estPerSymb, uint16_t startSymbIdx, - uint16_t noSymb - ); + uint16_t noSymb); + /* general function to estimate common phase error based upon PTRS */ void nr_ptrs_cpe_estimation(uint8_t K_ptrs, uint8_t ptrsReOffset, diff --git a/openair1/PHY/NR_REFSIG/sss_nr.h b/openair1/PHY/NR_REFSIG/sss_nr.h index 8175869205..5bb55ebe2f 100644 --- a/openair1/PHY/NR_REFSIG/sss_nr.h +++ b/openair1/PHY/NR_REFSIG/sss_nr.h @@ -33,9 +33,7 @@ #define SSS_NR_H #include "limits.h" -#include "PHY/defs_nr_UE.h" #include "PHY/types.h" - #include "pss_nr.h" /************** DEFINE ********************************************/ diff --git a/openair1/PHY/NR_REFSIG/ul_ref_seq_nr.h b/openair1/PHY/NR_REFSIG/ul_ref_seq_nr.h index 9ed101f247..845a2cd830 100644 --- a/openair1/PHY/NR_REFSIG/ul_ref_seq_nr.h +++ b/openair1/PHY/NR_REFSIG/ul_ref_seq_nr.h @@ -33,11 +33,8 @@ #ifndef LOWPAPR_SEQUENCES_NR_H #define LOWPAPR_SEQUENCES_NR_H -#include "PHY/defs_nr_UE.h" #include "PHY/types.h" - #include "PHY/NR_REFSIG/ss_pbch_nr.h" - #include "PHY/defs_nr_common.h" #include "PHY/defs_gNB.h" diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch.c b/openair1/PHY/NR_TRANSPORT/nr_dlsch.c index 9018aabfde..94531448a9 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dlsch.c +++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch.c @@ -37,6 +37,7 @@ #include "PHY/NR_REFSIG/dmrs_nr.h" #include "PHY/NR_REFSIG/ptrs_nr.h" #include "common/utils/nr/nr_common.h" +#include "PHY/NR_TRANSPORT/nr_transport_common_proto.h" #include "executables/softmodem-common.h" #include "SCHED_NR/sched_nr.h" diff --git a/openair1/PHY/defs_nr_UE.h b/openair1/PHY/defs_nr_UE.h index 2eca4fbbd1..daae2fec36 100644 --- a/openair1/PHY/defs_nr_UE.h +++ b/openair1/PHY/defs_nr_UE.h @@ -104,18 +104,11 @@ /// Context data structure for gNB subframe processing typedef struct { /// Component Carrier index - uint8_t CC_id; + uint8_t CC_id; /// Last RX timestamp openair0_timestamp_t timestamp_rx; } UE_nr_proc_t; -typedef enum { - NR_PBCH_EST=0, - NR_PDCCH_EST, - NR_PDSCH_EST, - NR_SSS_EST, -} NR_CHANNEL_EST_t; - #define debug_msg if (((mac_xface->frame%100) == 0) || (mac_xface->frame < 50)) msg #define NEIGHBOR_CELL_MAX_CONSECUTIVE_FAILURES 10 @@ -227,17 +220,6 @@ typedef struct { #define MAX_NR_DCI_DECODED_SLOT 10 // This value is not specified -typedef enum { - _format_0_0_found = 0, - _format_0_1_found = 1, - _format_1_0_found = 2, - _format_1_1_found = 3, - _format_2_0_found = 4, - _format_2_1_found = 5, - _format_2_2_found = 6, - _format_2_3_found = 7 -} format_found_t; - #endif typedef struct { int nb_search_space; @@ -246,18 +228,6 @@ typedef struct { #define NR_PSBCH_DMRS_LENGTH 297 // in mod symbols #define NR_PSBCH_DMRS_LENGTH_DWORD 20 // ceil(2(QPSK)*NR_PBCH_DMRS_LENGTH/32) - -/* NR Sidelink PSBCH payload fields - TODO: This will be removed in the future and - filled in by the upper layers once developed. */ -typedef struct { - uint32_t coverageIndicator : 1; - uint32_t tddConfig : 12; - uint32_t DFN : 10; - uint32_t slotIndex : 7; - uint32_t reserved : 2; -} PSBCH_payload; - #define PBCH_A 24 typedef struct { @@ -390,15 +360,11 @@ typedef struct PHY_VARS_NR_UE_s { fapi_nr_config_request_t nrUE_config; nr_synch_request_t synch_request; - NR_UE_PRACH *prach_vars[NUMBER_OF_CONNECTED_gNB_MAX]; - NR_UE_PRS *prs_vars[NR_MAX_PRS_COMB_SIZE]; - uint8_t prs_active_gNBs; + NR_UE_PRACH *prach_vars[NUMBER_OF_CONNECTED_gNB_MAX]; + NR_UE_PRS *prs_vars[NR_MAX_PRS_COMB_SIZE]; + uint8_t prs_active_gNBs; NR_DL_UE_HARQ_t dl_harq_processes[2][NR_MAX_DLSCH_HARQ_PROCESSES]; NR_UL_UE_HARQ_t ul_harq_processes[NR_MAX_ULSCH_HARQ_PROCESSES]; - //Paging parameters - uint32_t IMSImod1024; - uint32_t PF; - uint32_t PO; // Scrambling IDs used in PUSCH DMRS c16_t X_u[64][839]; @@ -427,21 +393,6 @@ typedef struct PHY_VARS_NR_UE_s { int dlsch_received[NUMBER_OF_CONNECTED_gNB_MAX]; int dlsch_received_last[NUMBER_OF_CONNECTED_gNB_MAX]; int dlsch_fer[NUMBER_OF_CONNECTED_gNB_MAX]; - int dlsch_SI_received[NUMBER_OF_CONNECTED_gNB_MAX]; - int dlsch_SI_errors[NUMBER_OF_CONNECTED_gNB_MAX]; - int dlsch_ra_received[NUMBER_OF_CONNECTED_gNB_MAX]; - int dlsch_ra_errors[NUMBER_OF_CONNECTED_gNB_MAX]; - int dlsch_p_received[NUMBER_OF_CONNECTED_gNB_MAX]; - int dlsch_p_errors[NUMBER_OF_CONNECTED_gNB_MAX]; - int dlsch_mch_received[NUMBER_OF_CONNECTED_gNB_MAX]; - int current_dlsch_cqi[NUMBER_OF_CONNECTED_gNB_MAX]; - int dlsch_mch_received_sf[MAX_MBSFN_AREA][NUMBER_OF_CONNECTED_gNB_MAX]; - int dlsch_mcch_received[MAX_MBSFN_AREA][NUMBER_OF_CONNECTED_gNB_MAX]; - int dlsch_mtch_received[MAX_MBSFN_AREA][NUMBER_OF_CONNECTED_gNB_MAX]; - int dlsch_mcch_errors[MAX_MBSFN_AREA][NUMBER_OF_CONNECTED_gNB_MAX]; - int dlsch_mtch_errors[MAX_MBSFN_AREA][NUMBER_OF_CONNECTED_gNB_MAX]; - int dlsch_mcch_trials[MAX_MBSFN_AREA][NUMBER_OF_CONNECTED_gNB_MAX]; - int dlsch_mtch_trials[MAX_MBSFN_AREA][NUMBER_OF_CONNECTED_gNB_MAX]; uint8_t init_sync_frame; /// temporary offset during cell search prior to MIB decoding int ssb_offset; From 1d9418097ff3fb58cb4f4246f404acb999946f40 Mon Sep 17 00:00:00 2001 From: Rakesh Mundlamuri Date: Mon, 16 Feb 2026 19:32:09 +0530 Subject: [PATCH 04/44] Move RCconfig_NR_NG() to NGAP --- CMakeLists.txt | 2 + openair2/GNB_APP/gnb_app.c | 1 + openair2/GNB_APP/gnb_config.c | 165 +-------------------------- openair2/GNB_APP/gnb_config.h | 1 - openair2/GNB_APP/gnb_config_common.c | 66 +++++++++++ openair2/GNB_APP/gnb_config_common.h | 26 +++++ openair2/GNB_APP/gnb_config_ng.c | 162 ++++++++++++++++++++++++++ openair2/GNB_APP/gnb_config_ng.h | 29 +++++ 8 files changed, 287 insertions(+), 165 deletions(-) create mode 100644 openair2/GNB_APP/gnb_config_common.c create mode 100644 openair2/GNB_APP/gnb_config_common.h create mode 100644 openair2/GNB_APP/gnb_config_ng.c create mode 100644 openair2/GNB_APP/gnb_config_ng.h diff --git a/CMakeLists.txt b/CMakeLists.txt index d0b9f17a02..0f2e8931a3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1308,6 +1308,8 @@ set (GNB_APP_SRC ${OPENAIR2_DIR}/GNB_APP/gnb_app.c ${OPENAIR2_DIR}/E1AP/e1ap_setup.c ${OPENAIR2_DIR}/GNB_APP/gnb_config.c + ${OPENAIR2_DIR}/GNB_APP/gnb_config_common.c + ${OPENAIR2_DIR}/GNB_APP/gnb_config_ng.c ) set (MCE_APP_SRC diff --git a/openair2/GNB_APP/gnb_app.c b/openair2/GNB_APP/gnb_app.c index 98546413a0..9597f61430 100644 --- a/openair2/GNB_APP/gnb_app.c +++ b/openair2/GNB_APP/gnb_app.c @@ -53,6 +53,7 @@ #include "openair2/E1AP/e1ap.h" #include "gnb_config.h" #include "openair2/LAYER2/NR_MAC_gNB/mac_proto.h" +#include "openair2/GNB_APP/gnb_config_ng.h" extern RAN_CONTEXT_t RC; /*------------------------------------------------------------------------------*/ diff --git a/openair2/GNB_APP/gnb_config.c b/openair2/GNB_APP/gnb_config.c index 667ab25093..d6d370fe70 100644 --- a/openair2/GNB_APP/gnb_config.c +++ b/openair2/GNB_APP/gnb_config.c @@ -79,7 +79,7 @@ #include "uper_encoder.h" #include "utils.h" #include "x2ap_messages_types.h" - +#include "gnb_config_common.h" static int DEFBANDS[] = {7}; static int DEFENBS[] = {0}; @@ -96,45 +96,6 @@ static int DEFRUTPCORES[] = {-1,-1,-1,-1}; (element)->choice.setup = CALLOC(1, sizeof(*((element)->choice.setup))); \ } while (0) -static uint16_t set_snssai_config(nssai_t *nssai, const int max_num_ssi, uint8_t k, uint8_t l) -{ - char snssaistr[MAX_OPTNAME_SIZE * 2 + 8]; - snprintf(snssaistr, sizeof(snssaistr), "%s.[%i].%s.[%i]", GNB_CONFIG_STRING_GNB_LIST, k, GNB_CONFIG_STRING_PLMN_LIST, l); - GET_PARAMS_LIST(SNSSAIParamList, - SNSSAIParams, - GNBSNSSAIPARAMS_DESC, - GNB_CONFIG_STRING_SNSSAI_LIST, - snssaistr, - SNSSAIPARAMS_CHECK); - uint16_t num_ssi = SNSSAIParamList.numelt; - AssertFatal(num_ssi < max_num_ssi, "S-NSSAI size %d exceeds the max array size %d", num_ssi, max_num_ssi); - for (int s = 0; s < num_ssi; ++s) { - nssai[s].sst = *SNSSAIParamList.paramarray[s][GNB_SLICE_SERVICE_TYPE_IDX].uptr; - // SD is optional - // 0xffffff is "no SD", see 23.003 Sec 28.4.2 - nssai[s].sd = *SNSSAIParamList.paramarray[s][GNB_SLICE_DIFFERENTIATOR_IDX].uptr; - AssertFatal(nssai[s].sd <= 0xffffff, "SD cannot be bigger than 0xffffff, but is %d\n", nssai[s].sd); - } - return num_ssi; -} - -static uint8_t set_plmn_config(plmn_id_t *p, uint8_t idx) -{ - char gnbpath[MAX_OPTNAME_SIZE * 2 + 8]; - snprintf(gnbpath, sizeof(gnbpath), "%s.[%i]", GNB_CONFIG_STRING_GNB_LIST, idx); - GET_PARAMS_LIST(PLMNParamList, PLMNParams, GNBPLMNPARAMS_DESC, GNB_CONFIG_STRING_PLMN_LIST, gnbpath, PLMNPARAMS_CHECK); - uint8_t num_plmn = PLMNParamList.numelt; - AssertFatal(num_plmn >= 1 && num_plmn <= 6, "The number of PLMN IDs must be in [1,6], but is %d\n", num_plmn); - for (int l = 0; l < num_plmn; ++l) { - plmn_id_t *plmn = &p[l]; - plmn->mcc = *PLMNParamList.paramarray[l][GNB_MOBILE_COUNTRY_CODE_IDX].uptr; - plmn->mnc = *PLMNParamList.paramarray[l][GNB_MOBILE_NETWORK_CODE_IDX].uptr; - plmn->mnc_digit_length = *PLMNParamList.paramarray[l][GNB_MNC_DIGIT_LENGTH].u8ptr; - AssertFatal((plmn->mnc_digit_length == 2) || (plmn->mnc_digit_length == 3), "BAD MNC DIGIT LENGTH %d", plmn->mnc_digit_length); - } - return num_plmn; -} - /** * Allocate memory and initialize ServingCellConfigCommon struct members */ @@ -2131,130 +2092,6 @@ gNB_RRC_INST *RCconfig_NRRRC() return rrc; } -int RCconfig_NR_NG(MessageDef *msg_p, uint32_t i) -{ - int j,k = 0; - int gnb_id; - - char* gnb_ipv4_address_for_NGU = NULL; - uint32_t gnb_port_for_NGU = 0; - char* gnb_ipv4_address_for_S1U = NULL; - uint32_t gnb_port_for_S1U = 0; - - GET_PARAMS(GNBSParams, GNBSPARAMS_DESC, NULL); - AssertFatal (i0) { - // Output a list of all gNBs. - GET_PARAMS_LIST(GNBParamList, GNBParams, GNBPARAMS_DESC, GNB_CONFIG_STRING_GNB_LIST, NULL); - if (GNBParamList.numelt > 0) { - for (k = 0; k < GNBParamList.numelt; k++) { - if (GNBParamList.paramarray[k][GNB_GNB_ID_IDX].uptr == NULL) { - // Calculate a default gNB ID - if (IS_SA_MODE(get_softmodem_params())) { - uint32_t hash; - - hash = ngap_generate_gNB_id (); - gnb_id = k + (hash & 0xFFFFFF8); - } else { - gnb_id = k; - } - } else { - gnb_id = *(GNBParamList.paramarray[k][GNB_GNB_ID_IDX].uptr); - } - - - // search if in active list - for (j=0; j < GNBSParams[GNB_ACTIVE_GNBS_IDX].numelt; j++) { - if (strcmp(GNBSParams[GNB_ACTIVE_GNBS_IDX].strlistptr[j], *(GNBParamList.paramarray[k][GNB_GNB_NAME_IDX].strptr)) == 0) { - - char aprefix[MAX_OPTNAME_SIZE*2 + 8]; - NGAP_REGISTER_GNB_REQ (msg_p).gNB_id = gnb_id; - - if (strcmp(*(GNBParamList.paramarray[k][GNB_CELL_TYPE_IDX].strptr), "CELL_MACRO_GNB") == 0) { - NGAP_REGISTER_GNB_REQ (msg_p).cell_type = CELL_MACRO_GNB; - } else if (strcmp(*(GNBParamList.paramarray[k][GNB_CELL_TYPE_IDX].strptr), "CELL_HOME_GNB") == 0) { - NGAP_REGISTER_GNB_REQ (msg_p).cell_type = CELL_HOME_ENB; - } else { - AssertFatal (0, - "Failed to parse gNB configuration file %s, gnb %u unknown value \"%s\" for cell_type choice: CELL_MACRO_GNB or CELL_HOME_GNB !\n", - RC.config_file_name, i, *(GNBParamList.paramarray[k][GNB_CELL_TYPE_IDX].strptr)); - } - - NGAP_REGISTER_GNB_REQ (msg_p).gNB_name = strdup(*(GNBParamList.paramarray[k][GNB_GNB_NAME_IDX].strptr)); - NGAP_REGISTER_GNB_REQ (msg_p).tac = *GNBParamList.paramarray[k][GNB_TRACKING_AREA_CODE_IDX].uptr; - AssertFatal(!GNBParamList.paramarray[k][GNB_MOBILE_COUNTRY_CODE_IDX_OLD].strptr - && !GNBParamList.paramarray[k][GNB_MOBILE_NETWORK_CODE_IDX_OLD].strptr, - "It seems that you use an old configuration file. Please change the existing\n" - " tracking_area_code = \"1\";\n" - " mobile_country_code = \"208\";\n" - " mobile_network_code = \"93\";\n" - "to\n" - " tracking_area_code = 1; // no string!!\n" - " plmn_list = ( { mcc = 208; mnc = 93; mnc_length = 2; } )\n"); - // PLMN - plmn_id_t p[PLMN_LIST_MAX_SIZE] = {0}; - NGAP_REGISTER_GNB_REQ(msg_p).num_plmn = set_plmn_config(p, 0); - for (int l = 0; l < NGAP_REGISTER_GNB_REQ(msg_p).num_plmn; ++l) { - NGAP_REGISTER_GNB_REQ(msg_p).plmn[l].plmn = p[l]; - // SNSSAI - NGAP_REGISTER_GNB_REQ(msg_p).plmn[l].num_nssai = set_snssai_config(NGAP_REGISTER_GNB_REQ(msg_p).plmn[l].s_nssai, 8, k, l); - } - NGAP_REGISTER_GNB_REQ(msg_p).default_drx = 0; - // NG - snprintf(aprefix, sizeof(aprefix), "%s.[%i]", GNB_CONFIG_STRING_GNB_LIST, k); - GET_PARAMS_LIST(NGParamList, NGParams, GNBNGPARAMS_DESC, GNB_CONFIG_STRING_AMF_IP_ADDRESS, aprefix); - NGAP_REGISTER_GNB_REQ (msg_p).nb_amf = 0; - - for (int l = 0; l < NGParamList.numelt; l++) { - NGAP_REGISTER_GNB_REQ (msg_p).nb_amf += 1; - strcpy(NGAP_REGISTER_GNB_REQ (msg_p).amf_ip_address[l].ipv4_address,*(NGParamList.paramarray[l][GNB_AMF_IPV4_ADDRESS_IDX].strptr)); - NGAP_REGISTER_GNB_REQ (msg_p).amf_ip_address[j].ipv4 = 1; - NGAP_REGISTER_GNB_REQ (msg_p).amf_ip_address[j].ipv6 = 0; - /* if no broadcasst_plmn array is defined, fill default values */ - if (NGAP_REGISTER_GNB_REQ(msg_p).broadcast_plmn_num[l] == 0) { - NGAP_REGISTER_GNB_REQ(msg_p).broadcast_plmn_num[l] = NGAP_REGISTER_GNB_REQ(msg_p).num_plmn; - for (int el = 0; el < NGAP_REGISTER_GNB_REQ(msg_p).num_plmn; ++el) - NGAP_REGISTER_GNB_REQ(msg_p).broadcast_plmn_index[l][el] = el; - } - } - - // SCTP SETTING - NGAP_REGISTER_GNB_REQ (msg_p).sctp_out_streams = SCTP_OUT_STREAMS; - NGAP_REGISTER_GNB_REQ (msg_p).sctp_in_streams = SCTP_IN_STREAMS; - if (IS_SA_MODE(get_softmodem_params())) { - snprintf(aprefix, sizeof(aprefix), "%s.[%d].%s", GNB_CONFIG_STRING_GNB_LIST, k, GNB_CONFIG_STRING_SCTP_CONFIG); - GET_PARAMS(SCTPParams, GNBSCTPPARAMS_DESC, aprefix); - NGAP_REGISTER_GNB_REQ (msg_p).sctp_in_streams = (uint16_t)*(SCTPParams[GNB_SCTP_INSTREAMS_IDX].uptr); - NGAP_REGISTER_GNB_REQ (msg_p).sctp_out_streams = (uint16_t)*(SCTPParams[GNB_SCTP_OUTSTREAMS_IDX].uptr); - } - - // NETWORK_INTERFACES - snprintf(aprefix, sizeof(aprefix), "%s.[%d].%s", GNB_CONFIG_STRING_GNB_LIST, k, GNB_CONFIG_STRING_NETWORK_INTERFACES_CONFIG); - GET_PARAMS(NETParams, GNBNETPARAMS_DESC, aprefix); - if (NETParams[GNB_IPV4_ADDRESS_FOR_NG_AMF_IDX].strptr != NULL) { - char *cidr = *(NETParams[GNB_IPV4_ADDRESS_FOR_NG_AMF_IDX].strptr); - char *save = NULL; - char *address = strtok_r(cidr, "/", &save); - strcpy(NGAP_REGISTER_GNB_REQ (msg_p).gnb_ip_address.ipv4_address, address); - LOG_I(GNB_APP, "Parsed IPv4 address for NG AMF: %s\n", address); - } - - NGAP_REGISTER_GNB_REQ (msg_p).gnb_ip_address.ipv6 = 0; - NGAP_REGISTER_GNB_REQ (msg_p).gnb_ip_address.ipv4 = 1; - - break; - } - } - } - } - } - return 0; -} - static pthread_mutex_t rc_mutex = PTHREAD_MUTEX_INITIALIZER; static bool rc_done = false; diff --git a/openair2/GNB_APP/gnb_config.h b/openair2/GNB_APP/gnb_config.h index c33c6964dc..1f48358e67 100644 --- a/openair2/GNB_APP/gnb_config.h +++ b/openair2/GNB_APP/gnb_config.h @@ -44,7 +44,6 @@ void RCconfig_nr_macrlc(configmodule_interface_t *cfg); void NRRCConfig(void); gNB_RRC_INST *RCconfig_NRRRC(); -int RCconfig_NR_NG(MessageDef *msg_p, uint32_t i); int RCconfig_NR_X2(MessageDef *msg_p, uint32_t i); void wait_f1_setup_response(void); f1ap_tdd_info_t read_tdd_config(const NR_ServingCellConfigCommon_t *scc); diff --git a/openair2/GNB_APP/gnb_config_common.c b/openair2/GNB_APP/gnb_config_common.c new file mode 100644 index 0000000000..ac5e840851 --- /dev/null +++ b/openair2/GNB_APP/gnb_config_common.c @@ -0,0 +1,66 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#include "openair2/GNB_APP/gnb_config_common.h" +#include "common/config/config_paramdesc.h" +#include "common/config/config_userapi.h" +#include "RRC_nr_paramsvalues.h" +#include "gnb_paramdef.h" +#include "sctp_default_values.h" + +uint16_t set_snssai_config(nssai_t *nssai, const int max_num_ssi, uint8_t k, uint8_t l) +{ + char snssaistr[MAX_OPTNAME_SIZE * 2 + 8]; + snprintf(snssaistr, sizeof(snssaistr), "%s.[%i].%s.[%i]", GNB_CONFIG_STRING_GNB_LIST, k, GNB_CONFIG_STRING_PLMN_LIST, l); + GET_PARAMS_LIST(SNSSAIParamList, + SNSSAIParams, + GNBSNSSAIPARAMS_DESC, + GNB_CONFIG_STRING_SNSSAI_LIST, + snssaistr, + SNSSAIPARAMS_CHECK); + uint16_t num_ssi = SNSSAIParamList.numelt; + AssertFatal(num_ssi < max_num_ssi, "S-NSSAI size %d exceeds the max array size %d", num_ssi, max_num_ssi); + for (int s = 0; s < num_ssi; ++s) { + nssai[s].sst = *SNSSAIParamList.paramarray[s][GNB_SLICE_SERVICE_TYPE_IDX].uptr; + // SD is optional + // 0xffffff is "no SD", see 23.003 Sec 28.4.2 + nssai[s].sd = *SNSSAIParamList.paramarray[s][GNB_SLICE_DIFFERENTIATOR_IDX].uptr; + AssertFatal(nssai[s].sd <= 0xffffff, "SD cannot be bigger than 0xffffff, but is %d\n", nssai[s].sd); + } + return num_ssi; +} + +uint8_t set_plmn_config(plmn_id_t *p, uint8_t idx) +{ + char gnbpath[MAX_OPTNAME_SIZE * 2 + 8]; + snprintf(gnbpath, sizeof(gnbpath), "%s.[%i]", GNB_CONFIG_STRING_GNB_LIST, idx); + GET_PARAMS_LIST(PLMNParamList, PLMNParams, GNBPLMNPARAMS_DESC, GNB_CONFIG_STRING_PLMN_LIST, gnbpath, PLMNPARAMS_CHECK); + uint8_t num_plmn = PLMNParamList.numelt; + AssertFatal(num_plmn >= 1 && num_plmn <= 6, "The number of PLMN IDs must be in [1,6], but is %d\n", num_plmn); + for (int l = 0; l < num_plmn; ++l) { + plmn_id_t *plmn = &p[l]; + plmn->mcc = *PLMNParamList.paramarray[l][GNB_MOBILE_COUNTRY_CODE_IDX].uptr; + plmn->mnc = *PLMNParamList.paramarray[l][GNB_MOBILE_NETWORK_CODE_IDX].uptr; + plmn->mnc_digit_length = *PLMNParamList.paramarray[l][GNB_MNC_DIGIT_LENGTH].u8ptr; + AssertFatal((plmn->mnc_digit_length == 2) || (plmn->mnc_digit_length == 3), "BAD MNC DIGIT LENGTH %d", plmn->mnc_digit_length); + } + return num_plmn; +} diff --git a/openair2/GNB_APP/gnb_config_common.h b/openair2/GNB_APP/gnb_config_common.h new file mode 100644 index 0000000000..8317709a78 --- /dev/null +++ b/openair2/GNB_APP/gnb_config_common.h @@ -0,0 +1,26 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#include +#include "common/5g_platform_types.h" + +uint16_t set_snssai_config(nssai_t *nssai, const int max_num_ssi, uint8_t k, uint8_t l); +uint8_t set_plmn_config(plmn_id_t *p, uint8_t idx); diff --git a/openair2/GNB_APP/gnb_config_ng.c b/openair2/GNB_APP/gnb_config_ng.c new file mode 100644 index 0000000000..632c670def --- /dev/null +++ b/openair2/GNB_APP/gnb_config_ng.c @@ -0,0 +1,162 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#include "gnb_config_ng.h" +#include +#include "assertions.h" +#include "common/ran_context.h" +#include "openair2/GNB_APP/gnb_config_common.h" +#include "common/config/config_paramdesc.h" +#include "sctp_default_values.h" +#include "gnb_paramdef.h" + +int RCconfig_NR_NG(MessageDef *msg_p, uint32_t i) +{ + int j, k = 0; + int gnb_id; + + char *gnb_ipv4_address_for_NGU = NULL; + uint32_t gnb_port_for_NGU = 0; + char *gnb_ipv4_address_for_S1U = NULL; + uint32_t gnb_port_for_S1U = 0; + + GET_PARAMS(GNBSParams, GNBSPARAMS_DESC, NULL); + AssertFatal(i < GNBSParams[GNB_ACTIVE_GNBS_IDX].numelt, + "Failed to parse config file %s, %uth attribute %s \n", + RC.config_file_name, + i, + GNB_CONFIG_STRING_ACTIVE_GNBS); + + if (GNBSParams[GNB_ACTIVE_GNBS_IDX].numelt > 0) { + // Output a list of all gNBs. + GET_PARAMS_LIST(GNBParamList, GNBParams, GNBPARAMS_DESC, GNB_CONFIG_STRING_GNB_LIST, NULL); + if (GNBParamList.numelt > 0) { + for (k = 0; k < GNBParamList.numelt; k++) { + if (GNBParamList.paramarray[k][GNB_GNB_ID_IDX].uptr == NULL) { + // Calculate a default gNB ID + if (IS_SA_MODE(get_softmodem_params())) { + uint32_t hash; + + hash = ngap_generate_gNB_id(); + gnb_id = k + (hash & 0xFFFFFF8); + } else { + gnb_id = k; + } + } else { + gnb_id = *(GNBParamList.paramarray[k][GNB_GNB_ID_IDX].uptr); + } + + // search if in active list + for (j = 0; j < GNBSParams[GNB_ACTIVE_GNBS_IDX].numelt; j++) { + if (strcmp(GNBSParams[GNB_ACTIVE_GNBS_IDX].strlistptr[j], *(GNBParamList.paramarray[k][GNB_GNB_NAME_IDX].strptr)) == 0) { + char aprefix[MAX_OPTNAME_SIZE * 2 + 8]; + NGAP_REGISTER_GNB_REQ(msg_p).gNB_id = gnb_id; + + if (strcmp(*(GNBParamList.paramarray[k][GNB_CELL_TYPE_IDX].strptr), "CELL_MACRO_GNB") == 0) { + NGAP_REGISTER_GNB_REQ(msg_p).cell_type = CELL_MACRO_GNB; + } else if (strcmp(*(GNBParamList.paramarray[k][GNB_CELL_TYPE_IDX].strptr), "CELL_HOME_GNB") == 0) { + NGAP_REGISTER_GNB_REQ(msg_p).cell_type = CELL_HOME_ENB; + } else { + AssertFatal(0, + "Failed to parse gNB configuration file %s, gnb %u unknown value \"%s\" for cell_type choice: " + "CELL_MACRO_GNB or CELL_HOME_GNB !\n", + RC.config_file_name, + i, + *(GNBParamList.paramarray[k][GNB_CELL_TYPE_IDX].strptr)); + } + + NGAP_REGISTER_GNB_REQ(msg_p).gNB_name = strdup(*(GNBParamList.paramarray[k][GNB_GNB_NAME_IDX].strptr)); + NGAP_REGISTER_GNB_REQ(msg_p).tac = *GNBParamList.paramarray[k][GNB_TRACKING_AREA_CODE_IDX].uptr; + AssertFatal(!GNBParamList.paramarray[k][GNB_MOBILE_COUNTRY_CODE_IDX_OLD].strptr + && !GNBParamList.paramarray[k][GNB_MOBILE_NETWORK_CODE_IDX_OLD].strptr, + "It seems that you use an old configuration file. Please change the existing\n" + " tracking_area_code = \"1\";\n" + " mobile_country_code = \"208\";\n" + " mobile_network_code = \"93\";\n" + "to\n" + " tracking_area_code = 1; // no string!!\n" + " plmn_list = ( { mcc = 208; mnc = 93; mnc_length = 2; } )\n"); + // PLMN + plmn_id_t p[PLMN_LIST_MAX_SIZE] = {0}; + NGAP_REGISTER_GNB_REQ(msg_p).num_plmn = set_plmn_config(p, 0); + for (int l = 0; l < NGAP_REGISTER_GNB_REQ(msg_p).num_plmn; ++l) { + NGAP_REGISTER_GNB_REQ(msg_p).plmn[l].plmn = p[l]; + // SNSSAI + NGAP_REGISTER_GNB_REQ(msg_p).plmn[l].num_nssai = + set_snssai_config(NGAP_REGISTER_GNB_REQ(msg_p).plmn[l].s_nssai, 8, k, l); + } + NGAP_REGISTER_GNB_REQ(msg_p).default_drx = 0; + // NG + snprintf(aprefix, sizeof(aprefix), "%s.[%i]", GNB_CONFIG_STRING_GNB_LIST, k); + GET_PARAMS_LIST(NGParamList, NGParams, GNBNGPARAMS_DESC, GNB_CONFIG_STRING_AMF_IP_ADDRESS, aprefix); + NGAP_REGISTER_GNB_REQ(msg_p).nb_amf = 0; + + for (int l = 0; l < NGParamList.numelt; l++) { + NGAP_REGISTER_GNB_REQ(msg_p).nb_amf += 1; + strcpy(NGAP_REGISTER_GNB_REQ(msg_p).amf_ip_address[l].ipv4_address, + *(NGParamList.paramarray[l][GNB_AMF_IPV4_ADDRESS_IDX].strptr)); + NGAP_REGISTER_GNB_REQ(msg_p).amf_ip_address[l].ipv4 = 1; + NGAP_REGISTER_GNB_REQ(msg_p).amf_ip_address[l].ipv6 = 0; + /* if no broadcasst_plmn array is defined, fill default values */ + if (NGAP_REGISTER_GNB_REQ(msg_p).broadcast_plmn_num[l] == 0) { + NGAP_REGISTER_GNB_REQ(msg_p).broadcast_plmn_num[l] = NGAP_REGISTER_GNB_REQ(msg_p).num_plmn; + for (int el = 0; el < NGAP_REGISTER_GNB_REQ(msg_p).num_plmn; ++el) + NGAP_REGISTER_GNB_REQ(msg_p).broadcast_plmn_index[l][el] = el; + } + } + + // SCTP SETTING + NGAP_REGISTER_GNB_REQ(msg_p).sctp_out_streams = SCTP_OUT_STREAMS; + NGAP_REGISTER_GNB_REQ(msg_p).sctp_in_streams = SCTP_IN_STREAMS; + if (IS_SA_MODE(get_softmodem_params())) { + snprintf(aprefix, sizeof(aprefix), "%s.[%d].%s", GNB_CONFIG_STRING_GNB_LIST, k, GNB_CONFIG_STRING_SCTP_CONFIG); + GET_PARAMS(SCTPParams, GNBSCTPPARAMS_DESC, aprefix); + NGAP_REGISTER_GNB_REQ(msg_p).sctp_in_streams = (uint16_t) * (SCTPParams[GNB_SCTP_INSTREAMS_IDX].uptr); + NGAP_REGISTER_GNB_REQ(msg_p).sctp_out_streams = (uint16_t) * (SCTPParams[GNB_SCTP_OUTSTREAMS_IDX].uptr); + } + + // NETWORK_INTERFACES + snprintf(aprefix, + sizeof(aprefix), + "%s.[%d].%s", + GNB_CONFIG_STRING_GNB_LIST, + k, + GNB_CONFIG_STRING_NETWORK_INTERFACES_CONFIG); + GET_PARAMS(NETParams, GNBNETPARAMS_DESC, aprefix); + if (NETParams[GNB_IPV4_ADDRESS_FOR_NG_AMF_IDX].strptr != NULL) { + char *cidr = *(NETParams[GNB_IPV4_ADDRESS_FOR_NG_AMF_IDX].strptr); + char *save = NULL; + char *address = strtok_r(cidr, "/", &save); + strcpy(NGAP_REGISTER_GNB_REQ(msg_p).gnb_ip_address.ipv4_address, address); + LOG_I(GNB_APP, "Parsed IPv4 address for NG AMF: %s\n", address); + } + + NGAP_REGISTER_GNB_REQ(msg_p).gnb_ip_address.ipv6 = 0; + NGAP_REGISTER_GNB_REQ(msg_p).gnb_ip_address.ipv4 = 1; + + break; + } + } + } + } + } + return 0; +} diff --git a/openair2/GNB_APP/gnb_config_ng.h b/openair2/GNB_APP/gnb_config_ng.h new file mode 100644 index 0000000000..792f55e940 --- /dev/null +++ b/openair2/GNB_APP/gnb_config_ng.h @@ -0,0 +1,29 @@ +/* + * 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 NGAP_GNB_CONFIG_H_ +#define NGAP_GNB_CONFIG_H_ +#include +#include "intertask_interface.h" + +int RCconfig_NR_NG(MessageDef *msg_p, uint32_t i); + +#endif /* NGAP_GNB_CONFIG_H_ */ From 786d8b34c09f7424f78343b218a4859ba30470d8 Mon Sep 17 00:00:00 2001 From: Rakesh Mundlamuri Date: Mon, 29 Dec 2025 13:33:45 +0530 Subject: [PATCH 05/44] Introduce NGAP emulator that connects to the AMF to perform NGAP enc/dec - Performs NGAP setup request and handles NGAP setup response - This is introduced to test NGAP enc/dec of the NRPPa messages To compile: openairinterface5g$ mkdir build openairinterface5g$ cd build openairinterface5g/build$ cmake .. -GNinja openairinterface5g/build$ ninja nr-cu-nrppa-test To run: openairinterface5g/build$ LD_LIBRARY_PATH=. ./tests/nr-cu-nrppa/nr-cu-nrppa-test -O ../tests/nr-cu-nrppa/nr-nrppa-test.conf --- tests/CMakeLists.txt | 1 + tests/nr-cu-nrppa/CMakeLists.txt | 10 +++ tests/nr-cu-nrppa/nr-cu-nrppa.c | 99 ++++++++++++++++++++++++++++ tests/nr-cu-nrppa/nr-nrppa-test.conf | 52 +++++++++++++++ 4 files changed, 162 insertions(+) create mode 100644 tests/nr-cu-nrppa/CMakeLists.txt create mode 100644 tests/nr-cu-nrppa/nr-cu-nrppa.c create mode 100644 tests/nr-cu-nrppa/nr-nrppa-test.conf diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index cefa52d456..63d036a83c 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -1 +1,2 @@ add_subdirectory(nr-cuup) +add_subdirectory(nr-cu-nrppa) diff --git a/tests/nr-cu-nrppa/CMakeLists.txt b/tests/nr-cu-nrppa/CMakeLists.txt new file mode 100644 index 0000000000..1db9b33e37 --- /dev/null +++ b/tests/nr-cu-nrppa/CMakeLists.txt @@ -0,0 +1,10 @@ +add_executable(nr-cu-nrppa-test nr-cu-nrppa.c + ${OPENAIR2_DIR}/GNB_APP/gnb_config_common.c + ${OPENAIR2_DIR}/GNB_APP/gnb_config_ng.c) + +target_link_libraries(nr-cu-nrppa-test PRIVATE + CONFIG_LIB ITTI SCTP_CLIENT + f1ap ngap SECURITY + UTIL softmodem_common) +target_link_libraries(nr-cu-nrppa-test PRIVATE asn1_lte_rrc_hdrs asn1_nr_rrc_hdrs) +add_dependencies(nr-cu-nrppa-test params_libconfig) diff --git a/tests/nr-cu-nrppa/nr-cu-nrppa.c b/tests/nr-cu-nrppa/nr-cu-nrppa.c new file mode 100644 index 0000000000..1436b7cd27 --- /dev/null +++ b/tests/nr-cu-nrppa/nr-cu-nrppa.c @@ -0,0 +1,99 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#include "executables/softmodem-common.h" +#include "common/utils/ocp_itti/intertask_interface.h" +#include "common/ran_context.h" +#include "nfapi/oai_integration/vendor_ext.h" +#include "openair2/GNB_APP/gnb_config_common.h" +#include "openair2/GNB_APP/gnb_config_ng.h" +#include "openair2/GNB_APP/gnb_paramdef.h" +#include "openair3/SCTP/sctp_default_values.h" + +RAN_CONTEXT_t RC; +THREAD_STRUCT thread_struct; +uint64_t downlink_frequency[MAX_NUM_CCs][4]; +int32_t uplink_frequency_offset[MAX_NUM_CCs][4]; +int oai_exit = 0; +int gnb_id; + +void exit_function(const char *file, const char *function, const int line, const char *s, const int assert) +{ + if (assert) { + abort(); + } else { + sleep(1); // allow other threads to exit first + exit(EXIT_SUCCESS); + } +} + +nfapi_mode_t nfapi_mod = -1; +void nfapi_setmode(nfapi_mode_t nfapi_mode) +{ + nfapi_mod = nfapi_mode; +} +nfapi_mode_t nfapi_getmode(void) +{ + return nfapi_mod; +} + +ngran_node_t get_node_type() +{ + return ngran_gNB_CUUP; +} + +configmodule_interface_t *uniqCfg = NULL; + +int main(int argc, char **argv) +{ + // load the config file + if ((uniqCfg = load_configmodule(argc, argv, CONFIG_ENABLECMDLINEONLY)) == NULL) { + exit_fun("[SOFTMODEM] Error, configuration module init failed\n"); + } + logInit(); + + set_softmodem_sighandler(); + + // Initialize ITTI tasks + itti_init(TASK_MAX, tasks_info); + + int rc; + rc = itti_create_task(TASK_SCTP, sctp_eNB_task, NULL); + AssertFatal(rc >= 0, "Create task for SCTP failed\n"); + + rc = itti_create_task(TASK_NGAP, ngap_gNB_task, NULL); + AssertFatal(rc >= 0, "Create task for NGAP failed\n"); + + MessageDef *msg_p; + msg_p = itti_alloc_new_message(TASK_GNB_APP, 0, NGAP_REGISTER_GNB_REQ); + RCconfig_NR_NG(msg_p, 0); + gnb_id = NGAP_REGISTER_GNB_REQ(msg_p).gNB_id; + + LOG_I(GNB_APP, "Sending NGAP_REGISTER_GNB_REQ to TASK_NGAP\n"); + itti_send_msg_to_task(TASK_NGAP, 0, msg_p); + + printf("TYPE TO TERMINATE\n"); + itti_wait_tasks_end(NULL); + + logClean(); + printf("Bye.\n"); + return 0; +} diff --git a/tests/nr-cu-nrppa/nr-nrppa-test.conf b/tests/nr-cu-nrppa/nr-nrppa-test.conf new file mode 100644 index 0000000000..f5d6ea673a --- /dev/null +++ b/tests/nr-cu-nrppa/nr-nrppa-test.conf @@ -0,0 +1,52 @@ +Active_gNBs = ( "gNB-OAI"); +# Asn1_verbosity, choice in: none, info, annoying +Asn1_verbosity = "none"; + +gNBs = +( + { + ////////// Identification parameters: + gNB_ID = 0xe00; + gNB_name = "gNB-OAI"; + + // Tracking area code, 0x0000 and 0xfffe are reserved values + tracking_area_code = 1; + plmn_list = ({ mcc = 001; mnc = 01; mnc_length = 2; snssaiList = ({ sst = 1; }) }); + + nr_cellid = 12345678L; + + # ------- SCTP definitions + SCTP : + { + # Number of streams to use in input/output + SCTP_INSTREAMS = 2; + SCTP_OUTSTREAMS = 2; + }; + + + ////////// AMF parameters: + amf_ip_address = ({ ipv4 = "192.168.70.132"; }); + + + NETWORK_INTERFACES : + { + GNB_IPV4_ADDRESS_FOR_NG_AMF = "192.168.70.129/24"; + GNB_IPV4_ADDRESS_FOR_NGU = "192.168.70.129/24"; + GNB_PORT_FOR_S1U = 2152; # Spec 2152 + }; + + } +); + +log_config : +{ + global_log_level ="info"; + hw_log_level ="info"; + phy_log_level ="info"; + mac_log_level ="info"; + rlc_log_level ="info"; + pdcp_log_level ="info"; + rrc_log_level ="info"; + ngap_log_level ="debug"; + f1ap_log_level ="debug"; +}; From dabb8d338f13a9693a518c5b01587cc8136cd88c Mon Sep 17 00:00:00 2001 From: Rakesh Mundlamuri Date: Tue, 3 Feb 2026 12:55:49 +0530 Subject: [PATCH 06/44] Add docker compose file of the 5G core network with the LMF feature --- .../oai-cn5g/conf/config.yaml | 20 ++ .../oai-cn5g/docker-compose-positioning.yaml | 195 ++++++++++++++++++ 2 files changed, 215 insertions(+) create mode 100644 doc/tutorial_resources/oai-cn5g/docker-compose-positioning.yaml diff --git a/doc/tutorial_resources/oai-cn5g/conf/config.yaml b/doc/tutorial_resources/oai-cn5g/conf/config.yaml index f18c965ed1..6e55c95bb3 100644 --- a/doc/tutorial_resources/oai-cn5g/conf/config.yaml +++ b/doc/tutorial_resources/oai-cn5g/conf/config.yaml @@ -100,6 +100,12 @@ nfs: port: 8080 api_version: v1 interface_name: eth0 + lmf: + host: oai-lmf + sbi: + port: 8080 + api_version: v1 + interface_name: eth0 #### Common for UDR and AMF database: @@ -220,6 +226,20 @@ upf: - dnn: "ims" - dnn: "default" +lmf: + http_threads_count: 8 + gnb_id_bits_count: 28 + num_gnb: 1 + trp_info_wait_ms: 500 + positioning_wait_ms: 500 + measurement_wait_ms: 500 + support_features: + request_trp_info: no + determine_num_gnb: yes + use_http2: yes + use_fqdn_dns: no + register_nrf: yes + ## DNN configuration dnns: - dnn: "oai" diff --git a/doc/tutorial_resources/oai-cn5g/docker-compose-positioning.yaml b/doc/tutorial_resources/oai-cn5g/docker-compose-positioning.yaml new file mode 100644 index 0000000000..6b75c22b6b --- /dev/null +++ b/doc/tutorial_resources/oai-cn5g/docker-compose-positioning.yaml @@ -0,0 +1,195 @@ +services: + mysql: + container_name: "mysql" + image: mysql:8.0 + volumes: + - ./database/oai_db.sql:/docker-entrypoint-initdb.d/oai_db.sql + - ./healthscripts/mysql-healthcheck.sh:/tmp/mysql-healthcheck.sh + environment: + - TZ=Europe/Paris + - MYSQL_DATABASE=oai_db + - MYSQL_USER=test + - MYSQL_PASSWORD=test + - MYSQL_ROOT_PASSWORD=linux + healthcheck: + test: /bin/bash -c "/tmp/mysql-healthcheck.sh" + interval: 5s + timeout: 2s + retries: 10 + networks: + public_net: + ipv4_address: 192.168.70.131 + + ims: + container_name: "ims" + image: oaisoftwarealliance/ims:latest + volumes: + - ./conf/sip.conf:/etc/asterisk/sip.conf + - ./conf/users.conf:/etc/asterisk/users.conf + healthcheck: + test: /bin/bash -c "pgrep asterisk" + interval: 5s + timeout: 2s + retries: 10 + networks: + public_net: + ipv4_address: 192.168.70.139 + oai-udr: + container_name: "oai-udr" + image: oaisoftwarealliance/oai-udr:develop + expose: + - 80/tcp + - 8080/tcp + volumes: + - ./conf/config.yaml:/openair-udr/etc/config.yaml + environment: + - TZ=Europe/Paris + depends_on: + - mysql + - oai-nrf + networks: + public_net: + ipv4_address: 192.168.70.136 + oai-udm: + container_name: "oai-udm" + image: oaisoftwarealliance/oai-udm:develop + expose: + - 80/tcp + - 8080/tcp + volumes: + - ./conf/config.yaml:/openair-udm/etc/config.yaml + environment: + - TZ=Europe/Paris + depends_on: + - oai-udr + networks: + public_net: + ipv4_address: 192.168.70.137 + oai-ausf: + container_name: "oai-ausf" + image: oaisoftwarealliance/oai-ausf:develop + expose: + - 80/tcp + - 8080/tcp + volumes: + - ./conf/config.yaml:/openair-ausf/etc/config.yaml + environment: + - TZ=Europe/Paris + depends_on: + - oai-udm + networks: + public_net: + ipv4_address: 192.168.70.138 + oai-nrf: + container_name: "oai-nrf" + image: oaisoftwarealliance/oai-nrf:develop + expose: + - 80/tcp + - 8080/tcp + volumes: + - ./conf/config.yaml:/openair-nrf/etc/config.yaml + environment: + - TZ=Europe/Paris + networks: + public_net: + ipv4_address: 192.168.70.130 + oai-amf: + container_name: "oai-amf" + image: oaisoftwarealliance/oai-amf:develop + expose: + - 80/tcp + - 8080/tcp + - 38412/sctp + volumes: + - ./conf/config.yaml:/openair-amf/etc/config.yaml + environment: + - TZ=Europe/Paris + depends_on: + - mysql + - oai-nrf + - oai-ausf + networks: + public_net: + ipv4_address: 192.168.70.132 + oai-lmf: + container_name: "oai-lmf" + image: oaisoftwarealliance/oai-lmf:develop + #image: oai-lmf:psoElementwiseTdoAmeanVarTDoAfilter + expose: + - 80/tcp + - 8080/tcp + volumes: + - ./conf/config.yaml:/openair-lmf/etc/config.yaml + environment: + - TZ=Europe/Paris + depends_on: + - mysql + - oai-nrf + - oai-amf + networks: + public_net: + ipv4_address: 192.168.70.141 + oai-smf: + container_name: "oai-smf" + image: oaisoftwarealliance/oai-smf:develop + expose: + - 80/tcp + - 8080/tcp + - 8805/udp + volumes: + - ./conf/config.yaml:/openair-smf/etc/config.yaml + environment: + - TZ=Europe/Paris + depends_on: + - oai-nrf + - oai-amf + networks: + public_net: + ipv4_address: 192.168.70.133 + oai-upf: + container_name: "oai-upf" + image: oaisoftwarealliance/oai-upf:develop + expose: + - 2152/udp + - 8805/udp + volumes: + - ./conf/config.yaml:/openair-upf/etc/config.yaml + environment: + - TZ=Europe/Paris + depends_on: + - oai-nrf + - oai-smf + cap_add: + - NET_ADMIN + - SYS_ADMIN + cap_drop: + - ALL + privileged: true + networks: + public_net: + ipv4_address: 192.168.70.134 + oai-ext-dn: + privileged: true + init: true + container_name: oai-ext-dn + image: oaisoftwarealliance/trf-gen-cn5g:jammy + entrypoint: /bin/bash -c \ + "ip route add 10.0.0.0/16 via 192.168.70.134 dev eth0; ip route; sleep infinity" + command: ["/bin/bash", "-c", "trap : SIGTERM SIGINT; sleep infinity & wait"] + healthcheck: + test: /bin/bash -c "ip r | grep 10.0.0" + interval: 5s + timeout: 2s + retries: 10 + networks: + public_net: + ipv4_address: 192.168.70.135 +networks: + public_net: + driver: bridge + name: oai-cn5g-public-net + ipam: + config: + - subnet: 192.168.70.128/26 + driver_opts: + com.docker.network.bridge.name: "oai-cn5g" From 08d7a150b11528b55263e8206b336d2e7b6b1238 Mon Sep 17 00:00:00 2001 From: Rakesh Mundlamuri Date: Sun, 1 Feb 2026 19:01:15 +0530 Subject: [PATCH 07/44] Add json file to initiate positioning procedure from the LMF --- .../positioning/InputData.json | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 doc/tutorial_resources/positioning/InputData.json diff --git a/doc/tutorial_resources/positioning/InputData.json b/doc/tutorial_resources/positioning/InputData.json new file mode 100644 index 0000000000..0caebbabba --- /dev/null +++ b/doc/tutorial_resources/positioning/InputData.json @@ -0,0 +1,43 @@ +{ + "externalClientType": "VALUE_ADDED_SERVICES", + "amfId": "128:1:1", + "locationQoS": { + "hAccuracy": 1.5, + "vAccuracy": 1.5, + "verticalRequested": true, + "responseTime": "LOW_DELAY", + "lcsQosClass": "BEST_EFFORT" + }, + "supportedGADShapes": [ + "POINT", + "POINT_UNCERTAINTY_CIRCLE" + ], + "supi": "imsi-001010000000001", + "ncgi": { + "plmnId": { + "mcc": "001", + "mnc": "01" + }, + "nrCellId": "14680064", + "nid": "0" + }, + "priority": "HIGHEST_PRIORITY", + "velocityRequested": "VELOCITY_IS_NOT_REQUESTED", + "lcsServiceType": 127, + "ldrType": "UE_AVAILABLE", + "hgmlcCallBackURI": "198.168.70.129", + "ldrReference": "11", + "lirReference": "1", + "periodicEventInfo": { + "reportingAmount": 10, + "reportingInterval": 60 + }, + "reportingAccessTypes": [ + "NR", + "NON_3GPP_CONNECTED_TO_5GC" + ], + "ueConnectivityStates": { + "accessType": "3GPP_ACCESS", + "connectivitystate": "IDLE" + } +} From bf90e523a75aaab51fff92f6c584df2c7c695dbb Mon Sep 17 00:00:00 2001 From: Rakesh Mundlamuri Date: Mon, 29 Dec 2025 16:07:23 +0530 Subject: [PATCH 08/44] Add NGAP UPLINK UE ASSOCIATED NRPPA TRANSPORT message encoding Reference: 3GPP 38.413 v16.0.0 Mandatory fields: AMF UE NGAP ID (supported) RAN UE NGAP ID (supported) Routing ID (supported) NRPPa-PDU (supported) --- CMakeLists.txt | 1 + openair2/COMMON/ngap_messages_types.h | 12 ++ .../ngap_gNB_NRPPa_transport_procedures.c | 129 ++++++++++++++++++ .../ngap_gNB_NRPPa_transport_procedures.h | 28 ++++ 4 files changed, 170 insertions(+) create mode 100644 openair3/NGAP/ngap_gNB_NRPPa_transport_procedures.c create mode 100644 openair3/NGAP/ngap_gNB_NRPPa_transport_procedures.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 0f2e8931a3..94209f6453 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -441,6 +441,7 @@ add_library(ngap ${NGAP_DIR}/ngap_gNB_overload.c ${NGAP_DIR}/ngap_gNB_trace.c ${NGAP_DIR}/ngap_gNB_ue_context.c + ${NGAP_DIR}/ngap_gNB_NRPPa_transport_procedures.c ) target_link_libraries(ngap PUBLIC asn1_ngap) target_link_libraries(ngap PRIVATE asn1_lte_rrc_hdrs asn1_nr_rrc_hdrs) diff --git a/openair2/COMMON/ngap_messages_types.h b/openair2/COMMON/ngap_messages_types.h index 02069d056e..e40c1059d0 100644 --- a/openair2/COMMON/ngap_messages_types.h +++ b/openair2/COMMON/ngap_messages_types.h @@ -1007,4 +1007,16 @@ typedef struct { ngap_ran_status_container_t ran_status; } ngap_ran_status_transfer_t; +// Uplink UE Associated NRPPA Transport message (9.2.9.2 3GPP 38.413 v16.0.0) +typedef struct { + // AMF UE NGAP ID (Mandatory) + uint64_t amf_ue_ngap_id; + // RAN UE NGAP ID (Mandatory) + uint32_t gNB_ue_ngap_id; + // Routing ID (Mandatory) + byte_array_t routing_id; + // NRPPa pdu (Mandatory) + byte_array_t nrppa_pdu; +} ngap_uplink_ue_associated_nrppa_t; + #endif /* NGAP_MESSAGES_TYPES_H_ */ diff --git a/openair3/NGAP/ngap_gNB_NRPPa_transport_procedures.c b/openair3/NGAP/ngap_gNB_NRPPa_transport_procedures.c new file mode 100644 index 0000000000..d799057ca5 --- /dev/null +++ b/openair3/NGAP/ngap_gNB_NRPPa_transport_procedures.c @@ -0,0 +1,129 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#include +#include +#include + +#include "assertions.h" +#include "conversions.h" + +#include "intertask_interface.h" + +#include "ngap_common.h" +#include "ngap_gNB_defs.h" +#include "ngap_gNB_itti_messaging.h" +#include "ngap_gNB_encoder.h" +#include "ngap_gNB_nnsf.h" +#include "ngap_gNB_ue_context.h" +#include "ngap_gNB_management_procedures.h" + +#include "ngap_gNB_NRPPa_transport_procedures.h" + +// UPLINK UE ASSOCIATED NRPPA TRANSPORT (9.2.9.2 of TS 38.413 Version 16.0.0) +int ngap_gNB_uplink_ue_associated_nrppa_transport(instance_t instance, const ngap_uplink_ue_associated_nrppa_t *msg) +{ + LOG_I(NGAP, "Initiating ngap_gNB_uplink_ue_associated_nrppa_transport \n"); + DevAssert(msg != NULL); + DevAssert(msg->routing_id.buf); + DevAssert(msg->routing_id.len); + DevAssert(msg->nrppa_pdu.buf); + DevAssert(msg->nrppa_pdu.len); + struct ngap_gNB_ue_context_s *ue_context_p = NULL; + ngap_gNB_instance_t *ngap_gNB_instance_p = NULL; + + // Retrieve the NGAP gNB instance associated with Mod_id + ngap_gNB_instance_p = ngap_gNB_get_instance(instance); + DevAssert(ngap_gNB_instance_p != NULL); + + if ((ue_context_p = ngap_get_ue_context(msg->gNB_ue_ngap_id)) == NULL) { + // The context for this gNB ue ngap id doesn't exist in the map of gNB UEs + LOG_E(NGAP, "Failed to find ue context associated with gNB ue ngap id: %08x\n", msg->gNB_ue_ngap_id); + return -1; + } + /* Prepare the NGAP message to encode */ + NGAP_NGAP_PDU_t pdu = {0}; + + // IE: 9.3.1.1 Message Type UplinkUEAssociatedNRPPaTransport + pdu.present = NGAP_NGAP_PDU_PR_initiatingMessage; + asn1cCalloc(pdu.choice.initiatingMessage, head); + head->procedureCode = NGAP_ProcedureCode_id_UplinkUEAssociatedNRPPaTransport; + head->criticality = NGAP_Criticality_ignore; + head->value.present = NGAP_InitiatingMessage__value_PR_UplinkUEAssociatedNRPPaTransport; + NGAP_UplinkUEAssociatedNRPPaTransport_t *out = &head->value.choice.UplinkUEAssociatedNRPPaTransport; + + // IE: 9.3.3.1 AMF UE NGAP ID (mandatory) + { + asn1cSequenceAdd(out->protocolIEs.list, NGAP_UplinkUEAssociatedNRPPaTransportIEs_t, ie); + ie->id = NGAP_ProtocolIE_ID_id_AMF_UE_NGAP_ID; + ie->criticality = NGAP_Criticality_reject; + ie->value.present = NGAP_UplinkUEAssociatedNRPPaTransportIEs__value_PR_AMF_UE_NGAP_ID; + asn_uint642INTEGER(&ie->value.choice.AMF_UE_NGAP_ID, msg->amf_ue_ngap_id); + } + + // IE: 9.3.3.2 RAN UE NGAP ID (mandatory) + { + asn1cSequenceAdd(out->protocolIEs.list, NGAP_UplinkUEAssociatedNRPPaTransportIEs_t, ie); + ie->id = NGAP_ProtocolIE_ID_id_RAN_UE_NGAP_ID; + ie->criticality = NGAP_Criticality_reject; + ie->value.present = NGAP_UplinkUEAssociatedNRPPaTransportIEs__value_PR_RAN_UE_NGAP_ID; + ie->value.choice.RAN_UE_NGAP_ID = msg->gNB_ue_ngap_id; + } + + // IE: 9.3.3.13 Routing ID (mandatory) + { + asn1cSequenceAdd(out->protocolIEs.list, NGAP_UplinkUEAssociatedNRPPaTransportIEs_t, ie); + ie->id = NGAP_ProtocolIE_ID_id_RoutingID; + ie->criticality = NGAP_Criticality_reject; + ie->value.present = NGAP_UplinkUEAssociatedNRPPaTransportIEs__value_PR_RoutingID; + ie->value.choice.RoutingID.buf = msg->routing_id.buf; + ie->value.choice.RoutingID.size = msg->routing_id.len; + } + + // IE: 9.3.3.14 NRPPa-PDU (mandatory) + { + asn1cSequenceAdd(out->protocolIEs.list, NGAP_UplinkUEAssociatedNRPPaTransportIEs_t, ie); + ie->id = NGAP_ProtocolIE_ID_id_NRPPa_PDU; + ie->criticality = NGAP_Criticality_reject; + ie->value.present = NGAP_UplinkUEAssociatedNRPPaTransportIEs__value_PR_NRPPa_PDU; + ie->value.choice.NRPPa_PDU.buf = msg->nrppa_pdu.buf; + ie->value.choice.NRPPa_PDU.size = msg->nrppa_pdu.len; + } + + // Encode NGAP message + uint8_t *buffer = NULL; + uint32_t length = 0; + if (ngap_gNB_encode_pdu(&pdu, &buffer, &length) < 0) { + LOG_E(NGAP, "Failed to encode Uplink UE Associated NRPPa Transport\n"); + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NGAP_NGAP_PDU, &pdu); + return -1; + } + LOG_I(NGAP, "Sending ngap_gNB_uplink_ue_associated_nrppa_transport over SCTP\n"); + + // UE associated signalling -> use the allocated stream + ngap_gNB_itti_send_sctp_data_req(ngap_gNB_instance_p->instance, + ue_context_p->amf_ref->assoc_id, + buffer, + length, + ue_context_p->tx_stream); + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NGAP_NGAP_PDU, &pdu); + return 0; +} diff --git a/openair3/NGAP/ngap_gNB_NRPPa_transport_procedures.h b/openair3/NGAP/ngap_gNB_NRPPa_transport_procedures.h new file mode 100644 index 0000000000..ed136bfce8 --- /dev/null +++ b/openair3/NGAP/ngap_gNB_NRPPa_transport_procedures.h @@ -0,0 +1,28 @@ +/* + * 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 NGAP_GNB_NRPPA_PROCEDURES_H_ +#define NGAP_GNB_NRPPA_PROCEDURES_H_ + +// UPLINK UE ASSOCIATED NRPPA TRANSPORT (9.2.9.2 of TS 38.413 Version 16.0.0) +int ngap_gNB_uplink_ue_associated_nrppa_transport(instance_t instance, const ngap_uplink_ue_associated_nrppa_t *msg); + +#endif /* NGAP_GNB_NRPPA_PROCEDURES_H_ */ From e832424240bd7ddc6dce0e6aead4e73ff50cdc8c Mon Sep 17 00:00:00 2001 From: Rakesh Mundlamuri Date: Mon, 29 Dec 2025 17:01:15 +0530 Subject: [PATCH 09/44] Add NGAP UPLINK NON UE ASSOCIATED NRPPA TRANSPORT message encoding Reference: 3GPP 38.413 v16.0.0 Mandatory fields: Routing ID (supported) NRPPa-PDU (supported) --- openair2/COMMON/ngap_messages_types.h | 8 +++ .../ngap_gNB_NRPPa_transport_procedures.c | 67 +++++++++++++++++++ .../ngap_gNB_NRPPa_transport_procedures.h | 3 + 3 files changed, 78 insertions(+) diff --git a/openair2/COMMON/ngap_messages_types.h b/openair2/COMMON/ngap_messages_types.h index e40c1059d0..c47a564acb 100644 --- a/openair2/COMMON/ngap_messages_types.h +++ b/openair2/COMMON/ngap_messages_types.h @@ -1019,4 +1019,12 @@ typedef struct { byte_array_t nrppa_pdu; } ngap_uplink_ue_associated_nrppa_t; +// Uplink NON UE Associated NRPPA Transport message (9.2.9.4 3GPP 38.413 v16.0.0) +typedef struct { + // Routing ID (Mandatory) + byte_array_t routing_id; + // NRPPa pdu (Mandatory) + byte_array_t nrppa_pdu; +} ngap_uplink_non_ue_associated_nrppa_t; + #endif /* NGAP_MESSAGES_TYPES_H_ */ diff --git a/openair3/NGAP/ngap_gNB_NRPPa_transport_procedures.c b/openair3/NGAP/ngap_gNB_NRPPa_transport_procedures.c index d799057ca5..56a85be44c 100644 --- a/openair3/NGAP/ngap_gNB_NRPPa_transport_procedures.c +++ b/openair3/NGAP/ngap_gNB_NRPPa_transport_procedures.c @@ -127,3 +127,70 @@ int ngap_gNB_uplink_ue_associated_nrppa_transport(instance_t instance, const nga ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NGAP_NGAP_PDU, &pdu); return 0; } + +// UPLINK NON UE ASSOCIATED NRPPA TRANSPORT (9.2.9.4 of TS 38.413 Version 16.0.0) +int ngap_gNB_uplink_non_ue_associated_nrppa_transport(instance_t instance, const ngap_uplink_non_ue_associated_nrppa_t *msg) +{ + LOG_I(NGAP, "ngap_gNB_uplink_non_ue_associated_nrppa_transport\n"); + DevAssert(msg != NULL); + DevAssert(msg->routing_id.buf); + DevAssert(msg->routing_id.len); + DevAssert(msg->nrppa_pdu.buf); + DevAssert(msg->nrppa_pdu.len); + + // Retrieve the NGAP gNB instance associated with Mod_id + ngap_gNB_instance_t *ngap_gNB_instance_p = NULL; + ngap_gNB_instance_p = ngap_gNB_get_instance(instance); + DevAssert(ngap_gNB_instance_p != NULL); + + // Retrieve the NGAP gNB amf data + ngap_gNB_amf_data_t *amf_desc_p = NULL; + amf_desc_p = ngap_gNB_get_AMF_from_instance(ngap_gNB_instance_p); + DevAssert(amf_desc_p != NULL); + + // Prepare the NGAP message to encode + NGAP_NGAP_PDU_t pdu = {0}; + + // IE: 9.3.1.1 Message Type UplinkNonUEAssociatedNRPPaTransport + pdu.present = NGAP_NGAP_PDU_PR_initiatingMessage; + asn1cCalloc(pdu.choice.initiatingMessage, head); + head->procedureCode = NGAP_ProcedureCode_id_UplinkNonUEAssociatedNRPPaTransport; + head->criticality = NGAP_Criticality_ignore; + head->value.present = NGAP_InitiatingMessage__value_PR_UplinkNonUEAssociatedNRPPaTransport; + NGAP_UplinkNonUEAssociatedNRPPaTransport_t *out = &head->value.choice.UplinkNonUEAssociatedNRPPaTransport; + + // IE: 9.3.3.13 Routing ID (mandatory) + { + asn1cSequenceAdd(out->protocolIEs.list, NGAP_UplinkNonUEAssociatedNRPPaTransportIEs_t, ie); + ie->id = NGAP_ProtocolIE_ID_id_RoutingID; + ie->criticality = NGAP_Criticality_reject; + ie->value.present = NGAP_UplinkNonUEAssociatedNRPPaTransportIEs__value_PR_RoutingID; + ie->value.choice.RoutingID.buf = msg->routing_id.buf; + ie->value.choice.RoutingID.size = msg->routing_id.len; + } + + // IE: 9.3.3.14 NRPPa-PDU (mandatory) + { + asn1cSequenceAdd(out->protocolIEs.list, NGAP_UplinkNonUEAssociatedNRPPaTransportIEs_t, ie); + ie->id = NGAP_ProtocolIE_ID_id_NRPPa_PDU; + ie->criticality = NGAP_Criticality_reject; + ie->value.present = NGAP_UplinkNonUEAssociatedNRPPaTransportIEs__value_PR_NRPPa_PDU; + ie->value.choice.NRPPa_PDU.buf = msg->nrppa_pdu.buf; + ie->value.choice.NRPPa_PDU.size = msg->nrppa_pdu.len; + } + + // Encode NGAP message + uint8_t *buffer = NULL; + uint32_t length = 0; + if (ngap_gNB_encode_pdu(&pdu, &buffer, &length) < 0) { + LOG_E(NGAP, "Failed to encode Uplink Non UE Associated NRPPa Transport\n"); + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NGAP_NGAP_PDU, &pdu); + return -1; + } + + // Non UE-Associated signalling -> stream = 0 + LOG_I(NGAP, "Sending ngap_gNB_uplink_non_ue_associated_nrppa_transport over SCTP (assoc_id %d)\n", amf_desc_p->assoc_id); + ngap_gNB_itti_send_sctp_data_req(ngap_gNB_instance_p->instance, amf_desc_p->assoc_id, buffer, length, 0); + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NGAP_NGAP_PDU, &pdu); + return 0; +} diff --git a/openair3/NGAP/ngap_gNB_NRPPa_transport_procedures.h b/openair3/NGAP/ngap_gNB_NRPPa_transport_procedures.h index ed136bfce8..2624bee0a4 100644 --- a/openair3/NGAP/ngap_gNB_NRPPa_transport_procedures.h +++ b/openair3/NGAP/ngap_gNB_NRPPa_transport_procedures.h @@ -25,4 +25,7 @@ // UPLINK UE ASSOCIATED NRPPA TRANSPORT (9.2.9.2 of TS 38.413 Version 16.0.0) int ngap_gNB_uplink_ue_associated_nrppa_transport(instance_t instance, const ngap_uplink_ue_associated_nrppa_t *msg); +// UPLINK NON UE ASSOCIATED NRPPA TRANSPORT (9.2.9.4 of TS 38.413 Version 16.0.0) +int ngap_gNB_uplink_non_ue_associated_nrppa_transport(instance_t instance, const ngap_uplink_non_ue_associated_nrppa_t *msg); + #endif /* NGAP_GNB_NRPPA_PROCEDURES_H_ */ From d4c0431cc7e020ed06383451181d39288692a480 Mon Sep 17 00:00:00 2001 From: Rakesh Mundlamuri Date: Mon, 29 Dec 2025 18:22:46 +0530 Subject: [PATCH 10/44] Add NGAP DOWNLINK UE ASSOCIATED NRPPA TRANSPORT message decoding Reference: 3GPP 38.413 v16.0.0 Mandatory fields: AMF UE NGAP ID (supported) RAN UE NGAP ID (supported) Routing ID (supported) NRPPa-PDU (supported) --- common/utils/ocp_itti/intertask_interface.h | 1 + openair2/COMMON/ngap_messages_def.h | 6 ++ openair2/COMMON/ngap_messages_types.h | 13 +++ .../ngap_gNB_NRPPa_transport_procedures.c | 81 +++++++++++++++++++ .../ngap_gNB_NRPPa_transport_procedures.h | 3 + 5 files changed, 104 insertions(+) diff --git a/common/utils/ocp_itti/intertask_interface.h b/common/utils/ocp_itti/intertask_interface.h index d23e62365d..7580698dcf 100644 --- a/common/utils/ocp_itti/intertask_interface.h +++ b/common/utils/ocp_itti/intertask_interface.h @@ -294,6 +294,7 @@ typedef struct { TASK_DEF(TASK_RAL_ENB, 200) \ TASK_DEF(TASK_S1AP, 200) \ TASK_DEF(TASK_NGAP, 200) \ + TASK_DEF(TASK_NRPPA, 200) \ TASK_DEF(TASK_X2AP, 200) \ TASK_DEF(TASK_M2AP_ENB, 200) \ TASK_DEF(TASK_M2AP_MCE, 200) \ diff --git a/openair2/COMMON/ngap_messages_def.h b/openair2/COMMON/ngap_messages_def.h index 09e893f874..95d29baab2 100644 --- a/openair2/COMMON/ngap_messages_def.h +++ b/openair2/COMMON/ngap_messages_def.h @@ -88,3 +88,9 @@ MESSAGE_DEF(NGAP_HANDOVER_CANCEL_ACK, MESSAGE_PRIORITY_MED, ngap_handover_cancel /* NGAP <-> RRC messages (can be initiated either by MME or gNB) */ MESSAGE_DEF(NGAP_UE_CONTEXT_RELEASE_REQ , MESSAGE_PRIORITY_MED, ngap_ue_release_req_t , ngap_ue_release_req) + +/* NGAP -> NRPPA messages*/ +MESSAGE_DEF(NGAP_DOWNLINKUEASSOCIATEDNRPPA, + MESSAGE_PRIORITY_MED, + ngap_downlink_ue_associated_nrppa_t, + ngap_downlink_ue_associated_nrppa) diff --git a/openair2/COMMON/ngap_messages_types.h b/openair2/COMMON/ngap_messages_types.h index c47a564acb..b33cb34b09 100644 --- a/openair2/COMMON/ngap_messages_types.h +++ b/openair2/COMMON/ngap_messages_types.h @@ -79,6 +79,7 @@ #define NGAP_UL_RAN_STATUS_TRANSFER(mSGpTR) (mSGpTR)->ittiMsg.ngap_ul_ran_status_transfer #define NGAP_DL_RAN_STATUS_TRANSFER(mSGpTR) (mSGpTR)->ittiMsg.ngap_dl_ran_status_transfer +#define NGAP_DOWNLINKUEASSOCIATEDNRPPA(mSGpTR) (mSGpTR)->ittiMsg.ngap_downlink_ue_associated_nrppa //-------------------------------------------------------------------------------------------// /* Length of the transport layer address string @@ -1027,4 +1028,16 @@ typedef struct { byte_array_t nrppa_pdu; } ngap_uplink_non_ue_associated_nrppa_t; +// Downlink UE Associated NRPPA Transport message (9.2.9.1 3GPP 38.413 v16.0.0) +typedef struct { + // AMF UE NGAP ID (Mandatory) + uint64_t amf_ue_ngap_id; + // RAN UE NGAP ID (Mandatory) + uint32_t gNB_ue_ngap_id; + // Routing ID (Mandatory) + byte_array_t routing_id; + // NRPPa pdu (Mandatory) + byte_array_t nrppa_pdu; +} ngap_downlink_ue_associated_nrppa_t; + #endif /* NGAP_MESSAGES_TYPES_H_ */ diff --git a/openair3/NGAP/ngap_gNB_NRPPa_transport_procedures.c b/openair3/NGAP/ngap_gNB_NRPPa_transport_procedures.c index 56a85be44c..67b1db1578 100644 --- a/openair3/NGAP/ngap_gNB_NRPPa_transport_procedures.c +++ b/openair3/NGAP/ngap_gNB_NRPPa_transport_procedures.c @@ -194,3 +194,84 @@ int ngap_gNB_uplink_non_ue_associated_nrppa_transport(instance_t instance, const ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NGAP_NGAP_PDU, &pdu); return 0; } + +// handle DOWNLINK UE ASSOCIATED NRPPA TRANSPORT (9.2.9.1 of TS 38.413 Version 16.0.0) +int ngap_gNB_handle_downlink_ue_associated_nrppa_transport(sctp_assoc_t assoc_id, uint32_t stream, NGAP_NGAP_PDU_t *pdu) +{ + DevAssert(pdu != NULL); + ngap_gNB_amf_data_t *amf_desc_p = NULL; + + if ((amf_desc_p = ngap_gNB_get_AMF(NULL, assoc_id, 0)) == NULL) { + NGAP_ERROR("[SCTP %d] Received NRPPa downlink message for non existing AMF context\n", assoc_id); + return -1; + } + + ngap_gNB_instance_t *ngap_gNB_instance = NULL; + ngap_gNB_instance = amf_desc_p->ngap_gNB_instance; + + // Prepare the NGAP message for NRPPA + NGAP_DownlinkUEAssociatedNRPPaTransport_t *container = NULL; + NGAP_DownlinkUEAssociatedNRPPaTransportIEs_t *ie = NULL; + + // IE: 9.3.1.1 Message Type + container = &pdu->choice.initiatingMessage->value.choice.DownlinkUEAssociatedNRPPaTransport; + + // IE: 9.3.3.1 AMF UE NGAP ID + uint64_t amf_ue_ngap_id; + NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_DownlinkUEAssociatedNRPPaTransportIEs_t, + ie, + container, + NGAP_ProtocolIE_ID_id_AMF_UE_NGAP_ID, + true); + asn_INTEGER2ulong(&(ie->value.choice.AMF_UE_NGAP_ID), &amf_ue_ngap_id); + + // IE: 9.3.3.2 RAN UE NGAP ID + NGAP_RAN_UE_NGAP_ID_t gnb_ue_ngap_id; + NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_DownlinkUEAssociatedNRPPaTransportIEs_t, + ie, + container, + NGAP_ProtocolIE_ID_id_RAN_UE_NGAP_ID, + true); + gnb_ue_ngap_id = ie->value.choice.RAN_UE_NGAP_ID; + + ngap_gNB_ue_context_t *ue_desc_p = NULL; + if ((ue_desc_p = ngap_get_ue_context(gnb_ue_ngap_id)) == NULL) { + NGAP_ERROR("[SCTP %d] Received NRPPa downlink message for non existing UE context gNB_UE_NGAP_ID: 0x%lx\n", + assoc_id, + gnb_ue_ngap_id); + return -1; + } + + // Is it the first outcome of the AMF for this UE ? If so store the amf UE ngap id + if (ue_desc_p->amf_ue_ngap_id == 0) { + ue_desc_p->amf_ue_ngap_id = amf_ue_ngap_id; + } else { + // We already have a amf ue ngap id check the received is the same + if (ue_desc_p->amf_ue_ngap_id != amf_ue_ngap_id) { + NGAP_ERROR("[SCTP %d] Mismatch in AMF UE NGAP ID (0x%lx != 0x%" PRIx64 "\n", + assoc_id, + amf_ue_ngap_id, + (uint64_t)ue_desc_p->amf_ue_ngap_id); + return -1; + } + } + + MessageDef *msg = itti_alloc_new_message(TASK_NGAP, 0, NGAP_DOWNLINKUEASSOCIATEDNRPPA); + ngap_downlink_ue_associated_nrppa_t *dl_ue_assoc_nrppa = &NGAP_DOWNLINKUEASSOCIATEDNRPPA(msg); + + dl_ue_assoc_nrppa->amf_ue_ngap_id = amf_ue_ngap_id; + dl_ue_assoc_nrppa->gNB_ue_ngap_id = gnb_ue_ngap_id; + + // IE: 9.3.3.13 Routing ID + NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_DownlinkUEAssociatedNRPPaTransportIEs_t, ie, container, NGAP_ProtocolIE_ID_id_RoutingID, true); + dl_ue_assoc_nrppa->routing_id = create_byte_array(ie->value.choice.RoutingID.size, ie->value.choice.RoutingID.buf); + + // IE: 9.3.3.14 NRPPa-PDU + NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_DownlinkUEAssociatedNRPPaTransportIEs_t, ie, container, NGAP_ProtocolIE_ID_id_NRPPa_PDU, true); + dl_ue_assoc_nrppa->nrppa_pdu = create_byte_array(ie->value.choice.NRPPa_PDU.size, ie->value.choice.NRPPa_PDU.buf); + + // Forward the NRPPA PDU to NRPPA + itti_send_msg_to_task(TASK_NRPPA, ngap_gNB_instance->instance, msg); + + return 0; +} diff --git a/openair3/NGAP/ngap_gNB_NRPPa_transport_procedures.h b/openair3/NGAP/ngap_gNB_NRPPa_transport_procedures.h index 2624bee0a4..c045ce31aa 100644 --- a/openair3/NGAP/ngap_gNB_NRPPa_transport_procedures.h +++ b/openair3/NGAP/ngap_gNB_NRPPa_transport_procedures.h @@ -28,4 +28,7 @@ int ngap_gNB_uplink_ue_associated_nrppa_transport(instance_t instance, const nga // UPLINK NON UE ASSOCIATED NRPPA TRANSPORT (9.2.9.4 of TS 38.413 Version 16.0.0) int ngap_gNB_uplink_non_ue_associated_nrppa_transport(instance_t instance, const ngap_uplink_non_ue_associated_nrppa_t *msg); +// DOWNLINK UE ASSOCIATED NRPPA TRANSPORT (9.2.9.1 of TS 38.413 Version 16.0.0) +int ngap_gNB_handle_downlink_ue_associated_nrppa_transport(sctp_assoc_t assoc_id, uint32_t stream, NGAP_NGAP_PDU_t *pdu); + #endif /* NGAP_GNB_NRPPA_PROCEDURES_H_ */ From 040b25bf008b85564c38866480e0c3af9f8e3617 Mon Sep 17 00:00:00 2001 From: Rakesh Mundlamuri Date: Mon, 29 Dec 2025 18:51:08 +0530 Subject: [PATCH 11/44] Add NGAP DOWNLINK NON UE ASSOCIATED NRPPA TRANSPORT message decoding Reference: 3GPP 38.413 v16.0.0 Mandatory fields: Routing ID (supported) NRPPa-PDU (supported) --- openair2/COMMON/ngap_messages_def.h | 4 ++ openair2/COMMON/ngap_messages_types.h | 9 +++++ .../ngap_gNB_NRPPa_transport_procedures.c | 37 +++++++++++++++++++ .../ngap_gNB_NRPPa_transport_procedures.h | 3 ++ 4 files changed, 53 insertions(+) diff --git a/openair2/COMMON/ngap_messages_def.h b/openair2/COMMON/ngap_messages_def.h index 95d29baab2..a82b3cb849 100644 --- a/openair2/COMMON/ngap_messages_def.h +++ b/openair2/COMMON/ngap_messages_def.h @@ -94,3 +94,7 @@ MESSAGE_DEF(NGAP_DOWNLINKUEASSOCIATEDNRPPA, MESSAGE_PRIORITY_MED, ngap_downlink_ue_associated_nrppa_t, ngap_downlink_ue_associated_nrppa) +MESSAGE_DEF(NGAP_DOWNLINKNONUEASSOCIATEDNRPPA, + MESSAGE_PRIORITY_MED, + ngap_downlink_non_ue_associated_nrppa_t, + ngap_downlink_non_ue_associated_nrppa) diff --git a/openair2/COMMON/ngap_messages_types.h b/openair2/COMMON/ngap_messages_types.h index b33cb34b09..e05f44f0b5 100644 --- a/openair2/COMMON/ngap_messages_types.h +++ b/openair2/COMMON/ngap_messages_types.h @@ -80,6 +80,7 @@ #define NGAP_DL_RAN_STATUS_TRANSFER(mSGpTR) (mSGpTR)->ittiMsg.ngap_dl_ran_status_transfer #define NGAP_DOWNLINKUEASSOCIATEDNRPPA(mSGpTR) (mSGpTR)->ittiMsg.ngap_downlink_ue_associated_nrppa +#define NGAP_DOWNLINKNONUEASSOCIATEDNRPPA(mSGpTR) (mSGpTR)->ittiMsg.ngap_downlink_non_ue_associated_nrppa //-------------------------------------------------------------------------------------------// /* Length of the transport layer address string @@ -1040,4 +1041,12 @@ typedef struct { byte_array_t nrppa_pdu; } ngap_downlink_ue_associated_nrppa_t; +// Downlink NON UE Associated NRPPA Transport message (9.2.9.3 3GPP 38.413 v16.0.0) +typedef struct { + // Routing ID (Mandatory) + byte_array_t routing_id; + // NRPPa pdu (Mandatory) + byte_array_t nrppa_pdu; +} ngap_downlink_non_ue_associated_nrppa_t; + #endif /* NGAP_MESSAGES_TYPES_H_ */ diff --git a/openair3/NGAP/ngap_gNB_NRPPa_transport_procedures.c b/openair3/NGAP/ngap_gNB_NRPPa_transport_procedures.c index 67b1db1578..37b5e3b344 100644 --- a/openair3/NGAP/ngap_gNB_NRPPa_transport_procedures.c +++ b/openair3/NGAP/ngap_gNB_NRPPa_transport_procedures.c @@ -275,3 +275,40 @@ int ngap_gNB_handle_downlink_ue_associated_nrppa_transport(sctp_assoc_t assoc_id return 0; } + +// handle DOWNLINK NON UE ASSOCIATED NRPPA TRANSPORT (9.2.9.3 of TS 38.413 Version 16.0.0) +int ngap_gNB_handle_downlink_non_ue_associated_nrppa_transport(sctp_assoc_t assoc_id, uint32_t stream, NGAP_NGAP_PDU_t *pdu) +{ + DevAssert(pdu != NULL); + ngap_gNB_amf_data_t *amf_desc_p = NULL; + + if ((amf_desc_p = ngap_gNB_get_AMF(NULL, assoc_id, 0)) == NULL) { + NGAP_ERROR("[SCTP %d] Received NRPPa downlink message for non existing AMF context\n", assoc_id); + return -1; + } + + ngap_gNB_instance_t *ngap_gNB_instance = NULL; + ngap_gNB_instance = amf_desc_p->ngap_gNB_instance; + + MessageDef *msg = itti_alloc_new_message(TASK_NGAP, 0, NGAP_DOWNLINKNONUEASSOCIATEDNRPPA); + ngap_downlink_non_ue_associated_nrppa_t *dl_non_ue_assoc_nrppa = &NGAP_DOWNLINKNONUEASSOCIATEDNRPPA(msg); + + // Prepare the NGAP message to forward to NRPPA + NGAP_DownlinkNonUEAssociatedNRPPaTransport_t *container; + NGAP_DownlinkNonUEAssociatedNRPPaTransportIEs_t *ie; + + // IE: 9.3.1.1 Message Type + container = &pdu->choice.initiatingMessage->value.choice.DownlinkNonUEAssociatedNRPPaTransport; + + // IE: 9.3.3.13 Routing ID + NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_DownlinkNonUEAssociatedNRPPaTransportIEs_t, ie, container, NGAP_ProtocolIE_ID_id_RoutingID, true); + dl_non_ue_assoc_nrppa->routing_id = create_byte_array(ie->value.choice.RoutingID.size, ie->value.choice.RoutingID.buf); + + // IE: 9.3.3.14 NRPPa-PDU + NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_DownlinkNonUEAssociatedNRPPaTransportIEs_t, ie, container, NGAP_ProtocolIE_ID_id_NRPPa_PDU, true); + dl_non_ue_assoc_nrppa->nrppa_pdu = create_byte_array(ie->value.choice.NRPPa_PDU.size, ie->value.choice.NRPPa_PDU.buf); + + itti_send_msg_to_task(TASK_NRPPA, ngap_gNB_instance->instance, msg); + + return 0; +} diff --git a/openair3/NGAP/ngap_gNB_NRPPa_transport_procedures.h b/openair3/NGAP/ngap_gNB_NRPPa_transport_procedures.h index c045ce31aa..a180888029 100644 --- a/openair3/NGAP/ngap_gNB_NRPPa_transport_procedures.h +++ b/openair3/NGAP/ngap_gNB_NRPPa_transport_procedures.h @@ -31,4 +31,7 @@ int ngap_gNB_uplink_non_ue_associated_nrppa_transport(instance_t instance, const // DOWNLINK UE ASSOCIATED NRPPA TRANSPORT (9.2.9.1 of TS 38.413 Version 16.0.0) int ngap_gNB_handle_downlink_ue_associated_nrppa_transport(sctp_assoc_t assoc_id, uint32_t stream, NGAP_NGAP_PDU_t *pdu); +// DOWNLINK UE ASSOCIATED NRPPA TRANSPORT (9.2.9.3 of TS 38.413 Version 16.0.0) +int ngap_gNB_handle_downlink_non_ue_associated_nrppa_transport(sctp_assoc_t assoc_id, uint32_t stream, NGAP_NGAP_PDU_t *pdu); + #endif /* NGAP_GNB_NRPPA_PROCEDURES_H_ */ From 2cfff7520f19a0204b691234009b7484fa01c9e2 Mon Sep 17 00:00:00 2001 From: Rakesh Mundlamuri Date: Mon, 29 Dec 2025 19:40:20 +0530 Subject: [PATCH 12/44] Add NGAP encoding procedures of Uplink NRPPA Transport procedures --- openair2/COMMON/ngap_messages_def.h | 5 +++++ openair2/COMMON/ngap_messages_types.h | 3 +++ openair3/NGAP/ngap_gNB.c | 9 +++++++++ openair3/NGAP/ngap_gNB_encoder.c | 4 +++- 4 files changed, 20 insertions(+), 1 deletion(-) diff --git a/openair2/COMMON/ngap_messages_def.h b/openair2/COMMON/ngap_messages_def.h index a82b3cb849..648bd565f3 100644 --- a/openair2/COMMON/ngap_messages_def.h +++ b/openair2/COMMON/ngap_messages_def.h @@ -98,3 +98,8 @@ MESSAGE_DEF(NGAP_DOWNLINKNONUEASSOCIATEDNRPPA, MESSAGE_PRIORITY_MED, ngap_downlink_non_ue_associated_nrppa_t, ngap_downlink_non_ue_associated_nrppa) +MESSAGE_DEF(NGAP_UPLINKUEASSOCIATEDNRPPA, MESSAGE_PRIORITY_MED, ngap_uplink_ue_associated_nrppa_t, ngap_uplink_ue_associated_nrppa) +MESSAGE_DEF(NGAP_UPLINKNONUEASSOCIATEDNRPPA, + MESSAGE_PRIORITY_MED, + ngap_uplink_non_ue_associated_nrppa_t, + ngap_uplink_non_ue_associated_nrppa) diff --git a/openair2/COMMON/ngap_messages_types.h b/openair2/COMMON/ngap_messages_types.h index e05f44f0b5..85d61bba39 100644 --- a/openair2/COMMON/ngap_messages_types.h +++ b/openair2/COMMON/ngap_messages_types.h @@ -81,6 +81,9 @@ #define NGAP_DOWNLINKUEASSOCIATEDNRPPA(mSGpTR) (mSGpTR)->ittiMsg.ngap_downlink_ue_associated_nrppa #define NGAP_DOWNLINKNONUEASSOCIATEDNRPPA(mSGpTR) (mSGpTR)->ittiMsg.ngap_downlink_non_ue_associated_nrppa + +#define NGAP_UPLINKUEASSOCIATEDNRPPA(mSGpTR) (mSGpTR)->ittiMsg.ngap_uplink_ue_associated_nrppa +#define NGAP_UPLINKNONUEASSOCIATEDNRPPA(mSGpTR) (mSGpTR)->ittiMsg.ngap_uplink_non_ue_associated_nrppa //-------------------------------------------------------------------------------------------// /* Length of the transport layer address string diff --git a/openair3/NGAP/ngap_gNB.c b/openair3/NGAP/ngap_gNB.c index 257ca25f1a..c9da148eea 100644 --- a/openair3/NGAP/ngap_gNB.c +++ b/openair3/NGAP/ngap_gNB.c @@ -58,6 +58,7 @@ #include "ngap_gNB_mobility_management.h" #include "ngap_gNB_ue_context.h" #include "ngap_gNB_pdu_session_management.h" +#include "ngap_gNB_NRPPa_transport_procedures.h" #include "oai_asn1.h" #include "openair3/SECU/kdf.h" #include "queue.h" @@ -626,6 +627,14 @@ void *ngap_gNB_process_itti_msg(void *notUsed) { ngap_gNB_handle_ul_ran_status_transfer(instance, &NGAP_UL_RAN_STATUS_TRANSFER(received_msg)); break; + case NGAP_UPLINKUEASSOCIATEDNRPPA: + ngap_gNB_uplink_ue_associated_nrppa_transport(instance, &NGAP_UPLINKUEASSOCIATEDNRPPA(received_msg)); + break; + + case NGAP_UPLINKNONUEASSOCIATEDNRPPA: + ngap_gNB_uplink_non_ue_associated_nrppa_transport(instance, &NGAP_UPLINKNONUEASSOCIATEDNRPPA(received_msg)); + break; + default: NGAP_ERROR("Received unhandled message: %d:%s\n", ITTI_MSG_ID(received_msg), ITTI_MSG_NAME(received_msg)); break; diff --git a/openair3/NGAP/ngap_gNB_encoder.c b/openair3/NGAP/ngap_gNB_encoder.c index ff318ed184..801ce95d42 100644 --- a/openair3/NGAP/ngap_gNB_encoder.c +++ b/openair3/NGAP/ngap_gNB_encoder.c @@ -56,7 +56,9 @@ static inline int ngap_gNB_encode_initiating(NGAP_NGAP_PDU_t *pdu, uint8_t **buf NGAP_ProcedureCode_id_UplinkRANStatusTransfer, NGAP_ProcedureCode_id_HandoverPreparation, NGAP_ProcedureCode_id_HandoverCancel, - NGAP_ProcedureCode_id_HandoverNotification}; + NGAP_ProcedureCode_id_HandoverNotification, + NGAP_ProcedureCode_id_UplinkUEAssociatedNRPPaTransport, + NGAP_ProcedureCode_id_UplinkNonUEAssociatedNRPPaTransport}; int i; for (i = 0; i < sizeofArray(tmp); i++) if (pdu->choice.initiatingMessage->procedureCode == tmp[i]) From 6eceaacb731a79d0464f59400aad834e2a8a578d Mon Sep 17 00:00:00 2001 From: Rakesh Mundlamuri Date: Mon, 29 Dec 2025 19:51:53 +0530 Subject: [PATCH 13/44] Add NGAP decoding procedures of Downlink NRPPA Transport procedures --- openair3/NGAP/ngap_gNB_decoder.c | 12 ++++++++++++ openair3/NGAP/ngap_gNB_handlers.c | 5 +++-- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/openair3/NGAP/ngap_gNB_decoder.c b/openair3/NGAP/ngap_gNB_decoder.c index 43110e9037..3993f8aa72 100644 --- a/openair3/NGAP/ngap_gNB_decoder.c +++ b/openair3/NGAP/ngap_gNB_decoder.c @@ -112,6 +112,18 @@ static int ngap_gNB_decode_initiating_message(NGAP_NGAP_PDU_t *pdu) { NGAP_INFO("DL RAN Status Transfer initiating message\n"); break; + case NGAP_ProcedureCode_id_DownlinkUEAssociatedNRPPaTransport: + res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_NGAP_NGAP_PDU, pdu); + free(res.buffer); + NGAP_INFO("DL UE Associated NRPPA Transport initiating message\n"); + break; + + case NGAP_ProcedureCode_id_DownlinkNonUEAssociatedNRPPaTransport: + res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_NGAP_NGAP_PDU, pdu); + free(res.buffer); + NGAP_INFO("DL NON UE Associated NRPPA Transport initiating message\n"); + break; + default: NGAP_ERROR("Unknown procedure ID (%d) for initiating message\n", (int)pdu->choice.initiatingMessage->procedureCode); diff --git a/openair3/NGAP/ngap_gNB_handlers.c b/openair3/NGAP/ngap_gNB_handlers.c index 9113f850ca..3dd9c39db3 100644 --- a/openair3/NGAP/ngap_gNB_handlers.c +++ b/openair3/NGAP/ngap_gNB_handlers.c @@ -50,6 +50,7 @@ #include "ngap_gNB_pdu_session_management.h" #include "ngap_gNB_nas_procedures.h" #include "ngap_gNB_paging.h" +#include "ngap_gNB_NRPPa_transport_procedures.h" #include "ngap_gNB_trace.h" #include "ngap_gNB_ue_context.h" #include "ngap_messages_types.h" @@ -1499,10 +1500,10 @@ const ngap_message_decoded_callback ngap_messages_callback[][3] = { {0, 0, 0}, /* CellTrafficTrace */ {ngap_gNB_handle_deactivate_trace, 0, 0}, /* DeactivateTrace */ {ngap_gNB_handle_nas_downlink, 0, 0}, /* DownlinkNASTransport */ - {0, 0, 0}, /* DownlinkNonUEAssociatedNRPPaTransport */ + {ngap_gNB_handle_downlink_non_ue_associated_nrppa_transport, 0, 0}, /* DownlinkNonUEAssociatedNRPPaTransport */ {0, 0, 0}, /* DownlinkRANConfigurationTransfer */ {ngap_gNB_handle_dl_ran_status_transfer, 0, 0}, /* DownlinkRANStatusTransfer */ - {0, 0, 0}, /* DownlinkUEAssociatedNRPPaTransport */ + {ngap_gNB_handle_downlink_ue_associated_nrppa_transport, 0, 0}, /* DownlinkUEAssociatedNRPPaTransport */ {ngap_gNB_handle_error_indication, 0, 0}, /* ErrorIndication */ {0, ngap_gNB_handle_handover_cancel_ack, 0}, /* HandoverCancel */ {0, 0, 0}, /* HandoverNotification */ From b07dc35c922d1ffd3a035d47f563216d65efbab4 Mon Sep 17 00:00:00 2001 From: francescomani Date: Fri, 27 Feb 2026 13:27:54 +0100 Subject: [PATCH 14/44] fix some of the unused function arguments (found using -Wunused-parameter) --- executables/nr-gnb.c | 8 +- executables/nr-ue.c | 2 +- openair1/PHY/INIT/nr_init_ue.c | 2 +- openair1/PHY/INIT/nr_phy_init.h | 2 +- .../NR_ESTIMATION/nr_ul_channel_estimation.c | 5 +- openair1/PHY/NR_REFSIG/nr_dmrs_rx.c | 3 - openair1/PHY/NR_REFSIG/nr_refsig.h | 3 - openair1/PHY/NR_REFSIG/ptrs_nr.c | 2 - openair1/PHY/NR_REFSIG/ptrs_nr.h | 2 - openair1/PHY/NR_TRANSPORT/nr_dlsch.c | 4 - openair1/PHY/NR_TRANSPORT/nr_dlsch.h | 1 - openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c | 1 - openair1/PHY/NR_TRANSPORT/nr_prs.c | 7 +- .../PHY/NR_TRANSPORT/nr_transport_proto.h | 8 +- openair1/PHY/NR_TRANSPORT/pucch_rx.c | 64 --------- openair1/PHY/NR_TRANSPORT/srs_rx.c | 1 - .../PHY/NR_UE_ESTIMATION/nr_adjust_synch_ue.c | 1 - .../nr_dl_channel_estimation.c | 8 +- openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h | 6 +- .../PHY/NR_UE_ESTIMATION/nr_ue_measurements.c | 5 +- openair1/PHY/NR_UE_TRANSPORT/csi_rx.c | 3 +- openair1/PHY/NR_UE_TRANSPORT/dci_nr.c | 127 ++++++++---------- .../NR_UE_TRANSPORT/nr_dlsch_demodulation.c | 10 +- .../PHY/NR_UE_TRANSPORT/nr_initial_sync.c | 3 +- .../PHY/NR_UE_TRANSPORT/nr_initial_sync_sl.c | 5 +- .../NR_UE_TRANSPORT/nr_transport_proto_ue.h | 4 +- .../PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c | 3 +- openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c | 9 +- openair1/PHY/NR_UE_TRANSPORT/pucch_nr.c | 12 +- openair1/PHY/NR_UE_TRANSPORT/pucch_nr.h | 12 +- openair1/PHY/NR_UE_TRANSPORT/sss_nr.c | 5 +- openair1/SCHED_NR/phy_procedures_nr_gNB.c | 17 +-- openair1/SCHED_NR/sched_nr.h | 3 +- openair1/SCHED_NR_UE/defs.h | 1 - openair1/SCHED_NR_UE/phy_procedures_nr_ue.c | 3 +- .../SCHED_NR_UE/phy_procedures_nr_ue_sl.c | 5 +- openair1/SCHED_NR_UE/pucch_uci_ue_nr.c | 8 +- openair1/SIMULATION/NR_PHY/dlschsim.c | 4 +- openair1/SIMULATION/NR_PHY/dlsim.c | 2 +- openair1/SIMULATION/NR_PHY/pbchsim.c | 4 +- openair1/SIMULATION/NR_PHY/prachsim.c | 2 +- openair1/SIMULATION/NR_PHY/psbchsim.c | 4 +- openair1/SIMULATION/NR_PHY/pucchsim.c | 8 +- openair1/SIMULATION/NR_PHY/ulschsim.c | 4 +- openair2/GNB_APP/gnb_config.c | 19 ++- openair2/LAYER2/NR_MAC_UE/config_ue.c | 6 +- openair2/LAYER2/NR_MAC_UE/config_ue_sl.c | 11 +- openair2/LAYER2/NR_MAC_UE/mac_proto.h | 15 +-- openair2/LAYER2/NR_MAC_UE/mac_tables.c | 3 +- openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c | 6 +- .../LAYER2/NR_MAC_UE/nr_ue_power_procedures.c | 4 +- openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c | 23 +--- openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c | 33 ++--- .../tests/test_nr_ue_ra_procedures.cpp | 6 +- openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c | 16 +-- 55 files changed, 166 insertions(+), 369 deletions(-) diff --git a/executables/nr-gnb.c b/executables/nr-gnb.c index c5c1dee427..5413108209 100644 --- a/executables/nr-gnb.c +++ b/executables/nr-gnb.c @@ -120,13 +120,7 @@ static void tx_func(processingData_L1tx_t *info) if (tx_slot_type == NR_DOWNLINK_SLOT || tx_slot_type == NR_MIXED_SLOT || get_softmodem_params()->continuous_tx || IS_SOFTMODEM_RFSIM || cfg->analog_beamforming_ve.analog_bf_vendor_ext.value) { start_meas(&info->gNB->phy_proc_tx); - phy_procedures_gNB_TX(info->gNB, - &sched_response.DL_req, - &sched_response.TX_req, - &sched_response.UL_dci_req, - frame_tx, - slot_tx, - 1); + phy_procedures_gNB_TX(info->gNB, &sched_response.DL_req, &sched_response.TX_req, &sched_response.UL_dci_req, frame_tx,slot_tx); PHY_VARS_gNB *gNB = info->gNB; processingData_RU_t syncMsgRU; diff --git a/executables/nr-ue.c b/executables/nr-ue.c index 88a8ff84c8..b6364e998f 100644 --- a/executables/nr-ue.c +++ b/executables/nr-ue.c @@ -225,7 +225,7 @@ static void UE_synch(void *arg) { ret = sl_nr_slss_search(UE, &syncD->proc, SL_NR_SSB_REPETITION_IN_FRAMES); } else { nr_get_carrier_frequencies(UE, &dl_carrier, &ul_carrier); - ret = nr_initial_sync(&syncD->proc, UE, 2, IS_SA_MODE(get_softmodem_params()), syncD->gscnInfo, syncD->numGscn); + ret = nr_initial_sync(&syncD->proc, UE, 2, syncD->gscnInfo, syncD->numGscn); } if (ret.cell_detected) { diff --git a/openair1/PHY/INIT/nr_init_ue.c b/openair1/PHY/INIT/nr_init_ue.c index e137bf5b4c..19977b01e3 100644 --- a/openair1/PHY/INIT/nr_init_ue.c +++ b/openair1/PHY/INIT/nr_init_ue.c @@ -291,7 +291,7 @@ static void sl_ue_free(PHY_VARS_NR_UE *UE) } } -void term_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB) +void term_nr_ue_signal(PHY_VARS_NR_UE *ue) { const NR_DL_FRAME_PARMS* fp = &ue->frame_parms; phy_term_nr_top(); diff --git a/openair1/PHY/INIT/nr_phy_init.h b/openair1/PHY/INIT/nr_phy_init.h index ec4a8de71b..ee3122e6e3 100644 --- a/openair1/PHY/INIT/nr_phy_init.h +++ b/openair1/PHY/INIT/nr_phy_init.h @@ -34,7 +34,7 @@ int nr_init_frame_parms_ue_sl(NR_DL_FRAME_PARMS *fp, int threequarter_fs, uint32_t ofdm_offset_divisor); int init_nr_ue_signal(PHY_VARS_NR_UE *ue,int nb_connected_eNB); -void term_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB); +void term_nr_ue_signal(PHY_VARS_NR_UE *ue); void init_nr_ue_transport(PHY_VARS_NR_UE *ue); void nr_dump_frame_parms(NR_DL_FRAME_PARMS *frame_parms); void phy_init_nr_gNB(PHY_VARS_gNB *gNB); diff --git a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c index b078d2be1c..45fe87e040 100644 --- a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c +++ b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c @@ -500,7 +500,6 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, float beta_dmrs_pusch = get_beta_dmrs(pusch_pdu->num_dmrs_cdm_grps_no_data, pusch_pdu->dmrs_config_type == pusch_dmrs_type2); int16_t dmrs_scaling = (1 / beta_dmrs_pusch) * (1 << 14); nr_pusch_dmrs_rx(fp->Ncp, - Ns, gold, pilot, (1000 + p), @@ -520,7 +519,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, "Num RBs not configured according to 3GPP 38.211 section 6.3.1.4. For PUSCH with transform precoding, num RBs " "cannot be multiple of any other primenumber other than 2,3,5\n"); AssertFatal(dmrs_seq != NULL, "DMRS low PAPR seq not found, check if DMRS sequences are generated"); - nr_pusch_lowpaprtype1_dmrs_rx(fp->Ncp, Ns, dmrs_seq, pilot, 1000, 0, nb_rb_pusch, 0, pusch_pdu->dmrs_config_type); + nr_pusch_lowpaprtype1_dmrs_rx(fp->Ncp, dmrs_seq, pilot, 1000, 0, nb_rb_pusch, 0, pusch_pdu->dmrs_config_type); #ifdef DEBUG_PUSCH printf("NR_UL_CHANNEL_EST: index %d, u %d,v %d\n", index, u, v); LOG_M("gNb_DMRS_SEQ.m", "gNb_DMRS_SEQ", dmrs_seq, 6 * nb_rb_pusch, 1, 1); @@ -725,8 +724,6 @@ void nr_pusch_ptrs_processing(PHY_VARS_gNB *gNB, *ptrsReOffset, *nb_rb, rel15_ul->rnti, - nr_tti_rx, - symbol, frame_parms->ofdm_symbol_size, (int16_t *)&pusch_vars->rxdataF_comp[aarx][(symbol * nb_re_pusch)], gold, diff --git a/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c b/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c index d06ce6d917..bb81bd5ad5 100644 --- a/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c +++ b/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c @@ -64,7 +64,6 @@ static inline c16_t get_modulated(const uint32_t *gold_sequence, const int idx_g } int nr_pusch_dmrs_rx(nr_prefix_type_t Ncp, - unsigned int Ns, const uint32_t *nr_gold_pusch, c16_t *output, unsigned short p, @@ -108,7 +107,6 @@ int nr_pusch_dmrs_rx(nr_prefix_type_t Ncp, } int nr_pdsch_dmrs_rx(nr_prefix_type_t Ncp, - unsigned int Ns, const unsigned int *nr_gold_pdsch, c16_t *output, unsigned short p, @@ -213,7 +211,6 @@ void nr_gen_ref_conj_symbols(const uint32_t *in, uint32_t length, c16_t *output, } int nr_pusch_lowpaprtype1_dmrs_rx(nr_prefix_type_t Ncp, - unsigned int Ns, c16_t *dmrs_seq, c16_t *output, unsigned short p, diff --git a/openair1/PHY/NR_REFSIG/nr_refsig.h b/openair1/PHY/NR_REFSIG/nr_refsig.h index e5a5e73229..87f12adc5a 100644 --- a/openair1/PHY/NR_REFSIG/nr_refsig.h +++ b/openair1/PHY/NR_REFSIG/nr_refsig.h @@ -36,7 +36,6 @@ uint32_t *nr_gold_csi_rs(int N_RB_DL, int symbols_per_slot, int slot, int symb, uint32_t *nr_gold_prs(int nid, int slot, int symbol); int nr_pdsch_dmrs_rx(nr_prefix_type_t Ncp, - unsigned int Ns, const unsigned int *nr_gold_pdsch, c16_t *output, unsigned short p, @@ -56,7 +55,6 @@ void nr_pbch_dmrs_rx(int dmrss, const unsigned int *nr_gold_pbch, c16_t *output, void nr_pdcch_dmrs_ref(const unsigned int *nr_gold_pdcch, c16_t *output, unsigned short nb_rb_corset); int nr_pusch_dmrs_rx(nr_prefix_type_t Ncp, - unsigned int Ns, const uint32_t *nr_gold_pusch, c16_t *output, unsigned short p, @@ -71,7 +69,6 @@ void nr_generate_modulation_table(void); extern simde__m128i byte2m128i[256]; int nr_pusch_lowpaprtype1_dmrs_rx(nr_prefix_type_t Ncp, - unsigned int Ns, c16_t *dmrs_seq, c16_t *output, unsigned short p, diff --git a/openair1/PHY/NR_REFSIG/ptrs_nr.c b/openair1/PHY/NR_REFSIG/ptrs_nr.c index f73a01a2d6..53cc36cb26 100644 --- a/openair1/PHY/NR_REFSIG/ptrs_nr.c +++ b/openair1/PHY/NR_REFSIG/ptrs_nr.c @@ -194,8 +194,6 @@ void nr_ptrs_cpe_estimation(uint8_t K_ptrs, uint8_t ptrsReOffset, uint16_t nb_rb, uint16_t rnti, - unsigned char Ns, - unsigned char symbol, uint16_t ofdm_symbol_size, int16_t *rxF_comp, const uint32_t *gold_seq, diff --git a/openair1/PHY/NR_REFSIG/ptrs_nr.h b/openair1/PHY/NR_REFSIG/ptrs_nr.h index 75f526dad5..5a3b03f9c3 100644 --- a/openair1/PHY/NR_REFSIG/ptrs_nr.h +++ b/openair1/PHY/NR_REFSIG/ptrs_nr.h @@ -93,8 +93,6 @@ void nr_ptrs_cpe_estimation(uint8_t K_ptrs, uint8_t ptrsReOffset, uint16_t nb_rb, uint16_t rnti, - unsigned char Ns, - unsigned char symbol, uint16_t ofdm_symbol_size, int16_t *rxF_comp, const uint32_t *gold_seq, diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch.c b/openair1/PHY/NR_TRANSPORT/nr_dlsch.c index 9018aabfde..c2f205406b 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dlsch.c +++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch.c @@ -261,7 +261,6 @@ static inline int dmrs_case00(c16_t *output, const int amp, int sz, int start_sc, - int remaining_re, int dmrs_port, const int dmrs_Type, int symbol_sz, @@ -438,7 +437,6 @@ static inline int do_onelayer(NR_DL_FRAME_PARMS *frame_parms, amp, sz, start_sc, - remaining_re, dmrs_port, dmrs_Type, symbol_sz, @@ -772,7 +770,6 @@ static int do_one_dlsch(unsigned char *input_ptr, PHY_VARS_gNB *gNB, NR_gNB_DLSC void nr_generate_pdsch(PHY_VARS_gNB *gNB, int n_dlsch, NR_gNB_DLSCH_t *dlsch_array, int frame, int slot) { - NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms; time_stats_t *dlsch_encoding_stats = &gNB->dlsch_encoding_stats; time_stats_t *tinput = &gNB->tinput; time_stats_t *tprep = &gNB->tprep; @@ -831,7 +828,6 @@ void nr_generate_pdsch(PHY_VARS_gNB *gNB, int n_dlsch, NR_gNB_DLSCH_t *dlsch_arr dlsch_array, frame, slot, - frame_parms, output, tinput, tprep, diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch.h b/openair1/PHY/NR_TRANSPORT/nr_dlsch.h index 0a82b2c47f..09de55da74 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dlsch.h +++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch.h @@ -42,7 +42,6 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB, NR_gNB_DLSCH_t *dlsch_array, int frame, uint8_t slot, - NR_DL_FRAME_PARMS *frame_parms, unsigned char *output, time_stats_t *tinput, time_stats_t *tprep, diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c b/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c index 8a73d7754a..b2e7772a36 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c +++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c @@ -106,7 +106,6 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB, NR_gNB_DLSCH_t *dlsch_array, int frame, uint8_t slot, - NR_DL_FRAME_PARMS *frame_parms, unsigned char *output, time_stats_t *tinput, time_stats_t *tprep, diff --git a/openair1/PHY/NR_TRANSPORT/nr_prs.c b/openair1/PHY/NR_TRANSPORT/nr_prs.c index be1bd8adb8..207a94447d 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_prs.c +++ b/openair1/PHY/NR_TRANSPORT/nr_prs.c @@ -27,12 +27,7 @@ //#define DEBUG_PRS_MOD //#define DEBUG_PRS_MAP -int nr_generate_prs(int slot, - c16_t *txdataF, - int16_t amp, - prs_config_t *prs_cfg, - nfapi_nr_config_request_scf_t *config, - const NR_DL_FRAME_PARMS *frame_parms) +int nr_generate_prs(int slot, c16_t *txdataF, int16_t amp, prs_config_t *prs_cfg, const NR_DL_FRAME_PARMS *frame_parms) { int k_prime = 0, k = 0, idx; diff --git a/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h b/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h index 29ae5bb612..a38bf9b6bb 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h +++ b/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h @@ -40,12 +40,7 @@ NR_gNB_PHY_STATS_t *get_phy_stats(PHY_VARS_gNB *gNB, uint16_t rnti); -int nr_generate_prs(int slot, - c16_t *txdataF, - int16_t amp, - prs_config_t *prs_cfg, - nfapi_nr_config_request_scf_t *config, - const NR_DL_FRAME_PARMS *frame_parms); +int nr_generate_prs(int slot, c16_t *txdataF, int16_t amp, prs_config_t *prs_cfg, const NR_DL_FRAME_PARMS *frame_parms); /*! \fn int nr_generate_pss @@ -224,7 +219,6 @@ void nr_fill_srs(PHY_VARS_gNB *gNB, int nr_get_srs_signal(PHY_VARS_gNB *gNB, c16_t **rxdataF, - frame_t frame, slot_t slot, nfapi_nr_srs_pdu_t *srs_pdu, nr_srs_info_t *nr_srs_info, diff --git a/openair1/PHY/NR_TRANSPORT/pucch_rx.c b/openair1/PHY/NR_TRANSPORT/pucch_rx.c index 61bdce06b2..a5a69a0f12 100644 --- a/openair1/PHY/NR_TRANSPORT/pucch_rx.c +++ b/openair1/PHY/NR_TRANSPORT/pucch_rx.c @@ -1372,67 +1372,3 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB, uci_pdu->pduBitmap|=8; } } - -void nr_dump_uci_stats(FILE *fd,PHY_VARS_gNB *gNB,int frame) { - int strpos = 0; - char output[16384]; - - for (int i = 0; i < MAX_MOBILES_PER_GNB; i++) { - NR_gNB_PHY_STATS_t *stats = &gNB->phy_stats[i]; - if (!stats->active) - return; - NR_gNB_UCI_STATS_t *uci_stats = &stats->uci_stats; - if (uci_stats->pucch0_sr_trials > 0) - strpos += sprintf(output + strpos, - "UCI %d RNTI %x: pucch0_sr_trials %d, pucch0_n00 %d dB, pucch0_n01 %d dB, pucch0_sr_thres %d dB, current " - "pucch1_stat0 %d dB, current pucch1_stat1 %d dB, positive SR count %d\n", - i, - stats->rnti, - uci_stats->pucch0_sr_trials, - uci_stats->pucch0_n00, - uci_stats->pucch0_n01, - uci_stats->pucch0_sr_thres, - dB_fixed(uci_stats->current_pucch0_sr_stat0), - dB_fixed(uci_stats->current_pucch0_sr_stat1), - uci_stats->pucch0_positive_SR); - if (uci_stats->pucch01_trials > 0) - strpos += sprintf(output + strpos, - "UCI %d RNTI %x: pucch01_trials %d, pucch0_n00 %d dB, pucch0_n01 %d dB, pucch0_thres %d dB, current " - "pucch0_stat0 %d dB, current pucch1_stat1 %d dB, pucch01_DTX %d\n", - i, - stats->rnti, - uci_stats->pucch01_trials, - uci_stats->pucch0_n01, - uci_stats->pucch0_n01, - uci_stats->pucch0_thres, - dB_fixed(uci_stats->current_pucch0_stat0), - dB_fixed(uci_stats->current_pucch0_stat1), - uci_stats->pucch01_DTX); - - if (uci_stats->pucch02_trials > 0) - strpos += sprintf(output + strpos, - "UCI %d RNTI %x: pucch01_trials %d, pucch0_n00 %d dB, pucch0_n01 %d dB, pucch0_thres %d dB, current " - "pucch0_stat0 %d dB, current pucch0_stat1 %d dB, pucch01_DTX %d\n", - i, - stats->rnti, - uci_stats->pucch02_trials, - uci_stats->pucch0_n00, - uci_stats->pucch0_n01, - uci_stats->pucch0_thres, - dB_fixed(uci_stats->current_pucch0_stat0), - dB_fixed(uci_stats->current_pucch0_stat1), - uci_stats->pucch02_DTX); - - if (uci_stats->pucch2_trials > 0) - strpos += sprintf(output + strpos, - "UCI %d RNTI %x: pucch2_trials %d, pucch2_DTX %d\n", - i, - stats->rnti, - uci_stats->pucch2_trials, - uci_stats->pucch2_DTX); - } - if (fd) - fprintf(fd, "%s", output); - else - printf("%s", output); -} diff --git a/openair1/PHY/NR_TRANSPORT/srs_rx.c b/openair1/PHY/NR_TRANSPORT/srs_rx.c index 5d84c11c99..0637a8abce 100644 --- a/openair1/PHY/NR_TRANSPORT/srs_rx.c +++ b/openair1/PHY/NR_TRANSPORT/srs_rx.c @@ -75,7 +75,6 @@ void nr_fill_srs(PHY_VARS_gNB *gNB, frame_t frame, slot_t slot, nfapi_nr_srs_pdu int nr_get_srs_signal(PHY_VARS_gNB *gNB, c16_t **rxdataF, - frame_t frame, slot_t slot, nfapi_nr_srs_pdu_t *srs_pdu, nr_srs_info_t *nr_srs_info, diff --git a/openair1/PHY/NR_UE_ESTIMATION/nr_adjust_synch_ue.c b/openair1/PHY/NR_UE_ESTIMATION/nr_adjust_synch_ue.c index a407282c1b..1568c9e68e 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/nr_adjust_synch_ue.c +++ b/openair1/PHY/NR_UE_ESTIMATION/nr_adjust_synch_ue.c @@ -34,7 +34,6 @@ int nr_adjust_synch_ue(NR_DL_FRAME_PARMS *frame_parms, PHY_VARS_NR_UE *ue, - module_id_t gNB_id, const int estimateSz, struct complex16 dl_ch_estimates_time[][estimateSz], uint8_t frame, diff --git a/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c b/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c index 8978527095..f0e53a1c04 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c +++ b/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c @@ -1295,7 +1295,7 @@ void nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, float beta_dmrs_pdsch = get_beta_dmrs(dlsch->n_dmrs_cdm_groups, config_type == NFAPI_NR_DMRS_TYPE2); int16_t dmrs_scaling = (int16_t)((1 / beta_dmrs_pdsch) * (1 << 14)); const uint32_t *gold = nr_gold_pdsch(fp->N_RB_DL, fp->symbols_per_slot, dlsch->dlDmrsScramblingId, dlsch->nscid, slot, symbol); - nr_pdsch_dmrs_rx(fp->Ncp, slot, gold, pilot, 1000 + p, 0, nb_rb_pdsch + rb_offset, config_type, dmrs_scaling); + nr_pdsch_dmrs_rx(fp->Ncp, gold, pilot, 1000 + p, 0, nb_rb_pdsch + rb_offset, config_type, dmrs_scaling); delay_t delay = {0}; @@ -1380,8 +1380,7 @@ void nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, * 2) Interpolate PTRS estimated value in TD after all PTRS symbols * 3) Compensate signal with PTRS estimation for slot *********************************************************************/ -void nr_pdsch_ptrs_processing(PHY_VARS_NR_UE *ue, - int nbRx, +void nr_pdsch_ptrs_processing(int nbRx, c16_t ptrs_phase_per_slot[][14], int32_t ptrs_re_per_slot[][14], uint32_t rx_size_symbol, @@ -1389,7 +1388,6 @@ void nr_pdsch_ptrs_processing(PHY_VARS_NR_UE *ue, NR_DL_FRAME_PARMS *frame_parms, NR_DL_UE_HARQ_t *dlsch0_harq, NR_DL_UE_HARQ_t *dlsch1_harq, - uint8_t gNB_id, uint8_t nr_slot_rx, unsigned char symbol, uint16_t rnti, @@ -1478,8 +1476,6 @@ void nr_pdsch_ptrs_processing(PHY_VARS_NR_UE *ue, *ptrsReOffset, *nb_rb, rnti, - nr_slot_rx, - symbol, frame_parms->ofdm_symbol_size, (int16_t *)(rxdataF_comp[0][aarx] + symbol * rx_size_symbol), gold, diff --git a/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h b/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h index 4a67f2956e..9b0f4a642a 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h +++ b/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h @@ -94,7 +94,6 @@ void nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, int nr_adjust_synch_ue(NR_DL_FRAME_PARMS *frame_parms, PHY_VARS_NR_UE *ue, - module_id_t gNB_id, int estimateSz, struct complex16 dl_ch_estimates_time[][estimateSz], uint8_t frame, @@ -108,7 +107,6 @@ void nr_ue_measurements(PHY_VARS_NR_UE *ue, int32_t dl_ch_estimates[][pdsch_est_size]); uint32_t nr_ue_calculate_ssb_rsrp(const NR_DL_FRAME_PARMS *fp, - const UE_nr_rxtx_proc_t *proc, const c16_t rxdataF[][fp->samples_per_slot_wCP], int symbol_offset, int ssb_start_subcarrier); @@ -139,8 +137,7 @@ void phy_adjust_gain_nr(PHY_VARS_NR_UE *ue, uint32_t rx_power_fil_dB, uint8_t gNB_id); -void nr_pdsch_ptrs_processing(PHY_VARS_NR_UE *ue, - int nbRx, +void nr_pdsch_ptrs_processing(int nbRx, c16_t ptrs_phase_per_slot[][14], int32_t ptrs_re_per_slot[][14], uint32_t rx_size_symbol, @@ -148,7 +145,6 @@ void nr_pdsch_ptrs_processing(PHY_VARS_NR_UE *ue, NR_DL_FRAME_PARMS *frame_parms, NR_DL_UE_HARQ_t *dlsch0_harq, NR_DL_UE_HARQ_t *dlsch1_harq, - uint8_t gNB_id, uint8_t nr_slot_rx, unsigned char symbol, uint16_t rnti, diff --git a/openair1/PHY/NR_UE_ESTIMATION/nr_ue_measurements.c b/openair1/PHY/NR_UE_ESTIMATION/nr_ue_measurements.c index 8a59470cbf..8b8fb62c53 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/nr_ue_measurements.c +++ b/openair1/PHY/NR_UE_ESTIMATION/nr_ue_measurements.c @@ -154,7 +154,6 @@ void nr_ue_measurements(PHY_VARS_NR_UE *ue, // This function calculates: // - SS reference signal received digital power in dB/RE uint32_t nr_ue_calculate_ssb_rsrp(const NR_DL_FRAME_PARMS *fp, - const UE_nr_rxtx_proc_t *proc, const c16_t rxdataF[][fp->samples_per_slot_wCP], int symbol_offset, int ssb_start_subcarrier) @@ -242,7 +241,7 @@ void nr_ue_ssb_rsrp_measurements(PHY_VARS_NR_UE *ue, if (fp->half_frame_bit) symbol_offset += (fp->slots_per_frame >> 1) * fp->symbols_per_slot; - uint32_t rsrp_avg = nr_ue_calculate_ssb_rsrp(fp, proc, rxdataF, symbol_offset, fp->ssb_start_subcarrier); + uint32_t rsrp_avg = nr_ue_calculate_ssb_rsrp(fp, rxdataF, symbol_offset, fp->ssb_start_subcarrier); float rsrp_db_per_re = 10 * log10(rsrp_avg); openair0_config_t *cfg0 = &openair0_cfg[ue->rf_map.card]; @@ -489,7 +488,7 @@ void do_neighboring_cell_measurements(UE_nr_rxtx_proc_t *proc, PHY_VARS_NR_UE *u } // RSRP measurements - neighboring_cell_info->ssb_rsrp = nr_ue_calculate_ssb_rsrp(frame_parms, proc, rxdataF, 0, frame_parms->ssb_start_subcarrier); + neighboring_cell_info->ssb_rsrp = nr_ue_calculate_ssb_rsrp(frame_parms, rxdataF, 0, frame_parms->ssb_start_subcarrier); neighboring_cell_info->ssb_rsrp_dBm = 10 * log10(neighboring_cell_info->ssb_rsrp) + 30 - SQ15_SQUARED_NORM_FACTOR_DB diff --git a/openair1/PHY/NR_UE_TRANSPORT/csi_rx.c b/openair1/PHY/NR_UE_TRANSPORT/csi_rx.c index d8604d4570..e190bcc031 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/csi_rx.c +++ b/openair1/PHY/NR_UE_TRANSPORT/csi_rx.c @@ -730,7 +730,6 @@ int nr_csi_rs_cqi_estimation(const uint32_t precoded_sinr, } static void nr_csi_im_power_estimation(const PHY_VARS_NR_UE *ue, - const UE_nr_rxtx_proc_t *proc, const fapi_nr_dl_config_csiim_pdu_rel15_t *csiim_config_pdu, uint32_t *interference_plus_noise_power, const c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]) @@ -822,7 +821,7 @@ void nr_ue_csi_im_procedures(PHY_VARS_NR_UE *ue, LOG_I(NR_PHY, "csiim_config_pdu->l_csiim = %i.%i.%i.%i\n", csiim_config_pdu->l_csiim[0], csiim_config_pdu->l_csiim[1], csiim_config_pdu->l_csiim[2], csiim_config_pdu->l_csiim[3]); #endif - nr_csi_im_power_estimation(ue, proc, csiim_config_pdu, &ue->nr_csi_info->interference_plus_noise_power, rxdataF); + nr_csi_im_power_estimation(ue, csiim_config_pdu, &ue->nr_csi_info->interference_plus_noise_power, rxdataF); ue->nr_csi_info->csi_im_meas_computed = true; } diff --git a/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c b/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c index b5f26266e5..65a0247046 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c +++ b/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c @@ -324,7 +324,6 @@ static void nr_pdcch_detection_mrc(int nb_ant, int sz, c16_t rxdataF_comp[][sz]) static void nr_rx_pdcch_symbol(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, int symbol, - int rel_symb_monOcc, int ss_idx, nr_phy_data_t *phy_data, int llr_size_symbol, @@ -430,12 +429,6 @@ int get_max_pdcch_monOcc(const NR_UE_PDCCH_CONFIG *phy_pdcch_config) return monOcc; } -static void nr_dci_decoding_procedure(PHY_VARS_NR_UE *ue, - const UE_nr_rxtx_proc_t *proc, - c16_t *pdcch_e_rx, - fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15, - fapi_nr_dci_indication_t *dci_ind); - void set_first_last_pdcch_symb(const NR_UE_PDCCH_CONFIG *phy_pdcch_config, int *first_symb, int *last_symb) { *first_symb = NR_SYMBOLS_PER_SLOT; // max first pdcch symbol @@ -478,7 +471,6 @@ void nr_pdcch_generate_llr(PHY_VARS_NR_UE *ue, nr_rx_pdcch_symbol(ue, proc, symbol, - rel_symb_monOcc, ss_idx, phy_data, llr_size_symbol, @@ -489,64 +481,6 @@ void nr_pdcch_generate_llr(PHY_VARS_NR_UE *ue, } } -/* Decode DCI from LLRs for each Search-Space and send to MAC */ -void nr_pdcch_dci_indication(const UE_nr_rxtx_proc_t *proc, - int llr_size, - int max_monOcc, - PHY_VARS_NR_UE *ue, - nr_phy_data_t *phy_data, - c16_t llr[phy_data->phy_pdcch_config.nb_search_space][max_monOcc][llr_size]) -{ - NR_UE_PDCCH_CONFIG *phy_pdcch_config = &phy_data->phy_pdcch_config; - - nr_downlink_indication_t dl_indication; - fapi_nr_dci_indication_t dci_ind = {.SFN = proc->frame_rx, .slot = proc->nr_slot_rx}; - - for (int ss_idx = 0; ss_idx < phy_pdcch_config->nb_search_space; ss_idx++) { - fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15 = &phy_pdcch_config->pdcch_config[ss_idx]; - uint8_t unused_start_symb[NR_SYMBOLS_PER_SLOT] = {0}; - const int num_monitoring_occ = get_pdcch_mon_occasions_slot(rel15, unused_start_symb); - const int llr_stride = llr_size / rel15->coreset.duration; - int n_rb, cset_start; - get_coreset_rballoc(rel15->coreset.frequency_domain_resource, &n_rb, &cset_start); - - for (int m = 0; m < num_monitoring_occ; m++) { - /// PDCCH/DCI e-sequence (input to rate matching). - c16_t pdcch_e_rx[NR_MAX_PDCCH_SIZE]; - - nr_pdcch_demapping_deinterleaving(n_rb, - llr[ss_idx][m], - pdcch_e_rx, - rel15->coreset.duration, - rel15->coreset.RegBundleSize, - rel15->coreset.InterleaverSize, - rel15->coreset.ShiftIndex, - rel15->number_of_candidates, - rel15->CCE, - rel15->L, - llr_stride); - - nr_dci_decoding_procedure(ue, proc, pdcch_e_rx, rel15, &dci_ind); - } - } - - for (int i = 0; i < dci_ind.number_of_dcis; i++) { - LOG_D(PHY, - "Frame.slot: %d.%d: DCI %i of %d total DCIs found --> rnti %x : format %d\n", - proc->frame_rx, - proc->nr_slot_rx, - i + 1, - dci_ind.number_of_dcis, - dci_ind.dci_list[i].rnti, - dci_ind.dci_list[i].dci_format); - } - - /* Send to MAC */ - nr_fill_dl_indication(&dl_indication, &dci_ind, NULL, proc, ue, phy_data); - ue->if_inst->dl_indication(&dl_indication); - phy_pdcch_config->nb_search_space = 0; -} - static void nr_pdcch_unscrambling(c16_t *e_rx, uint16_t scrambling_RNTI, uint32_t length, @@ -566,8 +500,7 @@ static void nr_pdcch_unscrambling(c16_t *e_rx, } } -static void nr_dci_decoding_procedure(PHY_VARS_NR_UE *ue, - const UE_nr_rxtx_proc_t *proc, +static void nr_dci_decoding_procedure(const UE_nr_rxtx_proc_t *proc, c16_t *pdcch_e_rx, fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15, fapi_nr_dci_indication_t *dci_ind) @@ -659,3 +592,61 @@ static void nr_dci_decoding_procedure(PHY_VARS_NR_UE *ue, e_rx_cand_idx += RE_PER_RB_OUT_DMRS * L * 6; // e_rx index for next candidate (L CCEs, 6 REGs per CCE and 9 REs per REG ) } } + +/* Decode DCI from LLRs for each Search-Space and send to MAC */ +void nr_pdcch_dci_indication(const UE_nr_rxtx_proc_t *proc, + int llr_size, + int max_monOcc, + PHY_VARS_NR_UE *ue, + nr_phy_data_t *phy_data, + c16_t llr[phy_data->phy_pdcch_config.nb_search_space][max_monOcc][llr_size]) +{ + NR_UE_PDCCH_CONFIG *phy_pdcch_config = &phy_data->phy_pdcch_config; + + nr_downlink_indication_t dl_indication; + fapi_nr_dci_indication_t dci_ind = {.SFN = proc->frame_rx, .slot = proc->nr_slot_rx}; + + for (int ss_idx = 0; ss_idx < phy_pdcch_config->nb_search_space; ss_idx++) { + fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15 = &phy_pdcch_config->pdcch_config[ss_idx]; + uint8_t unused_start_symb[NR_SYMBOLS_PER_SLOT] = {0}; + const int num_monitoring_occ = get_pdcch_mon_occasions_slot(rel15, unused_start_symb); + const int llr_stride = llr_size / rel15->coreset.duration; + int n_rb, cset_start; + get_coreset_rballoc(rel15->coreset.frequency_domain_resource, &n_rb, &cset_start); + + for (int m = 0; m < num_monitoring_occ; m++) { + /// PDCCH/DCI e-sequence (input to rate matching). + c16_t pdcch_e_rx[NR_MAX_PDCCH_SIZE]; + + nr_pdcch_demapping_deinterleaving(n_rb, + llr[ss_idx][m], + pdcch_e_rx, + rel15->coreset.duration, + rel15->coreset.RegBundleSize, + rel15->coreset.InterleaverSize, + rel15->coreset.ShiftIndex, + rel15->number_of_candidates, + rel15->CCE, + rel15->L, + llr_stride); + + nr_dci_decoding_procedure(proc, pdcch_e_rx, rel15, &dci_ind); + } + } + + for (int i = 0; i < dci_ind.number_of_dcis; i++) { + LOG_D(PHY, + "Frame.slot: %d.%d: DCI %i of %d total DCIs found --> rnti %x : format %d\n", + proc->frame_rx, + proc->nr_slot_rx, + i + 1, + dci_ind.number_of_dcis, + dci_ind.dci_list[i].rnti, + dci_ind.dci_list[i].dci_format); + } + + /* Send to MAC */ + nr_fill_dl_indication(&dl_indication, &dci_ind, NULL, proc, ue, phy_data); + ue->if_inst->dl_indication(&dl_indication); + phy_pdcch_config->nb_search_space = 0; +} diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c index 73bcbfab46..8333dead75 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c @@ -60,7 +60,6 @@ static void nr_dlsch_mmse(uint32_t rx_size_symbol, c16_t dl_ch_magb[][n_rx][rx_size_symbol], c16_t dl_ch_magr[][n_rx][rx_size_symbol], int32_t dl_ch_estimates_ext[][rx_size_symbol], - unsigned short nb_rb, unsigned char mod_order, int shift, unsigned char symbol, @@ -86,7 +85,6 @@ static void nr_dlsch_llr(uint32_t rx_size_symbol, c16_t dl_ch_mag[rx_size_symbol], c16_t dl_ch_magb[rx_size_symbol], c16_t dl_ch_magr[rx_size_symbol], - NR_DL_UE_HARQ_t *dlsch0_harq, NR_DL_UE_HARQ_t *dlsch1_harq, unsigned char symbol, uint32_t len, @@ -614,7 +612,6 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, dl_ch_magb, dl_ch_magr, dl_ch_estimates_ext, - nb_rb_pdsch, dlsch_config->qamModOrder, *log2_maxh, symbol, @@ -649,8 +646,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, /* Check for PTRS bitmap and process it respectively */ if((pduBitmap & 0x1) && (dlsch[0].rnti_type == TYPE_C_RNTI_)) { - nr_pdsch_ptrs_processing(ue, - nbRx, + nr_pdsch_ptrs_processing(nbRx, ptrs_phase_per_slot, ptrs_re_per_slot, rx_size_symbol, @@ -658,7 +654,6 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, fp, dlsch0_harq, dlsch1_harq, - gNB_id, nr_slot_rx, symbol, dlsch[0].rnti, @@ -674,7 +669,6 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, dl_ch_mag[0][0], dl_ch_magb[0][0], dl_ch_magr[0][0], - dlsch0_harq, dlsch1_harq, symbol, dl_valid_re[symbol], @@ -1364,7 +1358,6 @@ static void nr_dlsch_mmse(uint32_t rx_size_symbol, c16_t dl_ch_magb[][n_rx][rx_size_symbol], c16_t dl_ch_magr[][n_rx][rx_size_symbol], int32_t dl_ch_estimates_ext[][rx_size_symbol], - unsigned short nb_rb, unsigned char mod_order, int shift, unsigned char symbol, @@ -1556,7 +1549,6 @@ static void nr_dlsch_llr(uint32_t rx_size_symbol, c16_t dl_ch_mag[rx_size_symbol], c16_t dl_ch_magb[rx_size_symbol], c16_t dl_ch_magr[rx_size_symbol], - NR_DL_UE_HARQ_t *dlsch0_harq, NR_DL_UE_HARQ_t *dlsch1_harq, unsigned char symbol, uint32_t len, diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c b/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c index 9d2db73e66..31566fd3fd 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c @@ -374,7 +374,7 @@ void nr_scan_ssb(void *arg) &ssbInfo->pbchResult, rxdataF); // start pbch detection at first symbol after pss if (ssbInfo->syncRes.cell_detected) { - uint32_t rsrp_avg = nr_ue_calculate_ssb_rsrp(ssbInfo->fp, ssbInfo->proc, rxdataF, 0, ssbInfo->gscnInfo.ssbFirstSC); + uint32_t rsrp_avg = nr_ue_calculate_ssb_rsrp(ssbInfo->fp, rxdataF, 0, ssbInfo->gscnInfo.ssbFirstSC); int rsrp_db_per_re = 10 * log10(rsrp_avg); ssbInfo->adjust_rxgain = TARGET_RX_POWER - rsrp_db_per_re; LOG_I(PHY, "pbch rx ok. rsrp:%d dB/RE, adjust_rxgain:%d dB\n", rsrp_db_per_re, ssbInfo->adjust_rxgain); @@ -388,7 +388,6 @@ void nr_scan_ssb(void *arg) nr_initial_sync_t nr_initial_sync(UE_nr_rxtx_proc_t *proc, PHY_VARS_NR_UE *ue, int n_frames, - int sa, nr_gscn_info_t gscnInfo[MAX_GSCN_BAND], int numGscn) { diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync_sl.c b/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync_sl.c index 321281fcda..e407459bc8 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync_sl.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync_sl.c @@ -151,7 +151,6 @@ static int sl_nr_pss_correlation(PHY_VARS_NR_UE *UE, int frame_index) } static void sl_nr_extract_sss(PHY_VARS_NR_UE *ue, - UE_nr_rxtx_proc_t *proc, int32_t *tot_metric, uint8_t *phase_max, c16_t rxdataF[][ue->SL_UE_PHY_PARAMS.sl_frame_params.samples_per_slot_wCP]) @@ -440,7 +439,7 @@ nr_initial_sync_t sl_nr_slss_search(PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc, UE->common_vars.rxdata); } - sl_nr_extract_sss(UE, NULL, &metric_tdd_ncp, &phase_tdd_ncp, rxdataF); + sl_nr_extract_sss(UE, &metric_tdd_ncp, &phase_tdd_ncp, rxdataF); // save detected cell id to psbch rx_slss_id = UE->SL_UE_PHY_PARAMS.sync_params.N_sl_id; @@ -510,7 +509,7 @@ nr_initial_sync_t sl_nr_slss_search(PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc, sl_nr_rx_indication_t rx_ind = {0}; uint16_t number_pdus = 1; nr_fill_sl_indication(&sl_indication, &rx_ind, NULL, proc, UE, NULL); - nr_fill_sl_rx_indication(&rx_ind, SL_NR_RX_PDU_TYPE_SSB, UE, number_pdus, proc, (void *)decoded_output, rx_slss_id); + nr_fill_sl_rx_indication(&rx_ind, SL_NR_RX_PDU_TYPE_SSB, UE, number_pdus, (void *)decoded_output, rx_slss_id); LOG_D(PHY, "Sidelink SLSS SEARCH PSBCH RX OK. Send SL-SSB TO MAC\n"); diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h index 3daaaf0eee..6872306dfe 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h @@ -126,8 +126,7 @@ int nr_ulsch_encoding(PHY_VARS_NR_UE *ue, const uint8_t slot, unsigned int *G, int nb_ulsch, - uint8_t *ULSCH_ids, - uint16_t number_dmrs_symbols); + uint8_t *ULSCH_ids); /*! \brief Perform PUSCH scrambling. TS 38.211 V15.4.0 subclause 6.3.1.1 @param[in] in Pointer to input bits @@ -242,7 +241,6 @@ double nr_ue_pbch_freq_offset(const NR_DL_FRAME_PARMS *frame_parms, nr_initial_sync_t nr_initial_sync(UE_nr_rxtx_proc_t *proc, PHY_VARS_NR_UE *phy_vars_ue, int n_frames, - int sa, nr_gscn_info_t gscnInfo[MAX_GSCN_BAND], int numGscn); diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c index 852e87c071..4b769a8668 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c @@ -159,8 +159,7 @@ int nr_ulsch_encoding(PHY_VARS_NR_UE *ue, const uint8_t slot, unsigned int *G, int nb_ulsch, - uint8_t *ULSCH_ids, - uint16_t number_dmrs_symbols) + uint8_t *ULSCH_ids) { start_meas_nr_ue_phy(ue, ULSCH_ENCODING_STATS); diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c index 94ee8022a8..881ce016bc 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c @@ -435,8 +435,7 @@ static void map_current_symbol(const nr_phy_pxsch_params_t p, /* TS 38.211 table 6.4.1.1.3-1 and 2 */ -static void dmrs_amp_mult(const uint32_t dmrs_port, - const int Wt, +static void dmrs_amp_mult(const int Wt, const int Wf[2], const c16_t *mod_dmrs, c16_t *mod_dmrs_out, @@ -493,9 +492,9 @@ static void map_symbols(const nr_phy_pxsch_params_t p, c16_t mod_dmrs[ALNARS_16_4(n_dmrs)] __attribute((aligned(16))); if (p.transform_precoding == transformPrecoder_disabled) { nr_modulation(gold, n_dmrs * 2, DMRS_MOD_ORDER, (int16_t *)mod_dmrs); - dmrs_amp_mult(p.dmrs_port, p.Wt, p.Wf, mod_dmrs, mod_dmrs_amp, n_dmrs, p.dmrs_type, p.num_cdm_no_data); + dmrs_amp_mult(p.Wt, p.Wf, mod_dmrs, mod_dmrs_amp, n_dmrs, p.dmrs_type, p.num_cdm_no_data); } else { - dmrs_amp_mult(p.dmrs_port, p.Wt, p.Wf, dmrs_seq, mod_dmrs_amp, n_dmrs, p.dmrs_type, p.num_cdm_no_data); + dmrs_amp_mult(p.Wt, p.Wf, dmrs_seq, mod_dmrs_amp, n_dmrs, p.dmrs_type, p.num_cdm_no_data); } } else if ((p.pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_PTRS) && ptrs_symbol) { AssertFatal(p.transform_precoding == transformPrecoder_disabled, "PTRS NOT SUPPORTED IF TRANSFORM PRECODING IS ENABLED\n"); @@ -1190,7 +1189,7 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, rm_info = calc_rate_match_info_uci(pusch_pdu, harq_process_ul_ue, nl_qm, &G[pusch_id]); } - if (nr_ulsch_encoding(UE, &phy_data->ulsch, frame, slot, G, 1, ULSCH_ids, number_dmrs_symbols) == -1) { + if (nr_ulsch_encoding(UE, &phy_data->ulsch, frame, slot, G, 1, ULSCH_ids) == -1) { stop_meas_nr_ue_phy(UE, PUSCH_PROC_STATS); return; } diff --git a/openair1/PHY/NR_UE_TRANSPORT/pucch_nr.c b/openair1/PHY/NR_UE_TRANSPORT/pucch_nr.c index 51285edd0b..5f54b916b1 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/pucch_nr.c +++ b/openair1/PHY/NR_UE_TRANSPORT/pucch_nr.c @@ -52,8 +52,7 @@ //#define ONE_OVER_SQRT2 23170 // 32767/sqrt(2) = 23170 (ONE_OVER_SQRT2) //#define POLAR_CODING_DEBUG -void nr_generate_pucch0(const PHY_VARS_NR_UE *ue, - c16_t **txdataF, +void nr_generate_pucch0(c16_t **txdataF, const NR_DL_FRAME_PARMS *frame_parms, const int16_t amp16, const int nr_slot_tx, @@ -156,8 +155,7 @@ void nr_generate_pucch0(const PHY_VARS_NR_UE *ue, } } -void nr_generate_pucch1(const PHY_VARS_NR_UE *ue, - c16_t **txdataF, +void nr_generate_pucch1(c16_t **txdataF, const NR_DL_FRAME_PARMS *frame_parms, const int16_t amp16, const int nr_slot_tx, @@ -752,8 +750,7 @@ void nr_uci_encoding(uint64_t payload, uint8_t nr_bit, uint8_t nrofPRB, bool uci } } //#if 0 -void nr_generate_pucch2(const PHY_VARS_NR_UE *ue, - c16_t **txdataF, +void nr_generate_pucch2(c16_t **txdataF, const NR_DL_FRAME_PARMS *frame_parms, const int16_t amp16, const int nr_slot_tx, @@ -937,8 +934,7 @@ void nr_generate_pucch2(const PHY_VARS_NR_UE *ue, } } //#if 0 -void nr_generate_pucch3_4(const PHY_VARS_NR_UE *ue, - c16_t **txdataF, +void nr_generate_pucch3_4(c16_t **txdataF, const NR_DL_FRAME_PARMS *frame_parms, const int16_t amp16, const int nr_slot_tx, diff --git a/openair1/PHY/NR_UE_TRANSPORT/pucch_nr.h b/openair1/PHY/NR_UE_TRANSPORT/pucch_nr.h index 7f769872de..47b86c31c0 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/pucch_nr.h +++ b/openair1/PHY/NR_UE_TRANSPORT/pucch_nr.h @@ -42,29 +42,25 @@ #include "T.h" #define ONE_OVER_SQRT2 23170 // 32767/sqrt(2) = 23170 (ONE_OVER_SQRT2) -void nr_generate_pucch0(const PHY_VARS_NR_UE *ue, - c16_t **txdataF, +void nr_generate_pucch0(c16_t **txdataF, const NR_DL_FRAME_PARMS *frame_parms, const int16_t amp, const int nr_slot_tx, const fapi_nr_ul_config_pucch_pdu *pucch_pdu); -void nr_generate_pucch1(const PHY_VARS_NR_UE *ue, - c16_t **txdataF, +void nr_generate_pucch1(c16_t **txdataF, const NR_DL_FRAME_PARMS *frame_parms, const int16_t amp, const int nr_slot_tx, const fapi_nr_ul_config_pucch_pdu *pucch_pdu); -void nr_generate_pucch2(const PHY_VARS_NR_UE *ue, - c16_t **txdataF, +void nr_generate_pucch2(c16_t **txdataF, const NR_DL_FRAME_PARMS *frame_parms, const int16_t amp, const int nr_slot_tx, const fapi_nr_ul_config_pucch_pdu *pucch_pdu); -void nr_generate_pucch3_4(const PHY_VARS_NR_UE *ue, - c16_t **txdataF, +void nr_generate_pucch3_4(c16_t **txdataF, const NR_DL_FRAME_PARMS *frame_parms, const int16_t amp, const int nr_slot_tx, diff --git a/openair1/PHY/NR_UE_TRANSPORT/sss_nr.c b/openair1/PHY/NR_UE_TRANSPORT/sss_nr.c index da27ca8603..46a2ebfa31 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/sss_nr.c +++ b/openair1/PHY/NR_UE_TRANSPORT/sss_nr.c @@ -256,7 +256,6 @@ static int do_pss_sss_extract_nr( c16_t sss_ext[NB_ANTENNAS_RX][LENGTH_SSS_NR], uint8_t doPss, uint8_t doSss, - uint8_t subframe, int ssb_start_subcarrier, c16_t rxdataF[][frame_parms->samples_per_slot_wCP]) // add flag to indicate extracting only PSS, only SSS, or both { @@ -333,7 +332,6 @@ static int do_pss_sss_extract_nr( static int pss_sss_extract_nr(const NR_DL_FRAME_PARMS *frame_parms, c16_t pss_ext[NB_ANTENNAS_RX][LENGTH_PSS_NR], c16_t sss_ext[NB_ANTENNAS_RX][LENGTH_SSS_NR], - uint8_t subframe, int ssb_start_subcarrier, c16_t rxdataF[][frame_parms->samples_per_slot_wCP]) { @@ -342,7 +340,6 @@ static int pss_sss_extract_nr(const NR_DL_FRAME_PARMS *frame_parms, sss_ext, 1 /* doPss */, 1 /* doSss */, - subframe, ssb_start_subcarrier, rxdataF); } @@ -381,7 +378,7 @@ bool rx_sss_nr(const NR_DL_FRAME_PARMS *frame_parms, // pss sss extraction - pss_sss_extract_nr(frame_parms, pss_ext, sss_ext, 0, ssb_start_subcarrier, rxdataF); /* subframe */ + pss_sss_extract_nr(frame_parms, pss_ext, sss_ext, ssb_start_subcarrier, rxdataF); /* subframe */ #ifdef DEBUG_PLOT_SSS diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c index e304fe3dc9..cdf0a650b8 100644 --- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c +++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c @@ -209,10 +209,7 @@ void clear_slot_beamid(PHY_VARS_gNB *gNB, int slot) } } -static void nr_generate_csi_rs_gNB(PHY_VARS_gNB *gNB, - int slot, - const nfapi_nr_config_request_scf_t *cfg, - const nfapi_nr_dl_tti_csi_rs_pdu *csi_rs_pdu) +static void nr_generate_csi_rs_gNB(PHY_VARS_gNB *gNB, int slot, const nfapi_nr_dl_tti_csi_rs_pdu *csi_rs_pdu) { const nfapi_nr_dl_tti_csi_rs_pdu_rel15_t *csi_params = &csi_rs_pdu->csi_rs_pdu_rel15; if (csi_params->csi_type == 2) // ZP-CSI @@ -253,8 +250,7 @@ void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB, const nfapi_nr_tx_data_request_t *TX_req, const nfapi_nr_ul_dci_request_t *UL_dci_req, int frame, - int slot, - int do_meas) + int slot) { const NR_DL_FRAME_PARMS *fp = &gNB->frame_parms; nfapi_nr_config_request_scf_t *cfg = &gNB->gNB_config; @@ -280,7 +276,7 @@ void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB, { int slot_prs = (slot - i * prs_config->PRSResourceTimeGap + fp->slots_per_frame) % fp->slots_per_frame; LOG_D(PHY,"gNB_TX: frame %d, slot %d, slot_prs %d, PRS Resource ID %d\n",frame, slot, slot_prs, rsc_id); - nr_generate_prs(slot_prs, &gNB->common_vars.txdataF[0][0][txdataF_offset], AMP, prs_config, cfg, fp); + nr_generate_prs(slot_prs, &gNB->common_vars.txdataF[0][0][txdataF_offset], AMP, prs_config, fp); } } } @@ -299,7 +295,7 @@ void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB, nr_generate_dci(gNB, &dl_tti_pdu->pdcch_pdu.pdcch_pdu_rel15, txdataF_offset, &gNB->frame_parms, slot); break; case NFAPI_NR_DL_TTI_CSI_RS_PDU_TYPE: - nr_generate_csi_rs_gNB(gNB, slot, cfg, &dl_tti_pdu->csi_rs_pdu); + nr_generate_csi_rs_gNB(gNB, slot, &dl_tti_pdu->csi_rs_pdu); break; case NFAPI_NR_DL_TTI_PDSCH_PDU_TYPE: { int tx_data_idx = dl_tti_pdu->pdsch_pdu.pdsch_pdu_rel15.pduIndex; @@ -721,7 +717,6 @@ static void fill_ul_rb_mask(PHY_VARS_gNB *gNB, static int fill_srs_reported_symbol(nfapi_nr_srs_reported_symbol_t *reported_symbol, const nfapi_nr_srs_pdu_t *srs_pdu, - const int N_RB_UL, const int16_t *snr_per_rb, const int srs_est) { @@ -890,7 +885,7 @@ void nr_srs_rx_procedures(PHY_VARS_gNB *gNB, stop_meas(&gNB->generate_srs_stats); c16_t **rxdataF = gNB->common_vars.rxdataF[srs->beam_nb]; start_meas(&gNB->get_srs_signal_stats); - *srs_est = nr_get_srs_signal(gNB, rxdataF, frame_rx, slot_rx, srs_pdu, nr_srs_info, srs_received_signal, srs_received_noise); + *srs_est = nr_get_srs_signal(gNB, rxdataF, slot_rx, srs_pdu, nr_srs_info, srs_received_signal, srs_received_noise); stop_meas(&gNB->get_srs_signal_stats); uint32_t signal_power_avg = 0; @@ -1275,7 +1270,7 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, N AssertFatal(nr_srs_bf_report.num_reported_symbols == 1, "nr_srs_bf_report.num_reported_symbols %i not handled yet!\n", nr_srs_bf_report.num_reported_symbols); - fill_srs_reported_symbol(&nr_srs_bf_report.reported_symbol_list[0], srs_pdu, frame_parms->N_RB_UL, snr_per_rb, srs_est); + fill_srs_reported_symbol(&nr_srs_bf_report.reported_symbol_list[0], srs_pdu, snr_per_rb, srs_est); #ifdef SRS_IND_DEBUG LOG_I(NR_PHY, "nr_srs_bf_report.prg_size = %i\n", nr_srs_bf_report.prg_size); diff --git a/openair1/SCHED_NR/sched_nr.h b/openair1/SCHED_NR/sched_nr.h index 84691e9584..fbfb665ed1 100644 --- a/openair1/SCHED_NR/sched_nr.h +++ b/openair1/SCHED_NR/sched_nr.h @@ -38,8 +38,7 @@ void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB, const nfapi_nr_tx_data_request_t *TX_req, const nfapi_nr_ul_dci_request_t *UL_dci_req, int frame, - int slot, - int do_meas); + int slot); void nr_save_ul_tti_req(PHY_VARS_gNB *gNB, nfapi_nr_ul_tti_request_t *UL_tti_req); 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); diff --git a/openair1/SCHED_NR_UE/defs.h b/openair1/SCHED_NR_UE/defs.h index 5fe6e0c1bb..394b5592f5 100644 --- a/openair1/SCHED_NR_UE/defs.h +++ b/openair1/SCHED_NR_UE/defs.h @@ -172,7 +172,6 @@ void nr_fill_sl_rx_indication(sl_nr_rx_indication_t *rx_ind, uint8_t pdu_type, PHY_VARS_NR_UE *ue, uint16_t n_pdus, - const UE_nr_rxtx_proc_t *proc, void *typeSpecific, uint16_t rx_slss_id); diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c index 2da33ce205..cc6a2ee23b 100644 --- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c +++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c @@ -1066,7 +1066,6 @@ int pbch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_phy_da TracyCZone(ctx, true); int frame_rx = proc->frame_rx; int nr_slot_rx = proc->nr_slot_rx; - int gNB_id = proc->gNB_id; NR_DL_FRAME_PARMS *fp = &ue->frame_parms; int sampleShift = INT_MAX; nr_ue_dlsch_init(phy_data->dlsch, NR_MAX_NB_LAYERS>4 ? 2:1, ue->max_ldpc_iterations); @@ -1152,7 +1151,7 @@ int pbch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_phy_da if (ue->no_timing_correction == 0 && pbchSuccess == 0) { LOG_D(PHY,"start adjust sync slot = %d no timing %d\n", nr_slot_rx, ue->no_timing_correction); sampleShift = - nr_adjust_synch_ue(fp, ue, gNB_id, fp->ofdm_symbol_size, dl_ch_estimates_time, frame_rx, nr_slot_rx, 16384); + nr_adjust_synch_ue(fp, ue, fp->ofdm_symbol_size, dl_ch_estimates_time, frame_rx, nr_slot_rx, 16384); } if (get_nrUE_params()->cont_fo_comp && pbchSuccess == 0) { diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue_sl.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue_sl.c index 1e2151d1d3..9b17546f61 100644 --- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue_sl.c +++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue_sl.c @@ -66,7 +66,6 @@ void nr_fill_sl_rx_indication(sl_nr_rx_indication_t *rx_ind, uint8_t pdu_type, PHY_VARS_NR_UE *ue, uint16_t n_pdus, - const UE_nr_rxtx_proc_t *proc, void *typeSpecific, uint16_t rx_slss_id) { @@ -157,7 +156,7 @@ static int nr_ue_psbch_procedures(PHY_VARS_NR_UE *ue, } nr_fill_sl_indication(&sl_indication, &rx_ind, NULL, proc, ue, phy_data); - nr_fill_sl_rx_indication(&rx_ind, SL_NR_RX_PDU_TYPE_SSB, ue, number_pdus, proc, (void *)result, rx_slss_id); + nr_fill_sl_rx_indication(&rx_ind, SL_NR_RX_PDU_TYPE_SSB, ue, number_pdus, (void *)result, rx_slss_id); if (ue->if_inst && ue->if_inst->sl_indication) ue->if_inst->sl_indication(&sl_indication); @@ -232,7 +231,7 @@ int psbch_pscch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr if (ue->no_timing_correction == 0 && psbchSuccess == 0) { LOG_D(NR_PHY, "start adjust sync slot = %d no timing %d\n", nr_slot_rx, ue->no_timing_correction); sampleShift = - nr_adjust_synch_ue(fp, ue, proc->gNB_id, fp->ofdm_symbol_size, dl_ch_estimates_time, frame_rx, nr_slot_rx, 16384); + nr_adjust_synch_ue(fp, ue, fp->ofdm_symbol_size, dl_ch_estimates_time, frame_rx, nr_slot_rx, 16384); } LOG_D(NR_PHY, "Doing N0 measurements in %s\n", __FUNCTION__); diff --git a/openair1/SCHED_NR_UE/pucch_uci_ue_nr.c b/openair1/SCHED_NR_UE/pucch_uci_ue_nr.c index 03c14af9b9..be1187f574 100644 --- a/openair1/SCHED_NR_UE/pucch_uci_ue_nr.c +++ b/openair1/SCHED_NR_UE/pucch_uci_ue_nr.c @@ -176,17 +176,17 @@ void pucch_procedures_ue_nr(PHY_VARS_NR_UE *ue, switch(pucch_pdu->format_type) { case 0: - nr_generate_pucch0(ue, txdataF, &ue->frame_parms, tx_amp, nr_slot_tx, pucch_pdu); + nr_generate_pucch0(txdataF, &ue->frame_parms, tx_amp, nr_slot_tx, pucch_pdu); break; case 1: - nr_generate_pucch1(ue, txdataF, &ue->frame_parms, tx_amp, nr_slot_tx, pucch_pdu); + nr_generate_pucch1(txdataF, &ue->frame_parms, tx_amp, nr_slot_tx, pucch_pdu); break; case 2: - nr_generate_pucch2(ue, txdataF, &ue->frame_parms, tx_amp, nr_slot_tx, pucch_pdu); + nr_generate_pucch2(txdataF, &ue->frame_parms, tx_amp, nr_slot_tx, pucch_pdu); break; case 3: case 4: - nr_generate_pucch3_4(ue, txdataF, &ue->frame_parms, tx_amp, nr_slot_tx, pucch_pdu); + nr_generate_pucch3_4(txdataF, &ue->frame_parms, tx_amp, nr_slot_tx, pucch_pdu); break; } } diff --git a/openair1/SIMULATION/NR_PHY/dlschsim.c b/openair1/SIMULATION/NR_PHY/dlschsim.c index 076f05db48..6f4282f130 100644 --- a/openair1/SIMULATION/NR_PHY/dlschsim.c +++ b/openair1/SIMULATION/NR_PHY/dlschsim.c @@ -506,7 +506,7 @@ int main(int argc, char **argv) unsigned char output[nb_rb * NR_SYMBOLS_PER_SLOT * NR_NB_SC_PER_RB * NR_MAX_NB_LAYERS] __attribute__((aligned(64))); bzero(output, sizeof(output)); if (input_fd == NULL) { - nr_dlsch_encoding(gNB, 1, dlsch, frame, slot, frame_parms, output, NULL, NULL, NULL, NULL, NULL, NULL, NULL); + nr_dlsch_encoding(gNB, 1, dlsch, frame, slot, output, NULL, NULL, NULL, NULL, NULL, NULL, NULL); } for (SNR = snr0; SNR < snr1 && !stop; SNR += snr_step) { @@ -620,7 +620,7 @@ int main(int argc, char **argv) free(RC.gNB); free_nr_ue_dl_harq(UE->dl_harq_processes, 8, nb_rb); - term_nr_ue_signal(UE, 1); + term_nr_ue_signal(UE); free(UE); for (i = 0; i < 2; i++) { diff --git a/openair1/SIMULATION/NR_PHY/dlsim.c b/openair1/SIMULATION/NR_PHY/dlsim.c index bcce053231..b068936739 100644 --- a/openair1/SIMULATION/NR_PHY/dlsim.c +++ b/openair1/SIMULATION/NR_PHY/dlsim.c @@ -1120,7 +1120,7 @@ int main(int argc, char **argv) } start_meas(&gNB->phy_proc_tx); - phy_procedures_gNB_TX(gNB, &Sched_INFO->DL_req, &Sched_INFO->TX_req, &Sched_INFO->UL_dci_req, frame, slot, 1); + phy_procedures_gNB_TX(gNB, &Sched_INFO->DL_req, &Sched_INFO->TX_req, &Sched_INFO->UL_dci_req, frame, slot); stop_meas(&gNB->phy_proc_tx); int txdataF_offset = slot * frame_parms->samples_per_slot_wCP; diff --git a/openair1/SIMULATION/NR_PHY/pbchsim.c b/openair1/SIMULATION/NR_PHY/pbchsim.c index 087b17ab06..5702be2cf9 100644 --- a/openair1/SIMULATION/NR_PHY/pbchsim.c +++ b/openair1/SIMULATION/NR_PHY/pbchsim.c @@ -654,7 +654,7 @@ int main(int argc, char **argv) nr_gscn_info_t gscnInfo[MAX_GSCN_BAND] = {0}; const int numGscn = 1; gscnInfo[0].ssbFirstSC = frame_parms->ssb_start_subcarrier; - nr_initial_sync_t ret = nr_initial_sync(&proc, UE, 1, 0, gscnInfo, numGscn); + nr_initial_sync_t ret = nr_initial_sync(&proc, UE, 1, gscnInfo, numGscn); printf("nr_initial_sync1 returns %s\n", ret.cell_detected ? "cell detected" : "cell not detected"); if (!ret.cell_detected) n_errors++; @@ -761,7 +761,7 @@ int main(int argc, char **argv) free(RC.gNB[0]); free(RC.gNB); - term_nr_ue_signal(UE, 1); + term_nr_ue_signal(UE); free(UE); for (i=0; i<2; i++) { diff --git a/openair1/SIMULATION/NR_PHY/prachsim.c b/openair1/SIMULATION/NR_PHY/prachsim.c index 4da1accfe8..1f00bdd6cf 100644 --- a/openair1/SIMULATION/NR_PHY/prachsim.c +++ b/openair1/SIMULATION/NR_PHY/prachsim.c @@ -844,7 +844,7 @@ int main(int argc, char **argv){ free(RC.gNB[0]); free(RC.gNB); - term_nr_ue_signal(UE, 1); + term_nr_ue_signal(UE); free(UE->nrUE_config.prach_config.num_prach_fd_occasions_list); free(UE); free(PHY_vars_UE_g[0]); diff --git a/openair1/SIMULATION/NR_PHY/psbchsim.c b/openair1/SIMULATION/NR_PHY/psbchsim.c index 49d07616c4..cb78915cbb 100644 --- a/openair1/SIMULATION/NR_PHY/psbchsim.c +++ b/openair1/SIMULATION/NR_PHY/psbchsim.c @@ -673,8 +673,8 @@ int main(int argc, char **argv) free(r_re); free(r_im); - term_nr_ue_signal(UE_TX, 1); - term_nr_ue_signal(UE_RX, 1); + term_nr_ue_signal(UE_TX); + term_nr_ue_signal(UE_RX); free(UE_TX); free(UE_RX); diff --git a/openair1/SIMULATION/NR_PHY/pucchsim.c b/openair1/SIMULATION/NR_PHY/pucchsim.c index 980beac6b3..bfa294a55f 100644 --- a/openair1/SIMULATION/NR_PHY/pucchsim.c +++ b/openair1/SIMULATION/NR_PHY/pucchsim.c @@ -551,11 +551,11 @@ int main(int argc, char **argv) for (int aatx=0;aatx<1;aatx++) bzero(txdataF[aatx],frame_parms->ofdm_symbol_size*sizeof(int)); if(format==0 && do_DTX==0){ - nr_generate_pucch0(UE, txdataF, frame_parms, amp, nr_slot_tx, &pucch_tx_pdu); + nr_generate_pucch0(txdataF, frame_parms, amp, nr_slot_tx, &pucch_tx_pdu); } else if (format == 1 && do_DTX==0){ - nr_generate_pucch1(UE, txdataF, frame_parms, amp, nr_slot_tx, &pucch_tx_pdu); + nr_generate_pucch1(txdataF, frame_parms, amp, nr_slot_tx, &pucch_tx_pdu); } else if (do_DTX == 0){ - nr_generate_pucch2(UE, txdataF, frame_parms, amp, nr_slot_tx, &pucch_tx_pdu); + nr_generate_pucch2(txdataF, frame_parms, amp, nr_slot_tx, &pucch_tx_pdu); } // SNR Computation @@ -784,7 +784,7 @@ int main(int argc, char **argv) free(RC.gNB[0]); free(RC.gNB); - term_nr_ue_signal(UE, 1); + term_nr_ue_signal(UE); free(UE); for (int aatx=0; aatxgNB_config.tdd_table.max_tdd_periodicity_list[i].max_num_of_symbol_per_slot_list); free(gNB->gNB_config.tdd_table.max_tdd_periodicity_list); - term_nr_ue_signal(UE, 1); + term_nr_ue_signal(UE); free(UE); abortTpool(&gNB->threadPool); diff --git a/openair2/GNB_APP/gnb_config.c b/openair2/GNB_APP/gnb_config.c index 667ab25093..d9c581be23 100644 --- a/openair2/GNB_APP/gnb_config.c +++ b/openair2/GNB_APP/gnb_config.c @@ -816,7 +816,7 @@ void RCconfig_nr_prs(void) /** * @brief Get number or blacklisted UL PRBs and their mapping from gNB config */ -static int get_prb_blacklist(uint8_t instance, uint16_t *prbbl) +static int get_prb_blacklist(uint16_t *prbbl) { paramdef_t GNBSParams[] = GNBSPARAMS_DESC; paramlist_def_t GNBParamList = {GNB_CONFIG_STRING_GNB_LIST, NULL, 0}; @@ -870,7 +870,7 @@ void RCconfig_NR_L1(void) // PRB Blacklist uint16_t prbbl[MAX_BWP_SIZE] = {0}; - int num_ulprbbl = get_prb_blacklist(j, prbbl); + int num_ulprbbl = get_prb_blacklist(prbbl); if (num_ulprbbl != -1) { RC.gNB[j]->num_ulprbbl = num_ulprbbl; LOG_D(NR_PHY, "Copying %d blacklisted PRB to L1 context\n", RC.gNB[j]->num_ulprbbl); @@ -943,7 +943,7 @@ bool is_pattern2_config(paramdef_t *param) return true; } -static NR_ServingCellConfigCommon_t *get_scc_config(configmodule_interface_t *cfg, int minRXTXTIME, int do_SRS) +static NR_ServingCellConfigCommon_t *get_scc_config(int minRXTXTIME, int do_SRS) { NR_ServingCellConfigCommon_t *scc = calloc_or_fail(1, sizeof(*scc)); uint64_t ssb_bitmap=0xff; @@ -1039,8 +1039,7 @@ static NR_ServingCellConfigCommon_t *get_scc_config(configmodule_interface_t *cf return scc; } -static int read_du_cell_info(configmodule_interface_t *cfg, - bool separate_du, +static int read_du_cell_info(bool separate_du, uint32_t *gnb_id, uint64_t *gnb_du_id, char **name, @@ -1211,7 +1210,7 @@ static f1ap_setup_req_t *RC_read_F1Setup(uint64_t id, return req; } -static nr_ptrs_config_t *get_ptrs_config(int gnb_idx) +static nr_ptrs_config_t *get_ptrs_config() { char aprefix[MAX_OPTNAME_SIZE * 2 + 8]; snprintf(aprefix, sizeof(aprefix), "%s.[%i]", GNB_CONFIG_STRING_GNB_LIST, 0); @@ -1471,7 +1470,7 @@ void RCconfig_nr_macrlc(configmodule_interface_t *cfg) AssertFatal(config.maxMIMO_layers != 0 && config.maxMIMO_layers <= tot_ant, "Invalid maxMIMO_layers %d\n", config.maxMIMO_layers); config.redcap = get_redcap_config(0); - config.ptrs = get_ptrs_config(0); + config.ptrs = get_ptrs_config(); char aprefix[MAX_OPTNAME_SIZE * 2 + 8]; snprintf(aprefix, sizeof(aprefix), "%s.[%d].%s", GNB_CONFIG_STRING_GNB_LIST, 0, GNB_CONFIG_STRING_TIMERS_CONFIG); @@ -1523,7 +1522,7 @@ void RCconfig_nr_macrlc(configmodule_interface_t *cfg) config.num_agg_level_candidates[PDCCH_AGG_LEVEL8], config.num_agg_level_candidates[PDCCH_AGG_LEVEL16]); - NR_ServingCellConfigCommon_t *scc = get_scc_config(cfg, config.minRXTXTIME, config.do_SRS); + NR_ServingCellConfigCommon_t *scc = get_scc_config(config.minRXTXTIME, config.do_SRS); // BWP get_bwp_config(&config, scc); AssertFatal(config.num_additional_bwps <= 4, "Impossible to configure more than 4 additional BWPs\n"); @@ -1622,7 +1621,7 @@ void RCconfig_nr_macrlc(configmodule_interface_t *cfg) RC.nrmac[j]->identity_pm = *(MacRLC_ParamList.paramarray[j][MACRLC_IDENTITY_PM_IDX].u8ptr); // PRB Blacklist uint16_t prbbl[MAX_BWP_SIZE] = {0}; - int num_ulprbbl = get_prb_blacklist(j, prbbl); + int num_ulprbbl = get_prb_blacklist(prbbl); if (num_ulprbbl != -1) { LOG_I(NR_PHY, "Copying %d blacklisted PRB to L1 context\n", num_ulprbbl); memcpy(RC.nrmac[j]->ulprbbl, prbbl, MAX_BWP_SIZE * sizeof(prbbl[0])); @@ -1667,7 +1666,7 @@ void RCconfig_nr_macrlc(configmodule_interface_t *cfg) uint32_t gnb_id = 0; char *name = NULL; f1ap_served_cell_info_t info; - read_du_cell_info(cfg, NODE_IS_DU(node_type), &gnb_id, &gnb_du_id, &name, &info, 1); + read_du_cell_info(NODE_IS_DU(node_type), &gnb_id, &gnb_du_id, &name, &info, 1); NR_COMMON_channels_t *cc = &RC.nrmac[0]->common_channels[0]; cc->du_SIBs = fill_du_sibs(GNBParamList.paramarray[0]); diff --git a/openair2/LAYER2/NR_MAC_UE/config_ue.c b/openair2/LAYER2/NR_MAC_UE/config_ue.c index 2a5c8e041d..d16653487f 100644 --- a/openair2/LAYER2/NR_MAC_UE/config_ue.c +++ b/openair2/LAYER2/NR_MAC_UE/config_ue.c @@ -717,9 +717,7 @@ static void update_ss(void *ue_ss_in, void *nw_ss_in) } } -static void configure_common_ss_coreset(const NR_UE_MAC_INST_t *mac, - NR_BWP_PDCCH_t *pdcch, - NR_PDCCH_ConfigCommon_t *pdcch_ConfigCommon) +static void configure_common_ss_coreset(NR_BWP_PDCCH_t *pdcch, NR_PDCCH_ConfigCommon_t *pdcch_ConfigCommon) { if (!pdcch_ConfigCommon) return; @@ -1778,7 +1776,7 @@ static void configure_common_BWP_dl(NR_UE_MAC_INST_t *mac, int bwp_id, NR_BWP_Do NR_BWP_PDCCH_t *pdcch = &mac->config_BWP_PDCCH[bwp_id]; if (dl_common->pdcch_ConfigCommon) { if (dl_common->pdcch_ConfigCommon->present == NR_SetupRelease_PDCCH_ConfigCommon_PR_setup) - configure_common_ss_coreset(mac, pdcch, dl_common->pdcch_ConfigCommon->choice.setup); + configure_common_ss_coreset(pdcch, dl_common->pdcch_ConfigCommon->choice.setup); if (dl_common->pdcch_ConfigCommon->present == NR_SetupRelease_PDCCH_ConfigCommon_PR_release) release_common_ss_cset(pdcch); } diff --git a/openair2/LAYER2/NR_MAC_UE/config_ue_sl.c b/openair2/LAYER2/NR_MAC_UE/config_ue_sl.c index e6d872da81..809ce054f4 100644 --- a/openair2/LAYER2/NR_MAC_UE/config_ue_sl.c +++ b/openair2/LAYER2/NR_MAC_UE/config_ue_sl.c @@ -394,8 +394,7 @@ int nr_rrc_mac_config_req_sl_preconfig(module_id_t module_id, //Copies the values of SSB time allocation from ASN format to MAC context -static void sl_mac_config_ssb_time_alloc(uint8_t module_id, - NR_SL_SSB_TimeAllocation_r16_t *sl_SSB_TimeAllocation_r16, +static void sl_mac_config_ssb_time_alloc(NR_SL_SSB_TimeAllocation_r16_t *sl_SSB_TimeAllocation_r16, sl_ssb_timealloc_t *ssb_time_alloc) { @@ -432,9 +431,7 @@ void nr_rrc_mac_transmit_slss_req(module_id_t module_id, sl_mac->tx_sl_bch.num_ssb = 0; sl_mac->tx_sl_bch.ssb_slot = 0; - sl_mac_config_ssb_time_alloc(module_id, - ssb_ta, - &sl_mac->tx_sl_bch.ssb_time_alloc); + sl_mac_config_ssb_time_alloc(ssb_ta, &sl_mac->tx_sl_bch.ssb_time_alloc); LOG_I(NR_MAC,"[UE%d]SL RRC->MAC: TX SLSS REQ SLSS-id:%d, SL-MIB:%x, numssb:%d, offset:%d, interval:%d\n", module_id, sl_mac->tx_sl_bch.slss_id, @@ -489,9 +486,7 @@ void nr_rrc_mac_config_req_sl_mib(module_id_t module_id, sl_mac->rx_sl_bch.num_ssb = 0; sl_mac->rx_sl_bch.ssb_slot = 0; - sl_mac_config_ssb_time_alloc(module_id, - ssb_ta, - &sl_mac->rx_sl_bch.ssb_time_alloc); + sl_mac_config_ssb_time_alloc(ssb_ta, &sl_mac->rx_sl_bch.ssb_time_alloc); LOG_I(NR_MAC,"[UE%d]SL RRC->MAC: RX SLSS REQ SLSS-id:%d, SL-MIB:%x, numssb:%d, offset:%d, interval:%d\n", module_id, sl_mac->rx_sl_bch.slss_id, diff --git a/openair2/LAYER2/NR_MAC_UE/mac_proto.h b/openair2/LAYER2/NR_MAC_UE/mac_proto.h index 9ee1bfab28..d01c014527 100644 --- a/openair2/LAYER2/NR_MAC_UE/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_proto.h @@ -166,11 +166,7 @@ typedef struct { enum { b_none, b_long, b_short, b_short_trunc, b_long_trunc } type_bsr; } type_bsr_t; -int nr_write_ce_ulsch_pdu(uint8_t *mac_ce, - NR_UE_MAC_INST_t *mac, - NR_SINGLE_ENTRY_PHR_MAC_CE *power_headroom, - const type_bsr_t *bsr, - uint8_t *mac_ce_end); +int nr_write_ce_ulsch_pdu(uint8_t *mac_ce, NR_SINGLE_ENTRY_PHR_MAC_CE *power_headroom, const type_bsr_t *bsr, uint8_t *mac_ce_end); void ue_dci_configuration(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_request_t *dl_config, const frame_t frame, const int slot); void set_precoding_information_parameters(nfapi_nr_ue_pusch_pdu_t *pusch_config_pdu, @@ -241,10 +237,9 @@ int get_sum_delta_pucch(NR_UE_MAC_INST_t *mac, int slot, frame_t frame); void ul_ports_config(NR_UE_MAC_INST_t *mac, int *n_front_load_symb, nfapi_nr_ue_pusch_pdu_t *pusch_config_pdu, - dci_pdu_rel15_t *dci, - nr_dci_format_t dci_format); + dci_pdu_rel15_t *dci); -bool init_RA(NR_UE_MAC_INST_t *mac, int frame); +bool init_RA(NR_UE_MAC_INST_t *mac); /* Random Access */ /* \brief This function schedules the PRACH according to prach_ConfigurationIndex and TS 38.211 tables 6.3.3.2.x @@ -262,7 +257,7 @@ void configure_csi_resource_mapping(fapi_nr_dl_config_csirs_pdu_rel15_t *csirs_c bool is_lcid_suspended(NR_UE_MAC_INST_t *mac, int lcid); void nr_ra_contention_resolution_failed(NR_UE_MAC_INST_t *mac); -void nr_ra_succeeded(NR_UE_MAC_INST_t *mac, const uint8_t gNB_index, const frame_t frame, const int slot); +void nr_ra_succeeded(NR_UE_MAC_INST_t *mac, const frame_t frame, const int slot); void nr_ra_backoff_setting(RA_config_t *ra); void nr_get_RA_window(NR_UE_MAC_INST_t *mac); void prepare_msg4_msgb_feedback(NR_UE_MAC_INST_t *mac, int pid, int ack_nack); @@ -283,7 +278,7 @@ int16_t get_prach_tx_power(NR_UE_MAC_INST_t *mac); void schedule_RA_after_SR_failure(NR_UE_MAC_INST_t *mac); void nr_rar_not_successful(NR_UE_MAC_INST_t *mac); void ra_resource_selection(NR_UE_MAC_INST_t *mac); -void nr_Msg3_transmitted(NR_UE_MAC_INST_t *mac, uint8_t CC_id, frame_t frameP, slot_t slotP, uint8_t gNB_id); +void nr_Msg3_transmitted(NR_UE_MAC_INST_t *mac); void trigger_MAC_UE_RA(NR_UE_MAC_INST_t *mac, dci_pdu_rel15_t *pdcch_order); void nr_get_Msg3_MsgA_PUSCH_payload(NR_UE_MAC_INST_t *mac, uint8_t *buf, int TBS_max); void handle_time_alignment_timer_expired(NR_UE_MAC_INST_t *mac); diff --git a/openair2/LAYER2/NR_MAC_UE/mac_tables.c b/openair2/LAYER2/NR_MAC_UE/mac_tables.c index a313600609..90cdc26fe4 100644 --- a/openair2/LAYER2/NR_MAC_UE/mac_tables.c +++ b/openair2/LAYER2/NR_MAC_UE/mac_tables.c @@ -470,8 +470,7 @@ void set_antenna_port_parameters(fapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_pdu, void ul_ports_config(NR_UE_MAC_INST_t *mac, int *n_front_load_symb, nfapi_nr_ue_pusch_pdu_t *pusch_config_pdu, - dci_pdu_rel15_t *dci, - nr_dci_format_t dci_format) + dci_pdu_rel15_t *dci) { uint8_t rank = pusch_config_pdu->nrOfLayers; NR_PUSCH_Config_t *pusch_Config = mac->current_UL_BWP->pusch_Config; diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c index 47277f8a66..a93ad9f8d2 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c @@ -819,7 +819,7 @@ static void setup_ra_response_window(NR_UE_MAC_INST_t *mac, // Random Access procedure initialization as per 5.1.1 and initialization of variables specific // to Random Access type as specified in clause 5.1.1a (3GPP TS 38.321 version 16.2.1 Release 16) -bool init_RA(NR_UE_MAC_INST_t *mac, int frame) +bool init_RA(NR_UE_MAC_INST_t *mac) { RA_config_t *ra = &mac->ra; LOG_D(NR_MAC, "Initialization of RA\n"); @@ -1023,7 +1023,7 @@ bool init_RA(NR_UE_MAC_INST_t *mac, int frame) return true; } -void nr_Msg3_transmitted(NR_UE_MAC_INST_t *mac, uint8_t CC_id, frame_t frameP, slot_t slotP, uint8_t gNB_id) +void nr_Msg3_transmitted(NR_UE_MAC_INST_t *mac) { RA_config_t *ra = &mac->ra; NR_RACH_ConfigCommon_t *nr_rach_ConfigCommon = mac->current_UL_BWP->rach_ConfigCommon; @@ -1109,7 +1109,7 @@ void nr_get_Msg3_MsgA_PUSCH_payload(NR_UE_MAC_INST_t *mac, uint8_t *buf, int TBS // according to section 5 of 3GPP TS 38.321 version 16.2.1 Release 16 // todo: // - complete handling of received contention-based RA preamble -void nr_ra_succeeded(NR_UE_MAC_INST_t *mac, const uint8_t gNB_index, const frame_t frame, const int slot) +void nr_ra_succeeded(NR_UE_MAC_INST_t *mac, const frame_t frame, const int slot) { RA_config_t *ra = &mac->ra; diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_power_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_power_procedures.c index a409cbe653..668efba2f5 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_power_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_power_procedures.c @@ -59,7 +59,7 @@ static const int nb_symbols_excluding_dmrs[11][2][2] }; // ∆MPR according to Table 6.2.2-3 38.101-1 -static float get_delta_mpr(uint16_t nr_band, frame_type_t frame_type, int scs, int channel_bandwidth, int n_prbs, int start_prb, int power_class) +static float get_delta_mpr(uint16_t nr_band, frame_type_t frame_type, int scs, int channel_bandwidth, int power_class) { if (compare_relative_ul_channel_bw(nr_band, scs, channel_bandwidth, frame_type)) { if (power_class == 3) { @@ -191,7 +191,7 @@ float nr_get_Pcmax(int p_Max, int delta_TC = 0; float MPR = get_mpr(Qm, N_RB_UL, is_transform_precoding, n_prbs, start_prb, power_class); - float delta_MPR = get_delta_mpr(nr_band, frame_type, scs, channel_bandwidth, n_prbs, start_prb, power_class); + float delta_MPR = get_delta_mpr(nr_band, frame_type, scs, channel_bandwidth, power_class); int A_MPR = 0; // TODO too complicated to implement for now (see 6.2.3 in 38.101-1) int delta_rx_SRS = 0; // TODO for SRS int P_MPR = 0; // to ensure compliance with applicable electromagnetic energy absorption requirements diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c index 52ed7580c6..2c3ee539fc 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c @@ -3296,7 +3296,7 @@ static void nr_ue_process_rar(NR_UE_MAC_INST_t *mac, nr_downlink_indication_t *d rar = (NR_MAC_RAR *) (dlsch_buffer + n_subheaders + (n_subPDUs - 1) * sizeof(NR_MAC_RAR)); handle_rar_reception(mac, rar, frame, slot); if (ra->cfra) - nr_ra_succeeded(mac, dl_info->gNB_index, frame, slot); + nr_ra_succeeded(mac, frame, slot); break; } if (rarh->E == 0) { @@ -3818,12 +3818,7 @@ static bool check_ra_contention_resolution(const uint8_t *pdu, const uint8_t *co return true; } -static int nr_ue_validate_successrar(uint8_t *pduP, - int32_t pdu_len, - NR_UE_MAC_INST_t *mac, - uint8_t gNB_index, - frame_t frameP, - int slot) +static int nr_ue_validate_successrar(uint8_t *pduP, int32_t pdu_len, NR_UE_MAC_INST_t *mac, frame_t frameP, int slot) { // TS 38.321 - Figure 6.1.5a-1: BI MAC subheader // TS 38.321 - Figure 6.1.5a-3: SuccessRAR MAC subheader @@ -3885,7 +3880,7 @@ static int nr_ue_validate_successrar(uint8_t *pduP, if (ra->RA_active && ra_success) { nr_timer_stop(&ra->response_window_timer); - nr_ra_succeeded(mac, gNB_index, frameP, slot); + nr_ra_succeeded(mac, frameP, slot); } else if (!ra_success) { nr_ra_backoff_setting(ra); } @@ -3943,7 +3938,6 @@ static void nr_ue_process_mac_pdu(NR_UE_MAC_INST_t *mac, nr_downlink_indication_ fapi_nr_pdsch_pdu_t *pdsch_pdu = &(dl_info->rx_ind->rx_indication_body + pdu_id)->pdsch_pdu; uint8_t *pduP = pdsch_pdu->pdu; int32_t pdu_len = (int32_t)pdsch_pdu->pdu_length; - uint8_t gNB_index = dl_info->gNB_index; uint8_t CC_id = dl_info->cc_id; uint8_t done = 0; RA_config_t *ra = &mac->ra; @@ -3963,7 +3957,7 @@ static void nr_ue_process_mac_pdu(NR_UE_MAC_INST_t *mac, nr_downlink_indication_ dl_info->rx_ind->number_pdus); if (ra->ra_type == RA_2_STEP && ra->ra_state == nrRA_WAIT_MSGB) { - int n = nr_ue_validate_successrar(pduP, pdu_len, mac, gNB_index, frameP, slot); + int n = nr_ue_validate_successrar(pduP, pdu_len, mac, frameP, slot); pduP += n; pdu_len -= n; } @@ -4095,7 +4089,7 @@ static void nr_ue_process_mac_pdu(NR_UE_MAC_INST_t *mac, nr_downlink_indication_ bool ra_success = check_ra_contention_resolution(&pduP[1], ra->cont_res_id); if (ra->RA_active && ra_success) { - nr_ra_succeeded(mac, gNB_index, frameP, slot); + nr_ra_succeeded(mac, frameP, slot); } else if (!ra_success) { // consider this Contention Resolution not successful and discard the successfully decoded MAC PDU nr_ra_contention_resolution_failed(mac); @@ -4135,14 +4129,9 @@ static void nr_ue_process_mac_pdu(NR_UE_MAC_INST_t *mac, nr_downlink_indication_ * Function: generating MAC CEs (MAC CE and subheader) for the ULSCH PDU * Parameters: * @mac_ce pointer to the MAC sub-PDUs including the MAC CEs - * @mac pointer to the MAC instance * Return: number of written bytes */ -int nr_write_ce_ulsch_pdu(uint8_t *mac_ce, - NR_UE_MAC_INST_t *mac, - NR_SINGLE_ENTRY_PHR_MAC_CE *power_headroom, - const type_bsr_t *bsr, - uint8_t *mac_ce_end) +int nr_write_ce_ulsch_pdu(uint8_t *mac_ce, NR_SINGLE_ENTRY_PHR_MAC_CE *power_headroom, const type_bsr_t *bsr, uint8_t *mac_ce_end) { uint8_t *pdu = mac_ce; if (power_headroom) { diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c index d06c8302a6..cc933b50e4 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c @@ -324,7 +324,7 @@ fapi_nr_dl_config_request_t *get_dl_config_request(NR_UE_MAC_INST_t *mac, int sl return &mac->dl_config_request[slot]; } -void ul_layers_config(NR_UE_MAC_INST_t *mac, nfapi_nr_ue_pusch_pdu_t *pusch_config_pdu, dci_pdu_rel15_t *dci, nr_dci_format_t dci_format) +static void ul_layers_config(NR_UE_MAC_INST_t *mac, nfapi_nr_ue_pusch_pdu_t *pusch_config_pdu, dci_pdu_rel15_t *dci) { NR_UE_UL_BWP_t *current_UL_BWP = mac->current_UL_BWP; NR_SRS_Config_t *srs_config = current_UL_BWP->srs_Config; @@ -583,8 +583,8 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac, else pusch_config_pdu->num_dmrs_cdm_grps_no_data = 2; } else if (dci_format == NR_UL_DCI_FORMAT_0_1) { - ul_layers_config(mac, pusch_config_pdu, dci, dci_format); - ul_ports_config(mac, &dmrslength, pusch_config_pdu, dci, dci_format); + ul_layers_config(mac, pusch_config_pdu, dci); + ul_ports_config(mac, &dmrslength, pusch_config_pdu, dci); } else { LOG_E(NR_MAC, "UL grant from DCI format %d is not handled...\n", dci_format); mac->stats.bad_dci++; @@ -1459,7 +1459,7 @@ static void nr_update_sr(NR_UE_MAC_INST_t *mac, bool BSRsent) } } -static void nr_update_rlc_buffers_status(NR_UE_MAC_INST_t *mac, frame_t frameP, slot_t slotP, uint8_t gNB_index) +static void nr_update_rlc_buffers_status(NR_UE_MAC_INST_t *mac, frame_t frameP, slot_t slotP) { for (int i = 0; i < mac->lc_ordered_list.count; i++) { nr_lcordered_info_t *lc_info = mac->lc_ordered_list.array[i]; @@ -1987,10 +1987,8 @@ static uint8_t nr_locate_BsrIndexByBufferSize(int size, int value) } static void nr_ue_get_sdu_mac_ce_pre(NR_UE_MAC_INST_t *mac, - int CC_id, frame_t frame, slot_t slot, - uint8_t gNB_index, uint8_t *ulsch_buffer, uint32_t buflen, uint32_t *LCG_bytes, @@ -2172,8 +2170,7 @@ static void nr_ue_get_sdu_mac_ce_post(NR_UE_MAC_INST_t *mac, } } - int size = - nr_write_ce_ulsch_pdu(mac_ce_p->cur_ptr, mac, mac_ce_p->phr_len ? &mac_ce_p->phr : NULL, &mac_ce_p->bsr, mac_ce_p->pdu_end); + int size = nr_write_ce_ulsch_pdu(mac_ce_p->cur_ptr, mac_ce_p->phr_len ? &mac_ce_p->phr : NULL, &mac_ce_p->bsr, mac_ce_p->pdu_end); LOG_D(NR_MAC, "Added %d bytes of BSR\n", size); mac_ce_p->cur_ptr += size; } @@ -2272,7 +2269,6 @@ static uint select_logical_channels(NR_UE_MAC_INST_t *mac, nr_lcordered_info_t * static bool fill_mac_sdu(NR_UE_MAC_INST_t *mac, frame_t frame, slot_t slot, - uint8_t gNB_index, int lcid, uint count_same_priority_lcids, uint32_t buflen_ep, @@ -2406,18 +2402,14 @@ static bool fill_mac_sdu(NR_UE_MAC_INST_t *mac, to generate the complete MAC PDU with sub-headers and MAC CEs according to ULSCH MAC PDU generation (6.1.2 TS 38.321) the selected sub-header for the payload sub-PDUs is NR_MAC_SUBHEADER_LONG * @module_idP Module ID - * @CC_id Component Carrier index * @frame current UL frame * @slot current UL slot - * @gNB_index gNB index * @ulsch_buffer Pointer to ULSCH PDU * @buflen TBS */ static uint8_t nr_ue_get_sdu(NR_UE_MAC_INST_t *mac, - int CC_id, frame_t frame, slot_t slot, - uint8_t gNB_index, uint8_t *ulsch_buffer, const uint32_t buflen, int tx_power, @@ -2436,7 +2428,7 @@ static uint8_t nr_ue_get_sdu(NR_UE_MAC_INST_t *mac, uint32_t LCG_bytes[NR_MAX_NUM_LCGID] = {0}; nr_update_bsr(mac, LCG_bytes); - nr_ue_get_sdu_mac_ce_pre(mac, CC_id, frame, slot, gNB_index, ulsch_buffer, buflen, LCG_bytes, &mac_ce_info, tx_power, P_CMAX); + nr_ue_get_sdu_mac_ce_pre(mac, frame, slot, ulsch_buffer, buflen, LCG_bytes, &mac_ce_info, tx_power, P_CMAX); LOG_D(NR_MAC, "[UE %d] [%d.%d] process UL transport block with size TBS = %d bytes, number of existing LCids %d \n", @@ -2510,7 +2502,6 @@ static uint8_t nr_ue_get_sdu(NR_UE_MAC_INST_t *mac, if (!fill_mac_sdu(mac, frame, slot, - gNB_index, lcid, count_same_priority_lcids, buflen_ep, @@ -2563,12 +2554,10 @@ void nr_ue_ul_scheduler(NR_UE_MAC_INST_t *mac, nr_uplink_indication_t *ul_info) int cc_id = ul_info->cc_id; frame_t frame_tx = ul_info->frame; slot_t slot_tx = ul_info->slot; - uint32_t gNB_index = ul_info->gNB_index; - RA_config_t *ra = &mac->ra; if (mac->state == UE_PERFORMING_RA && ra->ra_state == nrRA_UE_IDLE) { - init_RA(mac, frame_tx); + init_RA(mac); // perform the Random Access Resource selection procedure (see clause 5.1.2 and .2a) ra_resource_selection(mac); } @@ -2579,7 +2568,7 @@ void nr_ue_ul_scheduler(NR_UE_MAC_INST_t *mac, nr_uplink_indication_t *ul_info) bool BSRsent = false; if (mac->state == UE_CONNECTED) { nr_ue_periodic_srs_scheduling(mac, frame_tx, slot_tx); - nr_update_rlc_buffers_status(mac, frame_tx, slot_tx, gNB_index); + nr_update_rlc_buffers_status(mac, frame_tx, slot_tx); } // Schedule ULSCH only if the current frame and slot match those in ul_config_req @@ -2637,7 +2626,7 @@ void nr_ue_ul_scheduler(NR_UE_MAC_INST_t *mac, nr_uplink_indication_t *ul_info) pdu->rb_size, pdu->rb_start); - nr_ue_get_sdu(mac, cc_id, frame_tx, slot_tx, gNB_index, ulsch_input_buffer, TBS_bytes, tx_power, P_CMAX, &BSRsent); + nr_ue_get_sdu(mac, frame_tx, slot_tx, ulsch_input_buffer, TBS_bytes, tx_power, P_CMAX, &BSRsent); pdu->tx_request_body.fapiTxPdu = ulsch_input_buffer; pdu->tx_request_body.pdu_length = TBS_bytes; number_of_pdus++; @@ -2654,11 +2643,11 @@ void nr_ue_ul_scheduler(NR_UE_MAC_INST_t *mac, nr_uplink_indication_t *ul_info) LOG_I(NR_MAC, "[RAPROC][%d.%d] RA-Msg3 retransmitted\n", frame_tx, slot_tx); // 38.321 restart the ra-ContentionResolutionTimer at each HARQ retransmission in the first symbol after the end of the Msg3 // transmission - nr_Msg3_transmitted(mac, cc_id, frame_tx, slot_tx, gNB_index); + nr_Msg3_transmitted(mac); } if (ra->ra_state == nrRA_WAIT_RAR && !ra->cfra) { LOG_A(NR_MAC, "[RAPROC][%d.%d] RA-Msg3 transmitted\n", frame_tx, slot_tx); - nr_Msg3_transmitted(mac, cc_id, frame_tx, slot_tx, gNB_index); + nr_Msg3_transmitted(mac); } if (ra->ra_state == nrRA_WAIT_MSGB && !ra->cfra) { LOG_A(NR_MAC, "[RAPROC][%d.%d] RA-MsgA-PUSCH transmitted\n", frame_tx, slot_tx); diff --git a/openair2/LAYER2/NR_MAC_UE/tests/test_nr_ue_ra_procedures.cpp b/openair2/LAYER2/NR_MAC_UE/tests/test_nr_ue_ra_procedures.cpp index f7fc520d06..cdbb3e9e3e 100644 --- a/openair2/LAYER2/NR_MAC_UE/tests/test_nr_ue_ra_procedures.cpp +++ b/openair2/LAYER2/NR_MAC_UE/tests/test_nr_ue_ra_procedures.cpp @@ -101,9 +101,8 @@ TEST(test_init_ra, four_step_cbra) mac.frame_structure.frame_type = TDD; mac.frame_structure.numb_slots_frame = 20; mac.frequency_range = FR1; - int frame = 151; - init_RA(&mac, frame); + init_RA(&mac); EXPECT_EQ(mac.ra.ra_type, RA_4_STEP); EXPECT_EQ(mac.state, UE_PERFORMING_RA); @@ -135,14 +134,13 @@ TEST(test_init_ra, four_step_cfra) mac.frame_structure.frame_type = TDD; mac.frame_structure.numb_slots_frame = 20; mac.frequency_range = FR1; - int frame = 151; NR_RACH_ConfigDedicated_t rach_ConfigDedicated = {0}; NR_CFRA_t cfra; rach_ConfigDedicated.cfra = &cfra; ra->rach_ConfigDedicated = &rach_ConfigDedicated; - init_RA(&mac, frame); + init_RA(&mac); EXPECT_EQ(mac.ra.ra_type, RA_4_STEP); EXPECT_EQ(mac.state, UE_PERFORMING_RA); diff --git a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c index 73845551af..5fb8ad78dd 100644 --- a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c +++ b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c @@ -106,7 +106,6 @@ void print_ue_mac_stats(const module_id_t mod, const int frame_rx, const int slo static int handle_bcch_bch(NR_UE_MAC_INST_t *mac, int cc_id, unsigned int gNB_index, - void *phy_data, uint8_t *pduP, unsigned int additional_bits, uint32_t ssb_index_mod8, @@ -149,17 +148,13 @@ static int handle_bcch_dlsch(NR_UE_MAC_INST_t *mac, } // L2 Abstraction Layer -static nr_dci_format_t handle_dci(NR_UE_MAC_INST_t *mac, - unsigned int gNB_index, - frame_t frame, - int slot, - fapi_nr_dci_indication_pdu_t *dci) +static nr_dci_format_t handle_dci(NR_UE_MAC_INST_t *mac, frame_t frame, int slot, fapi_nr_dci_indication_pdu_t *dci) { // if notification of a reception of a PDCCH transmission of the SpCell is received from lower layers // if the C-RNTI MAC CE was included in Msg3 // consider this Contention Resolution successful if (mac->msg3_C_RNTI && mac->ra.ra_state == nrRA_WAIT_CONTENTION_RESOLUTION) - nr_ra_succeeded(mac, gNB_index, frame, slot); + nr_ra_succeeded(mac, frame, slot); // suspend RAR response window timer // (in RFsim running multiple slot in parallel it might expire while decoding MSG2) @@ -245,11 +240,7 @@ static uint32_t nr_ue_dl_processing(NR_UE_MAC_INST_t *mac, nr_downlink_indicatio LOG_T(MAC, "[L2][IF MODULE][DL INDICATION][DCI_IND]\n"); for (int i = 0; i < dl_info->dci_ind->number_of_dcis; i++) { LOG_T(MAC, ">>>NR_IF_Module i=%d, dl_info->dci_ind->number_of_dcis=%d\n", i, dl_info->dci_ind->number_of_dcis); - nr_dci_format_t dci_format = handle_dci(mac, - dl_info->gNB_index, - dl_info->frame, - dl_info->slot, - dl_info->dci_ind->dci_list + i); + nr_dci_format_t dci_format = handle_dci(mac, dl_info->frame, dl_info->slot, dl_info->dci_ind->dci_list + i); /* The check below filters out UL_DCIs which are being processed as DL_DCIs. */ if (dci_format != NR_DL_DCI_FORMAT_1_0 && dci_format != NR_DL_DCI_FORMAT_1_1) { @@ -291,7 +282,6 @@ static uint32_t nr_ue_dl_processing(NR_UE_MAC_INST_t *mac, nr_downlink_indicatio ret_mask |= (handle_bcch_bch(mac, dl_info->cc_id, dl_info->gNB_index, - dl_info->phy_data, rx_indication_body.ssb_pdu.pdu, rx_indication_body.ssb_pdu.additional_bits, rx_indication_body.ssb_pdu.ssb_index, From d6858d01a070083398c05d88f06d674e1d68af68 Mon Sep 17 00:00:00 2001 From: Laurent THOMAS Date: Fri, 27 Feb 2026 16:53:58 +0100 Subject: [PATCH 15/44] make distinct names for structs and tyepdefs --- common/utils/actor/actor.h | 2 +- common/utils/actor/tests/test_actor.cpp | 2 +- common/utils/barrier/barrier.h | 2 +- nfapi/open-nFAPI/pnf/inc/pnf.h | 11 +-- nfapi/open-nFAPI/pnf/inc/pnf_p7.h | 10 +- .../pnf/public_inc/nfapi_pnf_interface.h | 4 +- nfapi/open-nFAPI/vnf/inc/vnf.h | 13 +-- nfapi/open-nFAPI/vnf/inc/vnf_p7.h | 11 +-- .../vnf/public_inc/nfapi_vnf_interface.h | 5 +- openair1/PHY/defs_RU.h | 8 +- openair1/PHY/defs_common.h | 3 +- openair1/PHY/defs_nr_common.h | 6 +- openair1/SCHED/nfapi_lte_dummy.c | 7 +- openair1/SCHED_NR/nr_ru_procedures.c | 2 +- openair2/COMMON/e1ap_messages_types.h | 6 +- openair2/COMMON/f1ap_messages_types.h | 74 +++++++-------- openair2/F1AP/f1ap_du_task.h | 4 +- openair2/F1AP/lib/f1ap_lib_common.h | 12 +-- openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h | 4 +- openair2/LAYER2/NR_MAC_gNB/nr_radio_config.h | 7 +- openair2/LAYER2/nr_pdcp/nr_pdcp_entity.c | 16 ++-- openair2/LAYER2/nr_pdcp/nr_pdcp_entity.h | 51 +++++----- openair2/LAYER2/nr_rlc/nr_rlc_entity.c | 59 +++++------- openair2/LAYER2/nr_rlc/nr_rlc_entity.h | 95 ++++++++----------- openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c | 3 +- .../tests/benchmark_nr_rlc_am_entity.cpp | 6 +- openair2/LAYER2/nr_rlc/tests/test.c | 24 ++--- .../nr_rlc/tests/test_nr_rlc_am_entity.cpp | 6 +- openair2/LAYER2/rlc_v2/rlc_entity.c | 49 +++++----- openair2/LAYER2/rlc_v2/rlc_entity.h | 79 +++++++-------- openair2/NR_UE_PHY_INTERFACE/NR_Packet_Drop.c | 2 +- openair2/NR_UE_PHY_INTERFACE/NR_Packet_Drop.h | 9 +- openair2/RRC/LTE/rrc_UE.c | 5 +- openair2/RRC/NR/rrc_gNB.c | 2 +- openair2/RRC/NR/rrc_gNB_du.c | 4 +- openair2/RRC/NR/rrc_gNB_du.h | 4 +- openair2/RRC/NR/rrc_gNB_mobility.c | 2 +- openair2/RRC/NR/rrc_gNB_mobility.h | 1 - 38 files changed, 264 insertions(+), 346 deletions(-) diff --git a/common/utils/actor/actor.h b/common/utils/actor/actor.h index 023533d2d7..8993916d39 100644 --- a/common/utils/actor/actor.h +++ b/common/utils/actor/actor.h @@ -29,7 +29,7 @@ #define SHUTDOWN_ACTOR(ptr) shutdown_actor((Actor_t *)ptr); -typedef struct Actor_t { +typedef struct { notifiedFIFO_t fifo; bool terminate; pthread_t thread; diff --git a/common/utils/actor/tests/test_actor.cpp b/common/utils/actor/tests/test_actor.cpp index 5f613846a2..a38046e5f8 100644 --- a/common/utils/actor/tests/test_actor.cpp +++ b/common/utils/actor/tests/test_actor.cpp @@ -93,7 +93,7 @@ TEST(DISABLED_actor, thread_safety_with_core_affinity) // Thread safety can be ensured through data separation, here using C inheritance-like // model -typedef struct TestActor_t { +typedef struct { Actor_t actor; int count; } TestActor_t; diff --git a/common/utils/barrier/barrier.h b/common/utils/barrier/barrier.h index e27b56e766..78fc36264d 100644 --- a/common/utils/barrier/barrier.h +++ b/common/utils/barrier/barrier.h @@ -27,7 +27,7 @@ typedef void (*callback_t)(void*); /// @brief This thread barrier allows modifying the maximum joins after it is initialized -typedef struct dynamic_barrier_t { +typedef struct { pthread_mutex_t barrier_lock; int completed_jobs; int max_joins; diff --git a/nfapi/open-nFAPI/pnf/inc/pnf.h b/nfapi/open-nFAPI/pnf/inc/pnf.h index 2dc2ce9de6..380890e07d 100644 --- a/nfapi/open-nFAPI/pnf/inc/pnf.h +++ b/nfapi/open-nFAPI/pnf/inc/pnf.h @@ -20,20 +20,17 @@ #include "nfapi_pnf_interface.h" +typedef struct pnf_s { + nfapi_pnf_config_t _public; -struct pnf_t { - - nfapi_pnf_config_t _public; - - int p5_sock; + int p5_sock; uint8_t tx_message_buffer[NFAPI_MAX_PACKED_MESSAGE_SIZE]; uint8_t sctp; uint8_t terminate; -}; - +} pnf_t; int pnf_connect(pnf_t *pnf); int pnf_message_pump(pnf_t *pnf); diff --git a/nfapi/open-nFAPI/pnf/inc/pnf_p7.h b/nfapi/open-nFAPI/pnf/inc/pnf_p7.h index 3040d9de09..3f6678fc65 100644 --- a/nfapi/open-nFAPI/pnf/inc/pnf_p7.h +++ b/nfapi/open-nFAPI/pnf/inc/pnf_p7.h @@ -80,12 +80,10 @@ typedef struct { } pnf_p7_rx_reassembly_queue_t; +typedef struct pnf_p7_s { + nfapi_pnf_p7_config_t _public; -struct pnf_p7_t { - - nfapi_pnf_p7_config_t _public; - - //private data + //private data int p7_sock; uint8_t terminate; @@ -138,7 +136,7 @@ struct pnf_p7_t { pnf_p7_stats_t stats; pnf_p7_nr_stats_t nr_stats; -}; +} pnf_p7_t; int pnf_p7_message_pump(pnf_p7_t* pnf_p7); int pnf_nr_p7_message_pump(pnf_p7_t* pnf_p7); diff --git a/nfapi/open-nFAPI/pnf/public_inc/nfapi_pnf_interface.h b/nfapi/open-nFAPI/pnf/public_inc/nfapi_pnf_interface.h index 306216a1d5..e4f863d7e2 100644 --- a/nfapi/open-nFAPI/pnf/public_inc/nfapi_pnf_interface.h +++ b/nfapi/open-nFAPI/pnf/public_inc/nfapi_pnf_interface.h @@ -31,8 +31,8 @@ extern "C" { #include #include "openair1/PHY/defs_gNB.h" -typedef struct pnf_t pnf_t; -typedef struct pnf_p7_t pnf_p7_t; +typedef struct pnf_s pnf_t; +typedef struct pnf_p7_s pnf_p7_t; /*! This enum is used to describe the states of the pnf */ diff --git a/nfapi/open-nFAPI/vnf/inc/vnf.h b/nfapi/open-nFAPI/vnf/inc/vnf.h index 39769314f4..98dd9df84d 100644 --- a/nfapi/open-nFAPI/vnf/inc/vnf.h +++ b/nfapi/open-nFAPI/vnf/inc/vnf.h @@ -20,19 +20,16 @@ #include "nfapi_vnf_interface.h" -struct vnf_t -{ +typedef struct vnf_s { + nfapi_vnf_config_t _public; - nfapi_vnf_config_t _public; - - uint8_t terminate; + uint8_t terminate; uint8_t sctp; uint8_t tx_message_buffer[NFAPI_MAX_PACKED_MESSAGE_SIZE]; - uint16_t next_phy_id; - -}; + uint16_t next_phy_id; +} vnf_t; int vnf_pack_and_send_p5_message(vnf_t* vnf, uint16_t p5_idx, nfapi_p4_p5_message_header_t* msg, uint16_t msg_len); diff --git a/nfapi/open-nFAPI/vnf/inc/vnf_p7.h b/nfapi/open-nFAPI/vnf/inc/vnf_p7.h index 7e04d69b49..47fa6053f1 100644 --- a/nfapi/open-nFAPI/vnf/inc/vnf_p7.h +++ b/nfapi/open-nFAPI/vnf/inc/vnf_p7.h @@ -107,11 +107,10 @@ typedef struct nfapi_vnf_p7_connection_info { } nfapi_vnf_p7_connection_info_t; -struct vnf_p7_t{ +typedef struct vnf_p7_s { + nfapi_vnf_p7_config_t _public; - nfapi_vnf_p7_config_t _public; - - // private data + // private data uint8_t terminate; nfapi_vnf_p7_connection_info_t* p7_connections; int socket; @@ -119,8 +118,8 @@ struct vnf_p7_t{ uint32_t slot_start_time_hr; uint8_t* rx_message_buffer; // would this be better put in the p7 conenction info? uint16_t rx_message_buffer_size; - -}; + +} vnf_p7_t; uint32_t vnf_get_current_time_hr(void); diff --git a/nfapi/open-nFAPI/vnf/public_inc/nfapi_vnf_interface.h b/nfapi/open-nFAPI/vnf/public_inc/nfapi_vnf_interface.h index 3f326e841c..7ddc19010d 100644 --- a/nfapi/open-nFAPI/vnf/public_inc/nfapi_vnf_interface.h +++ b/nfapi/open-nFAPI/vnf/public_inc/nfapi_vnf_interface.h @@ -30,9 +30,8 @@ extern "C" { #endif -typedef struct vnf_t vnf_t; -typedef struct vnf_p7_t vnf_p7_t; - +typedef struct vnf_s vnf_t; +typedef struct vnf_p7_s vnf_p7_t; /*! The nfapi VNF phy configuration information */ diff --git a/openair1/PHY/defs_RU.h b/openair1/PHY/defs_RU.h index 851d417804..0873340445 100644 --- a/openair1/PHY/defs_RU.h +++ b/openair1/PHY/defs_RU.h @@ -45,7 +45,7 @@ #define MAX_BANDS_PER_RRU 4 #define MAX_RRU_CONFIG_SIZE 1024 - +typedef struct NR_DL_FRAME_PARMS_s NR_DL_FRAME_PARMS; typedef enum { normal_txrx=0, @@ -176,7 +176,7 @@ typedef struct { int slot; const c16_t *rxdata; c16_t *rxdataF; - const struct NR_DL_FRAME_PARMS *fp; + const NR_DL_FRAME_PARMS *fp; int32_t sample_offet; task_ans_t *ans; } feprx_cmd_t; @@ -491,8 +491,8 @@ typedef struct RU_t_s { /// FAPI confiuration nfapi_nr_config_request_scf_t config; /// Frame parameters - struct LTE_DL_FRAME_PARMS *frame_parms; - struct NR_DL_FRAME_PARMS *nr_frame_parms; + struct LTE_DL_FRAME_PARMS_s *frame_parms; + struct NR_DL_FRAME_PARMS_s *nr_frame_parms; ///timing offset used in TDD int N_TA_offset; /// SF extension used in TDD (unit: number of samples at 30.72MHz) (this is an expert option) diff --git a/openair1/PHY/defs_common.h b/openair1/PHY/defs_common.h index 04d99108a1..b728fe89f0 100644 --- a/openair1/PHY/defs_common.h +++ b/openair1/PHY/defs_common.h @@ -598,8 +598,7 @@ typedef struct { int non_mbsfn_SubframeConfig; } NonMBSFN_config_t; - -typedef struct LTE_DL_FRAME_PARMS { +typedef struct LTE_DL_FRAME_PARMS_s { /// Number of resource blocks (RB) in DL uint8_t N_RB_DL; /// Number of resource blocks (RB) in UL diff --git a/openair1/PHY/defs_nr_common.h b/openair1/PHY/defs_nr_common.h index 199877d738..9018d59dac 100644 --- a/openair1/PHY/defs_nr_common.h +++ b/openair1/PHY/defs_nr_common.h @@ -156,9 +156,7 @@ typedef struct { } prach_list_t; void init_prach_list(prach_list_t *); -typedef struct NR_DL_FRAME_PARMS NR_DL_FRAME_PARMS; - -struct NR_DL_FRAME_PARMS { +typedef struct NR_DL_FRAME_PARMS_s { /// frequency range frequency_range_t freq_range; // /// Placeholder to replace overlapping fields below @@ -269,7 +267,7 @@ struct NR_DL_FRAME_PARMS { uint16_t tdd_slot_config; uint8_t tdd_period; bool print_ue_help_cmdline_log; -}; +} NR_DL_FRAME_PARMS; // PRS config structures typedef struct { diff --git a/openair1/SCHED/nfapi_lte_dummy.c b/openair1/SCHED/nfapi_lte_dummy.c index 5ddf2d3485..82a8a77309 100644 --- a/openair1/SCHED/nfapi_lte_dummy.c +++ b/openair1/SCHED/nfapi_lte_dummy.c @@ -4,11 +4,8 @@ #include "nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h" #include "openair2/NR_PHY_INTERFACE/NR_IF_Module.h" #include "openair1/PHY/LTE_TRANSPORT/transport_common.h" -typedef struct pnf_t pnf_t; -typedef struct pnf_p7_t pnf_p7_t; -typedef struct vnf_t vnf_t; -typedef struct vnf_p7_t vnf_p7_t; - +#include "nfapi/open-nFAPI/vnf/inc/vnf.h" +#include "nfapi/open-nFAPI/pnf/inc/pnf.h" int l1_north_init_gNB(void){return 0;} int slot_ahead = 6; diff --git a/openair1/SCHED_NR/nr_ru_procedures.c b/openair1/SCHED_NR/nr_ru_procedures.c index eb2c83c10a..ca712bbaf9 100644 --- a/openair1/SCHED_NR/nr_ru_procedures.c +++ b/openair1/SCHED_NR/nr_ru_procedures.c @@ -35,7 +35,7 @@ #include "sched_nr.h" #include "PHY/MODULATION/modulation_common.h" #include "PHY/MODULATION/nr_modulation.h" - +#include "openair1/PHY/defs_nr_common.h" #include "common/utils/LOG/log.h" #include "common/utils/system.h" diff --git a/openair2/COMMON/e1ap_messages_types.h b/openair2/COMMON/e1ap_messages_types.h index 48cfef98f3..4d1c9bbe9d 100644 --- a/openair2/COMMON/e1ap_messages_types.h +++ b/openair2/COMMON/e1ap_messages_types.h @@ -199,7 +199,7 @@ typedef struct { typedef nssai_t e1ap_nssai_t; -typedef struct e1ap_net_config_t { +typedef struct { net_ip_address_t CUUP_e1_ip_address; net_ip_address_t CUCP_e1_ip_address; uint16_t remotePortF1U; @@ -230,7 +230,7 @@ typedef struct e1ap_cucp_setup_req_s { uint64_t transac_id; } e1ap_cucp_setup_req_t; -typedef struct e1ap_register_req_t { +typedef struct { e1ap_setup_req_t setup_req; e1ap_net_config_t net_config; uint32_t gnb_id; // unused in CU-UP, but might be necessary for some functionality, e.g., E2 agent @@ -658,7 +658,7 @@ typedef struct e1ap_bearer_modif_resp_s { } e1ap_bearer_modif_resp_t; /* E1AP Connection Loss indication */ -typedef struct e1ap_lost_connection_t { +typedef struct { int dummy; } e1ap_lost_connection_t; diff --git a/openair2/COMMON/f1ap_messages_types.h b/openair2/COMMON/f1ap_messages_types.h index 5f430d0e39..3354388596 100644 --- a/openair2/COMMON/f1ap_messages_types.h +++ b/openair2/COMMON/f1ap_messages_types.h @@ -84,7 +84,7 @@ /* 9.3.1.42 of 3GPP TS 38.473 - gNB-CU System Information */ #define F1AP_MAX_NO_SIB_TYPES 32 -typedef struct f1ap_net_config_t { +typedef struct f1ap_net_config_s { char *CU_f1_ip_address; char *DU_f1c_ip_address; char *DU_f1u_ip_address; @@ -97,31 +97,31 @@ typedef struct f1ap_cp_tnl_s { uint16_t port; } f1ap_cp_tnl_t; -typedef enum f1ap_mode_t { F1AP_MODE_TDD = 0, F1AP_MODE_FDD = 1 } f1ap_mode_t; +typedef enum f1ap_mode_e { F1AP_MODE_TDD = 0, F1AP_MODE_FDD = 1 } f1ap_mode_t; -typedef struct f1ap_nr_frequency_info_t { +typedef struct f1ap_nr_frequency_info_s { uint32_t arfcn; int band; } f1ap_nr_frequency_info_t; -typedef struct f1ap_transmission_bandwidth_t { +typedef struct f1ap_transmission_bandwidth_s { uint8_t scs; uint16_t nrb; } f1ap_transmission_bandwidth_t; -typedef struct f1ap_fdd_info_t { +typedef struct f1ap_fdd_info_s { f1ap_nr_frequency_info_t ul_freqinfo; f1ap_nr_frequency_info_t dl_freqinfo; f1ap_transmission_bandwidth_t ul_tbw; f1ap_transmission_bandwidth_t dl_tbw; } f1ap_fdd_info_t; -typedef struct f1ap_tdd_info_t { +typedef struct f1ap_tdd_info_s { f1ap_nr_frequency_info_t freqinfo; f1ap_transmission_bandwidth_t tbw; } f1ap_tdd_info_t; -typedef struct f1ap_served_cell_info_t { +typedef struct f1ap_served_cell_info_s { // NR CGI (Mandatory) plmn_id_t plmn; uint64_t nr_cellid; // NR Global Cell Id @@ -143,7 +143,7 @@ typedef struct f1ap_served_cell_info_t { int measurement_timing_config_len; } f1ap_served_cell_info_t; -typedef struct f1ap_gnb_du_system_info_t { +typedef struct f1ap_gnb_du_system_info_s { // MIB message (Mandatory) uint8_t *mib; int mib_length; @@ -171,12 +171,12 @@ typedef struct f1ap_setup_req_s { } *cell; } f1ap_setup_req_t; -typedef struct f1ap_du_register_req_t { +typedef struct f1ap_du_register_req_s { f1ap_setup_req_t setup_req; f1ap_net_config_t net_config; } f1ap_du_register_req_t; -typedef struct f1ap_sib_msg_t { +typedef struct f1ap_sib_msg_s { /// RRC container with system information owned by gNB-CU uint8_t *SI_container; int SI_container_length; @@ -260,7 +260,7 @@ typedef struct f1ap_gnb_cu_configuration_update_failure_s { uint16_t criticality_diagnostics; } f1ap_gnb_cu_configuration_update_failure_t; -typedef struct f1ap_cell_status_t { +typedef struct f1ap_cell_status_s { // NR CGI plmn_id_t plmn; uint64_t nr_cellid; // NR Global Cell Id @@ -372,7 +372,7 @@ typedef enum preemption_vulnerability_e { PREEMPTABLE, } preemption_vulnerability_t; -typedef enum f1ap_rlc_mode_t { F1AP_RLC_MODE_AM, F1AP_RLC_MODE_UM_BIDIR, F1AP_RLC_UM_UNI_UL, F1AP_RLC_UM_UNI_DL } f1ap_rlc_mode_t; +typedef enum f1ap_rlc_mode_e { F1AP_RLC_MODE_AM, F1AP_RLC_MODE_UM_BIDIR, F1AP_RLC_UM_UNI_UL, F1AP_RLC_UM_UNI_DL } f1ap_rlc_mode_t; typedef struct f1ap_cu_to_du_rrc_info_s { byte_array_t *cg_configinfo; @@ -382,7 +382,7 @@ typedef struct f1ap_cu_to_du_rrc_info_s { byte_array_t *ho_prep_info; } f1ap_cu_to_du_rrc_info_t; -typedef struct f1ap_du_to_cu_rrc_info_t { +typedef struct f1ap_du_to_cu_rrc_info_s { byte_array_t cell_group_config; byte_array_t *meas_gap_config; } f1ap_du_to_cu_rrc_info_t; @@ -412,28 +412,28 @@ typedef enum lower_layer_status_e { LOWER_LAYERS_RESUME, } lower_layer_status_t; -typedef struct f1ap_srb_to_setup_t { +typedef struct f1ap_srb_to_setup_s { int id; } f1ap_srb_to_setup_t; -typedef struct f1ap_srb_setup_t { +typedef struct f1ap_srb_setup_s { int id; int lcid; } f1ap_srb_setup_t; /// 9.3.1.52 Packet Error Rate -typedef struct f1ap_per_t { +typedef struct f1ap_per_s { uint8_t scalar; uint8_t exponent; } f1ap_per_t; // 9.3.1.49 Non-Dynamic 5QI Descriptor -typedef struct f1ap_nondynamic_5qi_t { +typedef struct f1ap_nondynamic_5qi_s { int fiveQI; } f1ap_nondynamic_5qi_t; // 9.3.1.47 Dynamic 5QI Descriptor -typedef struct f1ap_dynamic_5qi_t { +typedef struct f1ap_dynamic_5qi_s { int prio; /// QoS Priority Level int pdb; /// Packet Delay Budget f1ap_per_t per; /// Packet Error Rate @@ -441,14 +441,14 @@ typedef struct f1ap_dynamic_5qi_t { int *avg_win; /// Averaging Window } f1ap_dynamic_5qi_t; -typedef struct f1ap_arp_t { +typedef struct f1ap_arp_s { uint16_t prio; preemption_capability_t preempt_cap; preemption_vulnerability_t preempt_vuln; } f1ap_arp_t; // 9.3.1.45 QoS Flow Level QoS Parameters -typedef struct f1ap_qos_flow_param_t { +typedef struct f1ap_qos_flow_param_s { fiveQI_t qos_type; union { f1ap_nondynamic_5qi_t nondyn; @@ -458,13 +458,13 @@ typedef struct f1ap_qos_flow_param_t { } f1ap_qos_flow_param_t; // in 9.2.2.1 Flows Mapped to DRB Item -typedef struct f1ap_drb_flows_mapped_t { +typedef struct f1ap_drb_flows_mapped_s { int qfi; f1ap_qos_flow_param_t param; } f1ap_drb_flows_mapped_t; /// in 9.2.2.1 DRB Info in UE Context Setup Request -typedef struct f1ap_drb_info_nr_t { +typedef struct f1ap_drb_info_nr_s { f1ap_qos_flow_param_t drb_qos; nssai_t nssai; int flows_len; @@ -473,7 +473,7 @@ typedef struct f1ap_drb_info_nr_t { typedef enum { F1AP_PDCP_SN_12B, F1AP_PDCP_SN_18B } f1ap_pdcp_sn_len_t; /// in 9.2.2.1 DRB to Be Setup Item IEs -typedef struct f1ap_drb_to_setup_t { +typedef struct f1ap_drb_to_setup_s { int id; enum { F1AP_QOS_CHOICE_EUTRAN, F1AP_QOS_CHOICE_NR } qos_choice; union { @@ -487,14 +487,14 @@ typedef struct f1ap_drb_to_setup_t { f1ap_pdcp_sn_len_t *ul_pdcp_sn_len; } f1ap_drb_to_setup_t; -typedef struct f1ap_drb_setup_t { +typedef struct f1ap_drb_setup_s { int id; int *lcid; int up_dl_tnl_len; f1ap_up_tnl_t up_dl_tnl[2]; } f1ap_drb_setup_t; -typedef struct f1ap_drb_to_release_t { +typedef struct f1ap_drb_to_release_s { int id; } f1ap_drb_to_release_t; @@ -534,7 +534,7 @@ typedef struct f1ap_ue_context_setup_resp_s { f1ap_srb_setup_t *srbs; } f1ap_ue_context_setup_resp_t; -typedef struct f1ap_ue_context_mod_req_t { +typedef struct f1ap_ue_context_mod_req_s { uint32_t gNB_CU_ue_id; uint32_t gNB_DU_ue_id; @@ -565,7 +565,7 @@ typedef struct f1ap_ue_context_mod_req_t { lower_layer_status_t *status; } f1ap_ue_context_mod_req_t; -typedef struct f1ap_ue_context_mod_resp { +typedef struct f1ap_ue_context_mod_resp_s { uint32_t gNB_CU_ue_id; uint32_t gNB_DU_ue_id; @@ -586,7 +586,7 @@ typedef enum F1ap_Cause_e { F1AP_CAUSE_MISC, } f1ap_Cause_t; -typedef struct f1ap_ue_context_modif_required_t { +typedef struct f1ap_ue_context_modif_required_s { uint32_t gNB_CU_ue_id; uint32_t gNB_DU_ue_id; du_to_cu_rrc_information_t *du_to_cu_rrc_information; @@ -594,28 +594,28 @@ typedef struct f1ap_ue_context_modif_required_t { long cause_value; } f1ap_ue_context_modif_required_t; -typedef struct f1ap_ue_context_modif_confirm_t { +typedef struct f1ap_ue_context_modif_confirm_s { uint32_t gNB_CU_ue_id; uint32_t gNB_DU_ue_id; uint8_t *rrc_container; int rrc_container_length; } f1ap_ue_context_modif_confirm_t; -typedef struct f1ap_ue_context_modif_refuse_t { +typedef struct f1ap_ue_context_modif_refuse_s { uint32_t gNB_CU_ue_id; uint32_t gNB_DU_ue_id; f1ap_Cause_t cause; long cause_value; } f1ap_ue_context_modif_refuse_t; -typedef struct f1ap_ue_context_rel_req_t { +typedef struct f1ap_ue_context_rel_req_s { uint32_t gNB_CU_ue_id; uint32_t gNB_DU_ue_id; f1ap_Cause_t cause; long cause_value; } f1ap_ue_context_rel_req_t; -typedef struct f1ap_ue_context_rel_cmd_t { +typedef struct f1ap_ue_context_rel_cmd_s { uint32_t gNB_CU_ue_id; uint32_t gNB_DU_ue_id; f1ap_Cause_t cause; @@ -627,7 +627,7 @@ typedef struct f1ap_ue_context_rel_cmd_t { uint32_t *old_gNB_DU_ue_id; // if after reestablishment request } f1ap_ue_context_rel_cmd_t; -typedef struct f1ap_ue_context_rel_cplt_t { +typedef struct f1ap_ue_context_rel_cplt_s { uint32_t gNB_CU_ue_id; uint32_t gNB_DU_ue_id; } f1ap_ue_context_rel_cplt_t; @@ -694,7 +694,7 @@ typedef struct { f1ap_paging_cell_item_t *cells; } f1ap_paging_t; -typedef struct f1ap_lost_connection_t { +typedef struct f1ap_lost_connection_s { int dummy; } f1ap_lost_connection_t; @@ -703,12 +703,12 @@ typedef enum F1AP_ResetType_e { F1AP_RESET_PART_OF_F1_INTERFACE } f1ap_ResetType_t; -typedef struct f1ap_ue_to_reset_t { +typedef struct f1ap_ue_to_reset_s { uint32_t *gNB_CU_ue_id; uint32_t *gNB_DU_ue_id; } f1ap_ue_to_reset_t; -typedef struct f1ap_reset_t { +typedef struct f1ap_reset_s { uint64_t transaction_id; f1ap_Cause_t cause; long cause_value; @@ -717,7 +717,7 @@ typedef struct f1ap_reset_t { f1ap_ue_to_reset_t *ue_to_reset; // array of num_ue_to_reset elements } f1ap_reset_t; -typedef struct f1ap_reset_ack_t { +typedef struct f1ap_reset_ack_s { uint64_t transaction_id; int num_ue_to_reset; f1ap_ue_to_reset_t *ue_to_reset; // array of num_ue_to_reset elements diff --git a/openair2/F1AP/f1ap_du_task.h b/openair2/F1AP/f1ap_du_task.h index 8ce8aacab6..8546ca6cb3 100644 --- a/openair2/F1AP/f1ap_du_task.h +++ b/openair2/F1AP/f1ap_du_task.h @@ -21,9 +21,9 @@ #ifndef F1AP_DU_TASK_H_ #define F1AP_DU_TASK_H_ +#include "openair2/COMMON/f1ap_messages_types.h" -struct f1ap_net_config_t; -void du_task_send_sctp_association_req(instance_t instance, struct f1ap_net_config_t *du_inst); +void du_task_send_sctp_association_req(instance_t instance, f1ap_net_config_t *du_inst); void du_task_handle_sctp_association_resp(instance_t instance, sctp_new_association_resp_t *sctp_new_association_resp); void du_task_handle_sctp_data_ind(instance_t instance, sctp_data_ind_t *sctp_data_ind); void *F1AP_DU_task(void *arg); diff --git a/openair2/F1AP/lib/f1ap_lib_common.h b/openair2/F1AP/lib/f1ap_lib_common.h index 94e0ee22c3..419ee278b1 100644 --- a/openair2/F1AP/lib/f1ap_lib_common.h +++ b/openair2/F1AP/lib/f1ap_lib_common.h @@ -83,14 +83,10 @@ } while (0) bool eq_f1ap_plmn(const plmn_id_t *a, const plmn_id_t *b); -struct f1ap_served_cell_info_t; -bool eq_f1ap_cell_info(const struct f1ap_served_cell_info_t *a, const struct f1ap_served_cell_info_t *b); -struct f1ap_gnb_du_system_info_t; -bool eq_f1ap_sys_info(const struct f1ap_gnb_du_system_info_t *a, const struct f1ap_gnb_du_system_info_t *b); -struct f1ap_nr_frequency_info_t; -bool eq_f1ap_freq_info(const struct f1ap_nr_frequency_info_t *a, const struct f1ap_nr_frequency_info_t *b); -struct f1ap_transmission_bandwidth_t; -bool eq_f1ap_tx_bandwidth(const struct f1ap_transmission_bandwidth_t *a, const struct f1ap_transmission_bandwidth_t *b); +bool eq_f1ap_cell_info(const f1ap_served_cell_info_t *a, const f1ap_served_cell_info_t *b); +bool eq_f1ap_sys_info(const f1ap_gnb_du_system_info_t *a, const f1ap_gnb_du_system_info_t *b); +bool eq_f1ap_freq_info(const f1ap_nr_frequency_info_t *a, const f1ap_nr_frequency_info_t *b); +bool eq_f1ap_tx_bandwidth(const f1ap_transmission_bandwidth_t *a, const f1ap_transmission_bandwidth_t *b); struct OCTET_STRING; uint8_t *cp_octet_string(const struct OCTET_STRING *os, int *len); diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h index 40ed4c6a50..adbba9c772 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h +++ b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h @@ -184,7 +184,7 @@ typedef enum { SSB_SINR, } nr_config_report_type_t; -typedef struct nr_mac_config_t { +typedef struct nr_mac_config_s { nr_pdsch_AntennaPorts_t pdsch_AntennaPorts; int pusch_AntennaPorts; int minRXTXTIME; @@ -855,7 +855,7 @@ typedef struct gNB_MAC_INST_s gNB_MAC_INST; 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 { +typedef struct { f1ap_setup_req_t *setup_req; f1ap_setup_resp_t *setup_resp; uint32_t gnb_id; // associated gNB's ID, not used in DU itself diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_radio_config.h b/openair2/LAYER2/NR_MAC_gNB/nr_radio_config.h index edf53f24f7..dc10904425 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_radio_config.h +++ b/openair2/LAYER2/NR_MAC_gNB/nr_radio_config.h @@ -38,13 +38,8 @@ struct NR_MeasurementTimingConfiguration; struct NR_PDSCH_TimeDomainResourceAllocationList; // forward declaration of MAC configuration parameters, definition is included in C file -struct nr_mac_config_t; -typedef struct nr_mac_config_t nr_mac_config_t; - -struct nr_mac_timers; +typedef struct nr_mac_config_s nr_mac_config_t; typedef struct nr_mac_timers nr_mac_timers_t; - -struct measgap_config; typedef struct measgap_config measgap_config_t; void nr_rrc_config_dl_tda(struct NR_PDSCH_TimeDomainResourceAllocationList *pdsch_TimeDomainAllocationList, diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.c index 25081891d3..42e09308f2 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.c +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.c @@ -303,7 +303,7 @@ static int nr_pdcp_entity_process_sdu(nr_pdcp_entity_t *entity, return header_size + size + integrity_size; } -static bool nr_pdcp_entity_check_integrity(struct nr_pdcp_entity_t *entity, +static bool nr_pdcp_entity_check_integrity(nr_pdcp_entity_t *entity, const uint8_t *buffer, int buffer_size, const nr_pdcp_integrity_data_t *msg_integrity) @@ -329,8 +329,7 @@ static bool nr_pdcp_entity_check_integrity(struct nr_pdcp_entity_t *entity, } /* may be called several times, take care to clean previous settings */ -static void nr_pdcp_entity_set_security(struct nr_pdcp_entity_t *entity, - const nr_pdcp_entity_security_keys_and_algos_t *parameters) +static void nr_pdcp_entity_set_security(nr_pdcp_entity_t *entity, const nr_pdcp_entity_security_keys_and_algos_t *parameters) { if (parameters->integrity_algorithm != -1) { entity->security_keys_and_algos.integrity_algorithm = parameters->integrity_algorithm; @@ -453,7 +452,7 @@ static void check_t_reordering(nr_pdcp_entity_t *entity) } } -static void nr_pdcp_entity_set_time(struct nr_pdcp_entity_t *entity, uint64_t now) +static void nr_pdcp_entity_set_time(nr_pdcp_entity_t *entity, uint64_t now) { entity->t_current = now; @@ -697,12 +696,13 @@ nr_pdcp_entity_t *new_nr_pdcp_entity( int pdusession_id, bool has_sdap_rx, bool has_sdap_tx, - void (*deliver_sdu)(void *deliver_sdu_data, struct nr_pdcp_entity_t *entity, - char *buf, int size, + void (*deliver_sdu)(void *deliver_sdu_data, + nr_pdcp_entity_t *entity, + char *buf, + int size, const nr_pdcp_integrity_data_t *msg_integrity), void *deliver_sdu_data, - void (*deliver_pdu)(void *deliver_pdu_data, ue_id_t ue_id, int rb_id, - char *buf, int size, int sdu_id), + void (*deliver_pdu)(void *deliver_pdu_data, ue_id_t ue_id, int rb_id, char *buf, int size, int sdu_id), void *deliver_pdu_data, int sn_size, int t_reordering, diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.h b/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.h index 84ecce8997..338279aec9 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.h +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.h @@ -92,36 +92,36 @@ typedef struct { uint8_t mode; /* 0: PDCP AM, 1: PDCP UM, 2: PDCP TM */ } nr_pdcp_statistics_t; -typedef struct nr_pdcp_entity_t { +typedef struct nr_pdcp_entity_s { nr_pdcp_entity_type_t type; /* functions provided by the PDCP module */ - void (*recv_pdu)(struct nr_pdcp_entity_t *entity, char *buffer, int size); - int (*process_sdu)(struct nr_pdcp_entity_t *entity, char *buffer, int size, - int sdu_id, char *pdu_buffer, int pdu_max_size); - void (*delete_entity)(struct nr_pdcp_entity_t *entity); - void (*release_entity)(struct nr_pdcp_entity_t *entity); - void (*suspend_entity)(struct nr_pdcp_entity_t *entity); - void (*reestablish_entity)(struct nr_pdcp_entity_t *entity, - const nr_pdcp_entity_security_keys_and_algos_t *parameters); - void (*get_stats)(struct nr_pdcp_entity_t *entity, nr_pdcp_statistics_t *out); + void (*recv_pdu)(struct nr_pdcp_entity_s *entity, char *buffer, int size); + int (*process_sdu)(struct nr_pdcp_entity_s *entity, char *buffer, int size, int sdu_id, char *pdu_buffer, int pdu_max_size); + void (*delete_entity)(struct nr_pdcp_entity_s *entity); + void (*release_entity)(struct nr_pdcp_entity_s *entity); + void (*suspend_entity)(struct nr_pdcp_entity_s *entity); + void (*reestablish_entity)(struct nr_pdcp_entity_s *entity, const nr_pdcp_entity_security_keys_and_algos_t *parameters); + void (*get_stats)(struct nr_pdcp_entity_s *entity, nr_pdcp_statistics_t *out); /* set_security: pass -1 to parameters->integrity_algorithm / parameters->ciphering_algorithm * to keep the corresponding current algorithm and key */ - void (*set_security)(struct nr_pdcp_entity_t *entity, - const nr_pdcp_entity_security_keys_and_algos_t *parameters); + void (*set_security)(struct nr_pdcp_entity_s *entity, const nr_pdcp_entity_security_keys_and_algos_t *parameters); /* check_integrity is used by RRC */ - bool (*check_integrity)(struct nr_pdcp_entity_t *entity, - const uint8_t *buffer, int buffer_length, + bool (*check_integrity)(struct nr_pdcp_entity_s *entity, + const uint8_t *buffer, + int buffer_length, const nr_pdcp_integrity_data_t *msg_integrity); - void (*set_time)(struct nr_pdcp_entity_t *entity, uint64_t now); + void (*set_time)(struct nr_pdcp_entity_s *entity, uint64_t now); /* callbacks provided to the PDCP module */ - void (*deliver_sdu)(void *deliver_sdu_data, struct nr_pdcp_entity_t *entity, - char *buf, int size, + void (*deliver_sdu)(void *deliver_sdu_data, + struct nr_pdcp_entity_s *entity, + char *buf, + int size, const nr_pdcp_integrity_data_t *msg_integrity); void *deliver_sdu_data; void (*deliver_pdu)(void *deliver_pdu_data, ue_id_t ue_id, int rb_id, @@ -186,10 +186,10 @@ typedef struct nr_pdcp_entity_t { bool entity_suspended; /* PDCP Count API */ - nr_pdcp_count_t (*get_pdcp_count_dl)(struct nr_pdcp_entity_t *entity); - nr_pdcp_count_t (*get_pdcp_count_ul)(struct nr_pdcp_entity_t *entity); - void (*set_pdcp_count_dl)(struct nr_pdcp_entity_t *entity, nr_pdcp_count_t count, int sn_size); - void (*set_pdcp_count_ul)(struct nr_pdcp_entity_t *entity, nr_pdcp_count_t count, int sn_size); + nr_pdcp_count_t (*get_pdcp_count_dl)(struct nr_pdcp_entity_s *entity); + nr_pdcp_count_t (*get_pdcp_count_ul)(struct nr_pdcp_entity_s *entity); + void (*set_pdcp_count_dl)(struct nr_pdcp_entity_s *entity, nr_pdcp_count_t count, int sn_size); + void (*set_pdcp_count_ul)(struct nr_pdcp_entity_s *entity, nr_pdcp_count_t count, int sn_size); } nr_pdcp_entity_t; @@ -200,12 +200,13 @@ nr_pdcp_entity_t *new_nr_pdcp_entity( int pdusession_id, bool has_sdap_rx, bool has_sdap_tx, - void (*deliver_sdu)(void *deliver_sdu_data, struct nr_pdcp_entity_t *entity, - char *buf, int size, + void (*deliver_sdu)(void *deliver_sdu_data, + struct nr_pdcp_entity_s *entity, + char *buf, + int size, const nr_pdcp_integrity_data_t *msg_integrity), void *deliver_sdu_data, - void (*deliver_pdu)(void *deliver_pdu_data, ue_id_t ue_id, int rb_id, - char *buf, int size, int sdu_id), + void (*deliver_pdu)(void *deliver_pdu_data, ue_id_t ue_id, int rb_id, char *buf, int size, int sdu_id), void *deliver_pdu_data, int sn_size, int t_reordering, diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_entity.c b/openair2/LAYER2/nr_rlc/nr_rlc_entity.c index e452981357..2bb407ad01 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_entity.c +++ b/openair2/LAYER2/nr_rlc/nr_rlc_entity.c @@ -71,26 +71,23 @@ static void nr_rlc_entity_get_stats( out->txsdu_avg_time_to_tx = 0; } -nr_rlc_entity_t *new_nr_rlc_entity_am( - int rx_maxsize, - int tx_maxsize, - void (*deliver_sdu)(void *deliver_sdu_data, struct nr_rlc_entity_t *entity, - char *buf, int size), - void *deliver_sdu_data, - void (*sdu_successful_delivery)(void *sdu_successful_delivery_data, - struct nr_rlc_entity_t *entity, - int sdu_id), - void *sdu_successful_delivery_data, - void (*max_retx_reached)(void *max_retx_reached_data, - struct nr_rlc_entity_t *entity), - void *max_retx_reached_data, - int t_poll_retransmit, - int t_reassembly, - int t_status_prohibit, - int poll_pdu, - int poll_byte, - int max_retx_threshold, - int sn_field_length) +nr_rlc_entity_t *new_nr_rlc_entity_am(int rx_maxsize, + int tx_maxsize, + void (*deliver_sdu)(void *deliver_sdu_data, nr_rlc_entity_t *entity, char *buf, int size), + void *deliver_sdu_data, + void (*sdu_successful_delivery)(void *sdu_successful_delivery_data, + nr_rlc_entity_t *entity, + int sdu_id), + void *sdu_successful_delivery_data, + void (*max_retx_reached)(void *max_retx_reached_data, nr_rlc_entity_t *entity), + void *max_retx_reached_data, + int t_poll_retransmit, + int t_reassembly, + int t_status_prohibit, + int poll_pdu, + int poll_byte, + int max_retx_threshold, + int sn_field_length) { nr_rlc_entity_am_t *ret; @@ -150,14 +147,12 @@ nr_rlc_entity_t *new_nr_rlc_entity_am( return (nr_rlc_entity_t *)ret; } -nr_rlc_entity_t *new_nr_rlc_entity_um( - int rx_maxsize, - int tx_maxsize, - void (*deliver_sdu)(void *deliver_sdu_data, struct nr_rlc_entity_t *entity, - char *buf, int size), - void *deliver_sdu_data, - int t_reassembly, - int sn_field_length) +nr_rlc_entity_t *new_nr_rlc_entity_um(int rx_maxsize, + int tx_maxsize, + void (*deliver_sdu)(void *deliver_sdu_data, nr_rlc_entity_t *entity, char *buf, int size), + void *deliver_sdu_data, + int t_reassembly, + int sn_field_length) { nr_rlc_entity_um_t *ret; @@ -203,11 +198,9 @@ nr_rlc_entity_t *new_nr_rlc_entity_um( return (nr_rlc_entity_t *)ret; } -nr_rlc_entity_t *new_nr_rlc_entity_tm( - int tx_maxsize, - void (*deliver_sdu)(void *deliver_sdu_data, struct nr_rlc_entity_t *entity, - char *buf, int size), - void *deliver_sdu_data) +nr_rlc_entity_t *new_nr_rlc_entity_tm(int tx_maxsize, + void (*deliver_sdu)(void *deliver_sdu_data, nr_rlc_entity_t *entity, char *buf, int size), + void *deliver_sdu_data) { nr_rlc_entity_tm_t *ret; diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_entity.h b/openair2/LAYER2/nr_rlc/nr_rlc_entity.h index 459e9f59a5..a16e3b7186 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_entity.h +++ b/openair2/LAYER2/nr_rlc/nr_rlc_entity.h @@ -97,41 +97,35 @@ typedef struct { int retx_size; } nr_rlc_entity_buffer_status_t; -typedef struct nr_rlc_entity_t { +typedef struct nr_rlc_entity_s { /* functions provided by the RLC module */ - void (*recv_pdu)(struct nr_rlc_entity_t *entity, char *buffer, int size); - nr_rlc_entity_buffer_status_t (*buffer_status)( - struct nr_rlc_entity_t *entity, int maxsize); - int (*generate_pdu)(struct nr_rlc_entity_t *entity, char *buffer, int size); + void (*recv_pdu)(struct nr_rlc_entity_s *entity, char *buffer, int size); + nr_rlc_entity_buffer_status_t (*buffer_status)(struct nr_rlc_entity_s *entity, int maxsize); + int (*generate_pdu)(struct nr_rlc_entity_s *entity, char *buffer, int size); - void (*recv_sdu)(struct nr_rlc_entity_t *entity, char *buffer, int size, - int sdu_id); + void (*recv_sdu)(struct nr_rlc_entity_s *entity, char *buffer, int size, int sdu_id); - void (*set_time)(struct nr_rlc_entity_t *entity, uint64_t now); + void (*set_time)(struct nr_rlc_entity_s *entity, uint64_t now); - void (*discard_sdu)(struct nr_rlc_entity_t *entity, int sdu_id); + void (*discard_sdu)(struct nr_rlc_entity_s *entity, int sdu_id); - void (*reestablishment)(struct nr_rlc_entity_t *entity); + void (*reestablishment)(struct nr_rlc_entity_s *entity); - void (*delete_entity)(struct nr_rlc_entity_t *entity); + void (*delete_entity)(struct nr_rlc_entity_s *entity); - int (*available_tx_space)(struct nr_rlc_entity_t *entity); - int (*tx_list_occupancy)(struct nr_rlc_entity_t *entity); + int (*available_tx_space)(struct nr_rlc_entity_s *entity); + int (*tx_list_occupancy)(struct nr_rlc_entity_s *entity); - void (*get_stats)(struct nr_rlc_entity_t *entity, nr_rlc_statistics_t *out); + void (*get_stats)(struct nr_rlc_entity_s *entity, nr_rlc_statistics_t *out); /* callbacks provided to the RLC module */ - void (*deliver_sdu)(void *deliver_sdu_data, struct nr_rlc_entity_t *entity, - char *buf, int size); + void (*deliver_sdu)(void *deliver_sdu_data, struct nr_rlc_entity_s *entity, char *buf, int size); void *deliver_sdu_data; - void (*sdu_successful_delivery)(void *sdu_successful_delivery_data, - struct nr_rlc_entity_t *entity, - int sdu_id); + void (*sdu_successful_delivery)(void *sdu_successful_delivery_data, struct nr_rlc_entity_s *entity, int sdu_id); void *sdu_successful_delivery_data; - void (*max_retx_reached)(void *max_retx_reached_data, - struct nr_rlc_entity_t *entity); + void (*max_retx_reached)(void *max_retx_reached_data, struct nr_rlc_entity_s *entity); void *max_retx_reached_data; /* buffer status computation */ nr_rlc_entity_buffer_status_t bstatus; @@ -141,41 +135,34 @@ typedef struct nr_rlc_entity_t { int avg_time_is_on; } nr_rlc_entity_t; -nr_rlc_entity_t *new_nr_rlc_entity_am( - int rx_maxsize, - int tx_maxsize, - void (*deliver_sdu)(void *deliver_sdu_data, struct nr_rlc_entity_t *entity, - char *buf, int size), - void *deliver_sdu_data, - void (*sdu_successful_delivery)(void *sdu_successful_delivery_data, - struct nr_rlc_entity_t *entity, - int sdu_id), - void *sdu_successful_delivery_data, - void (*max_retx_reached)(void *max_retx_reached_data, - struct nr_rlc_entity_t *entity), - void *max_retx_reached_data, - int t_poll_retransmit, - int t_reassembly, - int t_status_prohibit, - int poll_pdu, - int poll_byte, - int max_retx_threshold, - int sn_field_length); +nr_rlc_entity_t *new_nr_rlc_entity_am(int rx_maxsize, + int tx_maxsize, + void (*deliver_sdu)(void *deliver_sdu_data, nr_rlc_entity_t *entity, char *buf, int size), + void *deliver_sdu_data, + void (*sdu_successful_delivery)(void *sdu_successful_delivery_data, + nr_rlc_entity_t *entity, + int sdu_id), + void *sdu_successful_delivery_data, + void (*max_retx_reached)(void *max_retx_reached_data, nr_rlc_entity_t *entity), + void *max_retx_reached_data, + int t_poll_retransmit, + int t_reassembly, + int t_status_prohibit, + int poll_pdu, + int poll_byte, + int max_retx_threshold, + int sn_field_length); -nr_rlc_entity_t *new_nr_rlc_entity_um( - int rx_maxsize, - int tx_maxsize, - void (*deliver_sdu)(void *deliver_sdu_data, struct nr_rlc_entity_t *entity, - char *buf, int size), - void *deliver_sdu_data, - int t_reassembly, - int sn_field_length); +nr_rlc_entity_t *new_nr_rlc_entity_um(int rx_maxsize, + int tx_maxsize, + void (*deliver_sdu)(void *deliver_sdu_data, nr_rlc_entity_t *entity, char *buf, int size), + void *deliver_sdu_data, + int t_reassembly, + int sn_field_length); -nr_rlc_entity_t *new_nr_rlc_entity_tm( - int tx_maxsize, - void (*deliver_sdu)(void *deliver_sdu_data, struct nr_rlc_entity_t *entity, - char *buf, int size), - void *deliver_sdu_data); +nr_rlc_entity_t *new_nr_rlc_entity_tm(int tx_maxsize, + void (*deliver_sdu)(void *deliver_sdu_data, nr_rlc_entity_t *entity, char *buf, int size), + void *deliver_sdu_data); void nr_rlc_entity_um_reconfigure(nr_rlc_entity_t *_entity, int t_reassembly, int *sn_field_length); diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c index 126f9fb51c..133aea8d15 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c +++ b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c @@ -875,8 +875,7 @@ struct srb0_data { void (*send_initial_ul_rrc_message)(int ue_id, const uint8_t *sdu, sdu_size_t sdu_len, void *data); }; -void deliver_sdu_srb0(void *deliver_sdu_data, struct nr_rlc_entity_t *entity, - char *buf, int size) +void deliver_sdu_srb0(void *deliver_sdu_data, nr_rlc_entity_t *entity, char *buf, int size) { struct srb0_data *s0 = (struct srb0_data *)deliver_sdu_data; s0->send_initial_ul_rrc_message(s0->ue_id, (unsigned char *)buf, size, s0->data); diff --git a/openair2/LAYER2/nr_rlc/tests/benchmark_nr_rlc_am_entity.cpp b/openair2/LAYER2/nr_rlc/tests/benchmark_nr_rlc_am_entity.cpp index ac36b79211..fe51273e61 100644 --- a/openair2/LAYER2/nr_rlc/tests/benchmark_nr_rlc_am_entity.cpp +++ b/openair2/LAYER2/nr_rlc/tests/benchmark_nr_rlc_am_entity.cpp @@ -28,13 +28,13 @@ extern configmodule_interface_t *uniqCfg; } #include -void deliver_sdu(void *deliver_sdu_data, struct nr_rlc_entity_t *entity, char *buf, int size) +void deliver_sdu(void *deliver_sdu_data, nr_rlc_entity_t *entity, char *buf, int size) { } -void sdu_successful_delivery(void *sdu_successful_delivery_data, struct nr_rlc_entity_t *entity, int sdu_id) +void sdu_successful_delivery(void *sdu_successful_delivery_data, nr_rlc_entity_t *entity, int sdu_id) { } -void max_retx_reached(void *max_retx_reached_data, struct nr_rlc_entity_t *entity) +void max_retx_reached(void *max_retx_reached_data, nr_rlc_entity_t *entity) { } diff --git a/openair2/LAYER2/nr_rlc/tests/test.c b/openair2/LAYER2/nr_rlc/tests/test.c index 04e49c460a..6af48b474b 100644 --- a/openair2/LAYER2/nr_rlc/tests/test.c +++ b/openair2/LAYER2/nr_rlc/tests/test.c @@ -107,9 +107,7 @@ int test[] = { #include TEST }; -void deliver_sdu_gnb_am(void *deliver_sdu_data, - struct nr_rlc_entity_t *_entity, - char *buf, int size) +void deliver_sdu_gnb_am(void *deliver_sdu_data, nr_rlc_entity_t *_entity, char *buf, int size) { nr_rlc_entity_am_t *entity = (nr_rlc_entity_am_t *)_entity; printf("TEST: GNB: %"PRIu64": deliver SDU size %d [", @@ -118,9 +116,7 @@ void deliver_sdu_gnb_am(void *deliver_sdu_data, printf("]\n"); } -void deliver_sdu_gnb_um(void *deliver_sdu_data, - struct nr_rlc_entity_t *_entity, - char *buf, int size) +void deliver_sdu_gnb_um(void *deliver_sdu_data, nr_rlc_entity_t *_entity, char *buf, int size) { nr_rlc_entity_um_t *entity = (nr_rlc_entity_um_t *)_entity; printf("TEST: GNB: %"PRIu64": deliver SDU size %d [", @@ -129,9 +125,7 @@ void deliver_sdu_gnb_um(void *deliver_sdu_data, printf("]\n"); } -void deliver_sdu_gnb_tm(void *deliver_sdu_data, - struct nr_rlc_entity_t *_entity, - char *buf, int size) +void deliver_sdu_gnb_tm(void *deliver_sdu_data, nr_rlc_entity_t *_entity, char *buf, int size) { nr_rlc_entity_tm_t *entity = (nr_rlc_entity_tm_t *)_entity; printf("TEST: GNB: %"PRIu64": deliver SDU size %d [", @@ -157,9 +151,7 @@ void max_retx_reached_gnb(void *max_retx_reached_data, exit(1); } -void deliver_sdu_ue_am(void *deliver_sdu_data, - struct nr_rlc_entity_t *_entity, - char *buf, int size) +void deliver_sdu_ue_am(void *deliver_sdu_data, nr_rlc_entity_t *_entity, char *buf, int size) { nr_rlc_entity_am_t *entity = (nr_rlc_entity_am_t *)_entity; printf("TEST: UE: %"PRIu64": deliver SDU size %d [", @@ -168,9 +160,7 @@ void deliver_sdu_ue_am(void *deliver_sdu_data, printf("]\n"); } -void deliver_sdu_ue_um(void *deliver_sdu_data, - struct nr_rlc_entity_t *_entity, - char *buf, int size) +void deliver_sdu_ue_um(void *deliver_sdu_data, nr_rlc_entity_t *_entity, char *buf, int size) { nr_rlc_entity_um_t *entity = (nr_rlc_entity_um_t *)_entity; printf("TEST: UE: %"PRIu64": deliver SDU size %d [", @@ -179,9 +169,7 @@ void deliver_sdu_ue_um(void *deliver_sdu_data, printf("]\n"); } -void deliver_sdu_ue_tm(void *deliver_sdu_data, - struct nr_rlc_entity_t *_entity, - char *buf, int size) +void deliver_sdu_ue_tm(void *deliver_sdu_data, nr_rlc_entity_t *_entity, char *buf, int size) { nr_rlc_entity_tm_t *entity = (nr_rlc_entity_tm_t *)_entity; printf("TEST: UE: %"PRIu64": deliver SDU size %d [", diff --git a/openair2/LAYER2/nr_rlc/tests/test_nr_rlc_am_entity.cpp b/openair2/LAYER2/nr_rlc/tests/test_nr_rlc_am_entity.cpp index 5407f7b2ae..5f07b9243e 100644 --- a/openair2/LAYER2/nr_rlc/tests/test_nr_rlc_am_entity.cpp +++ b/openair2/LAYER2/nr_rlc/tests/test_nr_rlc_am_entity.cpp @@ -31,7 +31,7 @@ extern configmodule_interface_t *uniqCfg; int sdu_delivered_count = 0; int sdu_acked_count = 0; -void deliver_sdu(void *deliver_sdu_data, struct nr_rlc_entity_t *entity, char *buf, int size) +void deliver_sdu(void *deliver_sdu_data, nr_rlc_entity_t *entity, char *buf, int size) { sdu_delivered_count++; char payload[300]; @@ -40,13 +40,13 @@ void deliver_sdu(void *deliver_sdu_data, struct nr_rlc_entity_t *entity, char *b std::cout << "Delivered sdu: " << payload << std::endl; } -void sdu_successful_delivery(void *sdu_successful_delivery_data, struct nr_rlc_entity_t *entity, int sdu_id) +void sdu_successful_delivery(void *sdu_successful_delivery_data, nr_rlc_entity_t *entity, int sdu_id) { sdu_acked_count++; std::cout << "SDU " << sdu_id << " acked" << std::endl; } -void max_retx_reached(void *max_retx_reached_data, struct nr_rlc_entity_t *entity) +void max_retx_reached(void *max_retx_reached_data, nr_rlc_entity_t *entity) { } diff --git a/openair2/LAYER2/rlc_v2/rlc_entity.c b/openair2/LAYER2/rlc_v2/rlc_entity.c index d774e2b7e1..26af68e58b 100644 --- a/openair2/LAYER2/rlc_v2/rlc_entity.c +++ b/openair2/LAYER2/rlc_v2/rlc_entity.c @@ -28,25 +28,22 @@ #include "LOG/log.h" -rlc_entity_t *new_rlc_entity_am( - int rx_maxsize, - int tx_maxsize, - void (*deliver_sdu)(void *deliver_sdu_data, struct rlc_entity_t *entity, - char *buf, int size), - void *deliver_sdu_data, - void (*sdu_successful_delivery)(void *sdu_successful_delivery_data, - struct rlc_entity_t *entity, - int sdu_id), - void *sdu_successful_delivery_data, - void (*max_retx_reached)(void *max_retx_reached_data, - struct rlc_entity_t *entity), - void *max_retx_reached_data, - int t_reordering, - int t_status_prohibit, - int t_poll_retransmit, - int poll_pdu, - int poll_byte, - int max_retx_threshold) +rlc_entity_t *new_rlc_entity_am(int rx_maxsize, + int tx_maxsize, + void (*deliver_sdu)(void *deliver_sdu_data, rlc_entity_t *entity, char *buf, int size), + void *deliver_sdu_data, + void (*sdu_successful_delivery)(void *sdu_successful_delivery_data, + rlc_entity_t *entity, + int sdu_id), + void *sdu_successful_delivery_data, + void (*max_retx_reached)(void *max_retx_reached_data, rlc_entity_t *entity), + void *max_retx_reached_data, + int t_reordering, + int t_status_prohibit, + int t_poll_retransmit, + int poll_pdu, + int poll_byte, + int max_retx_threshold) { rlc_entity_am_t *ret; @@ -91,14 +88,12 @@ rlc_entity_t *new_rlc_entity_am( return (rlc_entity_t *)ret; } -rlc_entity_t *new_rlc_entity_um( - int rx_maxsize, - int tx_maxsize, - void (*deliver_sdu)(void *deliver_sdu_data, struct rlc_entity_t *entity, - char *buf, int size), - void *deliver_sdu_data, - int t_reordering, - int sn_field_length) +rlc_entity_t *new_rlc_entity_um(int rx_maxsize, + int tx_maxsize, + void (*deliver_sdu)(void *deliver_sdu_data, rlc_entity_t *entity, char *buf, int size), + void *deliver_sdu_data, + int t_reordering, + int sn_field_length) { rlc_entity_um_t *ret; diff --git a/openair2/LAYER2/rlc_v2/rlc_entity.h b/openair2/LAYER2/rlc_v2/rlc_entity.h index c9b35204f0..d0be4d87e7 100644 --- a/openair2/LAYER2/rlc_v2/rlc_entity.h +++ b/openair2/LAYER2/rlc_v2/rlc_entity.h @@ -32,66 +32,55 @@ typedef struct { int retx_size; } rlc_entity_buffer_status_t; -typedef struct rlc_entity_t { +typedef struct rlc_entity_s { /* functions provided by the RLC module */ - void (*recv_pdu)(struct rlc_entity_t *entity, char *buffer, int size); - rlc_entity_buffer_status_t (*buffer_status)( - struct rlc_entity_t *entity, int maxsize); - int (*generate_pdu)(struct rlc_entity_t *entity, char *buffer, int size); + void (*recv_pdu)(struct rlc_entity_s *entity, char *buffer, int size); + rlc_entity_buffer_status_t (*buffer_status)(struct rlc_entity_s *entity, int maxsize); + int (*generate_pdu)(struct rlc_entity_s *entity, char *buffer, int size); - void (*recv_sdu)(struct rlc_entity_t *entity, char *buffer, int size, - int sdu_id); + void (*recv_sdu)(struct rlc_entity_s *entity, char *buffer, int size, int sdu_id); - void (*set_time)(struct rlc_entity_t *entity, uint64_t now); + void (*set_time)(struct rlc_entity_s *entity, uint64_t now); - void (*discard_sdu)(struct rlc_entity_t *entity, int sdu_id); + void (*discard_sdu)(struct rlc_entity_s *entity, int sdu_id); - void (*reestablishment)(struct rlc_entity_t *entity); + void (*reestablishment)(struct rlc_entity_s *entity); - void (*delete)(struct rlc_entity_t *entity); + void (*delete)(struct rlc_entity_s *entity); /* callbacks provided to the RLC module */ - void (*deliver_sdu)(void *deliver_sdu_data, struct rlc_entity_t *entity, - char *buf, int size); + void (*deliver_sdu)(void *deliver_sdu_data, struct rlc_entity_s *entity, char *buf, int size); void *deliver_sdu_data; - void (*sdu_successful_delivery)(void *sdu_successful_delivery_data, - struct rlc_entity_t *entity, - int sdu_id); + void (*sdu_successful_delivery)(void *sdu_successful_delivery_data, struct rlc_entity_s *entity, int sdu_id); void *sdu_successful_delivery_data; - void (*max_retx_reached)(void *max_retx_reached_data, - struct rlc_entity_t *entity); + void (*max_retx_reached)(void *max_retx_reached_data, struct rlc_entity_s *entity); void *max_retx_reached_data; } rlc_entity_t; -rlc_entity_t *new_rlc_entity_am( - int rx_maxsize, - int tx_maxsize, - void (*deliver_sdu)(void *deliver_sdu_data, struct rlc_entity_t *entity, - char *buf, int size), - void *deliver_sdu_data, - void (*sdu_successful_delivery)(void *sdu_successful_delivery_data, - struct rlc_entity_t *entity, - int sdu_id), - void *sdu_successful_delivery_data, - void (*max_retx_reached)(void *max_retx_reached_data, - struct rlc_entity_t *entity), - void *max_retx_reached_data, - int t_reordering, - int t_status_prohibit, - int t_poll_retransmit, - int poll_pdu, - int poll_byte, - int max_retx_threshold); +rlc_entity_t *new_rlc_entity_am(int rx_maxsize, + int tx_maxsize, + void (*deliver_sdu)(void *deliver_sdu_data, rlc_entity_t *entity, char *buf, int size), + void *deliver_sdu_data, + void (*sdu_successful_delivery)(void *sdu_successful_delivery_data, + rlc_entity_t *entity, + int sdu_id), + void *sdu_successful_delivery_data, + void (*max_retx_reached)(void *max_retx_reached_data, rlc_entity_t *entity), + void *max_retx_reached_data, + int t_reordering, + int t_status_prohibit, + int t_poll_retransmit, + int poll_pdu, + int poll_byte, + int max_retx_threshold); -rlc_entity_t *new_rlc_entity_um( - int rx_maxsize, - int tx_maxsize, - void (*deliver_sdu)(void *deliver_sdu_data, struct rlc_entity_t *entity, - char *buf, int size), - void *deliver_sdu_data, - int t_reordering, - int sn_field_length); +rlc_entity_t *new_rlc_entity_um(int rx_maxsize, + int tx_maxsize, + void (*deliver_sdu)(void *deliver_sdu_data, rlc_entity_t *entity, char *buf, int size), + void *deliver_sdu_data, + int t_reordering, + int sn_field_length); #endif /* _RLC_ENTITY_H_ */ diff --git a/openair2/NR_UE_PHY_INTERFACE/NR_Packet_Drop.c b/openair2/NR_UE_PHY_INTERFACE/NR_Packet_Drop.c index 97c5a4e130..439371c013 100644 --- a/openair2/NR_UE_PHY_INTERFACE/NR_Packet_Drop.c +++ b/openair2/NR_UE_PHY_INTERFACE/NR_Packet_Drop.c @@ -25,7 +25,7 @@ nr_bler_struct nr_bler_data[NR_NUM_MCS]; -slot_rnti_mcs_s slot_rnti_mcs[NUM_NFAPI_SLOT]; +slot_rnti_mcs_t slot_rnti_mcs[NUM_NFAPI_SLOT]; void read_channel_param(const nfapi_nr_dl_tti_pdsch_pdu_rel15_t * pdu, int slot, int index) { if (pdu == NULL) diff --git a/openair2/NR_UE_PHY_INTERFACE/NR_Packet_Drop.h b/openair2/NR_UE_PHY_INTERFACE/NR_Packet_Drop.h index dcc5710724..4db7f64a4f 100644 --- a/openair2/NR_UE_PHY_INTERFACE/NR_Packet_Drop.h +++ b/openair2/NR_UE_PHY_INTERFACE/NR_Packet_Drop.h @@ -44,13 +44,6 @@ typedef struct { uint8_t area_code; } nr_channel_status; -typedef struct nr_phy_channel_params_t { - uint16_t sfn_slot; - uint16_t message_id; - uint16_t nb_of_csi; - nr_channel_status csi[NR_NUM_LAYER]; -} nr_phy_channel_params_t; - typedef struct { uint8_t slot; uint16_t rnti[MAX_NR_CHAN_PARAMS]; @@ -61,7 +54,7 @@ typedef struct { bool drop_flag[MAX_NR_CHAN_PARAMS]; bool latest; uint8_t area_code; -} slot_rnti_mcs_s; +} slot_rnti_mcs_t; typedef struct { uint16_t length; diff --git a/openair2/RRC/LTE/rrc_UE.c b/openair2/RRC/LTE/rrc_UE.c index 6b327d92bc..87481ec316 100644 --- a/openair2/RRC/LTE/rrc_UE.c +++ b/openair2/RRC/LTE/rrc_UE.c @@ -130,9 +130,8 @@ static int decode_SIB1( const protocol_ctxt_t *const ctxt_pP, const uint8_t eNB_ static int decode_SIB1_MBMS( const protocol_ctxt_t *const ctxt_pP, const uint8_t eNB_index, const uint8_t rsrq, const uint8_t rsrp ); -typedef struct rrc_dcch_data_copy_t -{ - LTE_DL_DCCH_Message_t *dl_dcch_msg; +typedef struct { + LTE_DL_DCCH_Message_t *dl_dcch_msg; } rrc_dcch_data_copy_t; static void rrc_ue_process_ueCapabilityEnquiry(const protocol_ctxt_t *const ctxt_pP, diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index 936f333124..7fea00e5dc 100644 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -207,7 +207,7 @@ static bool rrc_delay_transaction(instance_t instance, MessageDef *msg_p) return false; /* not delayed */ } -typedef struct deliver_ue_ctxt_release_data_t { +typedef struct { gNB_RRC_INST *rrc; f1ap_ue_context_rel_cmd_t *release_cmd; sctp_assoc_t assoc_id; diff --git a/openair2/RRC/NR/rrc_gNB_du.c b/openair2/RRC/NR/rrc_gNB_du.c index 76f1ab1741..70fec34a83 100644 --- a/openair2/RRC/NR/rrc_gNB_du.c +++ b/openair2/RRC/NR/rrc_gNB_du.c @@ -53,12 +53,12 @@ #include "utils.h" #include "xer_encoder.h" -static int get_dl_band(const struct f1ap_served_cell_info_t *cell_info) +static int get_dl_band(const f1ap_served_cell_info_t *cell_info) { return cell_info->mode == F1AP_MODE_TDD ? cell_info->tdd.freqinfo.band : cell_info->fdd.dl_freqinfo.band; } -static int get_ssb_scs(const struct f1ap_served_cell_info_t *cell_info) +static int get_ssb_scs(const f1ap_served_cell_info_t *cell_info) { return cell_info->mode == F1AP_MODE_TDD ? cell_info->tdd.tbw.scs : cell_info->fdd.dl_tbw.scs; } diff --git a/openair2/RRC/NR/rrc_gNB_du.h b/openair2/RRC/NR/rrc_gNB_du.h index 343ab5d189..e746b9af96 100644 --- a/openair2/RRC/NR/rrc_gNB_du.h +++ b/openair2/RRC/NR/rrc_gNB_du.h @@ -37,8 +37,8 @@ struct f1ap_served_cell_info_t; #include "f1ap_messages_types.h" #include "ngap_messages_types.h" -void rrc_gNB_process_f1_setup_req(struct f1ap_setup_req_s *req, sctp_assoc_t assoc_id); -void rrc_CU_process_f1_lost_connection(struct gNB_RRC_INST_s *rrc, struct f1ap_lost_connection_t *lc, sctp_assoc_t assoc_id); +void rrc_gNB_process_f1_setup_req(f1ap_setup_req_t *req, sctp_assoc_t assoc_id); +void rrc_CU_process_f1_lost_connection(struct gNB_RRC_INST_s *rrc, f1ap_lost_connection_t *lc, sctp_assoc_t assoc_id); void rrc_gNB_process_f1_du_configuration_update(struct f1ap_gnb_du_configuration_update_s *conf_up, sctp_assoc_t assoc_id); struct nr_rrc_du_container_t *get_du_for_ue(struct gNB_RRC_INST_s *rrc, uint32_t ue_id); diff --git a/openair2/RRC/NR/rrc_gNB_mobility.c b/openair2/RRC/NR/rrc_gNB_mobility.c index 4d2785d9a0..3c59cdfc16 100644 --- a/openair2/RRC/NR/rrc_gNB_mobility.c +++ b/openair2/RRC/NR/rrc_gNB_mobility.c @@ -163,7 +163,7 @@ static void nr_initiate_handover(const gNB_RRC_INST *rrc, rrc_f1_ue_context_setup_for_target_du(rrc, ue, target_cell, ho_prep_info); } -typedef struct deliver_ue_ctxt_modification_data_t { +typedef struct { gNB_RRC_INST *rrc; f1ap_ue_context_mod_req_t *modification_req; sctp_assoc_t assoc_id; diff --git a/openair2/RRC/NR/rrc_gNB_mobility.h b/openair2/RRC/NR/rrc_gNB_mobility.h index d4a51efeb9..6eb65b51e5 100644 --- a/openair2/RRC/NR/rrc_gNB_mobility.h +++ b/openair2/RRC/NR/rrc_gNB_mobility.h @@ -28,7 +28,6 @@ /* forward declarations */ typedef struct gNB_RRC_INST_s gNB_RRC_INST; typedef struct gNB_RRC_UE_s gNB_RRC_UE_t; -typedef struct nr_rrc_cell_container_t nr_rrc_cell_container_t; typedef struct NR_CellGroupConfig NR_CellGroupConfig_t; From 710ac4e29c9697f5b150ba42e4a1d776eb8970ea Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Mon, 2 Mar 2026 11:26:39 +0100 Subject: [PATCH 16/44] Remove unused files/targets in CMakeLists.txt --- CMakeLists.txt | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d0b9f17a02..d520e8cc50 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2012,11 +2012,9 @@ target_link_libraries(nr_pbchsim PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs) add_executable(nr_psbchsim ${OPENAIR1_DIR}/SIMULATION/NR_PHY/psbchsim.c ${NFAPI_USER_DIR}/nfapi.c - ${NFAPI_USER_DIR}/gnb_ind_vars.c - ${PHY_INTERFACE_DIR}/queue_t.c ) target_link_libraries(nr_psbchsim PRIVATE - -Wl,--start-group UTIL SIMU PHY_COMMON PHY_NR_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB SCHED_NR_UE_LIB MAC_UE_NR MAC_NR_COMMON CONFIG_LIB L2_NR -Wl,--end-group + -Wl,--start-group UTIL SIMU PHY_COMMON PHY_NR_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB SCHED_NR_UE_LIB MAC_UE_NR MAC_NR_COMMON CONFIG_LIB -Wl,--end-group m pthread ${T_LIB} ITTI dl physim_common softmodem_common ) target_link_libraries(nr_psbchsim PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs) @@ -2035,7 +2033,7 @@ add_executable(nr_dlsim ${PHY_INTERFACE_DIR}/queue_t.c ) target_link_libraries(nr_dlsim PRIVATE - -Wl,--start-group UTIL SIMU PHY_COMMON PHY_NR_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB SCHED_NR_UE_LIB MAC_UE_NR MAC_NR_COMMON nr_rrc CONFIG_LIB L2_NR x2ap SECURITY ngap -Wl,--end-group + -Wl,--start-group UTIL SIMU PHY_COMMON PHY_NR_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB SCHED_NR_UE_LIB MAC_UE_NR MAC_NR_COMMON CONFIG_LIB L2_NR -Wl,--end-group m pthread ${T_LIB} ITTI dl nr_ue_phy_meas physim_common softmodem_common ) @@ -2049,7 +2047,6 @@ target_link_libraries(nr_prachsim PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs) add_executable(nr_ulschsim ${OPENAIR1_DIR}/SIMULATION/NR_PHY/ulschsim.c - ${PHY_INTERFACE_DIR}/queue_t.c ) target_link_libraries(nr_ulschsim PRIVATE -Wl,--start-group UTIL SIMU PHY_COMMON PHY_NR_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB CONFIG_LIB MAC_NR_COMMON -Wl,--end-group @@ -2065,7 +2062,7 @@ add_executable(nr_ulsim ) target_link_libraries(nr_ulsim PRIVATE - -Wl,--start-group UTIL SIMU PHY_COMMON PHY_NR_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB SCHED_NR_UE_LIB MAC_UE_NR MAC_NR_COMMON nr_rrc CONFIG_LIB L2_NR x2ap SECURITY ngap -Wl,--end-group + -Wl,--start-group UTIL SIMU PHY_COMMON PHY_NR_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB SCHED_NR_UE_LIB MAC_UE_NR MAC_NR_COMMON CONFIG_LIB L2_NR -Wl,--end-group m pthread ${T_LIB} ITTI dl nr_ue_phy_meas physim_common softmodem_common ) target_link_libraries(nr_ulsim PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs) @@ -2073,8 +2070,6 @@ target_link_libraries(nr_ulsim PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs) add_executable(nr_srssim ${OPENAIR1_DIR}/SIMULATION/NR_PHY/srssim.c ${NFAPI_USER_DIR}/nfapi.c - ${NFAPI_USER_DIR}/gnb_ind_vars.c - ${PHY_INTERFACE_DIR}/queue_t.c ) target_link_libraries(nr_srssim PRIVATE From 649ae91e594a5bc0850714982d01eb192f3b321a Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Mon, 2 Mar 2026 11:28:07 +0100 Subject: [PATCH 17/44] Remove Ubuntu 20 support Ubuntu 20 is EOL [1] unless people pay for support. Therefore, remove it from build_helper. People can still use it, but might need to install a more recent cmake version (which the next commit will upgrade). The rest should be the same. [1] https://ubuntu.com/about/release-cycle --- cmake_targets/tools/build_helper | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/cmake_targets/tools/build_helper b/cmake_targets/tools/build_helper index 64c171276c..48f6d18a55 100755 --- a/cmake_targets/tools/build_helper +++ b/cmake_targets/tools/build_helper @@ -105,7 +105,6 @@ check_supported_distribution() { case "$distribution" in "ubuntu24.04") return 0 ;; "ubuntu22.04") return 0 ;; - "ubuntu20.04") return 0 ;; "debian11") return 0 ;; "debian12") return 0 ;; "fedora41") return 0 ;; @@ -281,7 +280,7 @@ check_install_usrp_uhd_driver(){ $SUDO apt-get update $SUDO apt-get -y install python3-tk $boost_libs_ubuntu libusb-1.0-0-dev case "$(get_distribution_release)" in - "ubuntu20.04" | "ubuntu22.04") + "ubuntu22.04") $SUDO apt-get -y install libuhd-dev libuhd4.5.0 uhd-host ;; esac @@ -441,7 +440,7 @@ check_install_additional_tools (){ local optional_packages="" if [[ "$OS_BASEDISTRO" == "debian" ]]; then case "$(get_distribution_release)" in - "ubuntu20.04" | "ubuntu22.04" | "debian11" | "debian12" ) + "ubuntu22.04" | "debian11" | "debian12" ) optional_packages="python3 python3-pip python3-dev python3-scipy python3-matplotlib python3-pyroute2 universal-ctags" ;; esac From d37cb161ea64fa33f78ca3f344a98f21f9fe404f Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Mon, 2 Mar 2026 12:13:25 +0100 Subject: [PATCH 18/44] Update minimum cmake version to 3.19 --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d520e8cc50..28b3445397 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -19,7 +19,7 @@ # * contact@openairinterface.org # */ -cmake_minimum_required (VERSION 3.16) +cmake_minimum_required (VERSION 3.19) project (OpenAirInterface LANGUAGES C CXX) set(CMAKE_CXX_STANDARD 17) set(OAI_VERSION 2.4.0) From 1ea2b1b3ac9220a74b9cf6e61606a45ae77764d3 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Mon, 2 Mar 2026 14:07:08 +0100 Subject: [PATCH 19/44] Upgrade Fedora req to 43 --- README.md | 2 +- cmake_targets/tools/build_helper | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 17e275f240..aba30a855b 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ Supported OS Ubuntu 22 Supported OS Ubuntu 24 Supported OS RHEL9 - Supported OS Fedora 41 + Supported OS Fedora 43

diff --git a/cmake_targets/tools/build_helper b/cmake_targets/tools/build_helper index 48f6d18a55..d2a3c2b3b9 100755 --- a/cmake_targets/tools/build_helper +++ b/cmake_targets/tools/build_helper @@ -107,8 +107,7 @@ check_supported_distribution() { "ubuntu22.04") return 0 ;; "debian11") return 0 ;; "debian12") return 0 ;; - "fedora41") return 0 ;; - "fedora40") return 0 ;; + "fedora43") return 0 ;; "rhel8.2") return 0 ;; "rhel8.3") return 0 ;; "rhel8.4") return 0 ;; From 757a3131a1024564118c1f60f74f9b0d4e3dbfb4 Mon Sep 17 00:00:00 2001 From: Raghavendra Dinavahi Date: Thu, 12 Feb 2026 20:20:55 +0100 Subject: [PATCH 20/44] UE: Fix if target cell has SSB at a different offset as in source cell Actual problem is that SYNC does not happen on the target cell as frame parameters is not updated and ssb start carrier is not correct in the UE frame parameters function nr_get_ssb_start_sc to determine ssb_start_subcarrier --- executables/nr-ue.c | 15 ++++++++++-- openair1/PHY/INIT/nr_parms.c | 14 ++++------- .../PHY/nr_phy_common/inc/nr_phy_common.h | 5 ++++ .../PHY/nr_phy_common/src/nr_phy_common.c | 23 +++++++++++++++++++ openair1/SCHED_NR/phy_procedures_nr_gNB.c | 16 ++++--------- openair2/LAYER2/NR_MAC_UE/config_ue.c | 21 +++++++++-------- 6 files changed, 61 insertions(+), 33 deletions(-) diff --git a/executables/nr-ue.c b/executables/nr-ue.c index 88a8ff84c8..bde020cbc7 100644 --- a/executables/nr-ue.c +++ b/executables/nr-ue.c @@ -486,12 +486,13 @@ static int handle_sync_req_from_mac(PHY_VARS_NR_UE *UE) UE->UE_scan_carrier = false; UE->target_Nid_cell = UE->synch_request.synch_req.target_Nid_cell; - const fapi_nr_ue_carrier_config_t *cfg = &UE->nrUE_config.carrier_config; + const fapi_nr_config_request_t *config = &UE->nrUE_config; + const fapi_nr_ue_carrier_config_t *cfg = &config->carrier_config; uint64_t dl_CarrierFreq = get_carrier_frequency(fp->N_RB_DL, fp->numerology_index, cfg->dl_frequency); uint64_t ul_CarrierFreq = get_carrier_frequency(fp->N_RB_UL, fp->numerology_index, cfg->uplink_frequency); if (dl_CarrierFreq != fp->dl_CarrierFreq || ul_CarrierFreq != fp->ul_CarrierFreq) { LOG_I(NR_PHY, - "[UE %d] RF frequency change: dl %lu->%lu Hz, ul %lu->%lu Hz (from dl_frequency=%u kHz, target_Nid_cell=%d)\n", + "[UE %d] SYNC REQ: RF frequency change: dl %lu->%lu Hz, ul %lu->%lu Hz (from dl_frequency=%u kHz, target_Nid_cell=%d)\n", UE->Mod_id, fp->dl_CarrierFreq, dl_CarrierFreq, @@ -505,6 +506,16 @@ static int handle_sync_req_from_mac(PHY_VARS_NR_UE *UE) init_symbol_rotation(fp); } + int ssb_start_subcarrier = nr_get_ssb_start_sc(fp->numerology_index, + config->ssb_table.ssb_offset_point_a, + config->ssb_table.ssb_subcarrier_offset, + fp->freq_range); + // SSB location can change during for ex: handover on the target cell + if (ssb_start_subcarrier != fp->ssb_start_subcarrier) { + fp->ssb_start_subcarrier = ssb_start_subcarrier; + LOG_I(NR_PHY, "SYNC REQ: SSB location changed:%d\n", fp->ssb_start_subcarrier); + } + // Apply Doppler based on NTN-Config for target cell if (UE->nrUE_config.ntn_config.is_targetcell) apply_ntn_timing_advance_and_doppler(UE, fp, -1); diff --git a/openair1/PHY/INIT/nr_parms.c b/openair1/PHY/INIT/nr_parms.c index 66f766571d..0e39e19d9e 100644 --- a/openair1/PHY/INIT/nr_parms.c +++ b/openair1/PHY/INIT/nr_parms.c @@ -24,6 +24,7 @@ #include "common/utils/LOG/log.h" #include "executables/softmodem-common.h" #include "PHY/MODULATION/nr_modulation.h" +#include "PHY/nr_phy_common/inc/nr_phy_common.h" /// Subcarrier spacings in Hz indexed by numerology index static const uint32_t nr_subcarrier_spacing[MAX_NUM_SUBCARRIER_SPACING] = {15e3, 30e3, 60e3, 120e3, 240e3}; @@ -421,16 +422,11 @@ int nr_init_frame_parms_ue(NR_DL_FRAME_PARMS *fp, fapi_nr_config_request_t* conf fp->samples_per_frame = 10 * fp->samples_per_subframe; fp->freq_range = get_freq_range_from_freq(fp->dl_CarrierFreq); - uint8_t sco = 0; - if (((fp->freq_range == FR1) && (config->ssb_table.ssb_subcarrier_offset < 24)) || - ((fp->freq_range == FR2) && (config->ssb_table.ssb_subcarrier_offset < 12))) { - if (fp->freq_range == FR1) - sco = config->ssb_table.ssb_subcarrier_offset>>config->ssb_config.scs_common; - else - sco = config->ssb_table.ssb_subcarrier_offset; - } + fp->ssb_start_subcarrier = nr_get_ssb_start_sc(config->ssb_config.scs_common, + config->ssb_table.ssb_offset_point_a, + config->ssb_table.ssb_subcarrier_offset, + fp->freq_range); - fp->ssb_start_subcarrier = (12 * config->ssb_table.ssb_offset_point_a + sco); set_Lmax(fp); fp->L_ssb = (((uint64_t) config->ssb_table.ssb_mask_list[0].ssb_mask)<<32) | config->ssb_table.ssb_mask_list[1].ssb_mask; diff --git a/openair1/PHY/nr_phy_common/inc/nr_phy_common.h b/openair1/PHY/nr_phy_common/inc/nr_phy_common.h index b4c0e1239c..67bed6eef4 100644 --- a/openair1/PHY/nr_phy_common/inc/nr_phy_common.h +++ b/openair1/PHY/nr_phy_common/inc/nr_phy_common.h @@ -389,4 +389,9 @@ void nr_generate_csi_rs(const NR_DL_FRAME_PARMS *frame_parms, const uint8_t cdm_type, c16_t **dataF); +int nr_get_ssb_start_sc(int scs, + int ssb_offset_point_a, + int ssb_sco, + frequency_range_t freq_range); + #endif diff --git a/openair1/PHY/nr_phy_common/src/nr_phy_common.c b/openair1/PHY/nr_phy_common/src/nr_phy_common.c index a723780f94..c29a3a4936 100644 --- a/openair1/PHY/nr_phy_common/src/nr_phy_common.c +++ b/openair1/PHY/nr_phy_common/src/nr_phy_common.c @@ -481,3 +481,26 @@ void nr_fo_compensation(double fo_Hz, int samples_per_ms, int sample_offset, con mult_complex_vectors(rxdata_in, rot, rxdata_out, size, 14); #endif } + +/*! +* Setting the first subcarrier +* 3GPP TS 38.211 sections 7.4.3.1 and 4.4.4.2 +* for FR1 offsetToPointA and k_SSB are expressed in terms of 15 kHz SCS +* for FR2 offsetToPointA is expressed in terms of 60 kHz SCS and k_SSB expressed in terms of the SCS provided +* by the higher-layer parameter subCarrierSpacingCommon +*/ +int nr_get_ssb_start_sc(int scs, int ssb_offset_point_a, int ssb_sco, frequency_range_t freq_range) +{ + const int prb_offset = + (freq_range == FR1) ? ssb_offset_point_a >> scs : ssb_offset_point_a >> (scs - 2); + const int sc_offset = + (freq_range == FR1) ? ssb_sco >> scs : ssb_sco; + + int ssb_start_subcarrier = (12 * prb_offset + sc_offset); + + LOG_D(NR_PHY, "prb_offset:%d, ssb_subcarrier_offset:%d,scs :%d, Fr:%d, ssb_start_subcarrier:%d\n", + prb_offset, ssb_sco, scs, freq_range, ssb_start_subcarrier); + + return ssb_start_subcarrier; + +} diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c index e304fe3dc9..baccacbf26 100644 --- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c +++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c @@ -118,9 +118,10 @@ void nr_common_signal_procedures(PHY_VARS_gNB *gNB, int frame, int slot, const n // by the higher-layer parameter subCarrierSpacingCommon nfapi_nr_config_request_scf_t *cfg = &gNB->gNB_config; const int scs = cfg->ssb_config.scs_common.value; - const int prb_offset = (fp->freq_range == FR1) ? pdu->ssbOffsetPointA >> scs : pdu->ssbOffsetPointA >> (scs - 2); - const int sc_offset = (fp->freq_range == FR1) ? pdu->SsbSubcarrierOffset >> scs : pdu->SsbSubcarrierOffset; - fp->ssb_start_subcarrier = (12 * prb_offset + sc_offset); + fp->ssb_start_subcarrier = nr_get_ssb_start_sc(scs, + pdu->ssbOffsetPointA, + pdu->SsbSubcarrierOffset, + fp->freq_range); if (fp->print_ue_help_cmdline_log && IS_SA_MODE(get_softmodem_params())) { fp->print_ue_help_cmdline_log = false; @@ -142,15 +143,6 @@ void nr_common_signal_procedures(PHY_VARS_gNB *gNB, int frame, int slot, const n fp->ssb_start_subcarrier, fp->threequarter_fs ? "-E" : ""); } - LOG_D(PHY, - "ssbOffsetPointA %d SSB SsbSubcarrierOffset %d prb_offset %d sc_offset %d scs %d ssb_start_subcarrier %d\n", - pdu->ssbOffsetPointA, - pdu->SsbSubcarrierOffset, - prb_offset, - sc_offset, - scs, - fp->ssb_start_subcarrier); - LOG_D(PHY,"SS TX: frame %d, slot %d, start_symbol %d\n", frame, slot, ssb_start_symbol); const nfapi_nr_tx_precoding_and_beamforming_t *pb = &pdu->precoding_and_beamforming; c16_t ***txdataF = gNB->common_vars.txdataF; diff --git a/openair2/LAYER2/NR_MAC_UE/config_ue.c b/openair2/LAYER2/NR_MAC_UE/config_ue.c index 2a5c8e041d..5d078cf941 100644 --- a/openair2/LAYER2/NR_MAC_UE/config_ue.c +++ b/openair2/LAYER2/NR_MAC_UE/config_ue.c @@ -537,16 +537,15 @@ static void config_common_ue(NR_UE_MAC_INST_t *mac, NR_ServingCellConfigCommon_t // SSB Table config if (frequencyInfoDL && frequencyInfoDL->absoluteFrequencySSB) { - int scs_scaling = 1 << (cfg->ssb_config.scs_common); - if (frequencyInfoDL->absoluteFrequencyPointA < 600000) - scs_scaling = scs_scaling * 3; - if (frequencyInfoDL->absoluteFrequencyPointA > 2016666) - scs_scaling = scs_scaling >> 2; - uint32_t absolute_diff = (*frequencyInfoDL->absoluteFrequencySSB - frequencyInfoDL->absoluteFrequencyPointA); - cfg->ssb_table.ssb_offset_point_a = absolute_diff / (12 * scs_scaling) - 10; + cfg->ssb_table.ssb_offset_point_a = get_ssb_offset_to_pointA(*frequencyInfoDL->absoluteFrequencySSB, + frequencyInfoDL->absoluteFrequencyPointA, + cfg->ssb_config.scs_common, + mac->frequency_range); cfg->ssb_table.ssb_period = *scc->ssb_periodicityServingCell; // NSA -> take ssb offset from SCS - cfg->ssb_table.ssb_subcarrier_offset = absolute_diff % (12 * scs_scaling); + cfg->ssb_table.ssb_subcarrier_offset = get_ssb_subcarrier_offset(*frequencyInfoDL->absoluteFrequencySSB, + frequencyInfoDL->absoluteFrequencyPointA, + cfg->ssb_config.scs_common); cfg->ssb_table.ssb_case = set_ssb_case(*scc->ssbSubcarrierSpacing, mac->nr_band); } @@ -2113,12 +2112,14 @@ static void handle_reconfiguration_with_sync(NR_UE_MAC_INST_t *mac, ra->ra_state = nrRA_UE_IDLE; nr_ue_mac_default_configs(mac); + // PHY CONFIG request should be sent, ahead of SYNC request + // As SYNC request processes the new config + mac->if_module->phy_config_request(&mac->phy_config); + mac->phy_config.config_req.ntn_config.params_changed = false; mac->synch_request.Mod_id = mac->ue_id; mac->synch_request.CC_id = cc_idP; mac->synch_request.synch_req.target_Nid_cell = mac->physCellId; mac->if_module->synch_request(&mac->synch_request); - mac->if_module->phy_config_request(&mac->phy_config); - mac->phy_config.config_req.ntn_config.params_changed = false; } static void configure_physicalcellgroup(NR_UE_MAC_INST_t *mac, From ccf4b425419a0c784511b83bae2b63946c244c34 Mon Sep 17 00:00:00 2001 From: Rakesh Mundlamuri Date: Tue, 30 Dec 2025 15:02:31 +0530 Subject: [PATCH 21/44] Add RCconfig_nr_positioning to obtain and fill TRP related parameters from config file --- openair1/PHY/defs_nr_common.h | 23 +++++++ openair2/COMMON/positioning_nr_paramdef.h | 62 +++++++++++++++++ openair2/GNB_APP/gnb_config.c | 1 + openair3/NRPPA/nrppa_gNB_config.c | 84 +++++++++++++++++++++++ openair3/NRPPA/nrppa_gNB_config.h | 30 ++++++++ tests/nr-cu-nrppa/nr-cu-nrppa.c | 1 + tests/nr-cu-nrppa/nr-nrppa-test.conf | 21 ++++++ 7 files changed, 222 insertions(+) create mode 100644 openair2/COMMON/positioning_nr_paramdef.h create mode 100644 openair3/NRPPA/nrppa_gNB_config.c create mode 100644 openair3/NRPPA/nrppa_gNB_config.h diff --git a/openair1/PHY/defs_nr_common.h b/openair1/PHY/defs_nr_common.h index 199877d738..2543eb6650 100644 --- a/openair1/PHY/defs_nr_common.h +++ b/openair1/PHY/defs_nr_common.h @@ -305,6 +305,29 @@ typedef struct { int32_t reserved; } prs_meas_t; +// Configuration parameters required for 5G Positioning +// TRP Cartesian Coordinate information +typedef struct trp_s { + // TRP id + uint32_t id; + // TRP x-axis value + uint32_t x_axis; + // TRP y-axis value + uint32_t y_axis; + // TRP z-axis value + uint32_t z_axis; + // 0 = mm, 1 = cm, 2 = dm + uint8_t unit; +} trp_t; + +#define MAX_NUM_TRPs 8 +typedef struct { + trp_t trps[MAX_NUM_TRPs]; + uint8_t num_trp; + // Serving gNB indicator + bool is_serving_gNB; +} positioning_config_t; + // rel16 prs k_prime table as per ts138.211 sec.7.4.1.7.2 #define K_PRIME_TABLE_ROW_SIZE 4 #define K_PRIME_TABLE_COL_SIZE 12 diff --git a/openair2/COMMON/positioning_nr_paramdef.h b/openair2/COMMON/positioning_nr_paramdef.h new file mode 100644 index 0000000000..6861db6778 --- /dev/null +++ b/openair2/COMMON/positioning_nr_paramdef.h @@ -0,0 +1,62 @@ +/* + * 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 __POSITIONING_NR_PARAMDEF__H__ +#define __POSITIONING_NR_PARAMDEF__H__ + +/* Positioning configuration section names */ +#define CONFIG_STRING_POSITIONING_CONFIG "positioning_config" + +/* Global parameters */ + +/* TRP configuration parameters names */ +#define CONFIG_STRING_POSITIONING_NUM_TRPS "NumTRPs" +#define CONFIG_STRING_POSITIONING_TRP_IDS_LIST "TRPIDs" +#define CONFIG_STRING_POSITIONING_TRP_X_AXIS_LIST "TRPxAxis" +#define CONFIG_STRING_POSITIONING_TRP_Y_AXIS_LIST "TRPyAxis" +#define CONFIG_STRING_POSITIONING_TRP_Z_AXIS_LIST "TRPzAxis" +#define CONFIG_STRING_POSITIONING_TRP_UNIT_LIST "Units" + +/* Help string for Positioning parameters */ +#define HELP_STRING_POSITIONING_NUM_TRPS "Number of TRPs connected with gNB(max 4)\n" +#define HELP_STRING_POSITIONING_TRP_IDS_LIST "User defined IDs for each TRP \n" +#define HELP_STRING_POSITIONING_TRP_X_AXIS_LIST "x-axis value of each TRP \n" +#define HELP_STRING_POSITIONING_TRP_Y_AXIS_LIST "y-axis value of each TRP \n" +#define HELP_STRING_POSITIONING_TRP_Z_AXIS_LIST "z-axis value of each TRP \n" +#define HELP_STRING_POSITIONING_TRP_UNIT_LIST "XYZ unit value of each TRP \n" + +/*----------------------------------------------------------------------------------------------------------------------------------------------------------------*/ +/* TRP configuration parameters */ +/* optname helpstr paramflags XXXptr defXXXval type + * numelt */ +/*----------------------------------------------------------------------------------------------------------------------------------------------------------------*/ +// clang-format off +#define POSITIONING_PARAMS_DESC { \ + {CONFIG_STRING_POSITIONING_NUM_TRPS, HELP_STRING_POSITIONING_NUM_TRPS, 0, .uptr=NULL, .defuintval=0, TYPE_UINT, 0}, \ + {CONFIG_STRING_POSITIONING_TRP_IDS_LIST, HELP_STRING_POSITIONING_TRP_IDS_LIST, 0, .uptr=NULL, .defintarrayval=0, TYPE_UINTARRAY, 0}, \ + {CONFIG_STRING_POSITIONING_TRP_X_AXIS_LIST, HELP_STRING_POSITIONING_TRP_X_AXIS_LIST, 0, .uptr=NULL, .defintarrayval=0, TYPE_UINTARRAY, 0}, \ + {CONFIG_STRING_POSITIONING_TRP_Y_AXIS_LIST, HELP_STRING_POSITIONING_TRP_Y_AXIS_LIST, 0, .uptr=NULL, .defintarrayval=0, TYPE_UINTARRAY, 0}, \ + {CONFIG_STRING_POSITIONING_TRP_Z_AXIS_LIST, HELP_STRING_POSITIONING_TRP_Z_AXIS_LIST, 0, .uptr=NULL, .defintarrayval=0, TYPE_UINTARRAY, 0}, \ + {CONFIG_STRING_POSITIONING_TRP_UNIT_LIST, HELP_STRING_POSITIONING_TRP_UNIT_LIST, 0, .uptr=NULL, .defintarrayval=0, TYPE_UINTARRAY, 0}, \ +} +// clang-format on + +#endif diff --git a/openair2/GNB_APP/gnb_config.c b/openair2/GNB_APP/gnb_config.c index d6d370fe70..3262f851a5 100644 --- a/openair2/GNB_APP/gnb_config.c +++ b/openair2/GNB_APP/gnb_config.c @@ -80,6 +80,7 @@ #include "utils.h" #include "x2ap_messages_types.h" #include "gnb_config_common.h" +#include "positioning_nr_paramdef.h" static int DEFBANDS[] = {7}; static int DEFENBS[] = {0}; diff --git a/openair3/NRPPA/nrppa_gNB_config.c b/openair3/NRPPA/nrppa_gNB_config.c new file mode 100644 index 0000000000..dc0590f603 --- /dev/null +++ b/openair3/NRPPA/nrppa_gNB_config.c @@ -0,0 +1,84 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#include "nrppa_gNB_config.h" +#include "assertions.h" +#include "openair1/PHY/defs_nr_common.h" +#include "openair1/PHY/defs_gNB.h" +#include "common/ran_context.h" +#include "positioning_nr_paramdef.h" + +positioning_config_t RCconfig_nr_positioning(void) +{ + positioning_config_t positioning_config = {0}; + paramdef_t positioning_params_desc[] = POSITIONING_PARAMS_DESC; + int num_params = sizeofArray(positioning_params_desc); + GET_PARAMS_LIST(POSITIONING_ParamList, POSITIONING_Params, POSITIONING_PARAMS_DESC, CONFIG_STRING_POSITIONING_CONFIG, NULL); + + if (POSITIONING_ParamList.numelt > 0) { + paramdef_t *params = POSITIONING_ParamList.paramarray[0]; + + uint8_t num_trp = *gpd(params, num_params, CONFIG_STRING_POSITIONING_NUM_TRPS)->uptr; + if (num_trp == 0) { + LOG_E(NR_PHY, "No TRP configuration found..!!!\n"); + return positioning_config; + } else if (num_trp > MAX_NUM_TRPs) { + AssertFatal(false, "Exceeded MAX number of TRPs\n"); + } + + uint8_t num_ids = gpd(params, num_params, CONFIG_STRING_POSITIONING_TRP_IDS_LIST)->numelt; + uint8_t num_x = gpd(params, num_params, CONFIG_STRING_POSITIONING_TRP_X_AXIS_LIST)->numelt; + uint8_t num_y = gpd(params, num_params, CONFIG_STRING_POSITIONING_TRP_Y_AXIS_LIST)->numelt; + uint8_t num_z = gpd(params, num_params, CONFIG_STRING_POSITIONING_TRP_Z_AXIS_LIST)->numelt; + uint8_t num_unit = gpd(params, num_params, CONFIG_STRING_POSITIONING_TRP_UNIT_LIST)->numelt; + + if (num_trp != num_ids || num_trp != num_x || num_trp != num_y || num_trp != num_z || num_trp != num_unit) { + AssertFatal(false, "Mismatch in the number of TRPs with the number of ids, x-axis, y-axis, z-axis, units\n"); + } + + positioning_config.num_trp = num_trp; + for (int l = 0; l < num_trp; l++) { + positioning_config.trps[l].id = gpd(params, num_params, CONFIG_STRING_POSITIONING_TRP_IDS_LIST)->uptr[l]; + positioning_config.trps[l].x_axis = gpd(params, num_params, CONFIG_STRING_POSITIONING_TRP_X_AXIS_LIST)->uptr[l]; + positioning_config.trps[l].y_axis = gpd(params, num_params, CONFIG_STRING_POSITIONING_TRP_Y_AXIS_LIST)->uptr[l]; + positioning_config.trps[l].z_axis = gpd(params, num_params, CONFIG_STRING_POSITIONING_TRP_Z_AXIS_LIST)->uptr[l]; + positioning_config.trps[l].unit = gpd(params, num_params, CONFIG_STRING_POSITIONING_TRP_UNIT_LIST)->uptr[l]; + } + } else { + LOG_I(NR_PHY, "No " CONFIG_STRING_POSITIONING_CONFIG " configuration found..!!\n"); + } + return positioning_config; +} + +void dump_positioning_config(const positioning_config_t *positioning_config) +{ + uint8_t num_trp = positioning_config->num_trp; + LOG_I(NR_PHY, "-----------------------------------------\n"); + LOG_I(NR_PHY, "Positioning Config\n"); + LOG_I(NR_PHY, "-----------------------------------------\n"); + LOG_I(NR_PHY, "Number of TRPs \t\t%d\n", num_trp); + for (int i = 0; i < num_trp; i++) { + LOG_I(NR_PHY, "X-axis of TRP ID %d \t\t%d\n", positioning_config->trps[i].id, positioning_config->trps[i].x_axis); + LOG_I(NR_PHY, "Y-axis of TRP ID %d \t\t%d\n", positioning_config->trps[i].id, positioning_config->trps[i].y_axis); + LOG_I(NR_PHY, "Z-axis of TRP ID %d \t\t%d\n", positioning_config->trps[i].id, positioning_config->trps[i].z_axis); + } + LOG_I(NR_PHY, "-----------------------------------------\n"); +} diff --git a/openair3/NRPPA/nrppa_gNB_config.h b/openair3/NRPPA/nrppa_gNB_config.h new file mode 100644 index 0000000000..3ae710a62c --- /dev/null +++ b/openair3/NRPPA/nrppa_gNB_config.h @@ -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 GNB_CONFIG_POSITIONING_H_ +#define GNB_CONFIG_POSITIONING_H_ + +#include "openair1/PHY/defs_nr_common.h" + +positioning_config_t RCconfig_nr_positioning(void); +void dump_positioning_config(const positioning_config_t *positioning_config); + +#endif /* GNB_CONFIG_POSITIONING_H_ */ diff --git a/tests/nr-cu-nrppa/nr-cu-nrppa.c b/tests/nr-cu-nrppa/nr-cu-nrppa.c index 1436b7cd27..2c29ce6258 100644 --- a/tests/nr-cu-nrppa/nr-cu-nrppa.c +++ b/tests/nr-cu-nrppa/nr-cu-nrppa.c @@ -27,6 +27,7 @@ #include "openair2/GNB_APP/gnb_config_ng.h" #include "openair2/GNB_APP/gnb_paramdef.h" #include "openair3/SCTP/sctp_default_values.h" +#include "openair3/NRPPA/nrppa_gNB_config.h" RAN_CONTEXT_t RC; THREAD_STRUCT thread_struct; diff --git a/tests/nr-cu-nrppa/nr-nrppa-test.conf b/tests/nr-cu-nrppa/nr-nrppa-test.conf index f5d6ea673a..aaaa45f176 100644 --- a/tests/nr-cu-nrppa/nr-nrppa-test.conf +++ b/tests/nr-cu-nrppa/nr-nrppa-test.conf @@ -38,6 +38,27 @@ gNBs = } ); +positioning_config = ( + { + NumTRPs = 4; # number of TRPs + TRPIDs = [1,2,3,4]; # userdefined distinct IDs + TRPxAxis = [71,21,10,45]; # X-axis value of each TRP + TRPyAxis = [11,22,62,14]; # Y-axis value of each TRP + TRPzAxis = [41,22,33,42]; # Z-axis value of each TRP + Units = [0, 0, 0, 0]; # 0 = mm, 1 = cm, 2 = dm + } +); + +L1s = ( + { + num_cc = 1; + tr_n_preference = "local_mac"; + prach_dtx_threshold = 120; + pucch0_dtx_threshold = 150; + ofdm_offset_divisor = 8; #set this to UINT_MAX for offset 0 + } +); + log_config : { global_log_level ="info"; From 446a905013d88a32d375081fe0ca71af0c4e1072 Mon Sep 17 00:00:00 2001 From: Rakesh Mundlamuri Date: Wed, 7 Jan 2026 12:08:25 +0530 Subject: [PATCH 22/44] Add TRP Information Request NRPPA message decoding procedures --- common/utils/LOG/log.h | 1 + common/utils/T/T_messages.txt | 21 ++ common/utils/ocp_itti/all_msg.h | 2 +- common/utils/ocp_itti/intertask_interface.h | 1 + openair2/COMMON/nrppa_messages_def.h | 25 +++ openair2/COMMON/nrppa_messages_types.h | 67 +++++++ openair3/NRPPA/CMakeLists.txt | 14 +- openair3/NRPPA/nrppa_common.h | 62 ++++++ openair3/NRPPA/nrppa_gNB.c | 79 ++++++++ openair3/NRPPA/nrppa_gNB.h | 32 ++++ openair3/NRPPA/nrppa_gNB_decoder.c | 116 ++++++++++++ openair3/NRPPA/nrppa_gNB_decoder.h | 30 +++ openair3/NRPPA/nrppa_gNB_handlers.c | 179 ++++++++++++++++++ openair3/NRPPA/nrppa_gNB_handlers.h | 28 +++ .../nrppa_gNB_location_information_transfer.c | 95 ++++++++++ .../nrppa_gNB_location_information_transfer.h | 28 +++ openair3/NRPPA/nrppa_gNB_ue_context.c | 85 +++++++++ openair3/NRPPA/nrppa_gNB_ue_context.h | 43 +++++ openair3/NRPPA/nrppa_includes.h | 39 ++++ tests/nr-cu-nrppa/CMakeLists.txt | 2 +- tests/nr-cu-nrppa/nr-cu-nrppa.c | 4 + 21 files changed, 948 insertions(+), 5 deletions(-) create mode 100644 openair2/COMMON/nrppa_messages_def.h create mode 100644 openair2/COMMON/nrppa_messages_types.h create mode 100644 openair3/NRPPA/nrppa_common.h create mode 100644 openair3/NRPPA/nrppa_gNB.c create mode 100644 openair3/NRPPA/nrppa_gNB.h create mode 100644 openair3/NRPPA/nrppa_gNB_decoder.c create mode 100644 openair3/NRPPA/nrppa_gNB_decoder.h create mode 100644 openair3/NRPPA/nrppa_gNB_handlers.c create mode 100644 openair3/NRPPA/nrppa_gNB_handlers.h create mode 100644 openair3/NRPPA/nrppa_gNB_location_information_transfer.c create mode 100644 openair3/NRPPA/nrppa_gNB_location_information_transfer.h create mode 100644 openair3/NRPPA/nrppa_gNB_ue_context.c create mode 100644 openair3/NRPPA/nrppa_gNB_ue_context.h create mode 100644 openair3/NRPPA/nrppa_includes.h diff --git a/common/utils/LOG/log.h b/common/utils/LOG/log.h index a9db2e9c5c..837c6897a6 100644 --- a/common/utils/LOG/log.h +++ b/common/utils/LOG/log.h @@ -165,6 +165,7 @@ static const char *const flag_name[] = {FOREACH_FLAG(FLAG_TEXT) ""}; COMP_DEF(M2AP, ) \ COMP_DEF(M3AP, ) \ COMP_DEF(NGAP, ) \ + COMP_DEF(NRPPA, ) \ COMP_DEF(GNB_APP, log) \ COMP_DEF(NR_RRC, log) \ COMP_DEF(NR_MAC, log) \ diff --git a/common/utils/T/T_messages.txt b/common/utils/T/T_messages.txt index d2405f9033..00f063f703 100644 --- a/common/utils/T/T_messages.txt +++ b/common/utils/T/T_messages.txt @@ -586,6 +586,27 @@ ID = LEGACY_NGAP_TRACE GROUP = ALL:LEGACY_NGAP:LEGACY_GROUP_TRACE:LEGACY FORMAT = string,log +ID = LEGACY_NRPPA_INFO + DESC = NRPPA legacy logs - info level + GROUP = ALL:LEGACY_NRPPA:LEGACY_GROUP_INFO:LEGACY + FORMAT = string,log +ID = LEGACY_NRPPA_ERROR + DESC = NRPPA legacy logs - error level + GROUP = ALL:LEGACY_NRPPA:LEGACY_GROUP_ERROR:LEGACY + FORMAT = string,log +ID = LEGACY_NRPPA_WARNING + DESC = NRPPA legacy logs - warning level + GROUP = ALL:LEGACY_NRPPA:LEGACY_GROUP_WARNING:LEGACY + FORMAT = string,log +ID = LEGACY_NRPPA_DEBUG + DESC = NRPPA legacy logs - debug level + GROUP = ALL:LEGACY_NRPPA:LEGACY_GROUP_DEBUG:LEGACY + FORMAT = string,log +ID = LEGACY_NRPPA_TRACE + DESC = NRPPA legacy logs - trace level + GROUP = ALL:LEGACY_NRPPA:LEGACY_GROUP_TRACE:LEGACY + FORMAT = string,log + ID = LEGACY_X2AP_INFO DESC = X2AP legacy logs - info level GROUP = ALL:LEGACY_X2AP:LEGACY_GROUP_INFO:LEGACY diff --git a/common/utils/ocp_itti/all_msg.h b/common/utils/ocp_itti/all_msg.h index 377bfc4343..8b74409a3c 100644 --- a/common/utils/ocp_itti/all_msg.h +++ b/common/utils/ocp_itti/all_msg.h @@ -14,4 +14,4 @@ #include "openair2/COMMON/f1ap_messages_def.h" #include "openair2/COMMON/e1ap_messages_def.h" #include "openair2/COMMON/ngap_messages_def.h" - +#include "openair2/COMMON/nrppa_messages_def.h" diff --git a/common/utils/ocp_itti/intertask_interface.h b/common/utils/ocp_itti/intertask_interface.h index 7580698dcf..353a0bae5a 100644 --- a/common/utils/ocp_itti/intertask_interface.h +++ b/common/utils/ocp_itti/intertask_interface.h @@ -230,6 +230,7 @@ typedef struct IttiMsgText_s { #include #include #include +#include #include #include #include diff --git a/openair2/COMMON/nrppa_messages_def.h b/openair2/COMMON/nrppa_messages_def.h new file mode 100644 index 0000000000..ae17d73742 --- /dev/null +++ b/openair2/COMMON/nrppa_messages_def.h @@ -0,0 +1,25 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#include "openair2/COMMON/nrppa_messages_types.h" + +// LMF -> CU +MESSAGE_DEF(NRPPA_TRP_INFORMATION_REQ, MESSAGE_PRIORITY_MED, nrppa_trp_information_req_t, nrppa_trp_information_req) diff --git a/openair2/COMMON/nrppa_messages_types.h b/openair2/COMMON/nrppa_messages_types.h new file mode 100644 index 0000000000..55563a59ab --- /dev/null +++ b/openair2/COMMON/nrppa_messages_types.h @@ -0,0 +1,67 @@ +/* + * 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 NRPPA_MESSAGES_TYPES_H_ +#define NRPPA_MESSAGES_TYPES_H_ + +// Defines to access message fields. + +#define NRPPA_TRP_INFORMATION_REQ(mSGpTR) (mSGpTR)->ittiMsg.nrppa_trp_information_req + +/* Structure of Positioning related NRPPA messages */ +/* IE structures for Positioning related messages as per TS 38.455 V16.7.1*/ + +typedef enum nrppa_trp_information_type_item_e { + NRPPA_TRP_INFORMATION_TYPE_ITEM_NR_PCI, + NRPPA_TRP_INFORMATION_TYPE_ITEM_NG_RAN_CGI, + NRPPA_TRP_INFORMATION_TYPE_ITEM_NR_ARFCN, + NRPPA_TRP_INFORMATION_TYPE_ITEM_PRS_CONFIG, + NRPPA_TRP_INFORMATION_TYPE_ITEM_SSB_CONFIG, + NRPPA_TRP_INFORMATION_TYPE_ITEM_SFN_INIT_TIME, + NRPPA_TRP_INFORMATION_TYPE_ITEM_SPATIAL_DIRECTION_INFO, + NRPPA_TRP_INFORMATION_TYPE_ITEM_GEO_COORDINATES +} nrppa_trp_information_type_item_pr; + +typedef struct nrppa_trp_information_type_list_s { + nrppa_trp_information_type_item_pr *trp_information_type_item; + uint8_t trp_information_type_list_length; +} nrppa_trp_information_type_list_t; + +typedef struct nrppa_trp_list_item_s { + uint32_t trp_id; +} nrppa_trp_list_item_t; + +typedef struct nrppa_trp_list_s { + nrppa_trp_list_item_t *trp_list_item; + uint32_t trp_list_length; +} nrppa_trp_list_t; + +typedef struct nrppa_trp_information_req_s { + // IE 9.2.4 (mandatory) + uint16_t transaction_id; + bool has_trp_list; + // mandatory + nrppa_trp_list_t trp_list; + // mandatory + nrppa_trp_information_type_list_t trp_information_type_list; +} nrppa_trp_information_req_t; + +#endif // NRPPA_MESSAGES_TYPES_H_ diff --git a/openair3/NRPPA/CMakeLists.txt b/openair3/NRPPA/CMakeLists.txt index 613cbfc3ce..28ad4c8618 100644 --- a/openair3/NRPPA/CMakeLists.txt +++ b/openair3/NRPPA/CMakeLists.txt @@ -1,5 +1,13 @@ add_subdirectory(MESSAGES) -add_executable(test_nrppa ${OPENAIR3_DIR}/NRPPA/test_nrppa.c ) -target_link_libraries(test_nrppa asn1_nrppa) - +add_library(nrppa + nrppa_gNB.c + nrppa_gNB_config.c + nrppa_gNB_handlers.c + nrppa_gNB_decoder.c + nrppa_gNB_ue_context.c + nrppa_gNB_location_information_transfer.c + ) + +target_link_libraries(nrppa PUBLIC asn1_nrppa) +target_link_libraries(nrppa PRIVATE asn1_lte_rrc_hdrs asn1_nr_rrc_hdrs) diff --git a/openair3/NRPPA/nrppa_common.h b/openair3/NRPPA/nrppa_common.h new file mode 100644 index 0000000000..b7c613e77a --- /dev/null +++ b/openair3/NRPPA/nrppa_common.h @@ -0,0 +1,62 @@ +/* + * 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 NRPPA_COMMON_H_ +#define NRPPA_COMMON_H_ + +#include "oai_asn1.h" +#include "common/utils/LOG/log.h" +#include "ds/byte_array.h" +#include "nrppa_includes.h" + +#define NRPPA_FIND_PROTOCOLIE_BY_ID(IE_TYPE, ie, container, IE_ID, mandatory) \ + do { \ + IE_TYPE **ptr; \ + ie = NULL; \ + for (ptr = container->protocolIEs.list.array; ptr < &container->protocolIEs.list.array[container->protocolIEs.list.count]; \ + ptr++) { \ + if ((*ptr)->id == IE_ID) { \ + ie = *ptr; \ + break; \ + } \ + } \ + if (ie == NULL) { \ + if (mandatory) { \ + AssertFatal(false, "NRPPA_FIND_PROTOCOLIE_BY_ID ie is NULL (searching for ie: %ld)\n", IE_ID); \ + } else { \ + LOG_I(NRPPA, "NRPPA_FIND_PROTOCOLIE_BY_ID ie is NULL (searching for ie: %ld)\n", IE_ID); \ + } \ + } \ + } while (0); \ + if (mandatory && !ie) \ + return -1 + +// gnb and ue related info in NRPPA message +typedef struct nrppa_gnb_ue_info_s { + instance_t instance; + int32_t gNB_ue_ngap_id; + int64_t amf_ue_ngap_id; + byte_array_t routing_id; +} nrppa_gnb_ue_info_t; + +typedef int (*nrppa_message_decoded_callback)(nrppa_gnb_ue_info_t *nrppa_msg_info, const NRPPA_NRPPA_PDU_t *pdu); + +#endif /* NRPPA_COMMON_H_ */ diff --git a/openair3/NRPPA/nrppa_gNB.c b/openair3/NRPPA/nrppa_gNB.c new file mode 100644 index 0000000000..d7f067de98 --- /dev/null +++ b/openair3/NRPPA/nrppa_gNB.c @@ -0,0 +1,79 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#include "tree.h" +#include "queue.h" + +#include "intertask_interface.h" + +#include "assertions.h" +#include "conversions.h" + +#include "nrppa_gNB.h" +#include "nrppa_common.h" +#include "nrppa_gNB_handlers.h" +#include "nrppa_gNB_location_information_transfer.h" + +void nrppa_gNB_init(void) +{ + LOG_I(NRPPA, "Starting NRPPA layer\n"); + itti_mark_task_ready(TASK_NRPPA); +} + +void *nrppa_gNB_process_itti_msg(void *notUsed) +{ + MessageDef *received_msg = NULL; + int result; + itti_receive_msg(TASK_NRPPA, &received_msg); + if (received_msg) { + instance_t instance = ITTI_MSG_DESTINATION_INSTANCE(received_msg); + LOG_I(NRPPA, "Received message %s\n", ITTI_MSG_NAME(received_msg)); + switch (ITTI_MSG_ID(received_msg)) { + case TERMINATE_MESSAGE: + LOG_W(NRPPA, " *** Exiting NRPPA thread\n"); + itti_exit_task(); + break; + case NGAP_DOWNLINKUEASSOCIATEDNRPPA: + nrppa_handle_downlink_ue_associated_nrppa_transport(instance, &NGAP_DOWNLINKUEASSOCIATEDNRPPA(received_msg)); + break; + case NGAP_DOWNLINKNONUEASSOCIATEDNRPPA: + nrppa_handle_downlink_non_ue_associated_nrppa_transport(instance, &NGAP_DOWNLINKNONUEASSOCIATEDNRPPA(received_msg)); + break; + default: + LOG_E(NRPPA, "Received unhandled message: %d:%s\n", ITTI_MSG_ID(received_msg), ITTI_MSG_NAME(received_msg)); + break; + } + result = itti_free(ITTI_MSG_ORIGIN_ID(received_msg), received_msg); + AssertFatal(result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result); + } + return NULL; +} + +void *nrppa_gNB_task(void *arg) +{ + nrppa_gNB_init(); + + while (1) { + (void)nrppa_gNB_process_itti_msg(NULL); + } + + return NULL; +} diff --git a/openair3/NRPPA/nrppa_gNB.h b/openair3/NRPPA/nrppa_gNB.h new file mode 100644 index 0000000000..628cfc4587 --- /dev/null +++ b/openair3/NRPPA/nrppa_gNB.h @@ -0,0 +1,32 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#include +#include + +#ifndef NRPPA_GNB_H_ +#define NRPPA_GNB_H_ + +void nrppa_gNB_init(void); +void *nrppa_gNB_process_itti_msg(void *notUsed); +void *nrppa_gNB_task(void *arg); + +#endif /* NRPPA_GNB_H_ */ diff --git a/openair3/NRPPA/nrppa_gNB_decoder.c b/openair3/NRPPA/nrppa_gNB_decoder.c new file mode 100644 index 0000000000..d197d0d141 --- /dev/null +++ b/openair3/NRPPA/nrppa_gNB_decoder.c @@ -0,0 +1,116 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#include "assertions.h" +#include "intertask_interface.h" +#include "nrppa_common.h" +#include "nrppa_gNB_decoder.h" + +static int nrppa_gNB_decode_initiating_message(NRPPA_NRPPA_PDU_t *pdu) +{ + asn_encode_to_new_buffer_result_t res = {NULL, {0, NULL, NULL}}; + DevAssert(pdu != NULL); + + switch (pdu->choice.initiatingMessage->procedureCode) { + case NRPPA_ProcedureCode_id_tRPInformationExchange: // TRPInformationRequest + res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_NRPPA_NRPPA_PDU, pdu); + LOG_I(NRPPA, "TRP Information Request initiating message\n"); + free(res.buffer); + break; + + default: + AssertFatal(false, "Unknown procedure ID (%d) for initiating message\n", (int)pdu->choice.initiatingMessage->procedureCode); + return -1; + } + return 0; +} + +static int nrppa_gNB_decode_successful_outcome(NRPPA_NRPPA_PDU_t *pdu) +{ + asn_encode_to_new_buffer_result_t res = {NULL, {0, NULL, NULL}}; + DevAssert(pdu != NULL); + + switch (pdu->choice.successfulOutcome->procedureCode) { + case NRPPA_ProcedureCode_id_tRPInformationExchange: + res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_NRPPA_NRPPA_PDU, pdu); + LOG_I(NRPPA, "TRP Information Response successfull outcome message\n"); + free(res.buffer); + break; + + default: + AssertFatal(false, + "Unknown procedure ID (%d) for successfull outcome message\n", + (int)pdu->choice.initiatingMessage->procedureCode); + return -1; + } + return 0; +} + +static int nrppa_gNB_decode_unsuccessful_outcome(NRPPA_NRPPA_PDU_t *pdu) +{ + asn_encode_to_new_buffer_result_t res = {NULL, {0, NULL, NULL}}; + DevAssert(pdu != NULL); + + switch (pdu->choice.unsuccessfulOutcome->procedureCode) { + case NRPPA_ProcedureCode_id_tRPInformationExchange: + res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_NRPPA_NRPPA_PDU, pdu); + LOG_I(NRPPA, "TRP Information Failure unsuccessfull outcome message\n"); + free(res.buffer); + break; + + default: + AssertFatal(false, + "Unknown procedure ID (%d) for unsuccessfull outcome message\n", + (int)pdu->choice.initiatingMessage->procedureCode); + return -1; + } + return 0; +} + +int nrppa_gNB_decode_pdu(NRPPA_NRPPA_PDU_t *pdu, const uint8_t *const buffer, const uint32_t length) +{ + asn_dec_rval_t dec_ret; + DevAssert(pdu != NULL); + DevAssert(buffer != NULL); + asn_codec_ctx_t st = {.max_stack_size = 100 * 1000}; // if we enable asn1c debug the stack size become large + dec_ret = aper_decode(&st, &asn_DEF_NRPPA_NRPPA_PDU, (void **)&pdu, buffer, length, 0, 0); + if (dec_ret.code != RC_OK) { + LOG_E(NRPPA, "Failed to decode pdu\n"); + return -1; + } + + switch (pdu->present) { + case NRPPA_NRPPA_PDU_PR_initiatingMessage: + return nrppa_gNB_decode_initiating_message(pdu); + + case NRPPA_NRPPA_PDU_PR_successfulOutcome: + return nrppa_gNB_decode_successful_outcome(pdu); + + case NRPPA_NRPPA_PDU_PR_unsuccessfulOutcome: + return nrppa_gNB_decode_unsuccessful_outcome(pdu); + + default: + LOG_I(NRPPA, "Unknown presence (%d) or not implemented\n", (int)pdu->present); + break; + } + + return -1; +} diff --git a/openair3/NRPPA/nrppa_gNB_decoder.h b/openair3/NRPPA/nrppa_gNB_decoder.h new file mode 100644 index 0000000000..668208b8a5 --- /dev/null +++ b/openair3/NRPPA/nrppa_gNB_decoder.h @@ -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 + */ + +#include "nrppa_common.h" + +#ifndef NRPPA_GNB_DECODER_H_ +#define NRPPA_GNB_DECODER_H_ + +int nrppa_gNB_decode_pdu(NRPPA_NRPPA_PDU_t *pdu, const uint8_t *const buffer, const uint32_t length) + __attribute__((warn_unused_result)); + +#endif /* NRPPA_GNB_DECODER_H_ */ diff --git a/openair3/NRPPA/nrppa_gNB_handlers.c b/openair3/NRPPA/nrppa_gNB_handlers.c new file mode 100644 index 0000000000..ce36e34d81 --- /dev/null +++ b/openair3/NRPPA/nrppa_gNB_handlers.c @@ -0,0 +1,179 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#include "intertask_interface.h" +#include "nrppa_gNB_handlers.h" +#include "nrppa_gNB_decoder.h" +#include "nrppa_common.h" +#include "nrppa_gNB_location_information_transfer.h" + +char *nrppa_direction2String(int nrppa_dir) +{ + static char *nrppa_direction_String[] = { + "", /* Nothing */ + "Originating message", /* originating message */ + "Successfull outcome", /* successfull outcome */ + "UnSuccessfull outcome", /* successfull outcome */ + }; + return (nrppa_direction_String[nrppa_dir]); +} + +/* Handlers matrix. Only gNB related procedure present here */ +nrppa_message_decoded_callback nrppa_messages_callback[][3] = { + {0, 0, 0}, // NRPPA_ProcedureCode_id_errorIndication ((NRPPA_ProcedureCode_t)0) + {0, 0, 0}, // NRPPA_ProcedureCode_id_privateMessage ((NRPPA_ProcedureCode_t)1) + {0, 0, 0}, // NRPPA_ProcedureCode_id_e_CIDMeasurementInitiation ((NRPPA_ProcedureCode_t)2) + {0, 0, 0}, // NRPPA_ProcedureCode_id_e_CIDMeasurementFailureIndication ((NRPPA_ProcedureCode_t)3) + {0, 0, 0}, // NRPPA_ProcedureCode_id_e_CIDMeasurementReport ((NRPPA_ProcedureCode_t)4) + {0, 0, 0}, // NRPPA_ProcedureCode_id_e_CIDMeasurementTermination ((NRPPA_ProcedureCode_t)5) + {0, 0, 0}, // NRPPA_ProcedureCode_id_oTDOAInformationExchange ((NRPPA_ProcedureCode_t)6) + {0, 0, 0}, // NRPPA_ProcedureCode_id_assistanceInformationControl ((NRPPA_ProcedureCode_t)7) + {0, 0, 0}, // NRPPA_ProcedureCode_id_assistanceInformationFeedback ((NRPPA_ProcedureCode_t)8) + {0, 0, 0}, // NRPPA_ProcedureCode_id_positioningInformationExchange ((NRPPA_ProcedureCode_t)9) + {0, 0, 0}, // NRPPA_ProcedureCode_id_positioningInformationUpdate ((NRPPA_ProcedureCode_t)10) + {0, 0, 0}, // NRPPA_ProcedureCode_id_Measurement ((NRPPA_ProcedureCode_t)11) + {0, 0, 0}, // NRPPA_ProcedureCode_id_MeasurementReport ((NRPPA_ProcedureCode_t)12) + {0, 0, 0}, // NRPPA_ProcedureCode_id_MeasurementUpdate ((NRPPA_ProcedureCode_t)13) + {0, 0, 0}, // NRPPA_ProcedureCode_id_MeasurementAbort ((NRPPA_ProcedureCode_t)14) + {0, 0, 0}, // NRPPA_ProcedureCode_id_MeasurementFailureIndication ((NRPPA_ProcedureCode_t)15) + {nrppa_gNB_handle_trp_information_request, 0, 0}, // NRPPA_ProcedureCode_id_tRPInformationExchange ((NRPPA_ProcedureCode_t)16) + {0, 0, 0}, // NRPPA_ProcedureCode_id_positioningActivation ((NRPPA_ProcedureCode_t)17) + {0, 0, 0}, // NRPPA_ProcedureCode_id_positioningDeactivation ((NRPPA_ProcedureCode_t)18) +}; + +// Processing DOWNLINK UE ASSOCIATED NRPPA TRANSPORT (9.2.9.1 of TS 38.413 Version 16.0.0) +int nrppa_handle_downlink_ue_associated_nrppa_transport(instance_t instance, const ngap_downlink_ue_associated_nrppa_t *msg) +{ + LOG_I(NRPPA, "Handling DOWNLINKUEASSOCIATEDNRPPA TRANSPORT\n"); + uint8_t *const data = msg->nrppa_pdu.buf; + const uint32_t data_length = msg->nrppa_pdu.len; + NRPPA_NRPPA_PDU_t pdu; + int ret; + DevAssert(data != NULL); + memset(&pdu, 0, sizeof(pdu)); + + if (nrppa_gNB_decode_pdu(&pdu, data, data_length) < 0) { + LOG_E(NRPPA, "Failed to decode PDU\n"); + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NRPPA_NRPPA_PDU, &pdu); + return -1; + } + /* Checking procedure Code and direction of message*/ + if (pdu.choice.initiatingMessage->procedureCode >= sizeof(nrppa_messages_callback) / (3 * sizeof(nrppa_message_decoded_callback)) + || (pdu.present > NRPPA_NRPPA_PDU_PR_unsuccessfulOutcome)) { + LOG_E(NRPPA, + "Either procedureCode %ld or direction %d exceed expected\n", + pdu.choice.initiatingMessage->procedureCode, + pdu.present); + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NRPPA_NRPPA_PDU, &pdu); + return -1; + } + + /* No handler present. + * This can mean not implemented or no procedure for gNB (wrong direction).*/ + if (nrppa_messages_callback[pdu.choice.initiatingMessage->procedureCode][pdu.present - 1] == NULL) { + LOG_E(NRPPA, + "No handler for procedureCode %ld in %s\n", + pdu.choice.initiatingMessage->procedureCode, + nrppa_direction2String(pdu.present - 1)); + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NRPPA_NRPPA_PDU, &pdu); + return -1; + } + + /* Calling the right handler*/ + nrppa_gnb_ue_info_t nrppa_msg_info; + nrppa_msg_info.instance = instance; + nrppa_msg_info.gNB_ue_ngap_id = msg->gNB_ue_ngap_id; + nrppa_msg_info.amf_ue_ngap_id = msg->amf_ue_ngap_id; + nrppa_msg_info.routing_id.buf = msg->routing_id.buf; + nrppa_msg_info.routing_id.len = msg->routing_id.len; + ret = (*nrppa_messages_callback[pdu.choice.initiatingMessage->procedureCode][pdu.present - 1])(&nrppa_msg_info, &pdu); + + if (msg->routing_id.buf) { + free(msg->routing_id.buf); + } + + if (msg->nrppa_pdu.buf) { + free(msg->nrppa_pdu.buf); + } + + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NRPPA_NRPPA_PDU, &pdu); + return ret; +} + +// Processing DOWNLINK NON UE ASSOCIATED NRPPA TRANSPORT (9.2.9.3 of TS 38.413 Version 16.0.0) +int nrppa_handle_downlink_non_ue_associated_nrppa_transport(instance_t instance, const ngap_downlink_non_ue_associated_nrppa_t *msg) +{ + LOG_I(NRPPA, "Handling DOWNLINKNONUEASSOCIATEDNRPPA TRANSPORT\n"); + uint8_t *const data = msg->nrppa_pdu.buf; + const uint32_t data_length = msg->nrppa_pdu.len; + NRPPA_NRPPA_PDU_t pdu; + int ret; + DevAssert(data != NULL); + memset(&pdu, 0, sizeof(pdu)); + + if (nrppa_gNB_decode_pdu(&pdu, data, data_length) < 0) { + LOG_E(NRPPA, "Failed to decode Downlink Non UE Associated NRPPa PDU\n"); + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NRPPA_NRPPA_PDU, &pdu); + return -1; + } + + /* Checking procedure Code and direction of message*/ + if (pdu.choice.initiatingMessage->procedureCode >= sizeof(nrppa_messages_callback) / (3 * sizeof(nrppa_message_decoded_callback)) + || (pdu.present > NRPPA_NRPPA_PDU_PR_unsuccessfulOutcome)) { + LOG_E(NRPPA, + "Either procedureCode %ld or direction %d exceed expected\n", + pdu.choice.initiatingMessage->procedureCode, + pdu.present); + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NRPPA_NRPPA_PDU, &pdu); + return -1; + } + + /* No handler present. + * This can mean not implemented or no procedure for gNB (wrong direction).*/ + if (nrppa_messages_callback[pdu.choice.initiatingMessage->procedureCode][pdu.present - 1] == NULL) { + LOG_E(NRPPA, + "No handler for procedureCode %ld in %s\n", + pdu.choice.initiatingMessage->procedureCode, + nrppa_direction2String(pdu.present - 1)); + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NRPPA_NRPPA_PDU, &pdu); + return -1; + } + + /* Calling the right handler*/ + nrppa_gnb_ue_info_t nrppa_msg_info; + nrppa_msg_info.instance = instance; + nrppa_msg_info.gNB_ue_ngap_id = 0; // non-ue associated + nrppa_msg_info.amf_ue_ngap_id = 0; // non-ue associated + nrppa_msg_info.routing_id.buf = msg->routing_id.buf; + nrppa_msg_info.routing_id.len = msg->routing_id.len; + ret = (*nrppa_messages_callback[pdu.choice.initiatingMessage->procedureCode][pdu.present - 1])(&nrppa_msg_info, &pdu); + + if (msg->routing_id.buf) { + free(msg->routing_id.buf); + } + + if (msg->nrppa_pdu.buf) { + free(msg->nrppa_pdu.buf); + } + + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NRPPA_NRPPA_PDU, &pdu); + return ret; +} diff --git a/openair3/NRPPA/nrppa_gNB_handlers.h b/openair3/NRPPA/nrppa_gNB_handlers.h new file mode 100644 index 0000000000..ecee41caa1 --- /dev/null +++ b/openair3/NRPPA/nrppa_gNB_handlers.h @@ -0,0 +1,28 @@ +/* + * 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 NRPPA_GNB_HANDLERS_H_ +#define NRPPA_GNB_HANDLERS_H_ + +int nrppa_handle_downlink_ue_associated_nrppa_transport(instance_t instance, const ngap_downlink_ue_associated_nrppa_t *msg); +int nrppa_handle_downlink_non_ue_associated_nrppa_transport(instance_t instance, + const ngap_downlink_non_ue_associated_nrppa_t *msg); +#endif /* NRPPA_GNB_HANDLERS_H_ */ diff --git a/openair3/NRPPA/nrppa_gNB_location_information_transfer.c b/openair3/NRPPA/nrppa_gNB_location_information_transfer.c new file mode 100644 index 0000000000..6a617ea02b --- /dev/null +++ b/openair3/NRPPA/nrppa_gNB_location_information_transfer.c @@ -0,0 +1,95 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#include "intertask_interface.h" +#include "nrppa_common.h" +#include "nrppa_gNB_location_information_transfer.h" +#include "nrppa_gNB_ue_context.h" +#include "nrppa_messages_types.h" + +void free_trp_information_request(nrppa_trp_information_req_t *msg) +{ + if (msg->trp_information_type_list.trp_information_type_item) { + free(msg->trp_information_type_list.trp_information_type_item); + } +} + +int nrppa_gNB_handle_trp_information_request(nrppa_gnb_ue_info_t *nrppa_msg_info, const NRPPA_NRPPA_PDU_t *pdu) +{ + LOG_I(NRPPA, "Processing Received TRP Information Request \n"); + DevAssert(pdu != NULL); + DevAssert(nrppa_msg_info != NULL); + + if (LOG_DEBUGFLAG(DEBUG_ASN1)) { + xer_fprint(stdout, &asn_DEF_NRPPA_NRPPA_PDU, pdu); + } + + // Forward request to RRC + MessageDef *msg = itti_alloc_new_message(TASK_RRC_GNB, 0, NRPPA_TRP_INFORMATION_REQ); + nrppa_trp_information_req_t *req = &NRPPA_TRP_INFORMATION_REQ(msg); + + // Processing Received TRPInformationRequest + NRPPA_TRPInformationRequest_t *container = NULL; + NRPPA_TRPInformationRequest_IEs_t *ie = NULL; + + // IE 9.2.3 Message type : mandatory + container = &pdu->choice.initiatingMessage->value.choice.TRPInformationRequest; + + // IE 9.2.4 nrppatransactionID : mandatory + req->transaction_id = pdu->choice.initiatingMessage->nrppatransactionID; + + // IE TRP List : optional + NRPPA_FIND_PROTOCOLIE_BY_ID(NRPPA_TRPInformationRequest_IEs_t, ie, container, NRPPA_ProtocolIE_ID_id_TRPList, false); + + if (ie == NULL) { + req->has_trp_list = false; + } else { + LOG_W(NRPPA, "TRPInformationRequest IE TRP List : not handled\n"); + } + + // IE TRP Information Type List: mandatory + // not implemented in oai-lmf + NRPPA_FIND_PROTOCOLIE_BY_ID(NRPPA_TRPInformationRequest_IEs_t, + ie, + container, + NRPPA_ProtocolIE_ID_id_TRPInformationTypeList, + false); + + if (ie == NULL) { + LOG_W(NRPPA, "TRPInformationRequest IE TRP Information Type List is mandatory but not handled\n"); + } else { + uint8_t trp_info_list_len = ie->value.choice.TRPInformationTypeList.list.count; + AssertError(trp_info_list_len > 0, return false, "at least 1 TRP Information Type must be present"); + nrppa_trp_information_type_list_t *trp_info_list = &req->trp_information_type_list; + trp_info_list->trp_information_type_list_length = trp_info_list_len; + trp_info_list->trp_information_type_item = calloc_or_fail(trp_info_list_len, sizeof(*trp_info_list->trp_information_type_item)); + for (int i = 0; i < trp_info_list_len; i++) { + trp_info_list->trp_information_type_item[i] = *ie->value.choice.TRPInformationTypeList.list.array[i]; + } + } + + nrppa_store_ue_context(nrppa_msg_info, req->transaction_id); + + LOG_I(NRPPA, "Forwarding to RRC TRPInformationRequest transaction_id=%d\n", req->transaction_id); + itti_send_msg_to_task(TASK_RRC_GNB, 0, msg); + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NRPPA_NRPPA_PDU, &pdu); + return 0; +} diff --git a/openair3/NRPPA/nrppa_gNB_location_information_transfer.h b/openair3/NRPPA/nrppa_gNB_location_information_transfer.h new file mode 100644 index 0000000000..5295505b22 --- /dev/null +++ b/openair3/NRPPA/nrppa_gNB_location_information_transfer.h @@ -0,0 +1,28 @@ +/* + * 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 NRPPA_GNB_POSITIONING_PROCEDURES_H_ +#define NRPPA_GNB_POSITIONING_PROCEDURES_H_ + +int nrppa_gNB_handle_trp_information_request(nrppa_gnb_ue_info_t *nrppa_msg_info, const NRPPA_NRPPA_PDU_t *pdu); +void free_trp_information_request(nrppa_trp_information_req_t *msg); + +#endif /* NRPPA_GNB_POSITIONING_PROCEDURES_H_ */ diff --git a/openair3/NRPPA/nrppa_gNB_ue_context.c b/openair3/NRPPA/nrppa_gNB_ue_context.c new file mode 100644 index 0000000000..1a1a0e7c0e --- /dev/null +++ b/openair3/NRPPA/nrppa_gNB_ue_context.c @@ -0,0 +1,85 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#include "nrppa_gNB_ue_context.h" +#include "tree.h" +#include "T.h" +#include "common/utils/T/T.h" +#include "common/utils/utils.h" +#include "common/utils/LOG/log.h" + +static RB_HEAD(nrppa_ue_map, nrppa_gNB_ue_context_s) nrppa_ue_head = RB_INITIALIZER(&nrppa_ue_head); + +/* Generate the tree management functions prototypes */ +RB_PROTOTYPE(nrppa_ue_map, nrppa_gNB_ue_context_s, entries, nrppa_gNB_compare_transaction_id); + +static int nrppa_gNB_compare_transaction_id(struct nrppa_gNB_ue_context_s *p1, struct nrppa_gNB_ue_context_s *p2) +{ + if (p1->transaction_id > p2->transaction_id) { + return 1; + } + + if (p1->transaction_id < p2->transaction_id) { + return -1; + } + + return 0; +} + +/* Generate the tree management functions */ +RB_GENERATE(nrppa_ue_map, nrppa_gNB_ue_context_s, entries, nrppa_gNB_compare_transaction_id); + +void nrppa_store_ue_context(const nrppa_gnb_ue_info_t *info, const uint16_t transaction_id) +{ + LOG_I(NRPPA, "Create NRPPa UE context (gNB UE ID %u) for transaction ID : %u\n", info->gNB_ue_ngap_id, transaction_id); + nrppa_gNB_ue_context_t *ue_info_p = calloc_or_fail(1, sizeof(*ue_info_p)); + ue_info_p->transaction_id = transaction_id; + ue_info_p->gNB_ue_ngap_id = info->gNB_ue_ngap_id; + ue_info_p->amf_ue_ngap_id = info->amf_ue_ngap_id; + if (info->routing_id.len > 0 && info->routing_id.buf != NULL) { + ue_info_p->routing_id.len = info->routing_id.len; + ue_info_p->routing_id.buf = calloc_or_fail(1, info->routing_id.len); + memcpy(ue_info_p->routing_id.buf, info->routing_id.buf, info->routing_id.len); + } else { + ue_info_p->routing_id.len = 0; + ue_info_p->routing_id.buf = NULL; + } + if (RB_INSERT(nrppa_ue_map, &nrppa_ue_head, ue_info_p)) + LOG_E(NRPPA, "Bug in UE uniq number allocation %u, we try to add a existing UE\n", ue_info_p->gNB_ue_ngap_id); + return; +} + +struct nrppa_gNB_ue_context_s *nrppa_get_ue_context(uint16_t transaction_id) +{ + nrppa_gNB_ue_context_t temp = {.transaction_id = transaction_id}; + return RB_FIND(nrppa_ue_map, &nrppa_ue_head, &temp); +} + +struct nrppa_gNB_ue_context_s *nrppa_detach_ue_context(uint16_t transaction_id) +{ + struct nrppa_gNB_ue_context_s *tmp = nrppa_get_ue_context(transaction_id); + if (tmp == NULL) { + LOG_E(NRPPA, "Trying to free a NULL UE context, %u\n", transaction_id); + return NULL; + } + RB_REMOVE(nrppa_ue_map, &nrppa_ue_head, tmp); + return tmp; +} diff --git a/openair3/NRPPA/nrppa_gNB_ue_context.h b/openair3/NRPPA/nrppa_gNB_ue_context.h new file mode 100644 index 0000000000..1aaeabe359 --- /dev/null +++ b/openair3/NRPPA/nrppa_gNB_ue_context.h @@ -0,0 +1,43 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#include +#include "tree.h" +#include "ds/byte_array.h" +#include "nrppa_common.h" + +#ifndef NRPPA_GNB_UE_CONTEXT_H_ +#define NRPPA_GNB_UE_CONTEXT_H_ + +typedef struct nrppa_gNB_ue_context_s { + /* Tree related data */ + RB_ENTRY(nrppa_gNB_ue_context_s) entries; + uint16_t transaction_id; + uint32_t gNB_ue_ngap_id; + uint64_t amf_ue_ngap_id; + byte_array_t routing_id; +} nrppa_gNB_ue_context_t; + +void nrppa_store_ue_context(const nrppa_gnb_ue_info_t *info, const uint16_t transaction_id); +nrppa_gNB_ue_context_t *nrppa_get_ue_context(uint16_t transaction_id); +nrppa_gNB_ue_context_t *nrppa_detach_ue_context(uint16_t transaction_id); + +#endif /* NRPPA_GNB_UE_CONTEXT_H_ */ diff --git a/openair3/NRPPA/nrppa_includes.h b/openair3/NRPPA/nrppa_includes.h new file mode 100644 index 0000000000..8239033926 --- /dev/null +++ b/openair3/NRPPA/nrppa_includes.h @@ -0,0 +1,39 @@ +/* + * 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 NRPPA_INCLUDE_H_ +#define NRPPA_INCLUDE_H_ + +#include "NRPPA_NRPPA-PDU.h" +#include "NRPPA_InitiatingMessage.h" +#include "NRPPA_SuccessfulOutcome.h" +#include "NRPPA_UnsuccessfulOutcome.h" +#include "NRPPA_ProtocolIE-ID.h" +#include "NRPPA_ProtocolIE-Field.h" +#include "NRPPA_ProtocolIE-Container.h" +#include "NRPPA_ProtocolExtensionField.h" +#include "NRPPA_ProtocolIE-ContainerList.h" +#include "NRPPA_ProtocolExtensionContainer.h" +#include "NRPPA_ProtocolIE-Single-Container.h" +#include "NRPPA_asn_constant.h" +#include "NRPPA_TRPInformationRequest.h" + +#endif /* NRPPA_INCLUDE_H_ */ diff --git a/tests/nr-cu-nrppa/CMakeLists.txt b/tests/nr-cu-nrppa/CMakeLists.txt index 1db9b33e37..f24ff4b880 100644 --- a/tests/nr-cu-nrppa/CMakeLists.txt +++ b/tests/nr-cu-nrppa/CMakeLists.txt @@ -5,6 +5,6 @@ add_executable(nr-cu-nrppa-test nr-cu-nrppa.c target_link_libraries(nr-cu-nrppa-test PRIVATE CONFIG_LIB ITTI SCTP_CLIENT f1ap ngap SECURITY - UTIL softmodem_common) + UTIL softmodem_common nrppa) target_link_libraries(nr-cu-nrppa-test PRIVATE asn1_lte_rrc_hdrs asn1_nr_rrc_hdrs) add_dependencies(nr-cu-nrppa-test params_libconfig) diff --git a/tests/nr-cu-nrppa/nr-cu-nrppa.c b/tests/nr-cu-nrppa/nr-cu-nrppa.c index 2c29ce6258..893ee63e8c 100644 --- a/tests/nr-cu-nrppa/nr-cu-nrppa.c +++ b/tests/nr-cu-nrppa/nr-cu-nrppa.c @@ -28,6 +28,7 @@ #include "openair2/GNB_APP/gnb_paramdef.h" #include "openair3/SCTP/sctp_default_values.h" #include "openair3/NRPPA/nrppa_gNB_config.h" +#include "openair3/NRPPA/nrppa_gNB.h" RAN_CONTEXT_t RC; THREAD_STRUCT thread_struct; @@ -83,6 +84,9 @@ int main(int argc, char **argv) rc = itti_create_task(TASK_NGAP, ngap_gNB_task, NULL); AssertFatal(rc >= 0, "Create task for NGAP failed\n"); + rc = itti_create_task(TASK_NRPPA, nrppa_gNB_task, NULL); + AssertFatal(rc >= 0, "Create task for NRPPA failed\n"); + MessageDef *msg_p; msg_p = itti_alloc_new_message(TASK_GNB_APP, 0, NGAP_REGISTER_GNB_REQ); RCconfig_NR_NG(msg_p, 0); From 0282e64a3bc659faa3ca556a6161e88c2703f473 Mon Sep 17 00:00:00 2001 From: Rakesh Mundlamuri Date: Thu, 22 Jan 2026 18:51:27 +0530 Subject: [PATCH 23/44] Add TRP Information Response NRPPA message encoding procedures Supported TRP Information Response Types: - PCI NR - NG RAN CGI - NR ARFCN - GEOGRAPHICAL COORDINATES --- openair2/COMMON/nrppa_messages_def.h | 1 + openair2/COMMON/nrppa_messages_types.h | 181 ++++++++++ openair3/NRPPA/CMakeLists.txt | 1 + openair3/NRPPA/nrppa_gNB.c | 3 + openair3/NRPPA/nrppa_gNB_encoder.c | 135 ++++++++ openair3/NRPPA/nrppa_gNB_encoder.h | 27 ++ .../nrppa_gNB_location_information_transfer.c | 322 ++++++++++++++++++ .../nrppa_gNB_location_information_transfer.h | 4 + openair3/NRPPA/nrppa_gNB_ue_context.c | 11 + openair3/NRPPA/nrppa_gNB_ue_context.h | 1 + openair3/NRPPA/nrppa_includes.h | 7 + tests/nr-cu-nrppa/nr-cu-nrppa.c | 108 ++++++ 12 files changed, 801 insertions(+) create mode 100644 openair3/NRPPA/nrppa_gNB_encoder.c create mode 100644 openair3/NRPPA/nrppa_gNB_encoder.h diff --git a/openair2/COMMON/nrppa_messages_def.h b/openair2/COMMON/nrppa_messages_def.h index ae17d73742..ecca67ba33 100644 --- a/openair2/COMMON/nrppa_messages_def.h +++ b/openair2/COMMON/nrppa_messages_def.h @@ -23,3 +23,4 @@ // LMF -> CU MESSAGE_DEF(NRPPA_TRP_INFORMATION_REQ, MESSAGE_PRIORITY_MED, nrppa_trp_information_req_t, nrppa_trp_information_req) +MESSAGE_DEF(NRPPA_TRP_INFORMATION_RESP, MESSAGE_PRIORITY_MED, nrppa_trp_information_resp_t, nrppa_trp_information_resp) diff --git a/openair2/COMMON/nrppa_messages_types.h b/openair2/COMMON/nrppa_messages_types.h index 55563a59ab..f461909a35 100644 --- a/openair2/COMMON/nrppa_messages_types.h +++ b/openair2/COMMON/nrppa_messages_types.h @@ -25,6 +25,7 @@ // Defines to access message fields. #define NRPPA_TRP_INFORMATION_REQ(mSGpTR) (mSGpTR)->ittiMsg.nrppa_trp_information_req +#define NRPPA_TRP_INFORMATION_RESP(mSGpTR) (mSGpTR)->ittiMsg.nrppa_trp_information_resp /* Structure of Positioning related NRPPA messages */ /* IE structures for Positioning related messages as per TS 38.455 V16.7.1*/ @@ -54,6 +55,179 @@ typedef struct nrppa_trp_list_s { uint32_t trp_list_length; } nrppa_trp_list_t; +typedef struct nrppa_access_point_position_s { + long latitude_sign; + long latitude; + long longitude; + long direction_of_altitude; + long altitude; + long uncertainty_semi_major; + long uncertainty_semi_minor; + long orientation_of_major_axis; + long uncertainty_altitude; + long confidence; +} nrppa_access_point_position_t; + +typedef struct nrppa_ngran_high_accuracy_access_point_position_s { + long latitude; + long longitude; + long altitude; + long uncertainty_semi_major; + long uncertainty_semi_minor; + long orientation_of_major_axis; + long horizontal_confidence; + long uncertainty_altitude; + long vertical_confidence; +} nrppa_ngran_high_accuracy_access_point_position_t; + +typedef union nrppa_trp_position_direct_accuracy_c { + nrppa_access_point_position_t trp_position; + nrppa_ngran_high_accuracy_access_point_position_t trp_HAposition; +} nrppa_trp_position_direct_accuracy_u; + +typedef enum nrppa_trp_position_direct_accuracy_e { + NRPPA_TRP_POSITION_DIRECT_ACCURACY_PR_NOTHING, + NRPPA_TRP_POSITION_DIRECT_ACCURACY_PR_TRPPOSITION, + NRPPA_TRP_POSITION_DIRECT_ACCURACY_PR_TRPHAPOSITION +} nrppa_trp_position_direct_accuracy_pr; + +typedef struct nrppa_trp_position_direct_accuracy_s { + nrppa_trp_position_direct_accuracy_pr present; + nrppa_trp_position_direct_accuracy_u choice; +} nrppa_trp_position_direct_accuracy_t; + +typedef struct nrppa_trp_position_direct_s { + nrppa_trp_position_direct_accuracy_t accuracy; +} nrppa_trp_position_direct_t; + +typedef enum nrppa_reference_point_e { + NRPPA_REFERENCE_POINT_PR_NOTHING, + NRPPA_REFERENCE_POINT_PR_COORDINATEID, + NRPPA_REFERENCE_POINT_PR_REFERENCEPOINTCOORDINATE, + NRPPA_REFERENCE_POINT_PR_REFERENCEPOINTCOORDINATEHA +} nrppa_reference_point_pr; + +typedef union nrppa_reference_point_c { + long coordinate_id; + nrppa_access_point_position_t reference_point_coordinate; + nrppa_ngran_high_accuracy_access_point_position_t reference_point_coordinateHA; +} nrppa_reference_point_u; + +typedef struct nrppa_reference_point_s { + nrppa_reference_point_pr present; + nrppa_reference_point_u choice; +} nrppa_reference_point_t; + +typedef struct nrppa_location_uncertainty_s { + long horizontal_uncertainty; + long horizontal_confidence; + long vertical_uncertainty; + long vertical_confidence; +} nrppa_location_uncertainty_t; + +typedef struct nrppa_relative_geodetic_location_s { + long milli_arc_second_units; + long height_units; + long delta_latitude; + long delta_longitude; + long delta_height; + nrppa_location_uncertainty_t location_uncertainty; +} nrppa_relative_geodetic_location_t; + +typedef struct nrppa_relative_cartesian_location_s { + long xyz_unit; + long xvalue; + long yvalue; + long zvalue; + nrppa_location_uncertainty_t location_uncertainty; +} nrppa_relative_cartesian_location_t; + +typedef union nrppa_trp_reference_point_type_c { + nrppa_relative_geodetic_location_t trp_position_relative_geodetic; + nrppa_relative_cartesian_location_t trp_position_relative_cartesian; +} nrppa_trp_reference_point_type_u; + +typedef enum nrppa_trp_reference_point_type_e { + NRPPA_TRP_REFERENCE_POINT_TYPE_PR_NOTHING, + NRPPA_TRP_REFERENCE_POINT_TYPE_PR_TRPPOSITION_RELATIVE_GEODETIC, + NRPPA_TRP_REFERENCE_POINT_TYPE_PR_TRPPOSITION_RELATIVE_CARTESIAN +} nrppa_trp_reference_point_type_pr; + +typedef struct nrppa_trp_reference_point_type_t { + nrppa_trp_reference_point_type_pr present; + nrppa_trp_reference_point_type_u choice; +} nrppa_trp_reference_point_type_t; + +typedef struct nrppa_trp_position_referenced_t { + nrppa_reference_point_t reference_point; + nrppa_trp_reference_point_type_t reference_point_type; +} nrppa_trp_position_referenced_t; + +typedef union nrppa_trp_position_definition_type_c { + nrppa_trp_position_direct_t direct; + nrppa_trp_position_referenced_t referenced; +} nrppa_trp_position_definition_type_u; + +typedef enum nrppa_trp_position_definition_type_e { + NRPPA_TRP_POSITION_DEFINITION_TYPE_PR_NOTHING, + NRPPA_TRP_POSITION_DEFINITION_TYPE_PR_DIRECT, + NRPPA_TRP_POSITION_DEFINITION_TYPE_PR_REFERENCED +} nrppa_trp_position_definition_type_pr; + +typedef struct nrppa_trp_position_definition_type_s { + nrppa_trp_position_definition_type_u choice; + nrppa_trp_position_definition_type_pr present; +} nrppa_trp_position_definition_type_t; + +typedef struct nrppa_geographical_coordinates_s { + nrppa_trp_position_definition_type_t trp_position_definition_type; +} nrppa_geographical_coordinates_t; + +typedef struct nrppa_ng_ran_cgi_s { + plmn_id_t plmn; + uint64_t nr_cellid; +} nrppa_ng_ran_cgi_t; + +typedef union nrppa_trp_information_type_response_item_c { + uint16_t pci_nr; + nrppa_ng_ran_cgi_t ng_ran_cgi; + uint32_t nr_arfcn; + nrppa_geographical_coordinates_t geographical_coordinates; +} nrppa_trp_information_type_response_item_u; + +typedef enum nrppa_trp_information_type_response_item_e { + NRPPA_TRP_INFORMATION_TYPE_RESPONSE_ITEM_PR_NOTHING, + NRPPA_TRP_INFORMATION_TYPE_RESPONSE_ITEM_PR_PCI_NR, + NRPPA_TRP_INFORMATION_TYPE_RESPONSE_ITEM_PR_NG_RAN_CGI, + NRPPA_TRP_INFORMATION_TYPE_RESPONSE_ITEM_PR_NRARFCN, + NRPPA_TRP_INFORMATION_TYPE_RESPONSE_ITEM_PR_PRSCONFIGURATION, + NRPPA_TRP_INFORMATION_TYPE_RESPONSE_ITEM_PR_SSBINFORMATION, + NRPPA_TRP_INFORMATION_TYPE_RESPONSE_ITEM_PR_SFNINITIALISATIONTIME, + NRPPA_TRP_INFORMATION_TYPE_RESPONSE_ITEM_PR_SPATIALDIRECTIONINFORMATION, + NRPPA_TRP_INFORMATION_TYPE_RESPONSE_ITEM_PR_GEOGRAPHICALCOORDINATES +} nrppa_trp_information_type_response_item_pr; + +typedef struct nrppa_trp_information_type_response_item_s { + nrppa_trp_information_type_response_item_pr present; + nrppa_trp_information_type_response_item_u choice; +} nrppa_trp_information_type_response_item_t; + +typedef struct nrppa_trp_information_type_response_list_s { + nrppa_trp_information_type_response_item_t *trp_information_type_response_item; + uint8_t trp_information_type_response_item_length; +} nrppa_trp_information_type_response_list_t; + +typedef struct nrppa_trp_information_s { + uint32_t trp_id; + nrppa_trp_information_type_response_list_t trp_information_type_response_list; +} nrppa_trp_information_t; + +// IE 9.3.1.176 (TS 38.473 V16.21.0) +typedef struct nrppa_trp_information_list_s { + nrppa_trp_information_t *trp_information_item; + uint32_t trp_information_item_length; +} nrppa_trp_information_list_t; + typedef struct nrppa_trp_information_req_s { // IE 9.2.4 (mandatory) uint16_t transaction_id; @@ -64,4 +238,11 @@ typedef struct nrppa_trp_information_req_s { nrppa_trp_information_type_list_t trp_information_type_list; } nrppa_trp_information_req_t; +typedef struct nrppa_trp_information_resp_s { + // IE 9.2.4 (mandatory) + uint16_t transaction_id; + // mandatory + nrppa_trp_information_list_t trp_information_list; +} nrppa_trp_information_resp_t; + #endif // NRPPA_MESSAGES_TYPES_H_ diff --git a/openair3/NRPPA/CMakeLists.txt b/openair3/NRPPA/CMakeLists.txt index 28ad4c8618..7ec77db3b5 100644 --- a/openair3/NRPPA/CMakeLists.txt +++ b/openair3/NRPPA/CMakeLists.txt @@ -7,6 +7,7 @@ add_library(nrppa nrppa_gNB_decoder.c nrppa_gNB_ue_context.c nrppa_gNB_location_information_transfer.c + nrppa_gNB_encoder.c ) target_link_libraries(nrppa PUBLIC asn1_nrppa) diff --git a/openair3/NRPPA/nrppa_gNB.c b/openair3/NRPPA/nrppa_gNB.c index d7f067de98..bb00cecd54 100644 --- a/openair3/NRPPA/nrppa_gNB.c +++ b/openair3/NRPPA/nrppa_gNB.c @@ -57,6 +57,9 @@ void *nrppa_gNB_process_itti_msg(void *notUsed) case NGAP_DOWNLINKNONUEASSOCIATEDNRPPA: nrppa_handle_downlink_non_ue_associated_nrppa_transport(instance, &NGAP_DOWNLINKNONUEASSOCIATEDNRPPA(received_msg)); break; + case NRPPA_TRP_INFORMATION_RESP: + nrppa_gNB_trp_information_response(instance, received_msg); + break; default: LOG_E(NRPPA, "Received unhandled message: %d:%s\n", ITTI_MSG_ID(received_msg), ITTI_MSG_NAME(received_msg)); break; diff --git a/openair3/NRPPA/nrppa_gNB_encoder.c b/openair3/NRPPA/nrppa_gNB_encoder.c new file mode 100644 index 0000000000..9ac0c4ecb0 --- /dev/null +++ b/openair3/NRPPA/nrppa_gNB_encoder.c @@ -0,0 +1,135 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#include +#include +#include +#include "nrppa_common.h" +#include "nrppa_gNB_encoder.h" + +static inline int nrppa_gNB_encode_initiating(NRPPA_NRPPA_PDU_t *pdu, uint8_t **buffer, uint32_t *len) +{ + DevAssert(pdu != NULL); + + const NRPPA_ProcedureCode_t tmp[] = {NRPPA_ProcedureCode_id_positioningInformationExchange, + NRPPA_ProcedureCode_id_positioningActivation, + NRPPA_ProcedureCode_id_positioningInformationUpdate, + NRPPA_ProcedureCode_id_positioningDeactivation, + NRPPA_ProcedureCode_id_tRPInformationExchange, + NRPPA_ProcedureCode_id_Measurement, + NRPPA_ProcedureCode_id_MeasurementReport, + NRPPA_ProcedureCode_id_MeasurementFailureIndication, + NRPPA_ProcedureCode_id_MeasurementAbort, + NRPPA_ProcedureCode_id_MeasurementUpdate}; + + int i; + for (i = 0; i < sizeofArray(tmp); i++) + if (pdu->choice.initiatingMessage->procedureCode == tmp[i]) + break; + if (i == sizeofArray(tmp)) { + LOG_E(NRPPA, "Unknown procedure ID (%d) for initiating message\n", (int)pdu->choice.initiatingMessage->procedureCode); + return -1; + } + + asn_encode_to_new_buffer_result_t res = asn_encode_to_new_buffer(NULL, ATS_ALIGNED_CANONICAL_PER, &asn_DEF_NRPPA_NRPPA_PDU, pdu); + AssertFatal(res.result.encoded > 0, "failed to encode NRPPA msg\n"); + *buffer = res.buffer; + *len = res.result.encoded; + return 0; +} + +static inline int nrppa_gNB_encode_successfull_outcome(NRPPA_NRPPA_PDU_t *pdu, uint8_t **buffer, uint32_t *len) +{ + DevAssert(pdu != NULL); + const NRPPA_ProcedureCode_t tmp[] = {NRPPA_ProcedureCode_id_positioningInformationExchange, + NRPPA_ProcedureCode_id_positioningActivation, + NRPPA_ProcedureCode_id_tRPInformationExchange, + NRPPA_ProcedureCode_id_Measurement}; + int i; + for (i = 0; i < sizeofArray(tmp); i++) + if (pdu->choice.successfulOutcome->procedureCode == tmp[i]) + break; + if (i == sizeofArray(tmp)) { + LOG_E(NRPPA, "Unknown procedure ID (%ld) for successfull outcome message\n", pdu->choice.successfulOutcome->procedureCode); + return -1; + } + // xer_fprint(stdout, &asn_DEF_NRPPA_NRPPA_PDU, pdu); + asn_encode_to_new_buffer_result_t res = asn_encode_to_new_buffer(NULL, ATS_ALIGNED_CANONICAL_PER, &asn_DEF_NRPPA_NRPPA_PDU, pdu); + AssertFatal(res.result.encoded > 0, "failed to encode NRPPA msg\n"); + *buffer = res.buffer; + *len = res.result.encoded; + return 0; +} + +static inline int nrppa_gNB_encode_unsuccessfull_outcome(NRPPA_NRPPA_PDU_t *pdu, uint8_t **buffer, uint32_t *len) +{ + DevAssert(pdu != NULL); + + const NRPPA_ProcedureCode_t tmp[] = {NRPPA_ProcedureCode_id_positioningInformationExchange, + NRPPA_ProcedureCode_id_positioningActivation, + NRPPA_ProcedureCode_id_tRPInformationExchange, + NRPPA_ProcedureCode_id_Measurement}; + + int i; + for (i = 0; i < sizeofArray(tmp); i++) + if (pdu->choice.unsuccessfulOutcome->procedureCode == tmp[i]) + break; + if (i == sizeofArray(tmp)) { + LOG_W(NRPPA, "Unknown procedure ID (%ld) for unsuccessfull outcome message\n", pdu->choice.unsuccessfulOutcome->procedureCode); + return -1; + } + + asn_encode_to_new_buffer_result_t res = asn_encode_to_new_buffer(NULL, ATS_ALIGNED_CANONICAL_PER, &asn_DEF_NRPPA_NRPPA_PDU, pdu); + AssertFatal(res.result.encoded > 0, "failed to encode NRPPA msg\n"); + *buffer = res.buffer; + *len = res.result.encoded; + return 0; +} + +int nrppa_gNB_encode_pdu(NRPPA_NRPPA_PDU_t *pdu, uint8_t **buffer, uint32_t *len) +{ + int ret = -1; + DevAssert(pdu != NULL); + DevAssert(buffer != NULL); + DevAssert(len != NULL); + + // xer_fprint(stdout, &asn_DEF_NRPPA_NRPPA_PDU, (void *)pdu); + + switch (pdu->present) { + case NRPPA_NRPPA_PDU_PR_initiatingMessage: + ret = nrppa_gNB_encode_initiating(pdu, buffer, len); + break; + + case NRPPA_NRPPA_PDU_PR_successfulOutcome: + ret = nrppa_gNB_encode_successfull_outcome(pdu, buffer, len); + break; + + case NRPPA_NRPPA_PDU_PR_unsuccessfulOutcome: + ret = nrppa_gNB_encode_unsuccessfull_outcome(pdu, buffer, len); + break; + + default: + LOG_E(NRPPA, "Unknown message outcome (%d) or not implemented", (int)pdu->present); + return -1; + } + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NRPPA_NRPPA_PDU, pdu); + return ret; +} diff --git a/openair3/NRPPA/nrppa_gNB_encoder.h b/openair3/NRPPA/nrppa_gNB_encoder.h new file mode 100644 index 0000000000..dee34a2060 --- /dev/null +++ b/openair3/NRPPA/nrppa_gNB_encoder.h @@ -0,0 +1,27 @@ +/* + * 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 NRPPA_GNB_ENCODER_H_ +#define NRPPA_GNB_ENCODER_H_ + +int nrppa_gNB_encode_pdu(NRPPA_NRPPA_PDU_t *pdu, uint8_t **buffer, uint32_t *len) __attribute__((warn_unused_result)); + +#endif /* NRPPA_GNB_ENCODER_H_ */ diff --git a/openair3/NRPPA/nrppa_gNB_location_information_transfer.c b/openair3/NRPPA/nrppa_gNB_location_information_transfer.c index 6a617ea02b..bc1af664cd 100644 --- a/openair3/NRPPA/nrppa_gNB_location_information_transfer.c +++ b/openair3/NRPPA/nrppa_gNB_location_information_transfer.c @@ -24,6 +24,8 @@ #include "nrppa_gNB_location_information_transfer.h" #include "nrppa_gNB_ue_context.h" #include "nrppa_messages_types.h" +#include "nrppa_gNB_encoder.h" +#include "openair3/UTILS/conversions.h" void free_trp_information_request(nrppa_trp_information_req_t *msg) { @@ -32,6 +34,235 @@ void free_trp_information_request(nrppa_trp_information_req_t *msg) } } +static NRPPA_TRPPositionDirect_t encode_trp_position_direct(nrppa_trp_position_direct_t *in) +{ + NRPPA_TRPPositionDirect_t out = {0}; + + switch (in->accuracy.present) { + case NRPPA_TRP_POSITION_DIRECT_ACCURACY_PR_NOTHING: + out.accuracy.present = NRPPA_TRPPositionDirectAccuracy_PR_NOTHING; + break; + case NRPPA_TRP_POSITION_DIRECT_ACCURACY_PR_TRPPOSITION: + out.accuracy.present = NRPPA_TRPPositionDirectAccuracy_PR_tRPPosition; + asn1cCalloc(out.accuracy.choice.tRPPosition, out_pos); + nrppa_access_point_position_t *in_pos = &in->accuracy.choice.trp_position; + + out_pos->latitudeSign = in_pos->latitude_sign; + out_pos->latitude = in_pos->latitude; + out_pos->longitude = in_pos->longitude; + out_pos->directionOfAltitude = in_pos->direction_of_altitude; + out_pos->altitude = in_pos->altitude; + out_pos->uncertaintySemi_major = in_pos->uncertainty_semi_major; + out_pos->uncertaintySemi_minor = in_pos->uncertainty_semi_minor; + out_pos->orientationOfMajorAxis = in_pos->orientation_of_major_axis; + out_pos->uncertaintyAltitude = in_pos->uncertainty_altitude; + out_pos->confidence = in_pos->confidence; + break; + case NRPPA_TRP_POSITION_DIRECT_ACCURACY_PR_TRPHAPOSITION: + out.accuracy.present = NRPPA_TRPPositionDirectAccuracy_PR_tRPHAposition; + asn1cCalloc(out.accuracy.choice.tRPHAposition, out_ha_pos); + nrppa_ngran_high_accuracy_access_point_position_t *in_ha_pos = &in->accuracy.choice.trp_HAposition; + out_ha_pos->latitude = in_ha_pos->latitude; + out_ha_pos->longitude = in_ha_pos->longitude; + out_ha_pos->altitude = in_ha_pos->altitude; + out_ha_pos->uncertaintySemi_major = in_ha_pos->uncertainty_semi_major; + out_ha_pos->uncertaintySemi_minor = in_ha_pos->uncertainty_semi_minor; + out_ha_pos->orientationOfMajorAxis = in_ha_pos->orientation_of_major_axis; + out_ha_pos->horizontalConfidence = in_ha_pos->horizontal_confidence; + out_ha_pos->uncertaintyAltitude = in_ha_pos->uncertainty_altitude; + out_ha_pos->verticalConfidence = in_ha_pos->vertical_confidence; + break; + default: + AssertFatal(false, "illegal direct accuracy entry\n"); + break; + } + return out; +} + +static NRPPA_TRPPositionReferenced_t encode_trp_position_referenced(nrppa_trp_position_referenced_t *in) +{ + NRPPA_TRPPositionReferenced_t out = {0}; + NRPPA_ReferencePoint_t *out_ref_point = &out.referencePoint; + nrppa_reference_point_t *in_ref_point = &in->reference_point; + switch (in_ref_point->present) { + case NRPPA_REFERENCE_POINT_PR_NOTHING: + out_ref_point->present = NRPPA_ReferencePoint_PR_NOTHING; + break; + case NRPPA_REFERENCE_POINT_PR_COORDINATEID: + out_ref_point->present = NRPPA_ReferencePoint_PR_relativeCoordinateID; + out_ref_point->choice.relativeCoordinateID = in_ref_point->choice.coordinate_id; + break; + case NRPPA_REFERENCE_POINT_PR_REFERENCEPOINTCOORDINATE: + out_ref_point->present = NRPPA_ReferencePoint_PR_referencePointCoordinate; + asn1cCalloc(out_ref_point->choice.referencePointCoordinate, out_ref_coord); + nrppa_access_point_position_t *in_ref_coord = &in_ref_point->choice.reference_point_coordinate; + out_ref_coord->latitudeSign = in_ref_coord->latitude_sign; + out_ref_coord->latitude = in_ref_coord->latitude; + out_ref_coord->longitude = in_ref_coord->longitude; + out_ref_coord->directionOfAltitude = in_ref_coord->direction_of_altitude; + out_ref_coord->altitude = in_ref_coord->altitude; + out_ref_coord->uncertaintySemi_major = in_ref_coord->uncertainty_semi_major; + out_ref_coord->uncertaintySemi_minor = in_ref_coord->uncertainty_semi_minor; + out_ref_coord->orientationOfMajorAxis = in_ref_coord->orientation_of_major_axis; + out_ref_coord->uncertaintyAltitude = in_ref_coord->uncertainty_altitude; + out_ref_coord->confidence = in_ref_coord->confidence; + break; + case NRPPA_REFERENCE_POINT_PR_REFERENCEPOINTCOORDINATEHA: + out_ref_point->present = NRPPA_ReferencePoint_PR_referencePointCoordinateHA; + asn1cCalloc(out_ref_point->choice.referencePointCoordinateHA, out_ref_coord_ha); + nrppa_ngran_high_accuracy_access_point_position_t *in_ref_coord_ha = &in_ref_point->choice.reference_point_coordinateHA; + out_ref_coord_ha->latitude = in_ref_coord_ha->latitude; + out_ref_coord_ha->longitude = in_ref_coord_ha->longitude; + out_ref_coord_ha->altitude = in_ref_coord_ha->altitude; + out_ref_coord_ha->uncertaintySemi_major = in_ref_coord_ha->uncertainty_semi_major; + out_ref_coord_ha->uncertaintySemi_minor = in_ref_coord_ha->uncertainty_semi_minor; + out_ref_coord_ha->orientationOfMajorAxis = in_ref_coord_ha->orientation_of_major_axis; + out_ref_coord_ha->horizontalConfidence = in_ref_coord_ha->horizontal_confidence; + out_ref_coord_ha->uncertaintyAltitude = in_ref_coord_ha->uncertainty_altitude; + out_ref_coord_ha->verticalConfidence = in_ref_coord_ha->vertical_confidence; + break; + default: + AssertFatal(false, "illegal reference point entry\n"); + break; + } + + NRPPA_TRPReferencePointType_t *out_ref_point_type = &out.referencePointType; + nrppa_trp_reference_point_type_t *in_ref_point_type = &in->reference_point_type; + switch (in_ref_point_type->present) { + case NRPPA_TRP_REFERENCE_POINT_TYPE_PR_NOTHING: + out_ref_point_type->present = NRPPA_TRPReferencePointType_PR_NOTHING; + break; + case NRPPA_TRP_REFERENCE_POINT_TYPE_PR_TRPPOSITION_RELATIVE_GEODETIC: + out_ref_point_type->present = NRPPA_TRPReferencePointType_PR_tRPPositionRelativeGeodetic; + asn1cCalloc(out_ref_point_type->choice.tRPPositionRelativeGeodetic, out_geodetic); + nrppa_relative_geodetic_location_t *in_geodetic = &in_ref_point_type->choice.trp_position_relative_geodetic; + out_geodetic->milli_Arc_SecondUnits = in_geodetic->milli_arc_second_units; + out_geodetic->heightUnits = in_geodetic->height_units; + out_geodetic->deltaLatitude = in_geodetic->delta_latitude; + out_geodetic->deltaLongitude = in_geodetic->delta_longitude; + out_geodetic->deltaHeight = in_geodetic->delta_height; + NRPPA_LocationUncertainty_t *out_loc_uncertainty_g = &out_geodetic->locationUncertainty; + nrppa_location_uncertainty_t *in_loc_uncertainty_g = &in_geodetic->location_uncertainty; + out_loc_uncertainty_g->horizontalUncertainty = in_loc_uncertainty_g->horizontal_uncertainty; + out_loc_uncertainty_g->horizontalConfidence = in_loc_uncertainty_g->horizontal_confidence; + out_loc_uncertainty_g->verticalUncertainty = in_loc_uncertainty_g->vertical_uncertainty; + out_loc_uncertainty_g->verticalConfidence = in_loc_uncertainty_g->vertical_confidence; + break; + case NRPPA_TRP_REFERENCE_POINT_TYPE_PR_TRPPOSITION_RELATIVE_CARTESIAN: + out_ref_point_type->present = NRPPA_TRPReferencePointType_PR_tRPPositionRelativeCartesian; + asn1cCalloc(out_ref_point_type->choice.tRPPositionRelativeCartesian, out_cartesian); + nrppa_relative_cartesian_location_t *in_cartesian = &in_ref_point_type->choice.trp_position_relative_cartesian; + + out_cartesian->xYZunit = in_cartesian->xyz_unit; + out_cartesian->xvalue = in_cartesian->xvalue; + out_cartesian->yvalue = in_cartesian->yvalue; + out_cartesian->zvalue = in_cartesian->zvalue; + NRPPA_LocationUncertainty_t *out_loc_uncertainty_c = &out_cartesian->locationUncertainty; + nrppa_location_uncertainty_t *in_loc_uncertainty_c = &in_cartesian->location_uncertainty; + out_loc_uncertainty_c->horizontalUncertainty = in_loc_uncertainty_c->horizontal_uncertainty; + out_loc_uncertainty_c->horizontalConfidence = in_loc_uncertainty_c->horizontal_confidence; + out_loc_uncertainty_c->verticalUncertainty = in_loc_uncertainty_c->vertical_uncertainty; + out_loc_uncertainty_c->verticalConfidence = in_loc_uncertainty_c->vertical_confidence; + break; + default: + AssertFatal(false, "illegal trp reference point type entry\n"); + break; + } + return out; +} + +static NRPPA_GeographicalCoordinates_t encode_geographical_coordinates_nrppa(nrppa_geographical_coordinates_t *in) +{ + NRPPA_GeographicalCoordinates_t out = {0}; + NRPPA_TRPPositionDefinitionType_t *out_type = &out.tRPPositionDefinitionType; + nrppa_trp_position_definition_type_t *in_type = &in->trp_position_definition_type; + switch (in_type->present) { + case NRPPA_TRP_POSITION_DEFINITION_TYPE_PR_NOTHING: + out_type->present = NRPPA_TRPPositionDefinitionType_PR_NOTHING; + break; + case NRPPA_TRP_POSITION_DEFINITION_TYPE_PR_DIRECT: + out_type->present = NRPPA_TRPPositionDefinitionType_PR_direct; + asn1cCalloc(out_type->choice.direct, direct); + *direct = encode_trp_position_direct(&in_type->choice.direct); + break; + case NRPPA_TRP_POSITION_DEFINITION_TYPE_PR_REFERENCED: + out_type->present = NRPPA_TRPPositionDefinitionType_PR_referenced; + asn1cCalloc(out_type->choice.referenced, referenced); + *referenced = encode_trp_position_referenced(&in_type->choice.referenced); + break; + default: + AssertFatal(false, "illegal Geographical Coordinates entry\n"); + break; + } + return out; +} + +NRPPA_TRPInformationItem_t encode_trp_info_type_response_item_nrppa(nrppa_trp_information_type_response_item_t *in) +{ + NRPPA_TRPInformationItem_t out = {0}; + switch (in->present) { + case NRPPA_TRP_INFORMATION_TYPE_RESPONSE_ITEM_PR_NOTHING: + out.present = NRPPA_TRPInformationItem_PR_NOTHING; + break; + case NRPPA_TRP_INFORMATION_TYPE_RESPONSE_ITEM_PR_PCI_NR: + out.present = NRPPA_TRPInformationItem_PR_pCI_NR; + out.choice.pCI_NR = in->choice.pci_nr; + break; + case NRPPA_TRP_INFORMATION_TYPE_RESPONSE_ITEM_PR_NG_RAN_CGI: + out.present = NRPPA_TRPInformationItem_PR_nG_RAN_CGI; + asn1cCalloc(out.choice.nG_RAN_CGI, nG_RAN_CGI); + MCC_MNC_TO_PLMNID(in->choice.ng_ran_cgi.plmn.mcc, + in->choice.ng_ran_cgi.plmn.mnc, + in->choice.ng_ran_cgi.plmn.mnc_digit_length, + &(nG_RAN_CGI->pLMN_Identity)); + nG_RAN_CGI->nG_RANcell.present = NRPPA_NG_RANCell_PR_nR_CellID; + NR_CELL_ID_TO_BIT_STRING(in->choice.ng_ran_cgi.nr_cellid, &(nG_RAN_CGI->nG_RANcell.choice.nR_CellID)); + break; + case NRPPA_TRP_INFORMATION_TYPE_RESPONSE_ITEM_PR_NRARFCN: + out.present = NRPPA_TRPInformationItem_PR_aRFCN; + out.choice.aRFCN = in->choice.nr_arfcn; + break; + case NRPPA_TRP_INFORMATION_TYPE_RESPONSE_ITEM_PR_PRSCONFIGURATION: + out.present = NRPPA_TRPInformationItem_PR_pRSConfiguration; + AssertFatal(false, "TRP information type response item PRS configuration unsupported\n"); + break; + case NRPPA_TRP_INFORMATION_TYPE_RESPONSE_ITEM_PR_SSBINFORMATION: + out.present = NRPPA_TRPInformationItem_PR_sSBinformation; + AssertFatal(false, "TRP information type response item SSB Information unsupported\n"); + break; + case NRPPA_TRP_INFORMATION_TYPE_RESPONSE_ITEM_PR_SFNINITIALISATIONTIME: + out.present = NRPPA_TRPInformationItem_PR_sFNInitialisationTime; + AssertFatal(false, "TRP information type response item SFN Initialization Time unsupported\n"); + break; + case NRPPA_TRP_INFORMATION_TYPE_RESPONSE_ITEM_PR_SPATIALDIRECTIONINFORMATION: + out.present = NRPPA_TRPInformationItem_PR_spatialDirectionInformation; + AssertFatal(false, "TRP information type response item Spatial Direction Information unsupported\n"); + break; + case NRPPA_TRP_INFORMATION_TYPE_RESPONSE_ITEM_PR_GEOGRAPHICALCOORDINATES: + out.present = NRPPA_TRPInformationItem_PR_geographicalCoordinates; + asn1cCalloc(out.choice.geographicalCoordinates, nrppa_geo_coord); + nrppa_geographical_coordinates_t *geo_coord = &in->choice.geographical_coordinates; + *nrppa_geo_coord = encode_geographical_coordinates_nrppa(geo_coord); + break; + default: + AssertFatal(false, "received illegal trp information type response item %d\n", in->present); + break; + } + return out; +} + +void free_trp_information_response(nrppa_trp_information_resp_t *msg) +{ + nrppa_trp_information_list_t *trp_information_list = &msg->trp_information_list; + uint32_t trp_info_item_length = trp_information_list->trp_information_item_length; + for (int i = 0; i < trp_info_item_length; i++) { + nrppa_trp_information_t *trp_information_item = &trp_information_list->trp_information_item[i]; + nrppa_trp_information_type_response_list_t *trp_info_type_resp_list = &trp_information_item->trp_information_type_response_list; + free(trp_info_type_resp_list->trp_information_type_response_item); + } + free(msg->trp_information_list.trp_information_item); +} + int nrppa_gNB_handle_trp_information_request(nrppa_gnb_ue_info_t *nrppa_msg_info, const NRPPA_NRPPA_PDU_t *pdu) { LOG_I(NRPPA, "Processing Received TRP Information Request \n"); @@ -93,3 +324,94 @@ int nrppa_gNB_handle_trp_information_request(nrppa_gnb_ue_info_t *nrppa_msg_info ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NRPPA_NRPPA_PDU, &pdu); return 0; } + +int nrppa_gNB_trp_information_response(instance_t instance, MessageDef *msg_p) +{ + DevAssert(msg_p); + nrppa_trp_information_resp_t *resp = &NRPPA_TRP_INFORMATION_RESP(msg_p); + nrppa_gNB_ue_context_t *ue_info = nrppa_detach_ue_context(resp->transaction_id); + + if (ue_info->gNB_ue_ngap_id != 0 && ue_info->amf_ue_ngap_id != 0) { + LOG_E(NRPPA, "Illegal gNB_ue_ngap_id %d and amf_ue_ngap_id %ld\n", ue_info->gNB_ue_ngap_id, ue_info->amf_ue_ngap_id); + free_trp_information_response(resp); + nrppa_free_ue_context(ue_info); + return -1; + } + + LOG_I(NRPPA, "Received TRP Information Response info from RRC with transaction_id = %u\n", ue_info->transaction_id); + + // Prepare NRPPA TRP Information transfer Response + NRPPA_NRPPA_PDU_t pdu = {0}; + + // IE: 9.2.3 Message Type : mandatory + pdu.present = NRPPA_NRPPA_PDU_PR_successfulOutcome; + asn1cCalloc(pdu.choice.successfulOutcome, head); + head->procedureCode = NRPPA_ProcedureCode_id_tRPInformationExchange; + head->criticality = NRPPA_Criticality_reject; + head->value.present = NRPPA_SuccessfulOutcome__value_PR_TRPInformationResponse; + + // IE 9.2.4 nrppatransactionID : mandatory + head->nrppatransactionID = resp->transaction_id; + NRPPA_TRPInformationResponse_t *out = &head->value.choice.TRPInformationResponse; + + // IE TRP Information List : mandatory + { + asn1cSequenceAdd(out->protocolIEs.list, NRPPA_TRPInformationResponse_IEs_t, ie); + ie->id = NRPPA_ProtocolIE_ID_id_TRPInformationList; + ie->criticality = NRPPA_Criticality_ignore; + ie->value.present = NRPPA_TRPInformationResponse_IEs__value_PR_TRPInformationList; + + uint32_t trp_info_item_len = resp->trp_information_list.trp_information_item_length; + for (int i = 0; i < trp_info_item_len; i++) { + // TRPInformationItem (M) + asn1cSequenceAdd(ie->value.choice.TRPInformationList.list, TRPInformationList__Member, trpinfolist_member); + nrppa_trp_information_t *nrppa_tRPInformation = &resp->trp_information_list.trp_information_item[i]; + + trpinfolist_member->tRP_ID = nrppa_tRPInformation->trp_id; + + NRPPA_TRPInformation_t *trp_info = &trpinfolist_member->tRPInformation; + + nrppa_trp_information_type_response_list_t *nrppa_tRPInformationTypeResponseList = + &nrppa_tRPInformation->trp_information_type_response_list; + uint8_t trp_info_type_resp_item_len = nrppa_tRPInformationTypeResponseList->trp_information_type_response_item_length; + + for (int j = 0; j < trp_info_type_resp_item_len; j++) { + asn1cSequenceAdd(trp_info->list, NRPPA_TRPInformationItem_t, trp_info_item); + nrppa_trp_information_type_response_item_t *resp_item = + &nrppa_tRPInformationTypeResponseList->trp_information_type_response_item[j]; + *trp_info_item = encode_trp_info_type_response_item_nrppa(resp_item); + } + } + } + + free_trp_information_response(resp); + + if (LOG_DEBUGFLAG(DEBUG_ASN1)) { + xer_fprint(stdout, &asn_DEF_NRPPA_NRPPA_PDU, &pdu); + } + + // Encode NRPPA message + uint8_t *buffer = NULL; + uint32_t length = 0; + if (nrppa_gNB_encode_pdu(&pdu, &buffer, &length) < 0) { + LOG_E(NRPPA, "Failed to encode Uplink NRPPa TRP Information Response\n"); + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NRPPA_NRPPA_PDU, &pdu); + return -1; + } + + MessageDef *msg = itti_alloc_new_message(TASK_NRPPA, 0, NGAP_UPLINKNONUEASSOCIATEDNRPPA); + ngap_uplink_non_ue_associated_nrppa_t *ULNRPPA = &NGAP_UPLINKNONUEASSOCIATEDNRPPA(msg); + + // Routing ID + ULNRPPA->routing_id = create_byte_array(ue_info->routing_id.len, ue_info->routing_id.buf); + + // NRPPa PDU + ULNRPPA->nrppa_pdu = create_byte_array(length, buffer); + + // Forward the NRPPA PDU to NGAP + itti_send_msg_to_task(TASK_NGAP, instance, msg); + nrppa_free_ue_context(ue_info); + free(buffer); + + return length; +} diff --git a/openair3/NRPPA/nrppa_gNB_location_information_transfer.h b/openair3/NRPPA/nrppa_gNB_location_information_transfer.h index 5295505b22..2f9ec72cd0 100644 --- a/openair3/NRPPA/nrppa_gNB_location_information_transfer.h +++ b/openair3/NRPPA/nrppa_gNB_location_information_transfer.h @@ -24,5 +24,9 @@ int nrppa_gNB_handle_trp_information_request(nrppa_gnb_ue_info_t *nrppa_msg_info, const NRPPA_NRPPA_PDU_t *pdu); void free_trp_information_request(nrppa_trp_information_req_t *msg); +int nrppa_gNB_trp_information_response(instance_t instance, MessageDef *msg_p); +void free_trp_information_request(nrppa_trp_information_req_t *msg); +NRPPA_TRPInformationItem_t encode_trp_info_type_response_item_nrppa(nrppa_trp_information_type_response_item_t *in); +void free_trp_information_response(nrppa_trp_information_resp_t *msg); #endif /* NRPPA_GNB_POSITIONING_PROCEDURES_H_ */ diff --git a/openair3/NRPPA/nrppa_gNB_ue_context.c b/openair3/NRPPA/nrppa_gNB_ue_context.c index 1a1a0e7c0e..b5da194205 100644 --- a/openair3/NRPPA/nrppa_gNB_ue_context.c +++ b/openair3/NRPPA/nrppa_gNB_ue_context.c @@ -83,3 +83,14 @@ struct nrppa_gNB_ue_context_s *nrppa_detach_ue_context(uint16_t transaction_id) RB_REMOVE(nrppa_ue_map, &nrppa_ue_head, tmp); return tmp; } + +void nrppa_free_ue_context(nrppa_gNB_ue_context_t *ue_info) +{ + if (!ue_info) + return; + + if (ue_info->routing_id.buf) { + free(ue_info->routing_id.buf); + } + free(ue_info); +} diff --git a/openair3/NRPPA/nrppa_gNB_ue_context.h b/openair3/NRPPA/nrppa_gNB_ue_context.h index 1aaeabe359..fc976c611d 100644 --- a/openair3/NRPPA/nrppa_gNB_ue_context.h +++ b/openair3/NRPPA/nrppa_gNB_ue_context.h @@ -39,5 +39,6 @@ typedef struct nrppa_gNB_ue_context_s { void nrppa_store_ue_context(const nrppa_gnb_ue_info_t *info, const uint16_t transaction_id); nrppa_gNB_ue_context_t *nrppa_get_ue_context(uint16_t transaction_id); nrppa_gNB_ue_context_t *nrppa_detach_ue_context(uint16_t transaction_id); +void nrppa_free_ue_context(nrppa_gNB_ue_context_t *ue_info); #endif /* NRPPA_GNB_UE_CONTEXT_H_ */ diff --git a/openair3/NRPPA/nrppa_includes.h b/openair3/NRPPA/nrppa_includes.h index 8239033926..63bb3fe248 100644 --- a/openair3/NRPPA/nrppa_includes.h +++ b/openair3/NRPPA/nrppa_includes.h @@ -35,5 +35,12 @@ #include "NRPPA_ProtocolIE-Single-Container.h" #include "NRPPA_asn_constant.h" #include "NRPPA_TRPInformationRequest.h" +#include "NRPPA_TRPInformationItem.h" +#include "NRPPA_TRPPositionDirect.h" +#include "NRPPA_NG-RANAccessPointPosition.h" +#include "NRPPA_NGRANHighAccuracyAccessPointPosition.h" +#include "NRPPA_TRPPositionReferenced.h" +#include "NRPPA_RelativeGeodeticLocation.h" +#include "NRPPA_RelativeCartesianLocation.h" #endif /* NRPPA_INCLUDE_H_ */ diff --git a/tests/nr-cu-nrppa/nr-cu-nrppa.c b/tests/nr-cu-nrppa/nr-cu-nrppa.c index 893ee63e8c..7d3d023f18 100644 --- a/tests/nr-cu-nrppa/nr-cu-nrppa.c +++ b/tests/nr-cu-nrppa/nr-cu-nrppa.c @@ -64,6 +64,111 @@ ngran_node_t get_node_type() configmodule_interface_t *uniqCfg = NULL; +static nrppa_trp_information_resp_t fill_trp_resp(uint8_t transaction_id) +{ + positioning_config_t positioning_config = RCconfig_nr_positioning(); + dump_positioning_config(&positioning_config); + nrppa_trp_information_resp_t resp = {0}; + resp.transaction_id = transaction_id; + + nrppa_trp_information_list_t *list = &resp.trp_information_list; + uint32_t trp_info_item_len = positioning_config.num_trp; + list->trp_information_item_length = trp_info_item_len; + list->trp_information_item = calloc_or_fail(trp_info_item_len, sizeof(*list->trp_information_item)); + + uint8_t resp_item_len = 3; + for (int i = 0; i < trp_info_item_len; i++) { + nrppa_trp_information_t *tRPInformation = &list->trp_information_item[i]; + tRPInformation->trp_id = positioning_config.trps[i].id; + nrppa_trp_information_type_response_list_t *resp_list = &tRPInformation->trp_information_type_response_list; + resp_list->trp_information_type_response_item_length = resp_item_len; + nrppa_trp_information_type_response_item_t *resp_item = calloc_or_fail(resp_item_len, sizeof(*resp_item)); + resp_list->trp_information_type_response_item = resp_item; + + // nrPCI + resp_item[0].present = NRPPA_TRP_INFORMATION_TYPE_RESPONSE_ITEM_PR_PCI_NR; + resp_item[0].choice.pci_nr = 123 + i; + + // nG_RAN_CGI + resp_item[1].present = NRPPA_TRP_INFORMATION_TYPE_RESPONSE_ITEM_PR_NG_RAN_CGI; + resp_item[1].choice.ng_ran_cgi.plmn.mcc = 001; + resp_item[1].choice.ng_ran_cgi.plmn.mnc = 01; + resp_item[1].choice.ng_ran_cgi.plmn.mnc_digit_length = 2; + resp_item[1].choice.ng_ran_cgi.nr_cellid = gnb_id << 8; // HACK: Made to work with lmf + + // geographicalCoordinates + resp_item[2].present = NRPPA_TRP_INFORMATION_TYPE_RESPONSE_ITEM_PR_GEOGRAPHICALCOORDINATES; + nrppa_geographical_coordinates_t *geographicalCoordinates = &resp_item[2].choice.geographical_coordinates; + nrppa_trp_position_definition_type_t *tRPPositionDefinitionType = &geographicalCoordinates->trp_position_definition_type; + // referenced + tRPPositionDefinitionType->present = NRPPA_TRP_POSITION_DEFINITION_TYPE_PR_REFERENCED; + nrppa_trp_position_referenced_t *referenced = &tRPPositionDefinitionType->choice.referenced; + // coordinate ID + referenced->reference_point.present = NRPPA_REFERENCE_POINT_PR_COORDINATEID; + referenced->reference_point.choice.coordinate_id = 2; + nrppa_trp_reference_point_type_t *referencePointType = &referenced->reference_point_type; + // relative cartesian + referencePointType->present = NRPPA_TRP_REFERENCE_POINT_TYPE_PR_TRPPOSITION_RELATIVE_CARTESIAN; + nrppa_relative_cartesian_location_t *trp_pos_cart = &referencePointType->choice.trp_position_relative_cartesian; + // 0 = millimeter + trp_pos_cart->xyz_unit = positioning_config.trps[i].unit; + + // random reference cartesian coordinates in millimeter + trp_pos_cart->xvalue = positioning_config.trps[i].x_axis; + trp_pos_cart->yvalue = positioning_config.trps[i].y_axis; + trp_pos_cart->zvalue = positioning_config.trps[i].z_axis; + // testing random values for uncertainity and confidence + trp_pos_cart->location_uncertainty.horizontal_uncertainty = i + 1; + trp_pos_cart->location_uncertainty.horizontal_confidence = i + 2; + trp_pos_cart->location_uncertainty.vertical_uncertainty = i + 3; + trp_pos_cart->location_uncertainty.vertical_confidence = i + 4; + } + return resp; +} + +void *rrc_gnb_task(void *args_p) +{ + MessageDef *msg_p; + MessageDef *msg_p_resp; + instance_t instance; + int result; + + itti_mark_task_ready(TASK_RRC_GNB); + LOG_I(NR_RRC, "Entering main loop of NR_RRC message task\n"); + + while (1) { + // Wait for a message + itti_receive_msg(TASK_RRC_GNB, &msg_p); + const char *msg_name_p = ITTI_MSG_NAME(msg_p); + instance = ITTI_MSG_DESTINATION_INSTANCE(msg_p); + LOG_D(NR_RRC, + "RRC GNB Task Received %s for instance %ld from task %s\n", + ITTI_MSG_NAME(msg_p), + ITTI_MSG_DESTINATION_INSTANCE(msg_p), + ITTI_MSG_ORIGIN_NAME(msg_p)); + switch (ITTI_MSG_ID(msg_p)) { + case TERMINATE_MESSAGE: + LOG_W(NR_RRC, " *** Exiting NR_RRC thread\n"); + itti_exit_task(); + break; + case NRPPA_TRP_INFORMATION_REQ: + nrppa_trp_information_req_t *trp_req = &NRPPA_TRP_INFORMATION_REQ(msg_p); + LOG_I(NR_RRC, "Received NRPPA_TRP_INFORMATION_REQ transaction_id %d\n", trp_req->transaction_id); + msg_p_resp = itti_alloc_new_message(TASK_RRC_GNB, 0, NRPPA_TRP_INFORMATION_RESP); + NRPPA_TRP_INFORMATION_RESP(msg_p_resp) = fill_trp_resp(trp_req->transaction_id); + LOG_I(NR_RRC, "Sending NRPPA_TRP_INFORMATION_RESP to TASK_NRPPA\n"); + itti_send_msg_to_task(TASK_NRPPA, 0, msg_p_resp); + break; + default: + LOG_E(NR_RRC, "[gNB %ld] Received unexpected message %s\n", instance, msg_name_p); + break; + } + result = itti_free(ITTI_MSG_ORIGIN_ID(msg_p), msg_p); + AssertFatal(result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result); + msg_p = NULL; + } +} + int main(int argc, char **argv) { // load the config file @@ -87,6 +192,9 @@ int main(int argc, char **argv) rc = itti_create_task(TASK_NRPPA, nrppa_gNB_task, NULL); AssertFatal(rc >= 0, "Create task for NRPPA failed\n"); + rc = itti_create_task(TASK_RRC_GNB, rrc_gnb_task, NULL); + AssertFatal(rc >= 0, "Create task for RRC failed\n"); + MessageDef *msg_p; msg_p = itti_alloc_new_message(TASK_GNB_APP, 0, NGAP_REGISTER_GNB_REQ); RCconfig_NR_NG(msg_p, 0); From 1be578e89348c456cff9800d78cee6afe5fd8a85 Mon Sep 17 00:00:00 2001 From: Rakesh Mundlamuri Date: Thu, 22 Jan 2026 19:04:21 +0530 Subject: [PATCH 24/44] Add Positioning Information Request NRPPA message decoding procedures --- openair2/COMMON/nrppa_messages_def.h | 4 +++ openair2/COMMON/nrppa_messages_types.h | 6 +++++ openair3/NRPPA/nrppa_gNB_decoder.c | 5 ++++ openair3/NRPPA/nrppa_gNB_handlers.c | 4 ++- .../nrppa_gNB_location_information_transfer.c | 27 +++++++++++++++++++ .../nrppa_gNB_location_information_transfer.h | 1 + 6 files changed, 46 insertions(+), 1 deletion(-) diff --git a/openair2/COMMON/nrppa_messages_def.h b/openair2/COMMON/nrppa_messages_def.h index ecca67ba33..e3ddeb244f 100644 --- a/openair2/COMMON/nrppa_messages_def.h +++ b/openair2/COMMON/nrppa_messages_def.h @@ -24,3 +24,7 @@ // LMF -> CU MESSAGE_DEF(NRPPA_TRP_INFORMATION_REQ, MESSAGE_PRIORITY_MED, nrppa_trp_information_req_t, nrppa_trp_information_req) MESSAGE_DEF(NRPPA_TRP_INFORMATION_RESP, MESSAGE_PRIORITY_MED, nrppa_trp_information_resp_t, nrppa_trp_information_resp) +MESSAGE_DEF(NRPPA_POSITIONING_INFORMATION_REQ, + MESSAGE_PRIORITY_MED, + nrppa_positioning_information_req_t, + nrppa_positioning_information_req) diff --git a/openair2/COMMON/nrppa_messages_types.h b/openair2/COMMON/nrppa_messages_types.h index f461909a35..fef930ac9a 100644 --- a/openair2/COMMON/nrppa_messages_types.h +++ b/openair2/COMMON/nrppa_messages_types.h @@ -26,6 +26,7 @@ #define NRPPA_TRP_INFORMATION_REQ(mSGpTR) (mSGpTR)->ittiMsg.nrppa_trp_information_req #define NRPPA_TRP_INFORMATION_RESP(mSGpTR) (mSGpTR)->ittiMsg.nrppa_trp_information_resp +#define NRPPA_POSITIONING_INFORMATION_REQ(mSGpTR) (mSGpTR)->ittiMsg.nrppa_positioning_information_req /* Structure of Positioning related NRPPA messages */ /* IE structures for Positioning related messages as per TS 38.455 V16.7.1*/ @@ -245,4 +246,9 @@ typedef struct nrppa_trp_information_resp_s { nrppa_trp_information_list_t trp_information_list; } nrppa_trp_information_resp_t; +typedef struct nrppa_positioning_information_req_s { + // IE 9.2.4 (mandatory) + uint16_t transaction_id; +} nrppa_positioning_information_req_t; + #endif // NRPPA_MESSAGES_TYPES_H_ diff --git a/openair3/NRPPA/nrppa_gNB_decoder.c b/openair3/NRPPA/nrppa_gNB_decoder.c index d197d0d141..94524fd060 100644 --- a/openair3/NRPPA/nrppa_gNB_decoder.c +++ b/openair3/NRPPA/nrppa_gNB_decoder.c @@ -35,6 +35,11 @@ static int nrppa_gNB_decode_initiating_message(NRPPA_NRPPA_PDU_t *pdu) LOG_I(NRPPA, "TRP Information Request initiating message\n"); free(res.buffer); break; + case NRPPA_ProcedureCode_id_positioningInformationExchange: // PositioningInformationRequest + res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_NRPPA_NRPPA_PDU, pdu); + LOG_I(NRPPA, "Positioning Information Request initiating message\n"); + free(res.buffer); + break; default: AssertFatal(false, "Unknown procedure ID (%d) for initiating message\n", (int)pdu->choice.initiatingMessage->procedureCode); diff --git a/openair3/NRPPA/nrppa_gNB_handlers.c b/openair3/NRPPA/nrppa_gNB_handlers.c index ce36e34d81..99299ecb64 100644 --- a/openair3/NRPPA/nrppa_gNB_handlers.c +++ b/openair3/NRPPA/nrppa_gNB_handlers.c @@ -47,7 +47,9 @@ nrppa_message_decoded_callback nrppa_messages_callback[][3] = { {0, 0, 0}, // NRPPA_ProcedureCode_id_oTDOAInformationExchange ((NRPPA_ProcedureCode_t)6) {0, 0, 0}, // NRPPA_ProcedureCode_id_assistanceInformationControl ((NRPPA_ProcedureCode_t)7) {0, 0, 0}, // NRPPA_ProcedureCode_id_assistanceInformationFeedback ((NRPPA_ProcedureCode_t)8) - {0, 0, 0}, // NRPPA_ProcedureCode_id_positioningInformationExchange ((NRPPA_ProcedureCode_t)9) + {nrppa_gNB_handle_positioning_information_request, + 0, + 0}, // NRPPA_ProcedureCode_id_positioningInformationExchange ((NRPPA_ProcedureCode_t)9) {0, 0, 0}, // NRPPA_ProcedureCode_id_positioningInformationUpdate ((NRPPA_ProcedureCode_t)10) {0, 0, 0}, // NRPPA_ProcedureCode_id_Measurement ((NRPPA_ProcedureCode_t)11) {0, 0, 0}, // NRPPA_ProcedureCode_id_MeasurementReport ((NRPPA_ProcedureCode_t)12) diff --git a/openair3/NRPPA/nrppa_gNB_location_information_transfer.c b/openair3/NRPPA/nrppa_gNB_location_information_transfer.c index bc1af664cd..6821e251ed 100644 --- a/openair3/NRPPA/nrppa_gNB_location_information_transfer.c +++ b/openair3/NRPPA/nrppa_gNB_location_information_transfer.c @@ -415,3 +415,30 @@ int nrppa_gNB_trp_information_response(instance_t instance, MessageDef *msg_p) return length; } + +int nrppa_gNB_handle_positioning_information_request(nrppa_gnb_ue_info_t *nrppa_msg_info, const NRPPA_NRPPA_PDU_t *pdu) +{ + DevAssert(pdu != NULL); + DevAssert(nrppa_msg_info != NULL); + + if (LOG_DEBUGFLAG(DEBUG_ASN1)) { + xer_fprint(stdout, &asn_DEF_NRPPA_NRPPA_PDU, pdu); + } + + LOG_I(NRPPA, "Processing Received Positioning Information Request\n"); + + // Preparing positioning information request for RRC + MessageDef *msg = itti_alloc_new_message(TASK_RRC_GNB, 0, NRPPA_POSITIONING_INFORMATION_REQ); + nrppa_positioning_information_req_t *req = &NRPPA_POSITIONING_INFORMATION_REQ(msg); + + // IE 9.2.4 nrppatransactionID : mandatory + req->transaction_id = pdu->choice.initiatingMessage->nrppatransactionID; + + nrppa_store_ue_context(nrppa_msg_info, req->transaction_id); + + LOG_I(NRPPA, "Forwarding to RRC Positioning Information Request transaction id=%d\n", req->transaction_id); + + itti_send_msg_to_task(TASK_RRC_GNB, 0, msg); + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NRPPA_NRPPA_PDU, &pdu); + return 0; +} diff --git a/openair3/NRPPA/nrppa_gNB_location_information_transfer.h b/openair3/NRPPA/nrppa_gNB_location_information_transfer.h index 2f9ec72cd0..5fbd697c07 100644 --- a/openair3/NRPPA/nrppa_gNB_location_information_transfer.h +++ b/openair3/NRPPA/nrppa_gNB_location_information_transfer.h @@ -28,5 +28,6 @@ int nrppa_gNB_trp_information_response(instance_t instance, MessageDef *msg_p); void free_trp_information_request(nrppa_trp_information_req_t *msg); NRPPA_TRPInformationItem_t encode_trp_info_type_response_item_nrppa(nrppa_trp_information_type_response_item_t *in); void free_trp_information_response(nrppa_trp_information_resp_t *msg); +int nrppa_gNB_handle_positioning_information_request(nrppa_gnb_ue_info_t *nrppa_msg_info, const NRPPA_NRPPA_PDU_t *pdu); #endif /* NRPPA_GNB_POSITIONING_PROCEDURES_H_ */ From 3dcdedb3f8b3512356ee737049fa0a83d395d235 Mon Sep 17 00:00:00 2001 From: Rakesh Mundlamuri Date: Thu, 22 Jan 2026 20:28:12 +0530 Subject: [PATCH 25/44] Send dummy UE registration request to the AMF to register the UE. This is required for positioning as we initiate positioning procedure based on the imsi. --- tests/nr-cu-nrppa/CMakeLists.txt | 3 +- tests/nr-cu-nrppa/nr-cu-nrppa.c | 134 +++++++++++++++++++++++++++++++ 2 files changed, 136 insertions(+), 1 deletion(-) diff --git a/tests/nr-cu-nrppa/CMakeLists.txt b/tests/nr-cu-nrppa/CMakeLists.txt index f24ff4b880..b61b0dd920 100644 --- a/tests/nr-cu-nrppa/CMakeLists.txt +++ b/tests/nr-cu-nrppa/CMakeLists.txt @@ -1,7 +1,8 @@ add_executable(nr-cu-nrppa-test nr-cu-nrppa.c ${OPENAIR2_DIR}/GNB_APP/gnb_config_common.c ${OPENAIR2_DIR}/GNB_APP/gnb_config_ng.c) - + +target_link_libraries(nr-cu-nrppa-test PRIVATE nr_nas nr_common lib_uicc usim_lib) target_link_libraries(nr-cu-nrppa-test PRIVATE CONFIG_LIB ITTI SCTP_CLIENT f1ap ngap SECURITY diff --git a/tests/nr-cu-nrppa/nr-cu-nrppa.c b/tests/nr-cu-nrppa/nr-cu-nrppa.c index 7d3d023f18..aad8855797 100644 --- a/tests/nr-cu-nrppa/nr-cu-nrppa.c +++ b/tests/nr-cu-nrppa/nr-cu-nrppa.c @@ -29,6 +29,8 @@ #include "openair3/SCTP/sctp_default_values.h" #include "openair3/NRPPA/nrppa_gNB_config.h" #include "openair3/NRPPA/nrppa_gNB.h" +#include "openair3/NAS/NR_UE/nr_nas_msg.h" +#include "executables/nr-uesoftmodem.h" RAN_CONTEXT_t RC; THREAD_STRUCT thread_struct; @@ -36,6 +38,7 @@ uint64_t downlink_frequency[MAX_NUM_CCs][4]; int32_t uplink_frequency_offset[MAX_NUM_CCs][4]; int oai_exit = 0; int gnb_id; +int NB_UE_INST = 1; void exit_function(const char *file, const char *function, const int line, const char *s, const int assert) { @@ -62,6 +65,25 @@ ngran_node_t get_node_type() return ngran_gNB_CUUP; } +nrUE_params_t *get_nrUE_params(void) +{ + static nrUE_params_t params = {0}; + params.extra_pdu_id = -1; + return ¶ms; +} + +void create_ue_ip_if(void) +{ +} + +void create_ue_eth_if(void) +{ +} + +void set_qfi(void) +{ +} + configmodule_interface_t *uniqCfg = NULL; static nrppa_trp_information_resp_t fill_trp_resp(uint8_t transaction_id) @@ -126,6 +148,106 @@ static nrppa_trp_information_resp_t fill_trp_resp(uint8_t transaction_id) return resp; } +// Initializing UE NAS Context with simulated SIM data +nr_ue_nas_t *simulated_ue_nas = NULL; +void init_ue_nas_context(void) +{ + simulated_ue_nas = calloc_or_fail(1, sizeof(nr_ue_nas_t)); + simulated_ue_nas->UE_id = 1; + simulated_ue_nas->security_container = calloc_or_fail(1, sizeof(stream_security_container_t)); + // Allocation and simulation of UICC data + simulated_ue_nas->uicc = calloc_or_fail(1, sizeof(uicc_t)); + // IMSI : 001010000000001 + simulated_ue_nas->uicc->imsiStr = calloc_or_fail(1, 16 * sizeof(char)); + strcpy(simulated_ue_nas->uicc->imsiStr, "001010000000001"); + simulated_ue_nas->uicc->nmc_size = 2; + // DNN : oai + simulated_ue_nas->uicc->dnnStr = calloc_or_fail(1, 32 * sizeof(char)); + strcpy(simulated_ue_nas->uicc->dnnStr, "oai"); + // IMEISV : 6754567890123413 + simulated_ue_nas->uicc->imeisvStr = calloc_or_fail(1, 17 * sizeof(char)); + strcpy(simulated_ue_nas->uicc->imeisvStr, "6754567890123413"); + // NSSAI: sst = 1, sd = 0xffffff + simulated_ue_nas->uicc->nssai_sst = 1; + simulated_ue_nas->uicc->nssai_sd = 0xffffff; + // Ki: fec86ba6eb707ed08905757b1bb44b8f + static const uint8_t TEST_K[16] = + {0xfe, 0xc8, 0x6b, 0xa6, 0xeb, 0x70, 0x7e, 0xd0, 0x89, 0x05, 0x75, 0x7b, 0x1b, 0xb4, 0x4b, 0x8f}; + memcpy(simulated_ue_nas->uicc->key, TEST_K, 16); + // OPc: c42449363bbad02b66d16bc975d77cc1 + static const uint8_t TEST_OPC[16] = + {0xc4, 0x24, 0x49, 0x36, 0x3b, 0xba, 0xd0, 0x2b, 0x66, 0xd1, 0x6b, 0xc9, 0x75, 0xd7, 0x7c, 0xc1}; + memcpy(simulated_ue_nas->uicc->opc, TEST_OPC, 16); + simulated_ue_nas->security.nas_count_ul = 0; + simulated_ue_nas->security.nas_count_dl = 0; + simulated_ue_nas->fiveGMM_state = FGS_DEREGISTERED; +} + +// Emulate registration request to register UE in the AMF (required for positioning) +void send_initial_ue_message(instance_t instance) +{ + MessageDef *msg_p = itti_alloc_new_message(TASK_RRC_GNB, 0, NGAP_NAS_FIRST_REQ); + + NGAP_NAS_FIRST_REQ(msg_p).gNB_ue_ngap_id = 1; // Simulated UE ID + + NGAP_NAS_FIRST_REQ(msg_p).plmn.mcc = 1; + NGAP_NAS_FIRST_REQ(msg_p).plmn.mnc = 1; + NGAP_NAS_FIRST_REQ(msg_p).plmn.mnc_digit_length = 2; + + NGAP_NAS_FIRST_REQ(msg_p).nr_cell_id = gnb_id; + + NGAP_NAS_FIRST_REQ(msg_p).establishment_cause = NGAP_RRC_CAUSE_MO_SIGNALLING; + + as_nas_info_t initialNasMsg = {0}; + generateRegistrationRequest(&initialNasMsg, simulated_ue_nas, false); + + NGAP_NAS_FIRST_REQ(msg_p).nas_pdu.buf = initialNasMsg.nas_data; + NGAP_NAS_FIRST_REQ(msg_p).nas_pdu.len = initialNasMsg.length; + + NGAP_NAS_FIRST_REQ(msg_p).ue_identity.presenceMask = 0; + + itti_send_msg_to_task(TASK_NGAP, instance, msg_p); +} + +void *gNB_app_task(void *args_p) +{ + MessageDef *msg_p = NULL; + const char *msg_name = NULL; + instance_t instance; + int result; + /* for no gcc warnings */ + (void)instance; + + itti_mark_task_ready(TASK_GNB_APP); + do { + // Wait for a message + itti_receive_msg(TASK_GNB_APP, &msg_p); + + msg_name = ITTI_MSG_NAME(msg_p); + instance = ITTI_MSG_DESTINATION_INSTANCE(msg_p); + + switch (ITTI_MSG_ID(msg_p)) { + case TERMINATE_MESSAGE: + LOG_W(GNB_APP, " *** Exiting GNB_APP thread\n"); + itti_exit_task(); + break; + + case NGAP_REGISTER_GNB_CNF: + LOG_I(GNB_APP, "[gNB %ld] Received %s: associated AMF %d\n", instance, msg_name, NGAP_REGISTER_GNB_CNF(msg_p).nb_amf); + send_initial_ue_message(instance); + break; + + default: + LOG_E(GNB_APP, "Received unexpected message %s\n", msg_name); + break; + } + result = itti_free(ITTI_MSG_ORIGIN_ID(msg_p), msg_p); + AssertFatal(result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result); + } while (1); + + return NULL; +} + void *rrc_gnb_task(void *args_p) { MessageDef *msg_p; @@ -151,6 +273,13 @@ void *rrc_gnb_task(void *args_p) LOG_W(NR_RRC, " *** Exiting NR_RRC thread\n"); itti_exit_task(); break; + case NGAP_DOWNLINK_NAS: + LOG_I(NR_RRC, "Ignore NGAP_DOWNLINK_NAS: dont have to handle"); + ngap_downlink_nas_t *nas = &NGAP_DOWNLINK_NAS(msg_p); + if (nas->nas_pdu.buf) { + free(nas->nas_pdu.buf); + } + break; case NRPPA_TRP_INFORMATION_REQ: nrppa_trp_information_req_t *trp_req = &NRPPA_TRP_INFORMATION_REQ(msg_p); LOG_I(NR_RRC, "Received NRPPA_TRP_INFORMATION_REQ transaction_id %d\n", trp_req->transaction_id); @@ -177,6 +306,8 @@ int main(int argc, char **argv) } logInit(); + init_ue_nas_context(); + set_softmodem_sighandler(); // Initialize ITTI tasks @@ -195,6 +326,9 @@ int main(int argc, char **argv) rc = itti_create_task(TASK_RRC_GNB, rrc_gnb_task, NULL); AssertFatal(rc >= 0, "Create task for RRC failed\n"); + rc = itti_create_task(TASK_GNB_APP, gNB_app_task, NULL); + AssertFatal(rc >= 0, "Create task for RRC failed\n"); + MessageDef *msg_p; msg_p = itti_alloc_new_message(TASK_GNB_APP, 0, NGAP_REGISTER_GNB_REQ); RCconfig_NR_NG(msg_p, 0); From 559e3c31de944d4621c41eb2a1869d6226c84d10 Mon Sep 17 00:00:00 2001 From: Rakesh Mundlamuri Date: Fri, 23 Jan 2026 17:50:39 +0530 Subject: [PATCH 26/44] Add Positioning Information Response NRPPA message encoding procedures --- openair2/COMMON/nrppa_messages_def.h | 4 + openair2/COMMON/nrppa_messages_types.h | 348 ++++++++ openair3/NRPPA/nrppa_gNB.c | 3 + .../nrppa_gNB_location_information_transfer.c | 802 ++++++++++++++++++ .../nrppa_gNB_location_information_transfer.h | 3 + openair3/NRPPA/nrppa_includes.h | 27 + tests/nr-cu-nrppa/nr-cu-nrppa.c | 291 +++++++ 7 files changed, 1478 insertions(+) diff --git a/openair2/COMMON/nrppa_messages_def.h b/openair2/COMMON/nrppa_messages_def.h index e3ddeb244f..d20bf1960a 100644 --- a/openair2/COMMON/nrppa_messages_def.h +++ b/openair2/COMMON/nrppa_messages_def.h @@ -28,3 +28,7 @@ MESSAGE_DEF(NRPPA_POSITIONING_INFORMATION_REQ, MESSAGE_PRIORITY_MED, nrppa_positioning_information_req_t, nrppa_positioning_information_req) +MESSAGE_DEF(NRPPA_POSITIONING_INFORMATION_RESP, + MESSAGE_PRIORITY_MED, + nrppa_positioning_information_resp_t, + nrppa_positioning_information_resp) diff --git a/openair2/COMMON/nrppa_messages_types.h b/openair2/COMMON/nrppa_messages_types.h index fef930ac9a..4522604422 100644 --- a/openair2/COMMON/nrppa_messages_types.h +++ b/openair2/COMMON/nrppa_messages_types.h @@ -27,6 +27,7 @@ #define NRPPA_TRP_INFORMATION_REQ(mSGpTR) (mSGpTR)->ittiMsg.nrppa_trp_information_req #define NRPPA_TRP_INFORMATION_RESP(mSGpTR) (mSGpTR)->ittiMsg.nrppa_trp_information_resp #define NRPPA_POSITIONING_INFORMATION_REQ(mSGpTR) (mSGpTR)->ittiMsg.nrppa_positioning_information_req +#define NRPPA_POSITIONING_INFORMATION_RESP(mSGpTR) (mSGpTR)->ittiMsg.nrppa_positioning_information_resp /* Structure of Positioning related NRPPA messages */ /* IE structures for Positioning related messages as per TS 38.455 V16.7.1*/ @@ -223,6 +224,346 @@ typedef struct nrppa_trp_information_s { nrppa_trp_information_type_response_list_t trp_information_type_response_list; } nrppa_trp_information_t; +typedef enum nrppa_subcarrier_spacing_e { + NRPPA_SUBCARRIER_SPACING_15KHZ, + NRPPA_SUBCARRIER_SPACING_30KHZ, + NRPPA_SUBCARRIER_SPACING_60KHZ, + NRPPA_SUBCARRIER_SPACING_120KHZ +} nrppa_subcarrier_spacing_pr; + +typedef struct nrppa_scs_specific_carrier_s { + uint32_t offset_to_carrier; + nrppa_subcarrier_spacing_pr subcarrier_spacing; + uint16_t carrier_bandwidth; +} nrppa_scs_specific_carrier_t; + +typedef struct nrppa_uplink_channel_bw_per_scs_list_s { + nrppa_scs_specific_carrier_t *scs_specific_carrier; + uint32_t scs_specific_carrier_list_length; +} nrppa_uplink_channel_bw_per_scs_list_t; + +typedef enum nrppa_transmission_comb_e { + NRPPA_TRANSMISSION_COMB_PR_NOTHING, + NRPPA_TRANSMISSION_COMB_PR_N2, + NRPPA_TRANSMISSION_COMB_PR_N4 +} nrppa_transmission_comb_pr; + +typedef struct nrppa_transmission_comb_n2_s { + uint8_t comb_offset_n2; + uint8_t cyclic_shift_n2; +} nrppa_transmission_comb_n2_t, nrppa_transmission_comb_pos_n2_t; + +typedef struct nrppa_transmission_comb_n4_s { + uint8_t comb_offset_n4; + uint8_t cyclic_shift_n4; +} nrppa_transmission_comb_n4_t, nrppa_transmission_comb_pos_n4_t; + +typedef union nrppa_transmission_comb_c { + nrppa_transmission_comb_n2_t n2; + nrppa_transmission_comb_n4_t n4; +} nrppa_transmission_comb_u; + +typedef struct nrppa_transmission_comb_s { + nrppa_transmission_comb_pr present; + nrppa_transmission_comb_u choice; +} nrppa_transmission_comb_t; + +typedef enum nrppa_srs_resource_type_periodicity_e { + NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT1 = 0, + NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT2, + NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT4, + NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT5, + NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT8, + NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT10, + NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT16, + NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT20, + NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT32, + NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT40, + NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT64, + NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT80, + NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT160, + NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT320, + NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT640, + NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT1280, + NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT2560 +} nrppa_srs_resource_type_periodicity_pr; + +typedef struct nrppa_resource_type_periodic_s { + nrppa_srs_resource_type_periodicity_pr periodicity; + uint16_t offset; +} nrppa_resource_type_periodic_t, nrppa_resource_type_semi_persistent_t; + +typedef union nrppa_resource_type_c { + nrppa_resource_type_periodic_t periodic; + nrppa_resource_type_semi_persistent_t semi_persistent; + bool aperiodic; +} nrppa_resource_type_u; + +typedef enum nrppa_resource_type_e { + NRPPA_RESOURCE_TYPE_PR_NOTHING, + NRPPA_RESOURCE_TYPE_PR_PERIODIC, + NRPPA_RESOURCE_TYPE_PR_SEMI_PERSISTENT, + NRPPA_RESOURCE_TYPE_PR_APERIODIC +} nrppa_resource_type_pr; + +typedef struct nrppa_resource_type_s { + nrppa_resource_type_pr present; + nrppa_resource_type_u choice; +} nrppa_resource_type_t; + +typedef struct nrppa_transmission_comb_n8_s { + uint8_t comb_offset_n8; + uint8_t cyclic_shift_n8; +} nrppa_transmission_comb_pos_n8_t; + +typedef union nrppa_transmission_comb_pos_c { + nrppa_transmission_comb_pos_n2_t n2; + nrppa_transmission_comb_pos_n4_t n4; + nrppa_transmission_comb_pos_n8_t n8; +} nrppa_transmission_comb_pos_u; + +typedef enum nrppa_transmission_comb_pos_e { + NRPPA_TRANSMISSION_COMB_POS_PR_NOTHING, + NRPPA_TRANSMISSION_COMB_POS_PR_N2, + NRPPA_TRANSMISSION_COMB_POS_PR_N4, + NRPPA_TRANSMISSION_COMB_POS_PR_N8 +} nrppa_transmission_comb_pos_pr; + +typedef struct nrppa_transmission_comb_pos_s { + nrppa_transmission_comb_pos_pr present; + nrppa_transmission_comb_pos_u choice; +} nrppa_transmission_comb_pos_t; + +typedef enum nrppa_srs_resource_type_pos_periodicity_e { + NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT1 = 0, + NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT2, + NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT4, + NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT5, + NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT8, + NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT10, + NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT16, + NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT20, + NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT32, + NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT40, + NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT64, + NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT80, + NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT160, + NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT320, + NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT640, + NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT1280, + NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT2560, + NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT5120, + NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT10240, + NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT20480, + NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT40960, + NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT81920 +} nrppa_srs_resource_type_pos_periodicity_pr; + +typedef struct nrppa_resource_type_periodic_pos_s { + nrppa_srs_resource_type_pos_periodicity_pr periodicity; + uint16_t offset; +} nrppa_resource_type_periodic_pos_t, nrppa_resource_type_semi_persistent_pos_t; + +typedef struct nrppa_resource_type_aperiodic_pos_s { + uint8_t slot_offset; +} nrppa_resource_type_aperiodic_pos_t; + +typedef union nrppa_resource_type_pos_c { + nrppa_resource_type_periodic_pos_t periodic; + nrppa_resource_type_semi_persistent_pos_t semi_persistent; + nrppa_resource_type_aperiodic_pos_t aperiodic; +} nrppa_resource_type_pos_u; + +typedef enum nrppa_resource_type_pos_e { + NRPPA_RESOURCE_TYPE_POS_PR_NOTHING, + NRPPA_RESOURCE_TYPE_POS_PR_PERIODIC, + NRPPA_RESOURCE_TYPE_POS_PR_SEMI_PERSISTENT, + NRPPA_RESOURCE_TYPE_POS_PR_APERIODIC +} nrppa_resource_type_pos_pr; + +typedef struct nrppa_resource_type_pos_s { + nrppa_resource_type_pos_pr present; + nrppa_resource_type_pos_u choice; +} nrppa_resource_type_pos_t; + +typedef struct nrppa_srs_resource_id_list_s { + long *srs_resource_id; + uint8_t srs_resource_id_list_length; +} nrppa_srs_resource_id_list_t; + +typedef struct nrppa_resource_set_type_aperiodic_s { + uint8_t srs_resource_trigger; + long slot_offset; +} nrppa_resource_set_type_aperiodic_t; + +typedef union nrppa_resource_set_type_c { + bool periodic; + bool semi_persistent; + nrppa_resource_set_type_aperiodic_t aperiodic; +} nrppa_resource_set_type_u; + +typedef enum nrppa_resource_set_type_e { + NRPPA_RESOURCE_SET_TYPE_PR_NOTHING, + NRPPA_RESOURCE_SET_TYPE_PR_PERIODIC, + NRPPA_RESOURCE_SET_TYPE_PR_SEMI_PERSISTENT, + NRPPA_RESOURCE_SET_TYPE_PR_APERIODIC +} nrppa_resource_set_type_pr; + +typedef struct nrppa_resource_set_type_s { + nrppa_resource_set_type_pr present; + nrppa_resource_set_type_u choice; +} nrppa_resource_set_type_t; + +typedef struct nrppa_pos_srs_resource_id_list_s { + long *srs_pos_resource_id; + uint32_t pos_srs_resource_id_list_length; +} nrppa_pos_srs_resource_id_list_t; + +typedef union nrppa_pos_resource_set_type_c { + bool periodic; + bool semi_persistent; + uint8_t srs_resource; +} nrppa_pos_resource_set_type_u; + +typedef enum nrppa_pos_resource_set_type_e { + NRPPA_POS_RESOURCE_SET_TYPE_PR_NOTHING, + NRPPA_POS_RESOURCE_SET_TYPE_PR_PERIODIC, + NRPPA_POS_RESOURCE_SET_TYPE_PR_SEMI_PERSISTENT, + NRPPA_POS_RESOURCE_SET_TYPE_PR_APERIODIC +} nrppa_pos_resource_set_type_pr; + +typedef struct nrppa_pos_resource_set_type_s { + nrppa_pos_resource_set_type_pr present; + nrppa_pos_resource_set_type_u choice; +} nrppa_pos_resource_set_type_t; + +typedef enum nrppa_srs_resource_number_of_ports_e { + NRPPA_SRS_NUMBER_OF_PORTS_N1, + NRPPA_SRS_NUMBER_OF_PORTS_N2, + NRPPA_SRS_NUMBER_OF_PORTS_N4 +} nrppa_srs_resource_number_of_ports_pr; + +typedef enum nrppa_srs_resource_number_of_symbols_e { + NRPPA_SRS_NUMBER_OF_SYMBOLS_N1, + NRPPA_SRS_NUMBER_OF_SYMBOLS_N2, + NRPPA_SRS_NUMBER_OF_SYMBOLS_N4 +} nrppa_srs_resource_number_of_symbols_pr; + +typedef enum nrppa_srs_repetition_factor_e { + NRPPA_SRS_REPETITION_FACTOR_RF1, + NRPPA_SRS_REPETITION_FACTOR_RF2, + NRPPA_SRS_REPETITION_FACTOR_RF4 +} nrppa_srs_repetition_factor_pr; + +typedef enum nrppa_srs_group_or_sequencehopping_e { + NRPPA_GROUPORSEQUENCEHOPPING_NOTHING, + NRPPA_GROUPORSEQUENCEHOPPING_GROUPHOPPING, + NRPPA_GROUPORSEQUENCEHOPPING_SEQUENCEHOPPING +} nrppa_srs_group_or_sequencehopping_pr; + +typedef struct nrppa_srs_resource_s { + uint32_t srs_resource_id; + nrppa_srs_resource_number_of_ports_pr nr_of_srs_ports; + nrppa_transmission_comb_t transmission_comb; + uint8_t start_position; + nrppa_srs_resource_number_of_symbols_pr nr_of_symbols; + nrppa_srs_repetition_factor_pr repetition_factor; + uint8_t freq_domain_position; + uint16_t freq_domain_shift; + uint8_t c_srs; + uint8_t b_srs; + uint8_t b_hop; + nrppa_srs_group_or_sequencehopping_pr group_or_sequence_hopping; + nrppa_resource_type_t resource_type; + uint16_t sequence_id; +} nrppa_srs_resource_t; + +typedef enum nrppa_srs_resource_item_number_of_symbols_e { + NRPPA_SRS_RESOURCE_ITEM_NUMBER_OF_SYMBOLS_N1, + NRPPA_SRS_RESOURCE_ITEM_NUMBER_OF_SYMBOLS_N2, + NRPPA_SRS_RESOURCE_ITEM_NUMBER_OF_SYMBOLS_N4, + NRPPA_SRS_RESOURCE_ITEM_NUMBER_OF_SYMBOLS_N8, + NRPPA_SRS_RESOURCE_ITEM_NUMBER_OF_SYMBOLS_N12 +} nrppa_srs_resource_item_number_of_symbols_pr; + +typedef struct nrppa_pos_srs_resource_item_s { + uint32_t srs_pos_resource_id; + nrppa_transmission_comb_pos_t transmission_comb_pos; + uint8_t start_position; + nrppa_srs_resource_item_number_of_symbols_pr nr_of_symbols; + uint16_t freq_domain_shift; + uint8_t c_srs; + nrppa_srs_group_or_sequencehopping_pr group_or_sequence_hopping; + nrppa_resource_type_pos_t resource_type_pos; + uint32_t sequence_id; +} nrppa_pos_srs_resource_item_t; + +typedef struct nrppa_srs_resource_set_s { + uint8_t srs_resource_set_id; + nrppa_srs_resource_id_list_t srs_resource_id_list; + nrppa_resource_set_type_t resource_set_type; +} nrppa_srs_resource_set_t; + +typedef struct nrppa_pos_srs_resource_set_item_s { + uint8_t pos_srs_resource_set_id; + nrppa_pos_srs_resource_id_list_t pos_srs_resource_id_list; + nrppa_pos_resource_set_type_t pos_resource_set_type; +} nrppa_pos_srs_resource_set_item_t; + +typedef struct nrppa_srs_resource_list_s { + nrppa_srs_resource_t *srs_resource; + uint32_t srs_resource_list_length; +} nrppa_srs_resource_list_t; + +typedef struct nrppa_pos_srs_resource_list_s { + nrppa_pos_srs_resource_item_t *pos_srs_resource_item; + uint32_t pos_srs_resource_list_length; +} nrppa_pos_srs_resource_list_t; + +typedef struct nrppa_srs_resource_set_list_s { + nrppa_srs_resource_set_t *srs_resource_set; + uint32_t srs_resource_set_list_length; +} nrppa_srs_resource_set_list_t; + +typedef struct nrppa_pos_srs_resource_set_list_s { + nrppa_pos_srs_resource_set_item_t *pos_srs_resource_set_item; + uint32_t pos_srs_resource_set_list_length; +} nrppa_pos_srs_resource_set_list_t; + +typedef struct nrppa_srs_config_s { + nrppa_srs_resource_list_t *srs_resource_list; + nrppa_pos_srs_resource_list_t *pos_srs_resource_list; + nrppa_srs_resource_set_list_t *srs_resource_set_list; + nrppa_pos_srs_resource_set_list_t *pos_srs_resource_set_list; +} nrppa_srs_config_t; + +typedef enum nrppa_cp_type_e { NRPPA_CP_TYPE_NORMAL, NRPPA_CP_TYPE_EXTENDED } nrppa_cp_type_pr; + +typedef struct nrppa_active_ul_bwp_s { + uint32_t location_and_bandwidth; + nrppa_subcarrier_spacing_pr subcarrier_spacing; + nrppa_cp_type_pr cyclic_prefix; + uint32_t tx_direct_current_location; + uint8_t shift_7_dot_5kHz; + nrppa_srs_config_t srs_config; +} nrppa_active_ul_bwp_t; + +typedef struct nrppa_srs_carrier_list_item_s { + uint32_t pointA; + nrppa_uplink_channel_bw_per_scs_list_t uplink_channel_bw_per_scs_list; + nrppa_active_ul_bwp_t active_ul_bwp; + uint16_t pci; +} nrppa_srs_carrier_list_item_t; + +typedef struct nrppa_srs_carrier_list_s { + nrppa_srs_carrier_list_item_t *srs_carrier_list_item; + uint32_t srs_carrier_list_length; +} nrppa_srs_carrier_list_t; + +typedef struct nrppa_srs_configuration_s { + nrppa_srs_carrier_list_t srs_carrier_list; +} nrppa_srs_configuration_t; + // IE 9.3.1.176 (TS 38.473 V16.21.0) typedef struct nrppa_trp_information_list_s { nrppa_trp_information_t *trp_information_item; @@ -251,4 +592,11 @@ typedef struct nrppa_positioning_information_req_s { uint16_t transaction_id; } nrppa_positioning_information_req_t; +typedef struct nrppa_positioning_information_resp_s { + // IE 9.2.4 (mandatory) + uint16_t transaction_id; + // IE 9.2.28 (optional) + nrppa_srs_configuration_t *srs_configuration; +} nrppa_positioning_information_resp_t; + #endif // NRPPA_MESSAGES_TYPES_H_ diff --git a/openair3/NRPPA/nrppa_gNB.c b/openair3/NRPPA/nrppa_gNB.c index bb00cecd54..19e76bc392 100644 --- a/openair3/NRPPA/nrppa_gNB.c +++ b/openair3/NRPPA/nrppa_gNB.c @@ -60,6 +60,9 @@ void *nrppa_gNB_process_itti_msg(void *notUsed) case NRPPA_TRP_INFORMATION_RESP: nrppa_gNB_trp_information_response(instance, received_msg); break; + case NRPPA_POSITIONING_INFORMATION_RESP: + nrppa_gNB_positioning_information_response(instance, received_msg); + break; default: LOG_E(NRPPA, "Received unhandled message: %d:%s\n", ITTI_MSG_ID(received_msg), ITTI_MSG_NAME(received_msg)); break; diff --git a/openair3/NRPPA/nrppa_gNB_location_information_transfer.c b/openair3/NRPPA/nrppa_gNB_location_information_transfer.c index 6821e251ed..5d1a43c0a6 100644 --- a/openair3/NRPPA/nrppa_gNB_location_information_transfer.c +++ b/openair3/NRPPA/nrppa_gNB_location_information_transfer.c @@ -263,6 +263,728 @@ void free_trp_information_response(nrppa_trp_information_resp_t *msg) free(msg->trp_information_list.trp_information_item); } +static NRPPA_SRSConfig_t encode_srs_config(const nrppa_srs_config_t *in_config) +{ + NRPPA_SRSConfig_t out_config = {0}; + // optional: srs_resource_list + if (in_config->srs_resource_list) { + nrppa_srs_resource_list_t *srs_resource_list = in_config->srs_resource_list; + uint32_t srs_resource_list_length = srs_resource_list->srs_resource_list_length; + asn1cCalloc(out_config.sRSResource_List, nrppa_sRSResource_List); + for (int i = 0; i < srs_resource_list_length; i++) { + asn1cSequenceAdd(nrppa_sRSResource_List->list, NRPPA_SRSResource_t, nrppa_srs_resource); + nrppa_srs_resource_t *srs_resource = &srs_resource_list->srs_resource[i]; + nrppa_srs_resource->sRSResourceID = srs_resource->srs_resource_id; + + switch (srs_resource->nr_of_srs_ports) { + case NRPPA_SRS_NUMBER_OF_PORTS_N1: + nrppa_srs_resource->nrofSRS_Ports = NRPPA_SRSResource__nrofSRS_Ports_port1; + break; + case NRPPA_SRS_NUMBER_OF_PORTS_N2: + nrppa_srs_resource->nrofSRS_Ports = NRPPA_SRSResource__nrofSRS_Ports_ports2; + break; + case NRPPA_SRS_NUMBER_OF_PORTS_N4: + nrppa_srs_resource->nrofSRS_Ports = NRPPA_SRSResource__nrofSRS_Ports_ports4; + break; + default: + AssertFatal(false, "illegal number of srs ports %d\n", srs_resource->nr_of_srs_ports); + break; + } + + nrppa_transmission_comb_t *srs_res_tx_comb = &srs_resource->transmission_comb; + switch (srs_res_tx_comb->present) { + case NRPPA_TRANSMISSION_COMB_PR_NOTHING: + nrppa_srs_resource->transmissionComb.present = NRPPA_TransmissionComb_PR_NOTHING; + break; + case NRPPA_TRANSMISSION_COMB_PR_N2: + nrppa_srs_resource->transmissionComb.present = NRPPA_TransmissionComb_PR_n2; + asn1cCalloc(nrppa_srs_resource->transmissionComb.choice.n2, nrppa_n2); + nrppa_n2->combOffset_n2 = srs_res_tx_comb->choice.n2.comb_offset_n2; + nrppa_n2->cyclicShift_n2 = srs_res_tx_comb->choice.n2.cyclic_shift_n2; + break; + case NRPPA_TRANSMISSION_COMB_PR_N4: + nrppa_srs_resource->transmissionComb.present = NRPPA_TransmissionComb_PR_n4; + asn1cCalloc(nrppa_srs_resource->transmissionComb.choice.n4, nrppa_n4); + nrppa_n4->combOffset_n4 = srs_res_tx_comb->choice.n4.comb_offset_n4; + nrppa_n4->cyclicShift_n4 = srs_res_tx_comb->choice.n4.cyclic_shift_n4; + break; + default: + AssertFatal(false, "illegal transmissionComb %d\n", srs_res_tx_comb->present); + break; + } + + nrppa_srs_resource->startPosition = srs_resource->start_position; + + switch (srs_resource->nr_of_symbols) { + case NRPPA_SRS_NUMBER_OF_SYMBOLS_N1: + nrppa_srs_resource->nrofSymbols = NRPPA_SRSResource__nrofSymbols_n1; + break; + case NRPPA_SRS_NUMBER_OF_SYMBOLS_N2: + nrppa_srs_resource->nrofSymbols = NRPPA_SRSResource__nrofSymbols_n2; + break; + case NRPPA_SRS_NUMBER_OF_SYMBOLS_N4: + nrppa_srs_resource->nrofSymbols = NRPPA_SRSResource__nrofSymbols_n4; + break; + default: + AssertFatal(false, "illegal number of symbols %d\n", srs_resource->nr_of_symbols); + break; + } + + switch (srs_resource->repetition_factor) { + case NRPPA_SRS_REPETITION_FACTOR_RF1: + nrppa_srs_resource->repetitionFactor = NRPPA_SRSResource__repetitionFactor_n1; + break; + case NRPPA_SRS_REPETITION_FACTOR_RF2: + nrppa_srs_resource->repetitionFactor = NRPPA_SRSResource__repetitionFactor_n2; + break; + case NRPPA_SRS_REPETITION_FACTOR_RF4: + nrppa_srs_resource->repetitionFactor = NRPPA_SRSResource__repetitionFactor_n4; + break; + default: + AssertFatal(false, "illegal repetition factor %d\n", srs_resource->repetition_factor); + break; + } + + nrppa_srs_resource->freqDomainPosition = srs_resource->freq_domain_position; + nrppa_srs_resource->freqDomainShift = srs_resource->freq_domain_shift; + nrppa_srs_resource->c_SRS = srs_resource->c_srs; + nrppa_srs_resource->b_SRS = srs_resource->b_srs; + nrppa_srs_resource->b_hop = srs_resource->b_hop; + + switch (srs_resource->group_or_sequence_hopping) { + case NRPPA_GROUPORSEQUENCEHOPPING_NOTHING: + nrppa_srs_resource->groupOrSequenceHopping = NRPPA_SRSResource__groupOrSequenceHopping_neither; + break; + case NRPPA_GROUPORSEQUENCEHOPPING_GROUPHOPPING: + nrppa_srs_resource->groupOrSequenceHopping = NRPPA_SRSResource__groupOrSequenceHopping_groupHopping; + break; + case NRPPA_GROUPORSEQUENCEHOPPING_SEQUENCEHOPPING: + nrppa_srs_resource->groupOrSequenceHopping = NRPPA_SRSResource__groupOrSequenceHopping_sequenceHopping; + break; + default: + AssertFatal(false, "illegal groupOrSequenceHopping %d\n", srs_resource->group_or_sequence_hopping); + break; + } + + NRPPA_ResourceType_t *nrppa_resourceType = &nrppa_srs_resource->resourceType; + nrppa_resource_type_t *resource_type = &srs_resource->resource_type; + if (resource_type->present == NRPPA_RESOURCE_TYPE_PR_NOTHING) { + nrppa_resourceType->present = NRPPA_ResourceType_PR_NOTHING; + } else if (resource_type->present == NRPPA_RESOURCE_TYPE_PR_PERIODIC) { + nrppa_resourceType->present = NRPPA_ResourceType_PR_periodic; + asn1cCalloc(nrppa_resourceType->choice.periodic, nrppa_periodic); + switch (resource_type->choice.periodic.periodicity) { + case NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT1: + nrppa_periodic->periodicity = NRPPA_ResourceTypePeriodic__periodicity_slot1; + break; + case NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT2: + nrppa_periodic->periodicity = NRPPA_ResourceTypePeriodic__periodicity_slot2; + break; + case NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT4: + nrppa_periodic->periodicity = NRPPA_ResourceTypePeriodic__periodicity_slot4; + break; + case NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT5: + nrppa_periodic->periodicity = NRPPA_ResourceTypePeriodic__periodicity_slot5; + break; + case NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT8: + nrppa_periodic->periodicity = NRPPA_ResourceTypePeriodic__periodicity_slot8; + break; + case NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT10: + nrppa_periodic->periodicity = NRPPA_ResourceTypePeriodic__periodicity_slot10; + break; + case NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT16: + nrppa_periodic->periodicity = NRPPA_ResourceTypePeriodic__periodicity_slot16; + break; + case NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT20: + nrppa_periodic->periodicity = NRPPA_ResourceTypePeriodic__periodicity_slot20; + break; + case NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT32: + nrppa_periodic->periodicity = NRPPA_ResourceTypePeriodic__periodicity_slot32; + break; + case NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT40: + nrppa_periodic->periodicity = NRPPA_ResourceTypePeriodic__periodicity_slot40; + break; + case NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT64: + nrppa_periodic->periodicity = NRPPA_ResourceTypePeriodic__periodicity_slot64; + break; + case NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT80: + nrppa_periodic->periodicity = NRPPA_ResourceTypePeriodic__periodicity_slot80; + break; + case NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT160: + nrppa_periodic->periodicity = NRPPA_ResourceTypePeriodic__periodicity_slot160; + break; + case NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT320: + nrppa_periodic->periodicity = NRPPA_ResourceTypePeriodic__periodicity_slot320; + break; + case NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT640: + nrppa_periodic->periodicity = NRPPA_ResourceTypePeriodic__periodicity_slot640; + break; + case NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT1280: + nrppa_periodic->periodicity = NRPPA_ResourceTypePeriodic__periodicity_slot1280; + break; + case NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT2560: + nrppa_periodic->periodicity = NRPPA_ResourceTypePeriodic__periodicity_slot2560; + break; + default: + AssertFatal(false, "illegal periodicity %d\n", resource_type->choice.periodic.periodicity); + break; + } + nrppa_periodic->offset = resource_type->choice.periodic.offset; + } else if (resource_type->present == NRPPA_RESOURCE_TYPE_PR_SEMI_PERSISTENT) { + nrppa_resourceType->present = NRPPA_ResourceType_PR_semi_persistent; + asn1cCalloc(nrppa_resourceType->choice.semi_persistent, nrppa_semi_persistent); + switch (resource_type->choice.semi_persistent.periodicity) { + case NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT1: + nrppa_semi_persistent->periodicity = NRPPA_ResourceTypeSemi_persistent__periodicity_slot1; + break; + case NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT2: + nrppa_semi_persistent->periodicity = NRPPA_ResourceTypeSemi_persistent__periodicity_slot2; + break; + case NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT4: + nrppa_semi_persistent->periodicity = NRPPA_ResourceTypeSemi_persistent__periodicity_slot4; + break; + case NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT5: + nrppa_semi_persistent->periodicity = NRPPA_ResourceTypeSemi_persistent__periodicity_slot5; + break; + case NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT8: + nrppa_semi_persistent->periodicity = NRPPA_ResourceTypeSemi_persistent__periodicity_slot8; + break; + case NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT10: + nrppa_semi_persistent->periodicity = NRPPA_ResourceTypeSemi_persistent__periodicity_slot10; + break; + case NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT16: + nrppa_semi_persistent->periodicity = NRPPA_ResourceTypeSemi_persistent__periodicity_slot16; + break; + case NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT20: + nrppa_semi_persistent->periodicity = NRPPA_ResourceTypeSemi_persistent__periodicity_slot20; + break; + case NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT32: + nrppa_semi_persistent->periodicity = NRPPA_ResourceTypeSemi_persistent__periodicity_slot32; + break; + case NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT40: + nrppa_semi_persistent->periodicity = NRPPA_ResourceTypeSemi_persistent__periodicity_slot40; + break; + case NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT64: + nrppa_semi_persistent->periodicity = NRPPA_ResourceTypeSemi_persistent__periodicity_slot64; + break; + case NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT80: + nrppa_semi_persistent->periodicity = NRPPA_ResourceTypeSemi_persistent__periodicity_slot80; + break; + case NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT160: + nrppa_semi_persistent->periodicity = NRPPA_ResourceTypeSemi_persistent__periodicity_slot160; + break; + case NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT320: + nrppa_semi_persistent->periodicity = NRPPA_ResourceTypeSemi_persistent__periodicity_slot320; + break; + case NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT640: + nrppa_semi_persistent->periodicity = NRPPA_ResourceTypeSemi_persistent__periodicity_slot640; + break; + case NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT1280: + nrppa_semi_persistent->periodicity = NRPPA_ResourceTypeSemi_persistent__periodicity_slot1280; + break; + case NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT2560: + nrppa_semi_persistent->periodicity = NRPPA_ResourceTypeSemi_persistent__periodicity_slot2560; + break; + default: + AssertFatal(false, "illegal periodicity %d\n", resource_type->choice.semi_persistent.periodicity); + break; + } + nrppa_semi_persistent->offset = resource_type->choice.semi_persistent.offset; + } else if (resource_type->present == NRPPA_RESOURCE_TYPE_PR_APERIODIC) { + nrppa_resourceType->present = NRPPA_ResourceType_PR_aperiodic; + asn1cCalloc(nrppa_resourceType->choice.aperiodic, nrppa_aperiodic); + nrppa_aperiodic->aperiodicResourceType = resource_type->choice.aperiodic; + } else { + AssertFatal(false, "illegal resourceType %d\n", resource_type->present); + } + + nrppa_srs_resource->sequenceId = srs_resource->sequence_id; + } + } + + // optional: pos_srs_resource_list + if (in_config->pos_srs_resource_list) { + nrppa_pos_srs_resource_list_t *pos_srs_resource_list = in_config->pos_srs_resource_list; + uint32_t pos_srs_resource_list_length = pos_srs_resource_list->pos_srs_resource_list_length; + asn1cCalloc(out_config.posSRSResource_List, nrppa_posSRSResource_List); + for (int i = 0; i < pos_srs_resource_list_length; i++) { + asn1cSequenceAdd(nrppa_posSRSResource_List->list, NRPPA_PosSRSResource_Item_t, nrppa_pos_srs_resource); + nrppa_pos_srs_resource_item_t *pos_srs_resource = &pos_srs_resource_list->pos_srs_resource_item[i]; + nrppa_pos_srs_resource->srs_PosResourceId = pos_srs_resource->srs_pos_resource_id; + + nrppa_transmission_comb_pos_t *pos_srs_res_tx_comb = &pos_srs_resource->transmission_comb_pos; + switch (pos_srs_res_tx_comb->present) { + case NRPPA_TRANSMISSION_COMB_POS_PR_NOTHING: + nrppa_pos_srs_resource->transmissionCombPos.present = NRPPA_TransmissionCombPos_PR_NOTHING; + break; + case NRPPA_TRANSMISSION_COMB_POS_PR_N2: + nrppa_pos_srs_resource->transmissionCombPos.present = NRPPA_TransmissionCombPos_PR_n2; + asn1cCalloc(nrppa_pos_srs_resource->transmissionCombPos.choice.n2, nrppa_pos_srs_resource_n2); + nrppa_transmission_comb_pos_n2_t *pos_srs_resource_n2 = &pos_srs_res_tx_comb->choice.n2; + nrppa_pos_srs_resource_n2->combOffset_n2 = pos_srs_resource_n2->comb_offset_n2; + nrppa_pos_srs_resource_n2->cyclicShift_n2 = pos_srs_resource_n2->cyclic_shift_n2; + break; + case NRPPA_TRANSMISSION_COMB_POS_PR_N4: + nrppa_pos_srs_resource->transmissionCombPos.present = NRPPA_TransmissionCombPos_PR_n4; + asn1cCalloc(nrppa_pos_srs_resource->transmissionCombPos.choice.n4, nrppa_pos_srs_resource_n4); + nrppa_transmission_comb_pos_n4_t *pos_srs_resource_n4 = &pos_srs_res_tx_comb->choice.n4; + nrppa_pos_srs_resource_n4->combOffset_n4 = pos_srs_resource_n4->comb_offset_n4; + nrppa_pos_srs_resource_n4->cyclicShift_n4 = pos_srs_resource_n4->cyclic_shift_n4; + break; + case NRPPA_TRANSMISSION_COMB_POS_PR_N8: + nrppa_pos_srs_resource->transmissionCombPos.present = NRPPA_TransmissionCombPos_PR_n8; + asn1cCalloc(nrppa_pos_srs_resource->transmissionCombPos.choice.n8, nrppa_pos_srs_resource_n8); + nrppa_transmission_comb_pos_n8_t *pos_srs_resource_n8 = &pos_srs_res_tx_comb->choice.n8; + nrppa_pos_srs_resource_n8->combOffset_n8 = pos_srs_resource_n8->comb_offset_n8; + nrppa_pos_srs_resource_n8->cyclicShift_n8 = pos_srs_resource_n8->cyclic_shift_n8; + break; + default: + AssertFatal(false, "illegal transmissionComb %d\n", pos_srs_res_tx_comb->present); + break; + } + + nrppa_pos_srs_resource->startPosition = pos_srs_resource->start_position; + + switch (pos_srs_resource->nr_of_symbols) { + case NRPPA_SRS_RESOURCE_ITEM_NUMBER_OF_SYMBOLS_N1: + nrppa_pos_srs_resource->nrofSymbols = NRPPA_PosSRSResource_Item__nrofSymbols_n1; + break; + case NRPPA_SRS_RESOURCE_ITEM_NUMBER_OF_SYMBOLS_N2: + nrppa_pos_srs_resource->nrofSymbols = NRPPA_PosSRSResource_Item__nrofSymbols_n2; + break; + case NRPPA_SRS_RESOURCE_ITEM_NUMBER_OF_SYMBOLS_N4: + nrppa_pos_srs_resource->nrofSymbols = NRPPA_PosSRSResource_Item__nrofSymbols_n4; + break; + case NRPPA_SRS_RESOURCE_ITEM_NUMBER_OF_SYMBOLS_N8: + nrppa_pos_srs_resource->nrofSymbols = NRPPA_PosSRSResource_Item__nrofSymbols_n8; + break; + case NRPPA_SRS_RESOURCE_ITEM_NUMBER_OF_SYMBOLS_N12: + nrppa_pos_srs_resource->nrofSymbols = NRPPA_PosSRSResource_Item__nrofSymbols_n12; + break; + default: + AssertFatal(false, "illegal number of symbols %d\n", pos_srs_resource->nr_of_symbols); + break; + } + + nrppa_pos_srs_resource->freqDomainShift = pos_srs_resource->freq_domain_shift; + nrppa_pos_srs_resource->c_SRS = pos_srs_resource->c_srs; + + switch (pos_srs_resource->group_or_sequence_hopping) { + case NRPPA_GROUPORSEQUENCEHOPPING_NOTHING: + nrppa_pos_srs_resource->groupOrSequenceHopping = NRPPA_PosSRSResource_Item__groupOrSequenceHopping_neither; + break; + case NRPPA_GROUPORSEQUENCEHOPPING_GROUPHOPPING: + nrppa_pos_srs_resource->groupOrSequenceHopping = NRPPA_PosSRSResource_Item__groupOrSequenceHopping_groupHopping; + break; + case NRPPA_GROUPORSEQUENCEHOPPING_SEQUENCEHOPPING: + nrppa_pos_srs_resource->groupOrSequenceHopping = NRPPA_PosSRSResource_Item__groupOrSequenceHopping_sequenceHopping; + break; + default: + AssertFatal(false, "illegal groupOrSequenceHopping %d\n", pos_srs_resource->group_or_sequence_hopping); + break; + } + + nrppa_resource_type_pos_t *resource_type_pos = &pos_srs_resource->resource_type_pos; + NRPPA_ResourceTypePos_t *nrppa_resourceTypePos = &nrppa_pos_srs_resource->resourceTypePos; + if (resource_type_pos->present == NRPPA_RESOURCE_TYPE_POS_PR_NOTHING) { + nrppa_resourceTypePos->present = NRPPA_ResourceTypePos_PR_NOTHING; + } else if (resource_type_pos->present == NRPPA_RESOURCE_TYPE_POS_PR_PERIODIC) { + nrppa_resourceTypePos->present = NRPPA_ResourceTypePos_PR_periodic; + asn1cCalloc(nrppa_resourceTypePos->choice.periodic, nrppa_pos_periodic); + switch (resource_type_pos->choice.periodic.periodicity) { + case NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT1: + nrppa_pos_periodic->periodicity = NRPPA_ResourceTypePeriodicPos__periodicity_slot1; + break; + case NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT2: + nrppa_pos_periodic->periodicity = NRPPA_ResourceTypePeriodicPos__periodicity_slot2; + break; + case NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT4: + nrppa_pos_periodic->periodicity = NRPPA_ResourceTypePeriodicPos__periodicity_slot4; + break; + case NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT5: + nrppa_pos_periodic->periodicity = NRPPA_ResourceTypePeriodicPos__periodicity_slot5; + break; + case NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT8: + nrppa_pos_periodic->periodicity = NRPPA_ResourceTypePeriodicPos__periodicity_slot8; + break; + case NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT10: + nrppa_pos_periodic->periodicity = NRPPA_ResourceTypePeriodicPos__periodicity_slot10; + break; + case NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT16: + nrppa_pos_periodic->periodicity = NRPPA_ResourceTypePeriodicPos__periodicity_slot16; + break; + case NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT20: + nrppa_pos_periodic->periodicity = NRPPA_ResourceTypePeriodicPos__periodicity_slot20; + break; + case NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT32: + nrppa_pos_periodic->periodicity = NRPPA_ResourceTypePeriodicPos__periodicity_slot32; + break; + case NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT40: + nrppa_pos_periodic->periodicity = NRPPA_ResourceTypePeriodicPos__periodicity_slot40; + break; + case NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT64: + nrppa_pos_periodic->periodicity = NRPPA_ResourceTypePeriodicPos__periodicity_slot64; + break; + case NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT80: + nrppa_pos_periodic->periodicity = NRPPA_ResourceTypePeriodicPos__periodicity_slot80; + break; + case NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT160: + nrppa_pos_periodic->periodicity = NRPPA_ResourceTypePeriodicPos__periodicity_slot160; + break; + case NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT320: + nrppa_pos_periodic->periodicity = NRPPA_ResourceTypePeriodicPos__periodicity_slot320; + break; + case NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT640: + nrppa_pos_periodic->periodicity = NRPPA_ResourceTypePeriodicPos__periodicity_slot640; + break; + case NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT1280: + nrppa_pos_periodic->periodicity = NRPPA_ResourceTypePeriodicPos__periodicity_slot1280; + break; + case NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT2560: + nrppa_pos_periodic->periodicity = NRPPA_ResourceTypePeriodicPos__periodicity_slot2560; + break; + case NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT5120: + nrppa_pos_periodic->periodicity = NRPPA_ResourceTypePeriodicPos__periodicity_slot5120; + break; + case NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT10240: + nrppa_pos_periodic->periodicity = NRPPA_ResourceTypePeriodicPos__periodicity_slot10240; + break; + case NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT20480: + nrppa_pos_periodic->periodicity = NRPPA_ResourceTypePeriodicPos__periodicity_slot20480; + break; + case NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT40960: + nrppa_pos_periodic->periodicity = NRPPA_ResourceTypePeriodicPos__periodicity_slot40960; + break; + case NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT81920: + nrppa_pos_periodic->periodicity = NRPPA_ResourceTypePeriodicPos__periodicity_slot81920; + break; + default: + AssertFatal(false, "illegal periodicity %d\n", resource_type_pos->choice.periodic.periodicity); + break; + } + + nrppa_pos_periodic->offset = resource_type_pos->choice.periodic.offset; + } else if (resource_type_pos->present == NRPPA_RESOURCE_TYPE_POS_PR_SEMI_PERSISTENT) { + nrppa_resourceTypePos->present = NRPPA_ResourceTypePos_PR_semi_persistent; + asn1cCalloc(nrppa_resourceTypePos->choice.semi_persistent, nrppa_pos_semi_persistent); + switch (resource_type_pos->choice.semi_persistent.periodicity) { + case NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT1: + nrppa_pos_semi_persistent->periodicity = NRPPA_ResourceTypeSemi_persistentPos__periodicity_slot1; + break; + case NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT2: + nrppa_pos_semi_persistent->periodicity = NRPPA_ResourceTypeSemi_persistentPos__periodicity_slot2; + break; + case NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT4: + nrppa_pos_semi_persistent->periodicity = NRPPA_ResourceTypeSemi_persistentPos__periodicity_slot4; + break; + case NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT5: + nrppa_pos_semi_persistent->periodicity = NRPPA_ResourceTypeSemi_persistentPos__periodicity_slot5; + break; + case NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT8: + nrppa_pos_semi_persistent->periodicity = NRPPA_ResourceTypeSemi_persistentPos__periodicity_slot8; + break; + case NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT10: + nrppa_pos_semi_persistent->periodicity = NRPPA_ResourceTypeSemi_persistentPos__periodicity_slot10; + break; + case NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT16: + nrppa_pos_semi_persistent->periodicity = NRPPA_ResourceTypeSemi_persistentPos__periodicity_slot16; + break; + case NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT20: + nrppa_pos_semi_persistent->periodicity = NRPPA_ResourceTypeSemi_persistentPos__periodicity_slot20; + break; + case NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT32: + nrppa_pos_semi_persistent->periodicity = NRPPA_ResourceTypeSemi_persistentPos__periodicity_slot32; + break; + case NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT40: + nrppa_pos_semi_persistent->periodicity = NRPPA_ResourceTypeSemi_persistentPos__periodicity_slot40; + break; + case NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT64: + nrppa_pos_semi_persistent->periodicity = NRPPA_ResourceTypeSemi_persistentPos__periodicity_slot64; + break; + case NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT80: + nrppa_pos_semi_persistent->periodicity = NRPPA_ResourceTypeSemi_persistentPos__periodicity_slot80; + break; + case NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT160: + nrppa_pos_semi_persistent->periodicity = NRPPA_ResourceTypeSemi_persistentPos__periodicity_slot160; + break; + case NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT320: + nrppa_pos_semi_persistent->periodicity = NRPPA_ResourceTypeSemi_persistentPos__periodicity_slot320; + break; + case NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT640: + nrppa_pos_semi_persistent->periodicity = NRPPA_ResourceTypeSemi_persistentPos__periodicity_slot640; + break; + case NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT1280: + nrppa_pos_semi_persistent->periodicity = NRPPA_ResourceTypeSemi_persistentPos__periodicity_slot1280; + break; + case NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT2560: + nrppa_pos_semi_persistent->periodicity = NRPPA_ResourceTypeSemi_persistentPos__periodicity_slot2560; + break; + case NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT5120: + nrppa_pos_semi_persistent->periodicity = NRPPA_ResourceTypeSemi_persistentPos__periodicity_slot5120; + break; + case NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT10240: + nrppa_pos_semi_persistent->periodicity = NRPPA_ResourceTypeSemi_persistentPos__periodicity_slot10240; + break; + case NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT20480: + nrppa_pos_semi_persistent->periodicity = NRPPA_ResourceTypeSemi_persistentPos__periodicity_slot20480; + break; + case NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT40960: + nrppa_pos_semi_persistent->periodicity = NRPPA_ResourceTypeSemi_persistentPos__periodicity_slot40960; + break; + case NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT81920: + nrppa_pos_semi_persistent->periodicity = NRPPA_ResourceTypeSemi_persistentPos__periodicity_slot81920; + break; + default: + AssertFatal(false, "illegal periodicity %d\n", resource_type_pos->choice.semi_persistent.periodicity); + break; + } + nrppa_pos_semi_persistent->offset = resource_type_pos->choice.semi_persistent.offset; + } else if (resource_type_pos->present == NRPPA_RESOURCE_TYPE_POS_PR_APERIODIC) { + nrppa_resourceTypePos->present = NRPPA_ResourceTypePos_PR_aperiodic; + asn1cCalloc(nrppa_resourceTypePos->choice.aperiodic, nrppa_pos_aperiodic); + nrppa_pos_aperiodic->slotOffset = resource_type_pos->choice.aperiodic.slot_offset; + } else { + AssertFatal(false, "illegal resourceType %d\n", resource_type_pos->present); + } + + nrppa_pos_srs_resource->sequenceId = pos_srs_resource->sequence_id; + } + } + + // optional: srs_resource_set_list + if (in_config->srs_resource_set_list) { + nrppa_srs_resource_set_list_t *srs_resource_set_list = in_config->srs_resource_set_list; + uint32_t srs_resource_set_list_length = srs_resource_set_list->srs_resource_set_list_length; + asn1cCalloc(out_config.sRSResourceSet_List, nrppa_sRSResourceSet_List); + for (int i = 0; i < srs_resource_set_list_length; i++) { + asn1cSequenceAdd(nrppa_sRSResourceSet_List->list, NRPPA_SRSResourceSet_t, nrppa_srs_resource_set); + nrppa_srs_resource_set_t *srs_resource_set = &srs_resource_set_list->srs_resource_set[i]; + nrppa_srs_resource_set->sRSResourceSetID = srs_resource_set->srs_resource_set_id; + uint8_t srs_resource_id_list_length = srs_resource_set->srs_resource_id_list.srs_resource_id_list_length; + for (int j = 0; j < srs_resource_id_list_length; j++) { + asn1cSequenceAdd(nrppa_srs_resource_set->sRSResourceID_List.list, NRPPA_SRSResourceID_t, nrppa_srs_resource_id); + *nrppa_srs_resource_id = srs_resource_set->srs_resource_id_list.srs_resource_id[j]; + } + + NRPPA_ResourceSetType_t *nrppa_resourceSetType = &nrppa_srs_resource_set->resourceSetType; + nrppa_resource_set_type_t *resource_set_type = &srs_resource_set->resource_set_type; + switch (resource_set_type->present) { + case NRPPA_RESOURCE_SET_TYPE_PR_NOTHING: + nrppa_resourceSetType->present = NRPPA_ResourceSetType_PR_NOTHING; + break; + case NRPPA_RESOURCE_SET_TYPE_PR_PERIODIC: + nrppa_resourceSetType->present = NRPPA_ResourceSetType_PR_periodic; + asn1cCalloc(nrppa_resourceSetType->choice.periodic, nrppa_periodic_set_type); + nrppa_periodic_set_type->periodicSet = resource_set_type->choice.periodic; + break; + case NRPPA_RESOURCE_SET_TYPE_PR_SEMI_PERSISTENT: + nrppa_resourceSetType->present = NRPPA_ResourceSetType_PR_semi_persistent; + asn1cCalloc(nrppa_resourceSetType->choice.semi_persistent, nrppa_semi_persistent_set_type); + nrppa_semi_persistent_set_type->semi_persistentSet = resource_set_type->choice.semi_persistent; + break; + case NRPPA_RESOURCE_SET_TYPE_PR_APERIODIC: + nrppa_resourceSetType->present = NRPPA_ResourceSetType_PR_aperiodic; + asn1cCalloc(nrppa_resourceSetType->choice.aperiodic, nrppa_aperiodic_set_type); + nrppa_aperiodic_set_type->sRSResourceTrigger = resource_set_type->choice.aperiodic.srs_resource_trigger; + nrppa_aperiodic_set_type->slotoffset = resource_set_type->choice.aperiodic.slot_offset; + break; + default: + AssertFatal(false, "illegal resource set type %d\n", resource_set_type->present); + break; + } + } + } + + // optional: pos_srs_resource_set_list + if (in_config->pos_srs_resource_set_list) { + nrppa_pos_srs_resource_set_list_t *pos_srs_resource_set_list = in_config->pos_srs_resource_set_list; + uint32_t pos_srs_resource_set_list_length = pos_srs_resource_set_list->pos_srs_resource_set_list_length; + asn1cCalloc(out_config.posSRSResourceSet_List, nrppa_posSRSResourceSet_List); + for (int i = 0; i < pos_srs_resource_set_list_length; i++) { + asn1cSequenceAdd(nrppa_posSRSResourceSet_List->list, NRPPA_PosSRSResourceSet_Item_t, nrppa_pos_srs_resource_set); + nrppa_pos_srs_resource_set_item_t *pos_srs_resource_set = &pos_srs_resource_set_list->pos_srs_resource_set_item[i]; + nrppa_pos_srs_resource_set->possrsResourceSetID = pos_srs_resource_set->pos_srs_resource_set_id; + uint8_t pos_srs_resource_id_list_length = pos_srs_resource_set->pos_srs_resource_id_list.pos_srs_resource_id_list_length; + for (int j = 0; j < pos_srs_resource_id_list_length; j++) { + asn1cSequenceAdd(nrppa_pos_srs_resource_set->possRSResourceID_List.list, + NRPPA_SRSPosResourceID_t, + nrppa_pos_srs_resource_id); + *nrppa_pos_srs_resource_id = pos_srs_resource_set->pos_srs_resource_id_list.srs_pos_resource_id[j]; + } + + NRPPA_PosResourceSetType_t *nrppa_posresourceSetType = &nrppa_pos_srs_resource_set->posresourceSetType; + nrppa_pos_resource_set_type_t *pos_resource_set_type = &pos_srs_resource_set->pos_resource_set_type; + switch (pos_resource_set_type->present) { + case NRPPA_POS_RESOURCE_SET_TYPE_PR_NOTHING: + nrppa_posresourceSetType->present = NRPPA_PosResourceSetType_PR_NOTHING; + break; + case NRPPA_POS_RESOURCE_SET_TYPE_PR_PERIODIC: + nrppa_posresourceSetType->present = NRPPA_PosResourceSetType_PR_periodic; + asn1cCalloc(nrppa_posresourceSetType->choice.periodic, nrppa_pos_periodic_set_type); + nrppa_pos_periodic_set_type->posperiodicSet = pos_resource_set_type->choice.periodic; + break; + case NRPPA_POS_RESOURCE_SET_TYPE_PR_SEMI_PERSISTENT: + nrppa_posresourceSetType->present = NRPPA_PosResourceSetType_PR_semi_persistent; + asn1cCalloc(nrppa_posresourceSetType->choice.semi_persistent, nrppa_pos_semi_persistent_set_type); + nrppa_pos_semi_persistent_set_type->possemi_persistentSet = pos_resource_set_type->choice.semi_persistent; + break; + case NRPPA_POS_RESOURCE_SET_TYPE_PR_APERIODIC: + nrppa_posresourceSetType->present = NRPPA_PosResourceSetType_PR_aperiodic; + asn1cCalloc(nrppa_posresourceSetType->choice.aperiodic, nrppa_pos_aperiodic_set_type); + nrppa_pos_aperiodic_set_type->sRSResourceTrigger = pos_resource_set_type->choice.srs_resource; + break; + default: + AssertFatal(false, "illegal resource set type pos %d\n", pos_resource_set_type->present); + break; + } + } + } + return out_config; +} + +static NRPPA_SRSCarrier_List_Item_t encode_srs_carrier_list_item(const nrppa_srs_carrier_list_item_t *in_item) +{ + NRPPA_SRSCarrier_List_Item_t out_item = {0}; + // pointA + out_item.pointA = in_item->pointA; + + // Uplink Channel BW-PerSCS-List + const nrppa_uplink_channel_bw_per_scs_list_t *uplink_channel_bw_per_scs_list = &in_item->uplink_channel_bw_per_scs_list; + NRPPA_UplinkChannelBW_PerSCS_List_t *nrppa_uplink_channel_bw_per_scs_list = &out_item.uplinkChannelBW_PerSCS_List; + + uint32_t scs_specific_carrier_list_length = uplink_channel_bw_per_scs_list->scs_specific_carrier_list_length; + for (int i = 0; i < scs_specific_carrier_list_length; i++) { + asn1cSequenceAdd(nrppa_uplink_channel_bw_per_scs_list->list, NRPPA_SCS_SpecificCarrier_t, nrppa_scs_specific_carrier); + nrppa_scs_specific_carrier_t *scs_specific_carrier = &uplink_channel_bw_per_scs_list->scs_specific_carrier[i]; + // offset to carrier + nrppa_scs_specific_carrier->offsetToCarrier = scs_specific_carrier->offset_to_carrier; + // subcarrier spacing + switch (scs_specific_carrier->subcarrier_spacing) { + case NRPPA_SUBCARRIER_SPACING_15KHZ: + nrppa_scs_specific_carrier->subcarrierSpacing = NRPPA_SCS_SpecificCarrier__subcarrierSpacing_kHz15; + break; + case NRPPA_SUBCARRIER_SPACING_30KHZ: + nrppa_scs_specific_carrier->subcarrierSpacing = NRPPA_SCS_SpecificCarrier__subcarrierSpacing_kHz30; + break; + case NRPPA_SUBCARRIER_SPACING_60KHZ: + nrppa_scs_specific_carrier->subcarrierSpacing = NRPPA_SCS_SpecificCarrier__subcarrierSpacing_kHz60; + break; + case NRPPA_SUBCARRIER_SPACING_120KHZ: + nrppa_scs_specific_carrier->subcarrierSpacing = NRPPA_SCS_SpecificCarrier__subcarrierSpacing_kHz120; + break; + default: + AssertFatal(false, "illegal subcarrier spacing %d\n", scs_specific_carrier->subcarrier_spacing); + break; + } + // carrier bandwidth + nrppa_scs_specific_carrier->carrierBandwidth = scs_specific_carrier->carrier_bandwidth; + } + + // Active UL BWP + NRPPA_ActiveULBWP_t *nrppa_active_ul_bwp = &out_item.activeULBWP; + const nrppa_active_ul_bwp_t *active_ul_bwp = &in_item->active_ul_bwp; + + // location and bandwidth + nrppa_active_ul_bwp->locationAndBandwidth = active_ul_bwp->location_and_bandwidth; + // subcarrier spacing + switch (active_ul_bwp->subcarrier_spacing) { + case NRPPA_SUBCARRIER_SPACING_15KHZ: + nrppa_active_ul_bwp->subcarrierSpacing = NRPPA_ActiveULBWP__subcarrierSpacing_kHz15; + break; + case NRPPA_SUBCARRIER_SPACING_30KHZ: + nrppa_active_ul_bwp->subcarrierSpacing = NRPPA_ActiveULBWP__subcarrierSpacing_kHz30; + break; + case NRPPA_SUBCARRIER_SPACING_60KHZ: + nrppa_active_ul_bwp->subcarrierSpacing = NRPPA_ActiveULBWP__subcarrierSpacing_kHz60; + break; + case NRPPA_SUBCARRIER_SPACING_120KHZ: + nrppa_active_ul_bwp->subcarrierSpacing = NRPPA_ActiveULBWP__subcarrierSpacing_kHz120; + break; + default: + AssertFatal(false, "illegal subcarrier spacing %d\n", active_ul_bwp->subcarrier_spacing); + break; + } + + // cyclic prefix + if (active_ul_bwp->cyclic_prefix == NRPPA_CP_TYPE_NORMAL) + nrppa_active_ul_bwp->cyclicPrefix = NRPPA_ActiveULBWP__cyclicPrefix_normal; + else + nrppa_active_ul_bwp->cyclicPrefix = NRPPA_ActiveULBWP__cyclicPrefix_extended; + + // Tx Direct Current Location + nrppa_active_ul_bwp->txDirectCurrentLocation = active_ul_bwp->tx_direct_current_location; + + // SRS Config + const nrppa_srs_config_t *sRSConfig = &active_ul_bwp->srs_config; + nrppa_active_ul_bwp->sRSConfig = encode_srs_config(sRSConfig); + return out_item; +} + +NRPPA_SRSCarrier_List_t encode_srs_carrier_list_nrppa(const nrppa_srs_carrier_list_t *in_list) +{ + NRPPA_SRSCarrier_List_t out_list = {0}; + uint32_t list_len = in_list->srs_carrier_list_length; + for (int i = 0; i < list_len; i++) { + asn1cSequenceAdd(out_list.list, NRPPA_SRSCarrier_List_Item_t, out_item); + nrppa_srs_carrier_list_item_t *in_item = &in_list->srs_carrier_list_item[i]; + *out_item = encode_srs_carrier_list_item(in_item); + } + return out_list; +} + +static void free_srs_carrier_list(nrppa_srs_carrier_list_t *srs_carrier_list) +{ + uint32_t srs_carrier_list_len = srs_carrier_list->srs_carrier_list_length; + for (int i = 0; i < srs_carrier_list_len; i++) { + nrppa_srs_carrier_list_item_t *srs_carrier_list_item = &srs_carrier_list->srs_carrier_list_item[i]; + free(srs_carrier_list_item->uplink_channel_bw_per_scs_list.scs_specific_carrier); + + nrppa_active_ul_bwp_t *active_ul_bwp = &srs_carrier_list_item->active_ul_bwp; + nrppa_srs_config_t *sRSConfig = &active_ul_bwp->srs_config; + if (sRSConfig->srs_resource_list) { + nrppa_srs_resource_list_t *srs_resource_list = sRSConfig->srs_resource_list; + free(srs_resource_list->srs_resource); + free(sRSConfig->srs_resource_list); + } + if (sRSConfig->pos_srs_resource_list) { + nrppa_pos_srs_resource_list_t *pos_srs_resource_list = sRSConfig->pos_srs_resource_list; + free(pos_srs_resource_list->pos_srs_resource_item); + free(sRSConfig->pos_srs_resource_list); + } + if (sRSConfig->srs_resource_set_list) { + nrppa_srs_resource_set_list_t *srs_resource_set_list = sRSConfig->srs_resource_set_list; + uint32_t srs_resource_set_list_length = srs_resource_set_list->srs_resource_set_list_length; + for (int j = 0; j < srs_resource_set_list_length; j++) { + nrppa_srs_resource_set_t *srs_resource_set = &srs_resource_set_list->srs_resource_set[j]; + free(srs_resource_set->srs_resource_id_list.srs_resource_id); + } + free(srs_resource_set_list->srs_resource_set); + free(sRSConfig->srs_resource_set_list); + } + if (sRSConfig->pos_srs_resource_set_list) { + nrppa_pos_srs_resource_set_list_t *pos_srs_resource_set_list = sRSConfig->pos_srs_resource_set_list; + uint32_t pos_srs_resource_set_list_length = pos_srs_resource_set_list->pos_srs_resource_set_list_length; + for (int j = 0; j < pos_srs_resource_set_list_length; j++) { + nrppa_pos_srs_resource_set_item_t *pos_srs_resource_set = &pos_srs_resource_set_list->pos_srs_resource_set_item[j]; + free(pos_srs_resource_set->pos_srs_resource_id_list.srs_pos_resource_id); + } + free(pos_srs_resource_set_list->pos_srs_resource_set_item); + free(sRSConfig->pos_srs_resource_set_list); + } + } + free(srs_carrier_list->srs_carrier_list_item); +} + +void free_positioning_information_response(nrppa_positioning_information_resp_t *msg) +{ + /* SRS Configuration (O) */ + if (msg->srs_configuration) { + nrppa_srs_carrier_list_t *srs_carrier_list = &msg->srs_configuration->srs_carrier_list; + free_srs_carrier_list(srs_carrier_list); + free(msg->srs_configuration); + } +} + int nrppa_gNB_handle_trp_information_request(nrppa_gnb_ue_info_t *nrppa_msg_info, const NRPPA_NRPPA_PDU_t *pdu) { LOG_I(NRPPA, "Processing Received TRP Information Request \n"); @@ -442,3 +1164,83 @@ int nrppa_gNB_handle_positioning_information_request(nrppa_gnb_ue_info_t *nrppa_ ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NRPPA_NRPPA_PDU, &pdu); return 0; } + +int nrppa_gNB_positioning_information_response(instance_t instance, MessageDef *msg_p) +{ + DevAssert(msg_p); + nrppa_positioning_information_resp_t *resp = &NRPPA_POSITIONING_INFORMATION_RESP(msg_p); + nrppa_gNB_ue_context_t *ue_info = nrppa_detach_ue_context(resp->transaction_id); + + if (ue_info->gNB_ue_ngap_id <= 0 && ue_info->amf_ue_ngap_id <= 0) { + LOG_E(NRPPA, "Illegal gNB_ue_ngap_id %d and amf_ue_ngap_id %ld\n", ue_info->gNB_ue_ngap_id, ue_info->amf_ue_ngap_id); + free_positioning_information_response(resp); + nrppa_free_ue_context(ue_info); + return -1; + } + + LOG_I(NRPPA, + "Received Positioning Information Response info from RRC with transaction_id = %u and gNB_ue_ngap_id %u\n", + ue_info->transaction_id, + ue_info->gNB_ue_ngap_id); + + // Prepare NRPPA TRP Information transfer Response + NRPPA_NRPPA_PDU_t pdu = {0}; + + // IE: 9.2.3 Message Type : mandatory + pdu.present = NRPPA_NRPPA_PDU_PR_successfulOutcome; + asn1cCalloc(pdu.choice.successfulOutcome, head); + head->procedureCode = NRPPA_ProcedureCode_id_positioningInformationExchange; + head->criticality = NRPPA_Criticality_reject; + head->value.present = NRPPA_SuccessfulOutcome__value_PR_PositioningInformationResponse; + + // IE 9.2.4 nrppatransactionID : mandatory + head->nrppatransactionID = resp->transaction_id; + NRPPA_PositioningInformationResponse_t *out = &head->value.choice.PositioningInformationResponse; + + // IE SRS Configuration : optional + { + if (resp->srs_configuration) { + asn1cSequenceAdd(out->protocolIEs.list, NRPPA_PositioningInformationResponse_IEs_t, ie); + ie->id = NRPPA_ProtocolIE_ID_id_SRSConfiguration; + ie->criticality = NRPPA_Criticality_ignore; + ie->value.present = NRPPA_PositioningInformationResponse_IEs__value_PR_SRSConfiguration; + nrppa_srs_carrier_list_t *srs_carrier_list = &resp->srs_configuration->srs_carrier_list; + ie->value.choice.SRSConfiguration.sRSCarrier_List = encode_srs_carrier_list_nrppa(srs_carrier_list); + } + } + + free_positioning_information_response(resp); + + LOG_I(NRPPA, "Calling encoder for Positioning Information Response \n"); + + if (LOG_DEBUGFLAG(DEBUG_ASN1)) { + xer_fprint(stdout, &asn_DEF_NRPPA_NRPPA_PDU, &pdu); + } + + // Encode NRPPA message + uint8_t *buffer = NULL; + uint32_t length = 0; + if (nrppa_gNB_encode_pdu(&pdu, &buffer, &length) < 0) { + LOG_E(NRPPA, "Failed to encode Uplink NRPPa PositioningInformationResponse\n"); + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NRPPA_NRPPA_PDU, &pdu); + return -1; + } + + MessageDef *msg = itti_alloc_new_message(TASK_NRPPA, 0, NGAP_UPLINKUEASSOCIATEDNRPPA); + ngap_uplink_ue_associated_nrppa_t *ULNRPPA = &NGAP_UPLINKUEASSOCIATEDNRPPA(msg); + + ULNRPPA->gNB_ue_ngap_id = ue_info->gNB_ue_ngap_id; + ULNRPPA->amf_ue_ngap_id = ue_info->amf_ue_ngap_id; + + // Routing ID + ULNRPPA->routing_id = create_byte_array(ue_info->routing_id.len, ue_info->routing_id.buf); + + // NRPPA PDU + ULNRPPA->nrppa_pdu = create_byte_array(length, buffer); + + // Forward the NRPPA PDU to NGAP + itti_send_msg_to_task(TASK_NGAP, instance, msg); + nrppa_free_ue_context(ue_info); + free(buffer); + return length; +} diff --git a/openair3/NRPPA/nrppa_gNB_location_information_transfer.h b/openair3/NRPPA/nrppa_gNB_location_information_transfer.h index 5fbd697c07..31ab194345 100644 --- a/openair3/NRPPA/nrppa_gNB_location_information_transfer.h +++ b/openair3/NRPPA/nrppa_gNB_location_information_transfer.h @@ -29,5 +29,8 @@ void free_trp_information_request(nrppa_trp_information_req_t *msg); NRPPA_TRPInformationItem_t encode_trp_info_type_response_item_nrppa(nrppa_trp_information_type_response_item_t *in); void free_trp_information_response(nrppa_trp_information_resp_t *msg); int nrppa_gNB_handle_positioning_information_request(nrppa_gnb_ue_info_t *nrppa_msg_info, const NRPPA_NRPPA_PDU_t *pdu); +int nrppa_gNB_positioning_information_response(instance_t instance, MessageDef *msg_p); +NRPPA_SRSCarrier_List_t encode_srs_carrier_list_nrppa(const nrppa_srs_carrier_list_t *in_list); +void free_positioning_information_response(nrppa_positioning_information_resp_t *msg); #endif /* NRPPA_GNB_POSITIONING_PROCEDURES_H_ */ diff --git a/openair3/NRPPA/nrppa_includes.h b/openair3/NRPPA/nrppa_includes.h index 63bb3fe248..6915b93370 100644 --- a/openair3/NRPPA/nrppa_includes.h +++ b/openair3/NRPPA/nrppa_includes.h @@ -42,5 +42,32 @@ #include "NRPPA_TRPPositionReferenced.h" #include "NRPPA_RelativeGeodeticLocation.h" #include "NRPPA_RelativeCartesianLocation.h" +#include "NRPPA_SRSCarrier-List-Item.h" +#include "NRPPA_SCS-SpecificCarrier.h" +#include "NRPPA_SRSConfig.h" +#include "NRPPA_SRSResource-List.h" +#include "NRPPA_SRSResource.h" +#include "NRPPA_ResourceType.h" +#include "NRPPA_ResourceTypePeriodic.h" +#include "NRPPA_ResourceTypeSemi-persistent.h" +#include "NRPPA_ResourceTypeAperiodic.h" +#include "NRPPA_PosSRSResource-List.h" +#include "NRPPA_ResourceTypePos.h" +#include "NRPPA_ResourceTypePeriodicPos.h" +#include "NRPPA_ResourceTypeSemi-persistentPos.h" +#include "NRPPA_ResourceTypeAperiodicPos.h" +#include "NRPPA_SRSResourceSet-List.h" +#include "NRPPA_SRSResourceSet.h" +#include "NRPPA_PosSRSResource-List.h" +#include "NRPPA_PosSRSResourceSet-Item.h" +#include "NRPPA_PosSRSResource-List.h" +#include "NRPPA_PosSRSResource-Item.h" +#include "NRPPA_ResourceSetTypePeriodic.h" +#include "NRPPA_ResourceSetTypeSemi-persistent.h" +#include "NRPPA_ResourceSetTypeAperiodic.h" +#include "NRPPA_PosSRSResourceSet-List.h" +#include "NRPPA_PosResourceSetTypePeriodic.h" +#include "NRPPA_PosResourceSetTypeSemi-persistent.h" +#include "NRPPA_PosResourceSetTypeAperiodic.h" #endif /* NRPPA_INCLUDE_H_ */ diff --git a/tests/nr-cu-nrppa/nr-cu-nrppa.c b/tests/nr-cu-nrppa/nr-cu-nrppa.c index aad8855797..ca47199133 100644 --- a/tests/nr-cu-nrppa/nr-cu-nrppa.c +++ b/tests/nr-cu-nrppa/nr-cu-nrppa.c @@ -148,6 +148,289 @@ static nrppa_trp_information_resp_t fill_trp_resp(uint8_t transaction_id) return resp; } +static nrppa_positioning_information_resp_t fill_position_information_resp(uint16_t transaction_id) +{ + nrppa_positioning_information_resp_t resp = {0}; + resp.transaction_id = transaction_id; + resp.srs_configuration = calloc_or_fail(1, sizeof(*resp.srs_configuration)); + nrppa_srs_carrier_list_t *srs_carrier_list = &resp.srs_configuration->srs_carrier_list; + uint32_t srs_carrier_list_len = 2; + srs_carrier_list->srs_carrier_list_length = srs_carrier_list_len; + srs_carrier_list->srs_carrier_list_item = calloc_or_fail(srs_carrier_list_len, sizeof(*srs_carrier_list->srs_carrier_list_item)); + for (int i = 0; i < srs_carrier_list_len; i++) { + nrppa_srs_carrier_list_item_t *srs_carrier_list_item = &srs_carrier_list->srs_carrier_list_item[i]; + // pointA + srs_carrier_list_item->pointA = 87641 + i; + + // Uplink Channel BW-PerSCS-List + nrppa_uplink_channel_bw_per_scs_list_t *uplink_channel_bw_per_scs_list = &srs_carrier_list_item->uplink_channel_bw_per_scs_list; + + uint32_t scs_specific_carrier_list_length = 3; + uplink_channel_bw_per_scs_list->scs_specific_carrier_list_length = scs_specific_carrier_list_length; + uplink_channel_bw_per_scs_list->scs_specific_carrier = + calloc_or_fail(scs_specific_carrier_list_length, sizeof(*uplink_channel_bw_per_scs_list->scs_specific_carrier)); + for (int j = 0; j < scs_specific_carrier_list_length; j++) { + nrppa_scs_specific_carrier_t *scs_specific_carrier = &uplink_channel_bw_per_scs_list->scs_specific_carrier[j]; + // offset to carrier + scs_specific_carrier->offset_to_carrier = 100 + i + j; + // subcarrier spacing + scs_specific_carrier->subcarrier_spacing = NRPPA_SUBCARRIER_SPACING_30KHZ; + // carrier bandwidth + scs_specific_carrier->carrier_bandwidth = 106 + i + j; + } + + // Active UL BWP + nrppa_active_ul_bwp_t *active_ul_bwp = &srs_carrier_list_item->active_ul_bwp; + + // location and bandwidth + active_ul_bwp->location_and_bandwidth = 2775 + i; + // subcarrier spacing + active_ul_bwp->subcarrier_spacing = NRPPA_SUBCARRIER_SPACING_30KHZ; + // cyclic prefix + active_ul_bwp->cyclic_prefix = NRPPA_CP_TYPE_NORMAL; + // Tx Direct Current Location + active_ul_bwp->tx_direct_current_location = 10 + i; + + // SRS Config + nrppa_srs_config_t *sRSConfig = &active_ul_bwp->srs_config; + + // srs_resource_list + sRSConfig->srs_resource_list = calloc_or_fail(1, sizeof(*sRSConfig->srs_resource_list)); + nrppa_srs_resource_list_t *srs_resource_list = sRSConfig->srs_resource_list; + uint32_t srs_resource_list_length = 3; + srs_resource_list->srs_resource_list_length = srs_resource_list_length; + srs_resource_list->srs_resource = calloc_or_fail(srs_resource_list_length, sizeof(*srs_resource_list->srs_resource)); + + // SRS resource config 1 : periodic + nrppa_srs_resource_t *srs_resource = &srs_resource_list->srs_resource[0]; + srs_resource->srs_resource_id = 22; + srs_resource->nr_of_srs_ports = NRPPA_SRS_NUMBER_OF_PORTS_N2; + srs_resource->transmission_comb.present = NRPPA_TRANSMISSION_COMB_PR_N2; + srs_resource->transmission_comb.choice.n2.comb_offset_n2 = 1; + srs_resource->transmission_comb.choice.n2.cyclic_shift_n2 = 3; + srs_resource->start_position = 8; + srs_resource->nr_of_symbols = NRPPA_SRS_NUMBER_OF_SYMBOLS_N4; + srs_resource->repetition_factor = NRPPA_SRS_REPETITION_FACTOR_RF2; + srs_resource->freq_domain_position = 32; + srs_resource->freq_domain_shift = 108; + srs_resource->c_srs = 31; + srs_resource->b_srs = 1; + srs_resource->b_hop = 3; + srs_resource->group_or_sequence_hopping = NRPPA_GROUPORSEQUENCEHOPPING_GROUPHOPPING; + srs_resource->resource_type.present = NRPPA_RESOURCE_TYPE_PR_PERIODIC; + + nrppa_resource_type_periodic_t *periodic = &srs_resource->resource_type.choice.periodic; + periodic->periodicity = NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT16; + periodic->offset = 1000; + srs_resource->sequence_id = 18; + + // SRS resource config 2 : semi-persistent + srs_resource = &srs_resource_list->srs_resource[1]; + srs_resource->srs_resource_id = 24; + srs_resource->nr_of_srs_ports = NRPPA_SRS_NUMBER_OF_PORTS_N4; + srs_resource->transmission_comb.present = NRPPA_TRANSMISSION_COMB_PR_N4; + srs_resource->transmission_comb.choice.n2.comb_offset_n2 = 3; + srs_resource->transmission_comb.choice.n2.cyclic_shift_n2 = 5; + srs_resource->start_position = 8; + srs_resource->nr_of_symbols = NRPPA_SRS_NUMBER_OF_SYMBOLS_N2; + srs_resource->repetition_factor = NRPPA_SRS_REPETITION_FACTOR_RF2; + srs_resource->freq_domain_position = 32; + srs_resource->freq_domain_shift = 108; + srs_resource->c_srs = 31; + srs_resource->b_srs = 1; + srs_resource->b_hop = 3; + srs_resource->group_or_sequence_hopping = NRPPA_GROUPORSEQUENCEHOPPING_GROUPHOPPING; + srs_resource->resource_type.present = NRPPA_RESOURCE_TYPE_PR_SEMI_PERSISTENT; + + srs_resource->resource_type.present = NRPPA_RESOURCE_TYPE_PR_SEMI_PERSISTENT; + nrppa_resource_type_semi_persistent_t *semi_persistent = &srs_resource->resource_type.choice.semi_persistent; + semi_persistent->periodicity = NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT40; + semi_persistent->offset = 1000; + srs_resource->sequence_id = 12; + + // SRS resource config 2 : aperiodic + srs_resource = &srs_resource_list->srs_resource[2]; + srs_resource->srs_resource_id = 26; + srs_resource->nr_of_srs_ports = NRPPA_SRS_NUMBER_OF_PORTS_N2; + srs_resource->transmission_comb.present = NRPPA_TRANSMISSION_COMB_PR_N2; + srs_resource->transmission_comb.choice.n2.comb_offset_n2 = 1; + srs_resource->transmission_comb.choice.n2.cyclic_shift_n2 = 3; + srs_resource->start_position = 8; + srs_resource->nr_of_symbols = NRPPA_SRS_NUMBER_OF_SYMBOLS_N4; + srs_resource->repetition_factor = NRPPA_SRS_REPETITION_FACTOR_RF2; + srs_resource->freq_domain_position = 32; + srs_resource->freq_domain_shift = 108; + srs_resource->c_srs = 31; + srs_resource->b_srs = 1; + srs_resource->b_hop = 3; + srs_resource->group_or_sequence_hopping = NRPPA_GROUPORSEQUENCEHOPPING_SEQUENCEHOPPING; + srs_resource->resource_type.present = NRPPA_RESOURCE_TYPE_PR_APERIODIC; + // set aperiodic = 0 to enable + srs_resource->resource_type.choice.aperiodic = 0; + srs_resource->sequence_id = 10; + + // optional: pos_srs_resource_list + sRSConfig->pos_srs_resource_list = calloc_or_fail(1, sizeof(*sRSConfig->pos_srs_resource_list)); + nrppa_pos_srs_resource_list_t *pos_srs_resource_list = sRSConfig->pos_srs_resource_list; + uint32_t pos_srs_resource_list_length = 3; + pos_srs_resource_list->pos_srs_resource_list_length = pos_srs_resource_list_length; + pos_srs_resource_list->pos_srs_resource_item = + calloc_or_fail(pos_srs_resource_list_length, sizeof(*pos_srs_resource_list->pos_srs_resource_item)); + + // periodic + nrppa_pos_srs_resource_item_t *pos_srs_resource = &pos_srs_resource_list->pos_srs_resource_item[0]; + pos_srs_resource->srs_pos_resource_id = 12; + pos_srs_resource->transmission_comb_pos.present = NRPPA_TRANSMISSION_COMB_POS_PR_N2; + pos_srs_resource->transmission_comb_pos.choice.n2.comb_offset_n2 = 1; + pos_srs_resource->transmission_comb_pos.choice.n2.cyclic_shift_n2 = 4; + pos_srs_resource->start_position = 9; + pos_srs_resource->nr_of_symbols = NRPPA_SRS_RESOURCE_ITEM_NUMBER_OF_SYMBOLS_N8; + pos_srs_resource->freq_domain_shift = 100; + pos_srs_resource->c_srs = 20; + pos_srs_resource->group_or_sequence_hopping = NRPPA_GROUPORSEQUENCEHOPPING_GROUPHOPPING; + pos_srs_resource->resource_type_pos.present = NRPPA_RESOURCE_TYPE_POS_PR_PERIODIC; + pos_srs_resource->resource_type_pos.choice.periodic.periodicity = NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT5; + pos_srs_resource->resource_type_pos.choice.periodic.offset = 10; + pos_srs_resource->sequence_id = 1; + + // semi-persistent + pos_srs_resource = &pos_srs_resource_list->pos_srs_resource_item[1]; + pos_srs_resource->srs_pos_resource_id = 13; + pos_srs_resource->transmission_comb_pos.present = NRPPA_TRANSMISSION_COMB_POS_PR_N4; + pos_srs_resource->transmission_comb_pos.choice.n4.comb_offset_n4 = 3; + pos_srs_resource->transmission_comb_pos.choice.n4.cyclic_shift_n4 = 5; + pos_srs_resource->start_position = 12; + pos_srs_resource->nr_of_symbols = NRPPA_SRS_RESOURCE_ITEM_NUMBER_OF_SYMBOLS_N12; + pos_srs_resource->freq_domain_shift = 100; + pos_srs_resource->c_srs = 20; + pos_srs_resource->group_or_sequence_hopping = NRPPA_GROUPORSEQUENCEHOPPING_GROUPHOPPING; + pos_srs_resource->resource_type_pos.present = NRPPA_RESOURCE_TYPE_POS_PR_SEMI_PERSISTENT; + pos_srs_resource->resource_type_pos.choice.semi_persistent.periodicity = NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT32; + pos_srs_resource->resource_type_pos.choice.semi_persistent.offset = 5; + pos_srs_resource->sequence_id = 2; + + // aperiodic + pos_srs_resource = &pos_srs_resource_list->pos_srs_resource_item[2]; + pos_srs_resource->srs_pos_resource_id = 14; + pos_srs_resource->transmission_comb_pos.present = NRPPA_TRANSMISSION_COMB_POS_PR_N8; + pos_srs_resource->transmission_comb_pos.choice.n8.comb_offset_n8 = 5; + pos_srs_resource->transmission_comb_pos.choice.n8.cyclic_shift_n8 = 2; + pos_srs_resource->start_position = 9; + pos_srs_resource->nr_of_symbols = NRPPA_SRS_RESOURCE_ITEM_NUMBER_OF_SYMBOLS_N4; + pos_srs_resource->freq_domain_shift = 100; + pos_srs_resource->c_srs = 20; + pos_srs_resource->group_or_sequence_hopping = NRPPA_GROUPORSEQUENCEHOPPING_SEQUENCEHOPPING; + pos_srs_resource->resource_type_pos.present = NRPPA_RESOURCE_TYPE_POS_PR_APERIODIC; + pos_srs_resource->resource_type_pos.choice.periodic.periodicity = NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT5; + pos_srs_resource->resource_type_pos.choice.aperiodic.slot_offset = 31; + pos_srs_resource->sequence_id = 3; + + // optional: srs_resource_set_list + sRSConfig->srs_resource_set_list = calloc_or_fail(1, sizeof(*sRSConfig->srs_resource_set_list)); + nrppa_srs_resource_set_list_t *srs_resource_set_list = sRSConfig->srs_resource_set_list; + uint32_t srs_resource_set_list_length = 3; + srs_resource_set_list->srs_resource_set_list_length = srs_resource_set_list_length; + srs_resource_set_list->srs_resource_set = + calloc_or_fail(srs_resource_set_list_length, sizeof(*srs_resource_set_list->srs_resource_set)); + + // periodic + nrppa_srs_resource_set_t *srs_resource_set = &srs_resource_set_list->srs_resource_set[0]; + srs_resource_set->srs_resource_set_id = 0; + uint8_t srs_resource_id_list_length = 5; + srs_resource_set->srs_resource_id_list.srs_resource_id_list_length = srs_resource_id_list_length; + srs_resource_set->srs_resource_id_list.srs_resource_id = + calloc_or_fail(srs_resource_id_list_length, sizeof(*srs_resource_set->srs_resource_id_list.srs_resource_id)); + for (int k = 0; k < srs_resource_id_list_length; k++) { + srs_resource_set->srs_resource_id_list.srs_resource_id[k] = k; + } + srs_resource_set->resource_set_type.present = NRPPA_RESOURCE_SET_TYPE_PR_PERIODIC; + // set periodic = 0 to enable + srs_resource_set->resource_set_type.choice.periodic = 0; + + // semi-persistent + srs_resource_set = &srs_resource_set_list->srs_resource_set[1]; + srs_resource_set->srs_resource_set_id = 1; + srs_resource_id_list_length = 5; + srs_resource_set->srs_resource_id_list.srs_resource_id_list_length = srs_resource_id_list_length; + srs_resource_set->srs_resource_id_list.srs_resource_id = + calloc_or_fail(srs_resource_id_list_length, sizeof(srs_resource_set->srs_resource_id_list.srs_resource_id)); + for (int k = 0; k < srs_resource_id_list_length; k++) { + srs_resource_set->srs_resource_id_list.srs_resource_id[k] = k; + } + srs_resource_set->resource_set_type.present = NRPPA_RESOURCE_SET_TYPE_PR_SEMI_PERSISTENT; + // set semi_persistent = 0 to enable + srs_resource_set->resource_set_type.choice.semi_persistent = 0; + + // aperiodic + srs_resource_set = &srs_resource_set_list->srs_resource_set[2]; + srs_resource_set->srs_resource_set_id = 2; + srs_resource_id_list_length = 5; + srs_resource_set->srs_resource_id_list.srs_resource_id_list_length = srs_resource_id_list_length; + srs_resource_set->srs_resource_id_list.srs_resource_id = + calloc_or_fail(srs_resource_id_list_length, sizeof(*srs_resource_set->srs_resource_id_list.srs_resource_id)); + for (int k = 0; k < srs_resource_id_list_length; k++) { + srs_resource_set->srs_resource_id_list.srs_resource_id[k] = k; + } + + srs_resource_set->resource_set_type.present = NRPPA_RESOURCE_SET_TYPE_PR_APERIODIC; + srs_resource_set->resource_set_type.choice.aperiodic.srs_resource_trigger = 2; + srs_resource_set->resource_set_type.choice.aperiodic.slot_offset = 20; + + // optional: pos_srs_resource_set_list + sRSConfig->pos_srs_resource_set_list = calloc_or_fail(1, sizeof(*sRSConfig->pos_srs_resource_set_list)); + nrppa_pos_srs_resource_set_list_t *pos_srs_resource_set_list = sRSConfig->pos_srs_resource_set_list; + uint32_t pos_srs_resource_set_list_length = 3; + pos_srs_resource_set_list->pos_srs_resource_set_list_length = pos_srs_resource_set_list_length; + pos_srs_resource_set_list->pos_srs_resource_set_item = + calloc_or_fail(pos_srs_resource_set_list_length, sizeof(*pos_srs_resource_set_list->pos_srs_resource_set_item)); + + // periodic + nrppa_pos_srs_resource_set_item_t *pos_srs_resource_set = &pos_srs_resource_set_list->pos_srs_resource_set_item[0]; + pos_srs_resource_set->pos_srs_resource_set_id = 0; + uint8_t pos_srs_resource_id_list_length = 5; + pos_srs_resource_set->pos_srs_resource_id_list.pos_srs_resource_id_list_length = pos_srs_resource_id_list_length; + pos_srs_resource_set->pos_srs_resource_id_list.srs_pos_resource_id = + calloc_or_fail(pos_srs_resource_id_list_length, + sizeof(*pos_srs_resource_set->pos_srs_resource_id_list.srs_pos_resource_id)); + for (int k = 0; k < pos_srs_resource_id_list_length; k++) { + pos_srs_resource_set->pos_srs_resource_id_list.srs_pos_resource_id[k] = k; + } + pos_srs_resource_set->pos_resource_set_type.present = NRPPA_POS_RESOURCE_SET_TYPE_PR_PERIODIC; + // set periodic = 0 to enable + pos_srs_resource_set->pos_resource_set_type.choice.periodic = 0; + + // semi-persistent + pos_srs_resource_set = &pos_srs_resource_set_list->pos_srs_resource_set_item[1]; + pos_srs_resource_set->pos_srs_resource_set_id = 1; + pos_srs_resource_id_list_length = 5; + pos_srs_resource_set->pos_srs_resource_id_list.pos_srs_resource_id_list_length = pos_srs_resource_id_list_length; + pos_srs_resource_set->pos_srs_resource_id_list.srs_pos_resource_id = + calloc_or_fail(pos_srs_resource_id_list_length, + sizeof(*pos_srs_resource_set->pos_srs_resource_id_list.srs_pos_resource_id)); + for (int k = 0; k < pos_srs_resource_id_list_length; k++) { + pos_srs_resource_set->pos_srs_resource_id_list.srs_pos_resource_id[k] = k; + } + pos_srs_resource_set->pos_resource_set_type.present = NRPPA_POS_RESOURCE_SET_TYPE_PR_SEMI_PERSISTENT; + // set semi_persistent = 0 to enable + pos_srs_resource_set->pos_resource_set_type.choice.semi_persistent = 0; + + // aperiodic + pos_srs_resource_set = &pos_srs_resource_set_list->pos_srs_resource_set_item[2]; + pos_srs_resource_set->pos_srs_resource_set_id = 2; + pos_srs_resource_id_list_length = 5; + pos_srs_resource_set->pos_srs_resource_id_list.pos_srs_resource_id_list_length = pos_srs_resource_id_list_length; + pos_srs_resource_set->pos_srs_resource_id_list.srs_pos_resource_id = + calloc_or_fail(pos_srs_resource_id_list_length, + sizeof(*pos_srs_resource_set->pos_srs_resource_id_list.srs_pos_resource_id)); + for (int k = 0; k < pos_srs_resource_id_list_length; k++) { + pos_srs_resource_set->pos_srs_resource_id_list.srs_pos_resource_id[k] = k; + } + pos_srs_resource_set->pos_resource_set_type.present = NRPPA_POS_RESOURCE_SET_TYPE_PR_APERIODIC; + pos_srs_resource_set->pos_resource_set_type.choice.srs_resource = 3; + } + return resp; +} + // Initializing UE NAS Context with simulated SIM data nr_ue_nas_t *simulated_ue_nas = NULL; void init_ue_nas_context(void) @@ -288,6 +571,14 @@ void *rrc_gnb_task(void *args_p) LOG_I(NR_RRC, "Sending NRPPA_TRP_INFORMATION_RESP to TASK_NRPPA\n"); itti_send_msg_to_task(TASK_NRPPA, 0, msg_p_resp); break; + case NRPPA_POSITIONING_INFORMATION_REQ: + nrppa_positioning_information_req_t *pos_req = &NRPPA_POSITIONING_INFORMATION_REQ(msg_p); + LOG_I(NR_RRC, "Received NRPPA_POSITIONING_INFORMATION_REQ transaction_id %d\n", pos_req->transaction_id); + msg_p_resp = itti_alloc_new_message(TASK_RRC_GNB, 0, NRPPA_POSITIONING_INFORMATION_RESP); + NRPPA_POSITIONING_INFORMATION_RESP(msg_p_resp) = fill_position_information_resp(pos_req->transaction_id); + LOG_I(NR_RRC, "Sending NRPPA_POSITIONING_INFORMATION_RESP to TASK_NRPPA\n"); + itti_send_msg_to_task(TASK_NRPPA, 0, msg_p_resp); + break; default: LOG_E(NR_RRC, "[gNB %ld] Received unexpected message %s\n", instance, msg_name_p); break; From defafa8d24c435305bf27d0762083dd4a2284fbe Mon Sep 17 00:00:00 2001 From: Rakesh Mundlamuri Date: Fri, 23 Jan 2026 18:48:15 +0530 Subject: [PATCH 27/44] Add Positioning Activation Request NRPPA message decoding procedures --- openair2/COMMON/nrppa_messages_def.h | 4 ++ openair2/COMMON/nrppa_messages_types.h | 24 +++++++ openair3/NRPPA/nrppa_gNB_decoder.c | 6 +- openair3/NRPPA/nrppa_gNB_handlers.c | 4 +- .../nrppa_gNB_location_information_transfer.c | 68 +++++++++++++++++++ .../nrppa_gNB_location_information_transfer.h | 3 + openair3/NRPPA/nrppa_includes.h | 2 + 7 files changed, 109 insertions(+), 2 deletions(-) diff --git a/openair2/COMMON/nrppa_messages_def.h b/openair2/COMMON/nrppa_messages_def.h index d20bf1960a..bb5d534856 100644 --- a/openair2/COMMON/nrppa_messages_def.h +++ b/openair2/COMMON/nrppa_messages_def.h @@ -32,3 +32,7 @@ MESSAGE_DEF(NRPPA_POSITIONING_INFORMATION_RESP, MESSAGE_PRIORITY_MED, nrppa_positioning_information_resp_t, nrppa_positioning_information_resp) +MESSAGE_DEF(NRPPA_POSITIONING_ACTIVATION_REQ, + MESSAGE_PRIORITY_MED, + nrppa_positioning_activation_req_t, + nrppa_positioning_activation_req) diff --git a/openair2/COMMON/nrppa_messages_types.h b/openair2/COMMON/nrppa_messages_types.h index 4522604422..077c5a89b0 100644 --- a/openair2/COMMON/nrppa_messages_types.h +++ b/openair2/COMMON/nrppa_messages_types.h @@ -28,6 +28,7 @@ #define NRPPA_TRP_INFORMATION_RESP(mSGpTR) (mSGpTR)->ittiMsg.nrppa_trp_information_resp #define NRPPA_POSITIONING_INFORMATION_REQ(mSGpTR) (mSGpTR)->ittiMsg.nrppa_positioning_information_req #define NRPPA_POSITIONING_INFORMATION_RESP(mSGpTR) (mSGpTR)->ittiMsg.nrppa_positioning_information_resp +#define NRPPA_POSITIONING_ACTIVATION_REQ(mSGpTR) (mSGpTR)->ittiMsg.nrppa_positioning_activation_req /* Structure of Positioning related NRPPA messages */ /* IE structures for Positioning related messages as per TS 38.455 V16.7.1*/ @@ -570,6 +571,22 @@ typedef struct nrppa_trp_information_list_s { uint32_t trp_information_item_length; } nrppa_trp_information_list_t; +typedef union nrppa_srs_type_c { + uint8_t *srs_resource_set_id; + bool *aperiodic; +} nrppa_srs_type_u; + +typedef enum nrppa_srs_type_e { + NRPPA_SRS_TYPE_PR_NOTHING, + NRPPA_SRS_TYPE_PR_SEMIPERSISTENTSRS, + NRPPA_SRS_TYPE_PR_APERIODICSRS +} nrppa_srs_type_pr; + +typedef struct nrppa_srs_type_s { + nrppa_srs_type_pr present; + nrppa_srs_type_u choice; +} nrppa_srs_type_t; + typedef struct nrppa_trp_information_req_s { // IE 9.2.4 (mandatory) uint16_t transaction_id; @@ -599,4 +616,11 @@ typedef struct nrppa_positioning_information_resp_s { nrppa_srs_configuration_t *srs_configuration; } nrppa_positioning_information_resp_t; +typedef struct nrppa_positioning_activation_req_s { + // IE 9.2.4 (mandatory) + uint16_t transaction_id; + // (mandatory) + nrppa_srs_type_t srs_type; +} nrppa_positioning_activation_req_t; + #endif // NRPPA_MESSAGES_TYPES_H_ diff --git a/openair3/NRPPA/nrppa_gNB_decoder.c b/openair3/NRPPA/nrppa_gNB_decoder.c index 94524fd060..340ff63baa 100644 --- a/openair3/NRPPA/nrppa_gNB_decoder.c +++ b/openair3/NRPPA/nrppa_gNB_decoder.c @@ -40,7 +40,11 @@ static int nrppa_gNB_decode_initiating_message(NRPPA_NRPPA_PDU_t *pdu) LOG_I(NRPPA, "Positioning Information Request initiating message\n"); free(res.buffer); break; - + case NRPPA_ProcedureCode_id_positioningActivation: + res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_NRPPA_NRPPA_PDU, pdu); + LOG_I(NRPPA, "Positioning Activation initiating message\n"); + free(res.buffer); + break; default: AssertFatal(false, "Unknown procedure ID (%d) for initiating message\n", (int)pdu->choice.initiatingMessage->procedureCode); return -1; diff --git a/openair3/NRPPA/nrppa_gNB_handlers.c b/openair3/NRPPA/nrppa_gNB_handlers.c index 99299ecb64..4689351b11 100644 --- a/openair3/NRPPA/nrppa_gNB_handlers.c +++ b/openair3/NRPPA/nrppa_gNB_handlers.c @@ -57,7 +57,9 @@ nrppa_message_decoded_callback nrppa_messages_callback[][3] = { {0, 0, 0}, // NRPPA_ProcedureCode_id_MeasurementAbort ((NRPPA_ProcedureCode_t)14) {0, 0, 0}, // NRPPA_ProcedureCode_id_MeasurementFailureIndication ((NRPPA_ProcedureCode_t)15) {nrppa_gNB_handle_trp_information_request, 0, 0}, // NRPPA_ProcedureCode_id_tRPInformationExchange ((NRPPA_ProcedureCode_t)16) - {0, 0, 0}, // NRPPA_ProcedureCode_id_positioningActivation ((NRPPA_ProcedureCode_t)17) + {nrppa_gNB_handle_positioning_activation_request, + 0, + 0}, // NRPPA_ProcedureCode_id_positioningActivation ((NRPPA_ProcedureCode_t)17) {0, 0, 0}, // NRPPA_ProcedureCode_id_positioningDeactivation ((NRPPA_ProcedureCode_t)18) }; diff --git a/openair3/NRPPA/nrppa_gNB_location_information_transfer.c b/openair3/NRPPA/nrppa_gNB_location_information_transfer.c index 5d1a43c0a6..dfaa7f1efc 100644 --- a/openair3/NRPPA/nrppa_gNB_location_information_transfer.c +++ b/openair3/NRPPA/nrppa_gNB_location_information_transfer.c @@ -985,6 +985,37 @@ void free_positioning_information_response(nrppa_positioning_information_resp_t } } +void decode_nrppa_srstype(NRPPA_SRSType_t *srs_type, nrppa_srs_type_t *out) +{ + switch (srs_type->present) { + case NRPPA_SRSType_PR_NOTHING: + out->present = NRPPA_SRS_TYPE_PR_NOTHING; + break; + case NRPPA_SRSType_PR_semipersistentSRS: + out->present = NRPPA_SRS_TYPE_PR_SEMIPERSISTENTSRS; + out->choice.srs_resource_set_id = calloc_or_fail(1, sizeof(*out->choice.srs_resource_set_id)); + *out->choice.srs_resource_set_id = srs_type->choice.semipersistentSRS->sRSResourceSetID; + break; + case NRPPA_SRSType_PR_aperiodicSRS: + out->present = NRPPA_SRS_TYPE_PR_APERIODICSRS; + out->choice.aperiodic = calloc_or_fail(1, sizeof(*out->choice.aperiodic)); + *out->choice.aperiodic = srs_type->choice.aperiodicSRS->aperiodic; + break; + default: + AssertFatal(false, "received illegal SRS type\n"); + break; + } +} + +void free_positioning_activation_request(nrppa_positioning_activation_req_t *msg) +{ + if (msg->srs_type.present == NRPPA_SRS_TYPE_PR_SEMIPERSISTENTSRS) { + free(msg->srs_type.choice.srs_resource_set_id); + } else if (msg->srs_type.present == NRPPA_SRS_TYPE_PR_APERIODICSRS) { + free(msg->srs_type.choice.aperiodic); + } +} + int nrppa_gNB_handle_trp_information_request(nrppa_gnb_ue_info_t *nrppa_msg_info, const NRPPA_NRPPA_PDU_t *pdu) { LOG_I(NRPPA, "Processing Received TRP Information Request \n"); @@ -1244,3 +1275,40 @@ int nrppa_gNB_positioning_information_response(instance_t instance, MessageDef * free(buffer); return length; } + +int nrppa_gNB_handle_positioning_activation_request(nrppa_gnb_ue_info_t *nrppa_msg_info, const NRPPA_NRPPA_PDU_t *pdu) +{ + LOG_I(NRPPA, "Processing Received Positioning Activation Request \n"); + DevAssert(pdu != NULL); + DevAssert(nrppa_msg_info != NULL); + + if (LOG_DEBUGFLAG(DEBUG_ASN1)) { + xer_fprint(stdout, &asn_DEF_NRPPA_NRPPA_PDU, pdu); + } + + // Preparing positioning information request for RRC + MessageDef *msg = itti_alloc_new_message(TASK_RRC_GNB, 0, NRPPA_POSITIONING_ACTIVATION_REQ); + nrppa_positioning_activation_req_t *req = &NRPPA_POSITIONING_ACTIVATION_REQ(msg); + + // Processing Received PositioningActivationRequest + NRPPA_PositioningActivationRequest_t *container = NULL; + NRPPA_PositioningActivationRequestIEs_t *ie = NULL; + + // IE 9.2.3 Message type : mandatory + container = &pdu->choice.initiatingMessage->value.choice.PositioningActivationRequest; + + // IE 9.2.4 nrppatransactionID : mandatory + req->transaction_id = pdu->choice.initiatingMessage->nrppatransactionID; + + // IE SRSType : mandatory + NRPPA_FIND_PROTOCOLIE_BY_ID(NRPPA_PositioningActivationRequestIEs_t, ie, container, NRPPA_ProtocolIE_ID_id_SRSType, true); + decode_nrppa_srstype(&ie->value.choice.SRSType, &req->srs_type); + + nrppa_store_ue_context(nrppa_msg_info, req->transaction_id); + + LOG_I(NRPPA, "Forwarding to RRC Positioning Activation Request transaction id = %d\n", req->transaction_id); + + itti_send_msg_to_task(TASK_RRC_GNB, 0, msg); + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NRPPA_NRPPA_PDU, &pdu); + return 0; +} diff --git a/openair3/NRPPA/nrppa_gNB_location_information_transfer.h b/openair3/NRPPA/nrppa_gNB_location_information_transfer.h index 31ab194345..d86c7b2744 100644 --- a/openair3/NRPPA/nrppa_gNB_location_information_transfer.h +++ b/openair3/NRPPA/nrppa_gNB_location_information_transfer.h @@ -32,5 +32,8 @@ int nrppa_gNB_handle_positioning_information_request(nrppa_gnb_ue_info_t *nrppa_ int nrppa_gNB_positioning_information_response(instance_t instance, MessageDef *msg_p); NRPPA_SRSCarrier_List_t encode_srs_carrier_list_nrppa(const nrppa_srs_carrier_list_t *in_list); void free_positioning_information_response(nrppa_positioning_information_resp_t *msg); +int nrppa_gNB_handle_positioning_activation_request(nrppa_gnb_ue_info_t *nrppa_msg_info, const NRPPA_NRPPA_PDU_t *pdu); +void decode_nrppa_srstype(NRPPA_SRSType_t *srs_type, nrppa_srs_type_t *out); +void free_positioning_activation_request(nrppa_positioning_activation_req_t *msg); #endif /* NRPPA_GNB_POSITIONING_PROCEDURES_H_ */ diff --git a/openair3/NRPPA/nrppa_includes.h b/openair3/NRPPA/nrppa_includes.h index 6915b93370..6465d6c0af 100644 --- a/openair3/NRPPA/nrppa_includes.h +++ b/openair3/NRPPA/nrppa_includes.h @@ -69,5 +69,7 @@ #include "NRPPA_PosResourceSetTypePeriodic.h" #include "NRPPA_PosResourceSetTypeSemi-persistent.h" #include "NRPPA_PosResourceSetTypeAperiodic.h" +#include "NRPPA_SemipersistentSRS.h" +#include "NRPPA_AperiodicSRS.h" #endif /* NRPPA_INCLUDE_H_ */ From 192508e6ccfb698a65387eaf916920a7d2781f66 Mon Sep 17 00:00:00 2001 From: Rakesh Mundlamuri Date: Fri, 23 Jan 2026 19:09:42 +0530 Subject: [PATCH 28/44] Add Positioning Activation Response NRPPA message encoding procedures --- openair2/COMMON/nrppa_messages_def.h | 4 ++ openair2/COMMON/nrppa_messages_types.h | 6 ++ openair3/NRPPA/nrppa_gNB.c | 3 + .../nrppa_gNB_location_information_transfer.c | 65 +++++++++++++++++++ .../nrppa_gNB_location_information_transfer.h | 1 + tests/nr-cu-nrppa/nr-cu-nrppa.c | 10 +++ 6 files changed, 89 insertions(+) diff --git a/openair2/COMMON/nrppa_messages_def.h b/openair2/COMMON/nrppa_messages_def.h index bb5d534856..d8090ab4a4 100644 --- a/openair2/COMMON/nrppa_messages_def.h +++ b/openair2/COMMON/nrppa_messages_def.h @@ -36,3 +36,7 @@ MESSAGE_DEF(NRPPA_POSITIONING_ACTIVATION_REQ, MESSAGE_PRIORITY_MED, nrppa_positioning_activation_req_t, nrppa_positioning_activation_req) +MESSAGE_DEF(NRPPA_POSITIONING_ACTIVATION_RESP, + MESSAGE_PRIORITY_MED, + nrppa_positioning_activation_resp_t, + nrppa_positioning_activation_resp) diff --git a/openair2/COMMON/nrppa_messages_types.h b/openair2/COMMON/nrppa_messages_types.h index 077c5a89b0..21f74288f5 100644 --- a/openair2/COMMON/nrppa_messages_types.h +++ b/openair2/COMMON/nrppa_messages_types.h @@ -29,6 +29,7 @@ #define NRPPA_POSITIONING_INFORMATION_REQ(mSGpTR) (mSGpTR)->ittiMsg.nrppa_positioning_information_req #define NRPPA_POSITIONING_INFORMATION_RESP(mSGpTR) (mSGpTR)->ittiMsg.nrppa_positioning_information_resp #define NRPPA_POSITIONING_ACTIVATION_REQ(mSGpTR) (mSGpTR)->ittiMsg.nrppa_positioning_activation_req +#define NRPPA_POSITIONING_ACTIVATION_RESP(mSGpTR) (mSGpTR)->ittiMsg.nrppa_positioning_activation_resp /* Structure of Positioning related NRPPA messages */ /* IE structures for Positioning related messages as per TS 38.455 V16.7.1*/ @@ -623,4 +624,9 @@ typedef struct nrppa_positioning_activation_req_s { nrppa_srs_type_t srs_type; } nrppa_positioning_activation_req_t; +typedef struct nrppa_positioning_activation_resp_s { + // IE 9.2.4 (mandatory) + uint16_t transaction_id; +} nrppa_positioning_activation_resp_t; + #endif // NRPPA_MESSAGES_TYPES_H_ diff --git a/openair3/NRPPA/nrppa_gNB.c b/openair3/NRPPA/nrppa_gNB.c index 19e76bc392..0da07e018e 100644 --- a/openair3/NRPPA/nrppa_gNB.c +++ b/openair3/NRPPA/nrppa_gNB.c @@ -63,6 +63,9 @@ void *nrppa_gNB_process_itti_msg(void *notUsed) case NRPPA_POSITIONING_INFORMATION_RESP: nrppa_gNB_positioning_information_response(instance, received_msg); break; + case NRPPA_POSITIONING_ACTIVATION_RESP: + nrppa_gNB_positioning_activation_response(instance, received_msg); + break; default: LOG_E(NRPPA, "Received unhandled message: %d:%s\n", ITTI_MSG_ID(received_msg), ITTI_MSG_NAME(received_msg)); break; diff --git a/openair3/NRPPA/nrppa_gNB_location_information_transfer.c b/openair3/NRPPA/nrppa_gNB_location_information_transfer.c index dfaa7f1efc..2bc0d9d9bc 100644 --- a/openair3/NRPPA/nrppa_gNB_location_information_transfer.c +++ b/openair3/NRPPA/nrppa_gNB_location_information_transfer.c @@ -1312,3 +1312,68 @@ int nrppa_gNB_handle_positioning_activation_request(nrppa_gnb_ue_info_t *nrppa_m ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NRPPA_NRPPA_PDU, &pdu); return 0; } + +int nrppa_gNB_positioning_activation_response(instance_t instance, MessageDef *msg_p) +{ + DevAssert(msg_p); + nrppa_positioning_activation_resp_t *resp = &NRPPA_POSITIONING_ACTIVATION_RESP(msg_p); + nrppa_gNB_ue_context_t *ue_info = nrppa_detach_ue_context(resp->transaction_id); + + if (ue_info->gNB_ue_ngap_id <= 0 && ue_info->amf_ue_ngap_id <= 0) { + LOG_E(NRPPA, "Illegal gNB_ue_ngap_id %d and amf_ue_ngap_id %ld\n", ue_info->gNB_ue_ngap_id, ue_info->amf_ue_ngap_id); + nrppa_free_ue_context(ue_info); + return -1; + } + + LOG_I(NRPPA, + "Received PositioningInformationResponse info from RRC with transaction_id=%u and gNB_ue_ngap_id %u\n", + ue_info->transaction_id, + ue_info->gNB_ue_ngap_id); + + // Prepare NRPPA TRP Information transfer Response + NRPPA_NRPPA_PDU_t pdu = {0}; + + // IE: 9.2.3 Message Type : mandatory + pdu.present = NRPPA_NRPPA_PDU_PR_successfulOutcome; + asn1cCalloc(pdu.choice.successfulOutcome, head); + head->procedureCode = NRPPA_ProcedureCode_id_positioningActivation; + head->criticality = NRPPA_Criticality_reject; + head->value.present = NRPPA_SuccessfulOutcome__value_PR_PositioningActivationResponse; + + // IE 9.2.4 nrppatransactionID : mandatory + head->nrppatransactionID = resp->transaction_id; + + LOG_I(NRPPA, "Calling encoder for PositioningActivationResponse \n"); + + if (LOG_DEBUGFLAG(DEBUG_ASN1)) { + xer_fprint(stdout, &asn_DEF_NRPPA_NRPPA_PDU, &pdu); + } + + // Encode NRPPA message + uint8_t *buffer = NULL; + uint32_t length = 0; + if (nrppa_gNB_encode_pdu(&pdu, &buffer, &length) < 0) { + LOG_E(NRPPA, "Failed to encode Uplink NRPPa PositioningActivationResponse\n"); + nrppa_free_ue_context(ue_info); + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NRPPA_NRPPA_PDU, &pdu); + return -1; + } + + MessageDef *msg = itti_alloc_new_message(TASK_NRPPA, 0, NGAP_UPLINKUEASSOCIATEDNRPPA); + ngap_uplink_ue_associated_nrppa_t *ULNRPPA = &NGAP_UPLINKUEASSOCIATEDNRPPA(msg); + + ULNRPPA->gNB_ue_ngap_id = ue_info->gNB_ue_ngap_id; + ULNRPPA->amf_ue_ngap_id = ue_info->amf_ue_ngap_id; + + // Routing ID + ULNRPPA->routing_id = create_byte_array(ue_info->routing_id.len, ue_info->routing_id.buf); + + // NRPPA PDU + ULNRPPA->nrppa_pdu = create_byte_array(length, buffer); + + // Forward the NRPPA PDU to NGAP + itti_send_msg_to_task(TASK_NGAP, instance, msg); + nrppa_free_ue_context(ue_info); + free(buffer); + return length; +} diff --git a/openair3/NRPPA/nrppa_gNB_location_information_transfer.h b/openair3/NRPPA/nrppa_gNB_location_information_transfer.h index d86c7b2744..dc64738dfd 100644 --- a/openair3/NRPPA/nrppa_gNB_location_information_transfer.h +++ b/openair3/NRPPA/nrppa_gNB_location_information_transfer.h @@ -35,5 +35,6 @@ void free_positioning_information_response(nrppa_positioning_information_resp_t int nrppa_gNB_handle_positioning_activation_request(nrppa_gnb_ue_info_t *nrppa_msg_info, const NRPPA_NRPPA_PDU_t *pdu); void decode_nrppa_srstype(NRPPA_SRSType_t *srs_type, nrppa_srs_type_t *out); void free_positioning_activation_request(nrppa_positioning_activation_req_t *msg); +int nrppa_gNB_positioning_activation_response(instance_t instance, MessageDef *msg_p); #endif /* NRPPA_GNB_POSITIONING_PROCEDURES_H_ */ diff --git a/tests/nr-cu-nrppa/nr-cu-nrppa.c b/tests/nr-cu-nrppa/nr-cu-nrppa.c index ca47199133..0edd0842f4 100644 --- a/tests/nr-cu-nrppa/nr-cu-nrppa.c +++ b/tests/nr-cu-nrppa/nr-cu-nrppa.c @@ -31,6 +31,7 @@ #include "openair3/NRPPA/nrppa_gNB.h" #include "openair3/NAS/NR_UE/nr_nas_msg.h" #include "executables/nr-uesoftmodem.h" +#include "openair3/NRPPA/nrppa_gNB_location_information_transfer.c" RAN_CONTEXT_t RC; THREAD_STRUCT thread_struct; @@ -579,6 +580,15 @@ void *rrc_gnb_task(void *args_p) LOG_I(NR_RRC, "Sending NRPPA_POSITIONING_INFORMATION_RESP to TASK_NRPPA\n"); itti_send_msg_to_task(TASK_NRPPA, 0, msg_p_resp); break; + case NRPPA_POSITIONING_ACTIVATION_REQ: + nrppa_positioning_activation_req_t *req = &NRPPA_POSITIONING_ACTIVATION_REQ(msg_p); + LOG_I(NR_RRC, "Received NRPPA_POSITIONING_ACTIVATION_REQ transaction_id %d\n", req->transaction_id); + msg_p_resp = itti_alloc_new_message(TASK_RRC_GNB, 0, NRPPA_POSITIONING_ACTIVATION_RESP); + NRPPA_POSITIONING_ACTIVATION_RESP(msg_p_resp).transaction_id = req->transaction_id; + LOG_I(NR_RRC, "Sending NRPPA_POSITIONING_ACTIVATION_RESP to TASK_NRPPA\n"); + itti_send_msg_to_task(TASK_NRPPA, 0, msg_p_resp); + free_positioning_activation_request(req); + break; default: LOG_E(NR_RRC, "[gNB %ld] Received unexpected message %s\n", instance, msg_name_p); break; From 4f8cde62236913baacfbfe7fb0428ffa0fb29af5 Mon Sep 17 00:00:00 2001 From: Rakesh Mundlamuri Date: Thu, 29 Jan 2026 16:38:07 +0530 Subject: [PATCH 29/44] Add Measurement Request NRPPA message decoding procedures --- openair2/COMMON/nrppa_messages_def.h | 1 + openair2/COMMON/nrppa_messages_types.h | 64 ++ openair3/NRPPA/CMakeLists.txt | 1 + openair3/NRPPA/nrppa_gNB_decoder.c | 5 + openair3/NRPPA/nrppa_gNB_handlers.c | 3 +- .../nrppa_gNB_location_information_transfer.c | 2 +- .../nrppa_gNB_location_information_transfer.h | 1 + ...ppa_gNB_measurement_information_transfer.c | 874 ++++++++++++++++++ ...ppa_gNB_measurement_information_transfer.h | 29 + openair3/NRPPA/nrppa_includes.h | 3 + 10 files changed, 981 insertions(+), 2 deletions(-) create mode 100644 openair3/NRPPA/nrppa_gNB_measurement_information_transfer.c create mode 100644 openair3/NRPPA/nrppa_gNB_measurement_information_transfer.h diff --git a/openair2/COMMON/nrppa_messages_def.h b/openair2/COMMON/nrppa_messages_def.h index d8090ab4a4..a68362b18c 100644 --- a/openair2/COMMON/nrppa_messages_def.h +++ b/openair2/COMMON/nrppa_messages_def.h @@ -40,3 +40,4 @@ MESSAGE_DEF(NRPPA_POSITIONING_ACTIVATION_RESP, MESSAGE_PRIORITY_MED, nrppa_positioning_activation_resp_t, nrppa_positioning_activation_resp) +MESSAGE_DEF(NRPPA_MEASUREMENT_REQ, MESSAGE_PRIORITY_MED, nrppa_measurement_req_t, nrppa_measurement_req) diff --git a/openair2/COMMON/nrppa_messages_types.h b/openair2/COMMON/nrppa_messages_types.h index 21f74288f5..dd42af6354 100644 --- a/openair2/COMMON/nrppa_messages_types.h +++ b/openair2/COMMON/nrppa_messages_types.h @@ -30,6 +30,7 @@ #define NRPPA_POSITIONING_INFORMATION_RESP(mSGpTR) (mSGpTR)->ittiMsg.nrppa_positioning_information_resp #define NRPPA_POSITIONING_ACTIVATION_REQ(mSGpTR) (mSGpTR)->ittiMsg.nrppa_positioning_activation_req #define NRPPA_POSITIONING_ACTIVATION_RESP(mSGpTR) (mSGpTR)->ittiMsg.nrppa_positioning_activation_resp +#define NRPPA_MEASUREMENT_REQ(mSGpTR) (mSGpTR)->ittiMsg.nrppa_measurement_req /* Structure of Positioning related NRPPA messages */ /* IE structures for Positioning related messages as per TS 38.455 V16.7.1*/ @@ -588,6 +589,52 @@ typedef struct nrppa_srs_type_s { nrppa_srs_type_u choice; } nrppa_srs_type_t; +typedef struct nrppa_trp_measurement_request_item_s { + uint32_t trp_id; +} nrppa_trp_measurement_request_item_t; + +typedef struct nrppa_trp_measurement_request_list_s { + nrppa_trp_measurement_request_item_t *trp_measurement_request_item; + uint32_t trp_measurement_request_list_length; +} nrppa_trp_measurement_request_list_t; + +typedef enum nrppa_pos_report_characteristics_e { + NRPPA_POSREPORTCHARACTERISTICS_ONDEMAND = 0, + NRPPA_POSREPORTCHARACTERISTICS_PERIODIC = 1 +} nrppa_report_characteristics_pr; + +typedef enum nrppa_pos_measurement_periodicity_e { + NRPPA_POSMEASUREMENTPERIODICITY_MS120 = 0, + NRPPA_POSMEASUREMENTPERIODICITY_MS240 = 1, + NRPPA_POSMEASUREMENTPERIODICITY_MS480 = 2, + NRPPA_POSMEASUREMENTPERIODICITY_MS640 = 3, + NRPPA_POSMEASUREMENTPERIODICITY_MS1024 = 4, + NRPPA_POSMEASUREMENTPERIODICITY_MS2048 = 5, + NRPPA_POSMEASUREMENTPERIODICITY_MS5120 = 6, + NRPPA_POSMEASUREMENTPERIODICITY_MS10240 = 7, + NRPPA_POSMEASUREMENTPERIODICITY_MIN1 = 8, + NRPPA_POSMEASUREMENTPERIODICITY_MIN6 = 9, + NRPPA_POSMEASUREMENTPERIODICITY_MIN12 = 10, + NRPPA_POSMEASUREMENTPERIODICITY_MIN30 = 11, + NRPPA_POSMEASUREMENTPERIODICITY_MIN60 = 12 +} nrppa_measurement_periodicity_pr; + +typedef enum nrppa_pos_measurement_type_e { + NRPPA_POSMEASUREMENTTYPE_GNB_RX_TX = 0, + NRPPA_POSMEASUREMENTTYPE_UL_SRS_RSRP = 1, + NRPPA_POSMEASUREMENTTYPE_UL_AOA = 2, + NRPPA_POSMEASUREMENTTYPE_UL_RTOA = 3 +} nrppa_measurement_type_pr; + +typedef struct nrppa_pos_measurement_quantities_item_s { + nrppa_measurement_type_pr measurement_type; +} nrppa_measurement_quantities_item_t; + +typedef struct nrppa_pos_measurement_quantities_s { + nrppa_measurement_quantities_item_t *measurement_quantities_item; + uint32_t measurement_quantities_length; +} nrppa_measurement_quantities_t; + typedef struct nrppa_trp_information_req_s { // IE 9.2.4 (mandatory) uint16_t transaction_id; @@ -629,4 +676,21 @@ typedef struct nrppa_positioning_activation_resp_s { uint16_t transaction_id; } nrppa_positioning_activation_resp_t; +typedef struct nrppa_measurement_req_s { + // IE 9.2.4 (mandatory) + uint16_t transaction_id; + // (mandatory) + uint32_t lmf_measurement_id; + // (mandatory) + nrppa_trp_measurement_request_list_t trp_measurement_request_list; + // (mandatory) ondemand = 0, periodic = 1 + nrppa_report_characteristics_pr report_characteristics; + // if report characteristics periodic + nrppa_measurement_periodicity_pr measurement_periodicity; + // (mandatory) + nrppa_measurement_quantities_t measurement_quantities; + // IE 9.2.28 (optional) + nrppa_srs_configuration_t *srs_configuration; +} nrppa_measurement_req_t; + #endif // NRPPA_MESSAGES_TYPES_H_ diff --git a/openair3/NRPPA/CMakeLists.txt b/openair3/NRPPA/CMakeLists.txt index 7ec77db3b5..45f0964667 100644 --- a/openair3/NRPPA/CMakeLists.txt +++ b/openair3/NRPPA/CMakeLists.txt @@ -8,6 +8,7 @@ add_library(nrppa nrppa_gNB_ue_context.c nrppa_gNB_location_information_transfer.c nrppa_gNB_encoder.c + nrppa_gNB_measurement_information_transfer.c ) target_link_libraries(nrppa PUBLIC asn1_nrppa) diff --git a/openair3/NRPPA/nrppa_gNB_decoder.c b/openair3/NRPPA/nrppa_gNB_decoder.c index 340ff63baa..756871bc59 100644 --- a/openair3/NRPPA/nrppa_gNB_decoder.c +++ b/openair3/NRPPA/nrppa_gNB_decoder.c @@ -45,6 +45,11 @@ static int nrppa_gNB_decode_initiating_message(NRPPA_NRPPA_PDU_t *pdu) LOG_I(NRPPA, "Positioning Activation initiating message\n"); free(res.buffer); break; + case NRPPA_ProcedureCode_id_Measurement: + res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_NRPPA_NRPPA_PDU, pdu); + LOG_I(NRPPA, "Positioning Measurement initiating message\n"); + free(res.buffer); + break; default: AssertFatal(false, "Unknown procedure ID (%d) for initiating message\n", (int)pdu->choice.initiatingMessage->procedureCode); return -1; diff --git a/openair3/NRPPA/nrppa_gNB_handlers.c b/openair3/NRPPA/nrppa_gNB_handlers.c index 4689351b11..476729cd36 100644 --- a/openair3/NRPPA/nrppa_gNB_handlers.c +++ b/openair3/NRPPA/nrppa_gNB_handlers.c @@ -24,6 +24,7 @@ #include "nrppa_gNB_decoder.h" #include "nrppa_common.h" #include "nrppa_gNB_location_information_transfer.h" +#include "nrppa_gNB_measurement_information_transfer.h" char *nrppa_direction2String(int nrppa_dir) { @@ -51,7 +52,7 @@ nrppa_message_decoded_callback nrppa_messages_callback[][3] = { 0, 0}, // NRPPA_ProcedureCode_id_positioningInformationExchange ((NRPPA_ProcedureCode_t)9) {0, 0, 0}, // NRPPA_ProcedureCode_id_positioningInformationUpdate ((NRPPA_ProcedureCode_t)10) - {0, 0, 0}, // NRPPA_ProcedureCode_id_Measurement ((NRPPA_ProcedureCode_t)11) + {nrppa_gNB_handle_measurement_request, 0, 0}, // NRPPA_ProcedureCode_id_Measurement ((NRPPA_ProcedureCode_t)11) {0, 0, 0}, // NRPPA_ProcedureCode_id_MeasurementReport ((NRPPA_ProcedureCode_t)12) {0, 0, 0}, // NRPPA_ProcedureCode_id_MeasurementUpdate ((NRPPA_ProcedureCode_t)13) {0, 0, 0}, // NRPPA_ProcedureCode_id_MeasurementAbort ((NRPPA_ProcedureCode_t)14) diff --git a/openair3/NRPPA/nrppa_gNB_location_information_transfer.c b/openair3/NRPPA/nrppa_gNB_location_information_transfer.c index 2bc0d9d9bc..bb3bc9f8bd 100644 --- a/openair3/NRPPA/nrppa_gNB_location_information_transfer.c +++ b/openair3/NRPPA/nrppa_gNB_location_information_transfer.c @@ -932,7 +932,7 @@ NRPPA_SRSCarrier_List_t encode_srs_carrier_list_nrppa(const nrppa_srs_carrier_li return out_list; } -static void free_srs_carrier_list(nrppa_srs_carrier_list_t *srs_carrier_list) +void free_srs_carrier_list(nrppa_srs_carrier_list_t *srs_carrier_list) { uint32_t srs_carrier_list_len = srs_carrier_list->srs_carrier_list_length; for (int i = 0; i < srs_carrier_list_len; i++) { diff --git a/openair3/NRPPA/nrppa_gNB_location_information_transfer.h b/openair3/NRPPA/nrppa_gNB_location_information_transfer.h index dc64738dfd..29d73c0059 100644 --- a/openair3/NRPPA/nrppa_gNB_location_information_transfer.h +++ b/openair3/NRPPA/nrppa_gNB_location_information_transfer.h @@ -31,6 +31,7 @@ void free_trp_information_response(nrppa_trp_information_resp_t *msg); int nrppa_gNB_handle_positioning_information_request(nrppa_gnb_ue_info_t *nrppa_msg_info, const NRPPA_NRPPA_PDU_t *pdu); int nrppa_gNB_positioning_information_response(instance_t instance, MessageDef *msg_p); NRPPA_SRSCarrier_List_t encode_srs_carrier_list_nrppa(const nrppa_srs_carrier_list_t *in_list); +void free_srs_carrier_list(nrppa_srs_carrier_list_t *srs_carrier_list); void free_positioning_information_response(nrppa_positioning_information_resp_t *msg); int nrppa_gNB_handle_positioning_activation_request(nrppa_gnb_ue_info_t *nrppa_msg_info, const NRPPA_NRPPA_PDU_t *pdu); void decode_nrppa_srstype(NRPPA_SRSType_t *srs_type, nrppa_srs_type_t *out); diff --git a/openair3/NRPPA/nrppa_gNB_measurement_information_transfer.c b/openair3/NRPPA/nrppa_gNB_measurement_information_transfer.c new file mode 100644 index 0000000000..02db797d81 --- /dev/null +++ b/openair3/NRPPA/nrppa_gNB_measurement_information_transfer.c @@ -0,0 +1,874 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#include "intertask_interface.h" +#include "nrppa_common.h" +#include "nrppa_gNB_ue_context.h" +#include "nrppa_messages_types.h" +#include "nrppa_gNB_encoder.h" +#include "openair3/UTILS/conversions.h" +#include "nrppa_gNB_measurement_information_transfer.h" +#include "nrppa_gNB_location_information_transfer.h" + +static void decode_srs_config(const NRPPA_SRSConfig_t *in_config, nrppa_srs_config_t *out_config) +{ + // optional: sRSResource_List + if (in_config->sRSResource_List) { + out_config->srs_resource_list = calloc_or_fail(1, sizeof(*out_config->srs_resource_list)); + nrppa_srs_resource_list_t *srs_resource_list = out_config->srs_resource_list; + uint32_t srs_resource_list_length = in_config->sRSResource_List->list.count; + srs_resource_list->srs_resource_list_length = srs_resource_list_length; + srs_resource_list->srs_resource = calloc_or_fail(srs_resource_list_length, sizeof(*srs_resource_list->srs_resource)); + for (int i = 0; i < srs_resource_list_length; i++) { + nrppa_srs_resource_t *srs_resource = &srs_resource_list->srs_resource[i]; + NRPPA_SRSResource_t *nrppa_srs_resource = in_config->sRSResource_List->list.array[i]; + srs_resource->srs_resource_id = nrppa_srs_resource->sRSResourceID; + switch (nrppa_srs_resource->nrofSRS_Ports) { + case NRPPA_SRSResource__nrofSRS_Ports_port1: + srs_resource->nr_of_srs_ports = NRPPA_SRS_NUMBER_OF_PORTS_N1; + break; + case NRPPA_SRSResource__nrofSRS_Ports_ports2: + srs_resource->nr_of_srs_ports = NRPPA_SRS_NUMBER_OF_PORTS_N2; + break; + case NRPPA_SRSResource__nrofSRS_Ports_ports4: + srs_resource->nr_of_srs_ports = NRPPA_SRS_NUMBER_OF_PORTS_N4; + break; + default: + AssertFatal(false, "illegal number of srs ports %ld\n", nrppa_srs_resource->nrofSRS_Ports); + break; + } + + nrppa_transmission_comb_t *srs_tx_comb = &srs_resource->transmission_comb; + NRPPA_TransmissionComb_t *nrppa_srs_tx_comb = &nrppa_srs_resource->transmissionComb; + switch (nrppa_srs_tx_comb->present) { + case NRPPA_TransmissionComb_PR_NOTHING: + srs_tx_comb->present = NRPPA_TRANSMISSION_COMB_PR_NOTHING; + break; + case NRPPA_TransmissionComb_PR_n2: + srs_tx_comb->present = NRPPA_TRANSMISSION_COMB_PR_N2; + srs_tx_comb->choice.n2.comb_offset_n2 = nrppa_srs_tx_comb->choice.n2->combOffset_n2; + srs_tx_comb->choice.n2.cyclic_shift_n2 = nrppa_srs_tx_comb->choice.n2->cyclicShift_n2; + break; + case NRPPA_TransmissionComb_PR_n4: + srs_tx_comb->present = NRPPA_TRANSMISSION_COMB_PR_N4; + srs_tx_comb->choice.n4.comb_offset_n4 = nrppa_srs_tx_comb->choice.n4->combOffset_n4; + srs_tx_comb->choice.n4.cyclic_shift_n4 = nrppa_srs_tx_comb->choice.n4->cyclicShift_n4; + break; + default: + AssertFatal(false, "illegal transmissionComb %d\n", nrppa_srs_tx_comb->present); + break; + } + + srs_resource->start_position = nrppa_srs_resource->startPosition; + + switch (nrppa_srs_resource->nrofSymbols) { + case NRPPA_SRSResource__nrofSymbols_n1: + srs_resource->nr_of_symbols = NRPPA_SRS_NUMBER_OF_SYMBOLS_N1; + break; + case NRPPA_SRSResource__nrofSymbols_n2: + srs_resource->nr_of_symbols = NRPPA_SRS_NUMBER_OF_SYMBOLS_N2; + break; + case NRPPA_SRSResource__nrofSymbols_n4: + srs_resource->nr_of_symbols = NRPPA_SRS_NUMBER_OF_SYMBOLS_N4; + break; + default: + AssertFatal(false, "illegal number of symbols %ld\n", nrppa_srs_resource->nrofSymbols); + break; + } + + switch (nrppa_srs_resource->repetitionFactor) { + case NRPPA_SRSResource__repetitionFactor_n1: + srs_resource->repetition_factor = NRPPA_SRS_REPETITION_FACTOR_RF1; + break; + case NRPPA_SRSResource__repetitionFactor_n2: + srs_resource->repetition_factor = NRPPA_SRS_REPETITION_FACTOR_RF2; + break; + case NRPPA_SRSResource__repetitionFactor_n4: + srs_resource->repetition_factor = NRPPA_SRS_REPETITION_FACTOR_RF4; + break; + default: + AssertFatal(false, "illegal repetition factor %ld\n", nrppa_srs_resource->repetitionFactor); + break; + } + + srs_resource->freq_domain_position = nrppa_srs_resource->freqDomainPosition; + srs_resource->freq_domain_shift = nrppa_srs_resource->freqDomainShift; + srs_resource->c_srs = nrppa_srs_resource->c_SRS; + srs_resource->b_srs = nrppa_srs_resource->b_SRS; + srs_resource->b_hop = nrppa_srs_resource->b_hop; + + switch (nrppa_srs_resource->groupOrSequenceHopping) { + case NRPPA_SRSResource__groupOrSequenceHopping_neither: + srs_resource->group_or_sequence_hopping = NRPPA_GROUPORSEQUENCEHOPPING_NOTHING; + break; + case NRPPA_SRSResource__groupOrSequenceHopping_groupHopping: + srs_resource->group_or_sequence_hopping = NRPPA_GROUPORSEQUENCEHOPPING_GROUPHOPPING; + break; + case NRPPA_SRSResource__groupOrSequenceHopping_sequenceHopping: + srs_resource->group_or_sequence_hopping = NRPPA_GROUPORSEQUENCEHOPPING_SEQUENCEHOPPING; + break; + default: + AssertFatal(false, "illegal groupOrSequenceHopping %ld\n", nrppa_srs_resource->groupOrSequenceHopping); + break; + } + + NRPPA_ResourceType_t *nrppa_resourceType = &nrppa_srs_resource->resourceType; + nrppa_resource_type_t *resource_type = &srs_resource->resource_type; + if (nrppa_resourceType->present == NRPPA_ResourceType_PR_NOTHING) { + resource_type->present = NRPPA_RESOURCE_TYPE_PR_NOTHING; + } else if (nrppa_resourceType->present == NRPPA_ResourceType_PR_periodic) { + resource_type->present = NRPPA_RESOURCE_TYPE_PR_PERIODIC; + nrppa_resource_type_periodic_t *periodic = &resource_type->choice.periodic; + switch (nrppa_resourceType->choice.periodic->periodicity) { + case NRPPA_ResourceTypePeriodic__periodicity_slot1: + periodic->periodicity = NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT1; + break; + case NRPPA_ResourceTypePeriodic__periodicity_slot2: + periodic->periodicity = NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT2; + break; + case NRPPA_ResourceTypePeriodic__periodicity_slot4: + periodic->periodicity = NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT4; + break; + case NRPPA_ResourceTypePeriodic__periodicity_slot5: + periodic->periodicity = NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT5; + break; + case NRPPA_ResourceTypePeriodic__periodicity_slot8: + periodic->periodicity = NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT8; + break; + case NRPPA_ResourceTypePeriodic__periodicity_slot10: + periodic->periodicity = NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT10; + break; + case NRPPA_ResourceTypePeriodic__periodicity_slot16: + periodic->periodicity = NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT16; + break; + case NRPPA_ResourceTypePeriodic__periodicity_slot20: + periodic->periodicity = NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT20; + break; + case NRPPA_ResourceTypePeriodic__periodicity_slot32: + periodic->periodicity = NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT32; + break; + case NRPPA_ResourceTypePeriodic__periodicity_slot40: + periodic->periodicity = NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT40; + break; + case NRPPA_ResourceTypePeriodic__periodicity_slot64: + periodic->periodicity = NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT64; + break; + case NRPPA_ResourceTypePeriodic__periodicity_slot80: + periodic->periodicity = NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT80; + break; + case NRPPA_ResourceTypePeriodic__periodicity_slot160: + periodic->periodicity = NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT160; + break; + case NRPPA_ResourceTypePeriodic__periodicity_slot320: + periodic->periodicity = NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT320; + break; + case NRPPA_ResourceTypePeriodic__periodicity_slot640: + periodic->periodicity = NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT640; + break; + case NRPPA_ResourceTypePeriodic__periodicity_slot1280: + periodic->periodicity = NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT1280; + break; + case NRPPA_ResourceTypePeriodic__periodicity_slot2560: + periodic->periodicity = NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT2560; + break; + default: + AssertFatal(false, "illegal periodicity %ld\n", nrppa_resourceType->choice.periodic->periodicity); + break; + } + periodic->offset = nrppa_resourceType->choice.periodic->offset; + } else if (nrppa_resourceType->present == NRPPA_ResourceType_PR_semi_persistent) { + resource_type->present = NRPPA_RESOURCE_TYPE_PR_SEMI_PERSISTENT; + nrppa_resource_type_semi_persistent_t *semi_persistent = &resource_type->choice.semi_persistent; + switch (nrppa_resourceType->choice.semi_persistent->periodicity) { + case NRPPA_ResourceTypeSemi_persistent__periodicity_slot1: + semi_persistent->periodicity = NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT1; + break; + case NRPPA_ResourceTypeSemi_persistent__periodicity_slot2: + semi_persistent->periodicity = NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT2; + break; + case NRPPA_ResourceTypeSemi_persistent__periodicity_slot4: + semi_persistent->periodicity = NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT4; + break; + case NRPPA_ResourceTypeSemi_persistent__periodicity_slot5: + semi_persistent->periodicity = NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT5; + break; + case NRPPA_ResourceTypeSemi_persistent__periodicity_slot8: + semi_persistent->periodicity = NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT8; + break; + case NRPPA_ResourceTypeSemi_persistent__periodicity_slot10: + semi_persistent->periodicity = NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT10; + break; + case NRPPA_ResourceTypeSemi_persistent__periodicity_slot16: + semi_persistent->periodicity = NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT16; + break; + case NRPPA_ResourceTypeSemi_persistent__periodicity_slot20: + semi_persistent->periodicity = NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT20; + break; + case NRPPA_ResourceTypeSemi_persistent__periodicity_slot32: + semi_persistent->periodicity = NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT32; + break; + case NRPPA_ResourceTypeSemi_persistent__periodicity_slot40: + semi_persistent->periodicity = NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT40; + break; + case NRPPA_ResourceTypeSemi_persistent__periodicity_slot64: + semi_persistent->periodicity = NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT64; + break; + case NRPPA_ResourceTypeSemi_persistent__periodicity_slot80: + semi_persistent->periodicity = NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT80; + break; + case NRPPA_ResourceTypeSemi_persistent__periodicity_slot160: + semi_persistent->periodicity = NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT160; + break; + case NRPPA_ResourceTypeSemi_persistent__periodicity_slot320: + semi_persistent->periodicity = NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT320; + break; + case NRPPA_ResourceTypeSemi_persistent__periodicity_slot640: + semi_persistent->periodicity = NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT640; + break; + case NRPPA_ResourceTypeSemi_persistent__periodicity_slot1280: + semi_persistent->periodicity = NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT1280; + break; + case NRPPA_ResourceTypeSemi_persistent__periodicity_slot2560: + semi_persistent->periodicity = NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT2560; + break; + default: + AssertFatal(false, "illegal periodicity %ld\n", nrppa_resourceType->choice.semi_persistent->periodicity); + break; + } + semi_persistent->offset = nrppa_resourceType->choice.semi_persistent->offset; + } else if (nrppa_resourceType->present == NRPPA_ResourceType_PR_aperiodic) { + resource_type->present = NRPPA_RESOURCE_TYPE_PR_APERIODIC; + resource_type->choice.aperiodic = nrppa_resourceType->choice.aperiodic->aperiodicResourceType; + } else { + AssertFatal(false, "illegal resourceType %d\n", nrppa_resourceType->present); + } + + srs_resource->sequence_id = nrppa_srs_resource->sequenceId; + } + } + + // optional: posSRSResource_List + if (in_config->posSRSResource_List) { + out_config->pos_srs_resource_list = calloc_or_fail(1, sizeof(*out_config->pos_srs_resource_list)); + nrppa_pos_srs_resource_list_t *pos_srs_resource_list = out_config->pos_srs_resource_list; + uint32_t pos_srs_resource_list_length = in_config->posSRSResource_List->list.count; + pos_srs_resource_list->pos_srs_resource_list_length = pos_srs_resource_list_length; + pos_srs_resource_list->pos_srs_resource_item = + calloc_or_fail(pos_srs_resource_list_length, sizeof(*pos_srs_resource_list->pos_srs_resource_item)); + for (int i = 0; i < pos_srs_resource_list_length; i++) { + NRPPA_PosSRSResource_Item_t *nrppa_pos_srs_resource = in_config->posSRSResource_List->list.array[i]; + nrppa_pos_srs_resource_item_t *pos_srs_resource = &pos_srs_resource_list->pos_srs_resource_item[i]; + pos_srs_resource->srs_pos_resource_id = nrppa_pos_srs_resource->srs_PosResourceId; + + NRPPA_TransmissionCombPos_t *nrppa_tx_comb_pos = &nrppa_pos_srs_resource->transmissionCombPos; + nrppa_transmission_comb_pos_t *tx_comb_pos = &pos_srs_resource->transmission_comb_pos; + switch (nrppa_tx_comb_pos->present) { + case NRPPA_TransmissionCombPos_PR_NOTHING: + tx_comb_pos->present = NRPPA_TRANSMISSION_COMB_POS_PR_NOTHING; + break; + case NRPPA_TransmissionCombPos_PR_n2: + tx_comb_pos->present = NRPPA_TRANSMISSION_COMB_POS_PR_N2; + tx_comb_pos->choice.n2.comb_offset_n2 = nrppa_tx_comb_pos->choice.n2->combOffset_n2; + tx_comb_pos->choice.n2.cyclic_shift_n2 = nrppa_tx_comb_pos->choice.n2->cyclicShift_n2; + break; + case NRPPA_TransmissionCombPos_PR_n4: + tx_comb_pos->present = NRPPA_TRANSMISSION_COMB_POS_PR_N4; + tx_comb_pos->choice.n4.comb_offset_n4 = nrppa_tx_comb_pos->choice.n4->combOffset_n4; + tx_comb_pos->choice.n4.cyclic_shift_n4 = nrppa_tx_comb_pos->choice.n4->cyclicShift_n4; + break; + case NRPPA_TransmissionCombPos_PR_n8: + tx_comb_pos->present = NRPPA_TRANSMISSION_COMB_POS_PR_N8; + tx_comb_pos->choice.n8.comb_offset_n8 = nrppa_tx_comb_pos->choice.n8->combOffset_n8; + tx_comb_pos->choice.n8.cyclic_shift_n8 = nrppa_tx_comb_pos->choice.n8->cyclicShift_n8; + break; + default: + AssertFatal(false, "illegal transmissionComb %d\n", nrppa_tx_comb_pos->present); + break; + } + + pos_srs_resource->start_position = nrppa_pos_srs_resource->startPosition; + + switch (nrppa_pos_srs_resource->nrofSymbols) { + case NRPPA_PosSRSResource_Item__nrofSymbols_n1: + pos_srs_resource->nr_of_symbols = NRPPA_SRS_RESOURCE_ITEM_NUMBER_OF_SYMBOLS_N1; + break; + case NRPPA_PosSRSResource_Item__nrofSymbols_n2: + pos_srs_resource->nr_of_symbols = NRPPA_SRS_RESOURCE_ITEM_NUMBER_OF_SYMBOLS_N2; + break; + case NRPPA_PosSRSResource_Item__nrofSymbols_n4: + pos_srs_resource->nr_of_symbols = NRPPA_SRS_RESOURCE_ITEM_NUMBER_OF_SYMBOLS_N4; + break; + case NRPPA_PosSRSResource_Item__nrofSymbols_n8: + pos_srs_resource->nr_of_symbols = NRPPA_SRS_RESOURCE_ITEM_NUMBER_OF_SYMBOLS_N8; + break; + case NRPPA_PosSRSResource_Item__nrofSymbols_n12: + pos_srs_resource->nr_of_symbols = NRPPA_SRS_RESOURCE_ITEM_NUMBER_OF_SYMBOLS_N12; + break; + default: + AssertFatal(false, "illegal number of symbols %ld\n", nrppa_pos_srs_resource->nrofSymbols); + break; + } + + pos_srs_resource->freq_domain_shift = nrppa_pos_srs_resource->freqDomainShift; + pos_srs_resource->c_srs = nrppa_pos_srs_resource->c_SRS; + + switch (nrppa_pos_srs_resource->groupOrSequenceHopping) { + case NRPPA_PosSRSResource_Item__groupOrSequenceHopping_neither: + pos_srs_resource->group_or_sequence_hopping = NRPPA_GROUPORSEQUENCEHOPPING_NOTHING; + break; + case NRPPA_PosSRSResource_Item__groupOrSequenceHopping_groupHopping: + pos_srs_resource->group_or_sequence_hopping = NRPPA_GROUPORSEQUENCEHOPPING_GROUPHOPPING; + break; + case NRPPA_PosSRSResource_Item__groupOrSequenceHopping_sequenceHopping: + pos_srs_resource->group_or_sequence_hopping = NRPPA_GROUPORSEQUENCEHOPPING_SEQUENCEHOPPING; + break; + default: + AssertFatal(false, "illegal groupOrSequenceHopping %ld\n", nrppa_pos_srs_resource->groupOrSequenceHopping); + break; + } + + NRPPA_ResourceTypePos_t *nrppa_res_type_pos = &nrppa_pos_srs_resource->resourceTypePos; + nrppa_resource_type_pos_t *res_type_pos = &pos_srs_resource->resource_type_pos; + if (nrppa_res_type_pos->present == NRPPA_ResourceTypePos_PR_NOTHING) { + res_type_pos->present = NRPPA_RESOURCE_TYPE_POS_PR_NOTHING; + } else if (nrppa_res_type_pos->present == NRPPA_ResourceTypePos_PR_periodic) { + res_type_pos->present = NRPPA_RESOURCE_TYPE_POS_PR_PERIODIC; + nrppa_resource_type_periodic_pos_t *pos_periodic = &res_type_pos->choice.periodic; + switch (nrppa_res_type_pos->choice.periodic->periodicity) { + case NRPPA_ResourceTypePeriodicPos__periodicity_slot1: + pos_periodic->periodicity = NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT1; + break; + case NRPPA_ResourceTypePeriodicPos__periodicity_slot2: + pos_periodic->periodicity = NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT2; + break; + case NRPPA_ResourceTypePeriodicPos__periodicity_slot4: + pos_periodic->periodicity = NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT4; + break; + case NRPPA_ResourceTypePeriodicPos__periodicity_slot5: + pos_periodic->periodicity = NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT5; + break; + case NRPPA_ResourceTypePeriodicPos__periodicity_slot8: + pos_periodic->periodicity = NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT8; + break; + case NRPPA_ResourceTypePeriodicPos__periodicity_slot10: + pos_periodic->periodicity = NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT10; + break; + case NRPPA_ResourceTypePeriodicPos__periodicity_slot16: + pos_periodic->periodicity = NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT16; + break; + case NRPPA_ResourceTypePeriodicPos__periodicity_slot20: + pos_periodic->periodicity = NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT20; + break; + case NRPPA_ResourceTypePeriodicPos__periodicity_slot32: + pos_periodic->periodicity = NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT32; + break; + case NRPPA_ResourceTypePeriodicPos__periodicity_slot40: + pos_periodic->periodicity = NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT40; + break; + case NRPPA_ResourceTypePeriodicPos__periodicity_slot64: + pos_periodic->periodicity = NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT64; + break; + case NRPPA_ResourceTypePeriodicPos__periodicity_slot80: + pos_periodic->periodicity = NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT80; + break; + case NRPPA_ResourceTypePeriodicPos__periodicity_slot160: + pos_periodic->periodicity = NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT160; + break; + case NRPPA_ResourceTypePeriodicPos__periodicity_slot320: + pos_periodic->periodicity = NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT320; + break; + case NRPPA_ResourceTypePeriodicPos__periodicity_slot640: + pos_periodic->periodicity = NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT640; + break; + case NRPPA_ResourceTypePeriodicPos__periodicity_slot1280: + pos_periodic->periodicity = NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT1280; + break; + case NRPPA_ResourceTypePeriodicPos__periodicity_slot2560: + pos_periodic->periodicity = NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT2560; + break; + case NRPPA_ResourceTypePeriodicPos__periodicity_slot5120: + pos_periodic->periodicity = NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT5120; + break; + case NRPPA_ResourceTypePeriodicPos__periodicity_slot10240: + pos_periodic->periodicity = NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT10240; + break; + case NRPPA_ResourceTypePeriodicPos__periodicity_slot20480: + pos_periodic->periodicity = NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT20480; + break; + case NRPPA_ResourceTypePeriodicPos__periodicity_slot40960: + pos_periodic->periodicity = NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT40960; + break; + case NRPPA_ResourceTypePeriodicPos__periodicity_slot81920: + pos_periodic->periodicity = NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT81920; + break; + default: + AssertFatal(false, "illegal periodicity %ld\n", nrppa_res_type_pos->choice.periodic->periodicity); + break; + } + pos_periodic->offset = nrppa_res_type_pos->choice.periodic->offset; + } else if (nrppa_res_type_pos->present == NRPPA_ResourceTypePos_PR_semi_persistent) { + res_type_pos->present = NRPPA_RESOURCE_TYPE_POS_PR_SEMI_PERSISTENT; + nrppa_resource_type_semi_persistent_pos_t *pos_semi_persistent = &res_type_pos->choice.semi_persistent; + switch (nrppa_res_type_pos->choice.semi_persistent->periodicity) { + case NRPPA_ResourceTypeSemi_persistentPos__periodicity_slot1: + pos_semi_persistent->periodicity = NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT1; + break; + case NRPPA_ResourceTypeSemi_persistentPos__periodicity_slot2: + pos_semi_persistent->periodicity = NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT2; + break; + case NRPPA_ResourceTypeSemi_persistentPos__periodicity_slot4: + pos_semi_persistent->periodicity = NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT4; + break; + case NRPPA_ResourceTypeSemi_persistentPos__periodicity_slot5: + pos_semi_persistent->periodicity = NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT5; + break; + case NRPPA_ResourceTypeSemi_persistentPos__periodicity_slot8: + pos_semi_persistent->periodicity = NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT8; + break; + case NRPPA_ResourceTypeSemi_persistentPos__periodicity_slot10: + pos_semi_persistent->periodicity = NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT10; + break; + case NRPPA_ResourceTypeSemi_persistentPos__periodicity_slot16: + pos_semi_persistent->periodicity = NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT16; + break; + case NRPPA_ResourceTypeSemi_persistentPos__periodicity_slot20: + pos_semi_persistent->periodicity = NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT20; + break; + case NRPPA_ResourceTypeSemi_persistentPos__periodicity_slot32: + pos_semi_persistent->periodicity = NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT32; + break; + case NRPPA_ResourceTypeSemi_persistentPos__periodicity_slot40: + pos_semi_persistent->periodicity = NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT40; + break; + case NRPPA_ResourceTypeSemi_persistentPos__periodicity_slot64: + pos_semi_persistent->periodicity = NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT64; + break; + case NRPPA_ResourceTypeSemi_persistentPos__periodicity_slot80: + pos_semi_persistent->periodicity = NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT80; + break; + case NRPPA_ResourceTypeSemi_persistentPos__periodicity_slot160: + pos_semi_persistent->periodicity = NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT160; + break; + case NRPPA_ResourceTypeSemi_persistentPos__periodicity_slot320: + pos_semi_persistent->periodicity = NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT320; + break; + case NRPPA_ResourceTypeSemi_persistentPos__periodicity_slot640: + pos_semi_persistent->periodicity = NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT640; + break; + case NRPPA_ResourceTypeSemi_persistentPos__periodicity_slot1280: + pos_semi_persistent->periodicity = NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT1280; + break; + case NRPPA_ResourceTypeSemi_persistentPos__periodicity_slot2560: + pos_semi_persistent->periodicity = NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT2560; + break; + case NRPPA_ResourceTypeSemi_persistentPos__periodicity_slot5120: + pos_semi_persistent->periodicity = NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT5120; + break; + case NRPPA_ResourceTypeSemi_persistentPos__periodicity_slot10240: + pos_semi_persistent->periodicity = NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT10240; + break; + case NRPPA_ResourceTypeSemi_persistentPos__periodicity_slot20480: + pos_semi_persistent->periodicity = NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT20480; + break; + case NRPPA_ResourceTypeSemi_persistentPos__periodicity_slot40960: + pos_semi_persistent->periodicity = NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT40960; + break; + case NRPPA_ResourceTypeSemi_persistentPos__periodicity_slot81920: + pos_semi_persistent->periodicity = NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT81920; + break; + default: + AssertFatal(false, "illegal periodicity %ld\n", nrppa_res_type_pos->choice.semi_persistent->periodicity); + break; + } + pos_semi_persistent->offset = nrppa_res_type_pos->choice.semi_persistent->offset; + } else if (nrppa_res_type_pos->present == NRPPA_ResourceTypePos_PR_aperiodic) { + res_type_pos->present = NRPPA_RESOURCE_TYPE_POS_PR_APERIODIC; + res_type_pos->choice.aperiodic.slot_offset = nrppa_res_type_pos->choice.aperiodic->slotOffset; + } else { + AssertFatal(false, "illegal resourceType %d\n", nrppa_res_type_pos->present); + } + + pos_srs_resource->sequence_id = nrppa_pos_srs_resource->sequenceId; + } + } + + // optional: sRSResourceSet_List + if (in_config->sRSResourceSet_List) { + out_config->srs_resource_set_list = calloc_or_fail(1, sizeof(*out_config->srs_resource_set_list)); + nrppa_srs_resource_set_list_t *srs_resource_set_list = out_config->srs_resource_set_list; + uint32_t srs_resource_set_list_length = in_config->sRSResourceSet_List->list.count; + srs_resource_set_list->srs_resource_set_list_length = srs_resource_set_list_length; + srs_resource_set_list->srs_resource_set = + calloc_or_fail(srs_resource_set_list_length, sizeof(*srs_resource_set_list->srs_resource_set)); + for (int i = 0; i < srs_resource_set_list_length; i++) { + NRPPA_SRSResourceSet_t *nrppa_srs_resource_set = in_config->sRSResourceSet_List->list.array[i]; + nrppa_srs_resource_set_t *srs_resource_set = &srs_resource_set_list->srs_resource_set[i]; + srs_resource_set->srs_resource_set_id = nrppa_srs_resource_set->sRSResourceSetID; + uint8_t srs_resource_id_list_length = nrppa_srs_resource_set->sRSResourceID_List.list.count; + srs_resource_set->srs_resource_id_list.srs_resource_id_list_length = srs_resource_id_list_length; + srs_resource_set->srs_resource_id_list.srs_resource_id = + calloc_or_fail(srs_resource_id_list_length, sizeof(*srs_resource_set->srs_resource_id_list.srs_resource_id)); + for (int j = 0; j < srs_resource_id_list_length; j++) { + NRPPA_SRSResourceID_t *nrppa_srs_resource_id = nrppa_srs_resource_set->sRSResourceID_List.list.array[j]; + srs_resource_set->srs_resource_id_list.srs_resource_id[j] = *nrppa_srs_resource_id; + } + + NRPPA_ResourceSetType_t *nrppa_res_set_type = &nrppa_srs_resource_set->resourceSetType; + nrppa_resource_set_type_t *res_set_type = &srs_resource_set->resource_set_type; + switch (nrppa_res_set_type->present) { + case NRPPA_ResourceSetType_PR_NOTHING: + res_set_type->present = NRPPA_RESOURCE_SET_TYPE_PR_NOTHING; + break; + case NRPPA_ResourceSetType_PR_periodic: + res_set_type->present = NRPPA_RESOURCE_SET_TYPE_PR_PERIODIC; + res_set_type->choice.periodic = nrppa_res_set_type->choice.periodic->periodicSet; + break; + case NRPPA_ResourceSetType_PR_semi_persistent: + res_set_type->present = NRPPA_RESOURCE_SET_TYPE_PR_SEMI_PERSISTENT; + res_set_type->choice.semi_persistent = nrppa_res_set_type->choice.semi_persistent->semi_persistentSet; + break; + case NRPPA_ResourceSetType_PR_aperiodic: + res_set_type->present = NRPPA_RESOURCE_SET_TYPE_PR_APERIODIC; + res_set_type->choice.aperiodic.srs_resource_trigger = nrppa_res_set_type->choice.aperiodic->sRSResourceTrigger; + res_set_type->choice.aperiodic.slot_offset = nrppa_res_set_type->choice.aperiodic->slotoffset; + break; + default: + AssertFatal(false, "illegal resource set type %d\n", nrppa_res_set_type->present); + break; + } + } + } + + // optional: posSRSResourceSet_List + if (in_config->posSRSResourceSet_List) { + out_config->pos_srs_resource_set_list = calloc_or_fail(1, sizeof(*out_config->pos_srs_resource_set_list)); + nrppa_pos_srs_resource_set_list_t *pos_srs_resource_set_list = out_config->pos_srs_resource_set_list; + uint32_t pos_srs_resource_set_list_length = in_config->posSRSResourceSet_List->list.count; + pos_srs_resource_set_list->pos_srs_resource_set_list_length = pos_srs_resource_set_list_length; + pos_srs_resource_set_list->pos_srs_resource_set_item = + calloc_or_fail(pos_srs_resource_set_list_length, sizeof(*pos_srs_resource_set_list->pos_srs_resource_set_item)); + for (int i = 0; i < pos_srs_resource_set_list_length; i++) { + NRPPA_PosSRSResourceSet_Item_t *nrppa_pos_srs_resource_set = in_config->posSRSResourceSet_List->list.array[i]; + nrppa_pos_srs_resource_set_item_t *pos_srs_resource_set = &pos_srs_resource_set_list->pos_srs_resource_set_item[i]; + pos_srs_resource_set->pos_srs_resource_set_id = nrppa_pos_srs_resource_set->possrsResourceSetID; + uint8_t pos_srs_resource_id_list_length = nrppa_pos_srs_resource_set->possRSResourceID_List.list.count; + pos_srs_resource_set->pos_srs_resource_id_list.pos_srs_resource_id_list_length = pos_srs_resource_id_list_length; + pos_srs_resource_set->pos_srs_resource_id_list.srs_pos_resource_id = + calloc_or_fail(pos_srs_resource_id_list_length, + sizeof(*pos_srs_resource_set->pos_srs_resource_id_list.srs_pos_resource_id)); + for (int j = 0; j < pos_srs_resource_id_list_length; j++) { + NRPPA_SRSPosResourceID_t *nrppa_pos_srs_resource_id = nrppa_pos_srs_resource_set->possRSResourceID_List.list.array[j]; + pos_srs_resource_set->pos_srs_resource_id_list.srs_pos_resource_id[j] = *nrppa_pos_srs_resource_id; + } + + NRPPA_PosResourceSetType_t *nrppa_pos_res_set_type = &nrppa_pos_srs_resource_set->posresourceSetType; + nrppa_pos_resource_set_type_t *pos_res_set_type = &pos_srs_resource_set->pos_resource_set_type; + switch (nrppa_pos_res_set_type->present) { + case NRPPA_PosResourceSetType_PR_NOTHING: + pos_res_set_type->present = NRPPA_POS_RESOURCE_SET_TYPE_PR_NOTHING; + break; + case NRPPA_PosResourceSetType_PR_periodic: + pos_res_set_type->present = NRPPA_POS_RESOURCE_SET_TYPE_PR_PERIODIC; + pos_res_set_type->choice.periodic = nrppa_pos_res_set_type->choice.periodic->posperiodicSet; + break; + case NRPPA_PosResourceSetType_PR_semi_persistent: + pos_res_set_type->present = NRPPA_POS_RESOURCE_SET_TYPE_PR_SEMI_PERSISTENT; + pos_res_set_type->choice.semi_persistent = nrppa_pos_res_set_type->choice.semi_persistent->possemi_persistentSet; + break; + case NRPPA_PosResourceSetType_PR_aperiodic: + pos_res_set_type->present = NRPPA_POS_RESOURCE_SET_TYPE_PR_APERIODIC; + pos_res_set_type->choice.srs_resource = nrppa_pos_res_set_type->choice.aperiodic->sRSResourceTrigger; + break; + default: + AssertFatal(false, "illegal resource set type pos %d\n", nrppa_pos_res_set_type->present); + break; + } + } + } +} + +static void decode_srs_carrier_list_item(const NRPPA_SRSCarrier_List_Item_t *in_item, nrppa_srs_carrier_list_item_t *out_item) +{ + // pointA + out_item->pointA = in_item->pointA; + + // Uplink Channel BW-PerSCS-List + nrppa_uplink_channel_bw_per_scs_list_t *uplink_channel_bw_per_scs_list = &out_item->uplink_channel_bw_per_scs_list; + const NRPPA_UplinkChannelBW_PerSCS_List_t *nrppa_uplink_channel_bw_per_scs_list = &in_item->uplinkChannelBW_PerSCS_List; + + uint32_t scs_specific_carrier_list_length = nrppa_uplink_channel_bw_per_scs_list->list.count; + AssertFatal(scs_specific_carrier_list_length > 0, "Atleast 1 uplink channel bw per scs list should be present\n"); + uplink_channel_bw_per_scs_list->scs_specific_carrier_list_length = scs_specific_carrier_list_length; + uplink_channel_bw_per_scs_list->scs_specific_carrier = + calloc_or_fail(scs_specific_carrier_list_length, sizeof(*uplink_channel_bw_per_scs_list->scs_specific_carrier)); + for (int i = 0; i < scs_specific_carrier_list_length; i++) { + NRPPA_SCS_SpecificCarrier_t *nrppa_scs_specific_carrier = nrppa_uplink_channel_bw_per_scs_list->list.array[i]; + nrppa_scs_specific_carrier_t *scs_specific_carrier = &uplink_channel_bw_per_scs_list->scs_specific_carrier[i]; + // offset to carrier + scs_specific_carrier->offset_to_carrier = nrppa_scs_specific_carrier->offsetToCarrier; + // subcarrier spacing + switch (nrppa_scs_specific_carrier->subcarrierSpacing) { + case NRPPA_SCS_SpecificCarrier__subcarrierSpacing_kHz15: + scs_specific_carrier->subcarrier_spacing = NRPPA_SUBCARRIER_SPACING_15KHZ; + break; + case NRPPA_SCS_SpecificCarrier__subcarrierSpacing_kHz30: + scs_specific_carrier->subcarrier_spacing = NRPPA_SUBCARRIER_SPACING_30KHZ; + break; + case NRPPA_SCS_SpecificCarrier__subcarrierSpacing_kHz60: + scs_specific_carrier->subcarrier_spacing = NRPPA_SUBCARRIER_SPACING_60KHZ; + break; + case NRPPA_SCS_SpecificCarrier__subcarrierSpacing_kHz120: + scs_specific_carrier->subcarrier_spacing = NRPPA_SUBCARRIER_SPACING_120KHZ; + break; + default: + AssertFatal(false, "illegal subcarrier spacing %ld\n", nrppa_scs_specific_carrier->subcarrierSpacing); + break; + } + // carrier bandwidth + scs_specific_carrier->carrier_bandwidth = nrppa_scs_specific_carrier->carrierBandwidth; + } + + // Active UL BWP + const NRPPA_ActiveULBWP_t *nrppa_active_ul_bwp = &in_item->activeULBWP; + nrppa_active_ul_bwp_t *active_ul_bwp = &out_item->active_ul_bwp; + + // location and bandwidth + active_ul_bwp->location_and_bandwidth = nrppa_active_ul_bwp->locationAndBandwidth; + // subcarrier spacing + switch (nrppa_active_ul_bwp->subcarrierSpacing) { + case NRPPA_ActiveULBWP__subcarrierSpacing_kHz15: + active_ul_bwp->subcarrier_spacing = NRPPA_SUBCARRIER_SPACING_15KHZ; + break; + case NRPPA_ActiveULBWP__subcarrierSpacing_kHz30: + active_ul_bwp->subcarrier_spacing = NRPPA_SUBCARRIER_SPACING_30KHZ; + break; + case NRPPA_ActiveULBWP__subcarrierSpacing_kHz60: + active_ul_bwp->subcarrier_spacing = NRPPA_SUBCARRIER_SPACING_60KHZ; + break; + case NRPPA_ActiveULBWP__subcarrierSpacing_kHz120: + active_ul_bwp->subcarrier_spacing = NRPPA_SUBCARRIER_SPACING_120KHZ; + break; + default: + AssertFatal(false, "illegal subcarrier spacing %ld\n", nrppa_active_ul_bwp->subcarrierSpacing); + break; + } + + // cyclic prefix + if (nrppa_active_ul_bwp->cyclicPrefix == NRPPA_ActiveULBWP__cyclicPrefix_normal) + active_ul_bwp->cyclic_prefix = NRPPA_CP_TYPE_NORMAL; + else + active_ul_bwp->cyclic_prefix = NRPPA_CP_TYPE_EXTENDED; + + // Tx Direct Current Location + active_ul_bwp->tx_direct_current_location = nrppa_active_ul_bwp->txDirectCurrentLocation; + + // SRS Config + const NRPPA_SRSConfig_t *nrppa_sRSConfig = &nrppa_active_ul_bwp->sRSConfig; + nrppa_srs_config_t *sRSConfig = &active_ul_bwp->srs_config; + decode_srs_config(nrppa_sRSConfig, sRSConfig); +} + +void decode_srs_carrier_list(nrppa_srs_carrier_list_t *out_list, const NRPPA_SRSCarrier_List_t *in_list) +{ + uint32_t list_len = in_list->list.count; + AssertFatal(list_len > 0, "atleast 1 SRS carrier list must be present"); + out_list->srs_carrier_list_length = list_len; + out_list->srs_carrier_list_item = calloc_or_fail(list_len, sizeof(*out_list->srs_carrier_list_item)); + for (int i = 0; i < list_len; i++) { + NRPPA_SRSCarrier_List_Item_t *in_item = in_list->list.array[i]; + nrppa_srs_carrier_list_item_t *out_item = &out_list->srs_carrier_list_item[i]; + decode_srs_carrier_list_item(in_item, out_item); + } +} + +void free_measurement_request(nrppa_measurement_req_t *msg) +{ + free(msg->trp_measurement_request_list.trp_measurement_request_item); + if (msg->measurement_quantities.measurement_quantities_item) { + free(msg->measurement_quantities.measurement_quantities_item); + } + + /* SRS Configuration (O) */ + if (msg->srs_configuration) { + nrppa_srs_carrier_list_t *srs_carrier_list = &msg->srs_configuration->srs_carrier_list; + free_srs_carrier_list(srs_carrier_list); + free(msg->srs_configuration); + } +} + +int nrppa_gNB_handle_measurement_request(nrppa_gnb_ue_info_t *nrppa_msg_info, const NRPPA_NRPPA_PDU_t *pdu) +{ + DevAssert(pdu != NULL); + DevAssert(nrppa_msg_info != NULL); + + LOG_I(NRPPA, "Processing Received Measurement Request \n"); + if (LOG_DEBUGFLAG(DEBUG_ASN1)) { + xer_fprint(stdout, &asn_DEF_NRPPA_NRPPA_PDU, pdu); + } + + // Forward request to RRC + MessageDef *msg = itti_alloc_new_message(TASK_RRC_GNB, 0, NRPPA_MEASUREMENT_REQ); + nrppa_measurement_req_t *req = &NRPPA_MEASUREMENT_REQ(msg); + + // Processing Received TRPInformationRequest + NRPPA_MeasurementRequest_t *container = NULL; + NRPPA_MeasurementRequest_IEs_t *ie = NULL; + + // IE 9.2.3 Message type : mandatory + container = &pdu->choice.initiatingMessage->value.choice.MeasurementRequest; + + // IE 9.2.4 nrppatransactionID : mandatory + req->transaction_id = pdu->choice.initiatingMessage->nrppatransactionID; + + NRPPA_FIND_PROTOCOLIE_BY_ID(NRPPA_MeasurementRequest_IEs_t, ie, container, NRPPA_ProtocolIE_ID_id_LMF_Measurement_ID, true); + + // LMF Measurement ID : mandatory + req->lmf_measurement_id = ie->value.choice.Measurement_ID; + + // IE TRP Measurement Request List : mandatory + NRPPA_FIND_PROTOCOLIE_BY_ID(NRPPA_MeasurementRequest_IEs_t, + ie, + container, + NRPPA_ProtocolIE_ID_id_TRP_MeasurementRequestList, + true); + NRPPA_TRP_MeasurementRequestList_t *nrppa_trp_meas_list = &ie->value.choice.TRP_MeasurementRequestList; + uint8_t meas_req_item_len = nrppa_trp_meas_list->list.count; + AssertError(meas_req_item_len > 0, return false, "at least 1 TRP Measurement Request Item must be present"); + nrppa_trp_measurement_request_list_t *trp_meas_list = &req->trp_measurement_request_list; + trp_meas_list->trp_measurement_request_list_length = meas_req_item_len; + trp_meas_list->trp_measurement_request_item = + calloc_or_fail(meas_req_item_len, sizeof(*trp_meas_list->trp_measurement_request_item)); + for (int i = 0; i < meas_req_item_len; i++) { + trp_meas_list->trp_measurement_request_item[i].trp_id = nrppa_trp_meas_list->list.array[i]->tRP_ID; + } + + // IE Report Characteristics : mandatory + NRPPA_FIND_PROTOCOLIE_BY_ID(NRPPA_MeasurementRequest_IEs_t, ie, container, NRPPA_ProtocolIE_ID_id_ReportCharacteristics, true); + switch (ie->value.choice.ReportCharacteristics) { + case NRPPA_ReportCharacteristics_onDemand: + req->report_characteristics = NRPPA_POSREPORTCHARACTERISTICS_ONDEMAND; + break; + case NRPPA_ReportCharacteristics_periodic: + req->report_characteristics = NRPPA_POSREPORTCHARACTERISTICS_PERIODIC; + break; + default: + AssertError(false, return false, "illegal report characteristics\n"); + break; + } + + // IE Measurement Periodicity : C-if Report Charateristics periodic + if (req->report_characteristics == NRPPA_POSREPORTCHARACTERISTICS_PERIODIC) { + NRPPA_FIND_PROTOCOLIE_BY_ID(NRPPA_MeasurementRequest_IEs_t, ie, container, NRPPA_ProtocolIE_ID_id_MeasurementPeriodicity, true); + switch (ie->value.choice.MeasurementPeriodicity) { + case NRPPA_MeasurementPeriodicity_ms120: + req->measurement_periodicity = NRPPA_POSMEASUREMENTPERIODICITY_MS120; + break; + case NRPPA_MeasurementPeriodicity_ms240: + req->measurement_periodicity = NRPPA_POSMEASUREMENTPERIODICITY_MS240; + break; + case NRPPA_MeasurementPeriodicity_ms480: + req->measurement_periodicity = NRPPA_POSMEASUREMENTPERIODICITY_MS480; + break; + case NRPPA_MeasurementPeriodicity_ms640: + req->measurement_periodicity = NRPPA_POSMEASUREMENTPERIODICITY_MS640; + break; + case NRPPA_MeasurementPeriodicity_ms1024: + req->measurement_periodicity = NRPPA_POSMEASUREMENTPERIODICITY_MS1024; + break; + case NRPPA_MeasurementPeriodicity_ms2048: + req->measurement_periodicity = NRPPA_POSMEASUREMENTPERIODICITY_MS2048; + break; + case NRPPA_MeasurementPeriodicity_ms5120: + req->measurement_periodicity = NRPPA_POSMEASUREMENTPERIODICITY_MS5120; + break; + case NRPPA_MeasurementPeriodicity_ms10240: + req->measurement_periodicity = NRPPA_POSMEASUREMENTPERIODICITY_MS10240; + break; + case NRPPA_MeasurementPeriodicity_min1: + req->measurement_periodicity = NRPPA_POSMEASUREMENTPERIODICITY_MIN1; + break; + case NRPPA_MeasurementPeriodicity_min6: + req->measurement_periodicity = NRPPA_POSMEASUREMENTPERIODICITY_MIN6; + break; + case NRPPA_MeasurementPeriodicity_min12: + req->measurement_periodicity = NRPPA_POSMEASUREMENTPERIODICITY_MIN12; + break; + case NRPPA_MeasurementPeriodicity_min30: + req->measurement_periodicity = NRPPA_POSMEASUREMENTPERIODICITY_MIN30; + break; + case NRPPA_MeasurementPeriodicity_min60: + req->measurement_periodicity = NRPPA_POSMEASUREMENTPERIODICITY_MIN60; + break; + default: + AssertError(false, return false, "illegal measurement periodicity\n"); + break; + } + } + + // IE Measurement Quantity : mandatory (but not handled in OAI-LMF) + NRPPA_FIND_PROTOCOLIE_BY_ID(NRPPA_MeasurementRequest_IEs_t, ie, container, NRPPA_ProtocolIE_ID_id_MeasurementQuantities, false); + if (ie == NULL) { + LOG_W(NRPPA, "MeasurementQuantities is madatory but not handled in OAI LMF\n"); + } else { + NRPPA_TRPMeasurementQuantities_t *nrppa_meas_q = &ie->value.choice.TRPMeasurementQuantities; + uint32_t q_len = nrppa_meas_q->list.count; + AssertError(q_len > 0, return false, "at least 1 TRP Measurement Quantity must be present"); + nrppa_measurement_quantities_t *meas_q = &req->measurement_quantities; + meas_q->measurement_quantities_length = q_len; + meas_q->measurement_quantities_item = calloc_or_fail(q_len, sizeof(*meas_q->measurement_quantities_item)); + nrppa_measurement_quantities_item_t *q_item = meas_q->measurement_quantities_item; + for (int i = 0; i < meas_req_item_len; i++) { + switch (nrppa_meas_q->list.array[i]->tRPMeasurementQuantities_Item) { + case NRPPA_TRPMeasurementQuantities_Item_gNB_RxTxTimeDiff: + q_item[i].measurement_type = NRPPA_POSMEASUREMENTTYPE_GNB_RX_TX; + break; + case NRPPA_TRPMeasurementQuantities_Item_uL_SRS_RSRP: + q_item[i].measurement_type = NRPPA_POSMEASUREMENTTYPE_UL_SRS_RSRP; + break; + case NRPPA_TRPMeasurementQuantities_Item_uL_AoA: + q_item[i].measurement_type = NRPPA_POSMEASUREMENTTYPE_UL_AOA; + break; + case NRPPA_TRPMeasurementQuantities_Item_uL_RTOA: + q_item[i].measurement_type = NRPPA_POSMEASUREMENTTYPE_UL_RTOA; + break; + default: + AssertError(false, return false, "illegal measurement quantity\n"); + break; + } + } + } + + // IE SRS Configuration : optional + NRPPA_FIND_PROTOCOLIE_BY_ID(NRPPA_MeasurementRequest_IEs_t, ie, container, NRPPA_ProtocolIE_ID_id_SRSConfiguration, false); + if (ie != NULL) { + NRPPA_SRSCarrier_List_t *nrppa_srs_carrier_list = &ie->value.choice.SRSConfiguration.sRSCarrier_List; + req->srs_configuration = calloc_or_fail(1, sizeof(*req->srs_configuration)); + nrppa_srs_carrier_list_t *srs_carrier_list = &req->srs_configuration->srs_carrier_list; + decode_srs_carrier_list(srs_carrier_list, nrppa_srs_carrier_list); + } + + nrppa_store_ue_context(nrppa_msg_info, req->transaction_id); + + LOG_I(NRPPA, "Forwarding to RRC Measurement Request transaction_id %d\n", req->transaction_id); + itti_send_msg_to_task(TASK_RRC_GNB, 0, msg); + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NRPPA_NRPPA_PDU, &pdu); + return 0; +} diff --git a/openair3/NRPPA/nrppa_gNB_measurement_information_transfer.h b/openair3/NRPPA/nrppa_gNB_measurement_information_transfer.h new file mode 100644 index 0000000000..f154fc1ce8 --- /dev/null +++ b/openair3/NRPPA/nrppa_gNB_measurement_information_transfer.h @@ -0,0 +1,29 @@ +/* + * 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 NRPPA_GNB_MEASUREMENT_INFORMATION_TRANSFER_H_ +#define NRPPA_GNB_MEASUREMENT_INFORMATION_TRANSFER_H_ + +int nrppa_gNB_handle_measurement_request(nrppa_gnb_ue_info_t *nrppa_msg_info, const NRPPA_NRPPA_PDU_t *pdu); +void decode_srs_carrier_list(nrppa_srs_carrier_list_t *out_list, const NRPPA_SRSCarrier_List_t *in_list); +void free_measurement_request(nrppa_measurement_req_t *msg); + +#endif /* NRPPA_GNB_MEASUREMENT_INFORMATION_TRANSFER_H_ */ diff --git a/openair3/NRPPA/nrppa_includes.h b/openair3/NRPPA/nrppa_includes.h index 6465d6c0af..64c642587c 100644 --- a/openair3/NRPPA/nrppa_includes.h +++ b/openair3/NRPPA/nrppa_includes.h @@ -71,5 +71,8 @@ #include "NRPPA_PosResourceSetTypeAperiodic.h" #include "NRPPA_SemipersistentSRS.h" #include "NRPPA_AperiodicSRS.h" +#include "NRPPA_TRP-MeasurementRequestItem.h" +#include "NRPPA_TRPMeasurementQuantities-Item.h" +#include "NRPPA_TRPMeasurementQuantitiesList-Item.h" #endif /* NRPPA_INCLUDE_H_ */ From cbc85dd448d57455b47a906ff9f564e0ebf7a097 Mon Sep 17 00:00:00 2001 From: Rakesh Mundlamuri Date: Thu, 29 Jan 2026 23:23:52 +0530 Subject: [PATCH 30/44] Add Measurement Response NRPPA message encoding procedures --- openair2/COMMON/nrppa_messages_def.h | 1 + openair2/COMMON/nrppa_messages_types.h | 128 +++++++++ openair3/NRPPA/nrppa_gNB.c | 4 + ...ppa_gNB_measurement_information_transfer.c | 269 ++++++++++++++++++ ...ppa_gNB_measurement_information_transfer.h | 3 + openair3/NRPPA/nrppa_includes.h | 5 + tests/nr-cu-nrppa/nr-cu-nrppa.c | 86 ++++++ 7 files changed, 496 insertions(+) diff --git a/openair2/COMMON/nrppa_messages_def.h b/openair2/COMMON/nrppa_messages_def.h index a68362b18c..aa40adce44 100644 --- a/openair2/COMMON/nrppa_messages_def.h +++ b/openair2/COMMON/nrppa_messages_def.h @@ -41,3 +41,4 @@ MESSAGE_DEF(NRPPA_POSITIONING_ACTIVATION_RESP, nrppa_positioning_activation_resp_t, nrppa_positioning_activation_resp) MESSAGE_DEF(NRPPA_MEASUREMENT_REQ, MESSAGE_PRIORITY_MED, nrppa_measurement_req_t, nrppa_measurement_req) +MESSAGE_DEF(NRPPA_MEASUREMENT_RESP, MESSAGE_PRIORITY_MED, nrppa_measurement_resp_t, nrppa_measurement_resp) diff --git a/openair2/COMMON/nrppa_messages_types.h b/openair2/COMMON/nrppa_messages_types.h index dd42af6354..881362231d 100644 --- a/openair2/COMMON/nrppa_messages_types.h +++ b/openair2/COMMON/nrppa_messages_types.h @@ -31,6 +31,7 @@ #define NRPPA_POSITIONING_ACTIVATION_REQ(mSGpTR) (mSGpTR)->ittiMsg.nrppa_positioning_activation_req #define NRPPA_POSITIONING_ACTIVATION_RESP(mSGpTR) (mSGpTR)->ittiMsg.nrppa_positioning_activation_resp #define NRPPA_MEASUREMENT_REQ(mSGpTR) (mSGpTR)->ittiMsg.nrppa_measurement_req +#define NRPPA_MEASUREMENT_RESP(mSGpTR) (mSGpTR)->ittiMsg.nrppa_measurement_resp /* Structure of Positioning related NRPPA messages */ /* IE structures for Positioning related messages as per TS 38.455 V16.7.1*/ @@ -635,6 +636,122 @@ typedef struct nrppa_pos_measurement_quantities_s { uint32_t measurement_quantities_length; } nrppa_measurement_quantities_t; +typedef struct nrppa_lcs_to_gcs_translationaoa_c { + uint16_t alpha; + uint16_t beta; + uint16_t gamma; +} nrppa_lcs_to_gcs_translationaoa_t; + +typedef struct nrppa_ul_aoa_s { + uint16_t azimuth_aoa; + uint16_t *zenith_aoa; + nrppa_lcs_to_gcs_translationaoa_t *lcs_to_gcs_translation_aoa; +} nrppa_ul_aoa_t; + +typedef union nrppa_relative_path_delay_c { + uint32_t k0; + uint32_t k1; + uint32_t k2; + uint32_t k3; + uint32_t k4; + uint32_t k5; +} nrppa_relative_path_delay_u, nrppa_ul_rtoa_measurement_u, nrppa_gnb_rx_tx_time_diff_u; + +typedef enum nrppa_gnb_rx_tx_time_diff_meas_e { + NRPPA_GNBRXTXTIMEDIFFMEAS_PR_NOTHING, + NRPPA_GNBRXTXTIMEDIFFMEAS_PR_K0, + NRPPA_GNBRXTXTIMEDIFFMEAS_PR_K1, + NRPPA_GNBRXTXTIMEDIFFMEAS_PR_K2, + NRPPA_GNBRXTXTIMEDIFFMEAS_PR_K3, + NRPPA_GNBRXTXTIMEDIFFMEAS_PR_K4, + NRPPA_GNBRXTXTIMEDIFFMEAS_PR_K5 +} nrppa_gnb_rx_tx_time_diff_pr; + +typedef struct nrppa_gnb_rx_tx_time_diff_s { + nrppa_gnb_rx_tx_time_diff_pr present; + nrppa_gnb_rx_tx_time_diff_u choice; +} nrppa_gnb_rx_tx_time_diff_t; + +typedef enum nrppa_ul_rtoa_measurement_e { + NRPPA_ULRTOAMEAS_PR_NOTHING, + NRPPA_ULRTOAMEAS_PR_K0, + NRPPA_ULRTOAMEAS_PR_K1, + NRPPA_ULRTOAMEAS_PR_K2, + NRPPA_ULRTOAMEAS_PR_K3, + NRPPA_ULRTOAMEAS_PR_K4, + NRPPA_ULRTOAMEAS_PR_K5 +} nrppa_ul_rtoa_measurement_pr; + +typedef struct nrppa_ul_rtoa_measurement_s { + nrppa_ul_rtoa_measurement_pr present; + nrppa_ul_rtoa_measurement_u choice; +} nrppa_ul_rtoa_measurement_t; + +typedef union nrppa_measured_results_value_c { + nrppa_ul_aoa_t ul_angle_of_arrival; + uint8_t ul_srs_rsrp; + nrppa_ul_rtoa_measurement_t ul_rtoa; + nrppa_gnb_rx_tx_time_diff_t gnb_rx_tx_time_diff; +} nrppa_measured_results_value_u; + +typedef enum nrppa_measured_results_value_e { + NRPPA_MEASURED_RESULTS_VALUE_PR_NOTHING, + NRPPA_MEASURED_RESULTS_VALUE_PR_UL_ANGLEOFARRIVAL, + NRPPA_MEASURED_RESULTS_VALUE_PR_UL_SRS_RSRP, + NRPPA_MEASURED_RESULTS_VALUE_PR_UL_RTOA, + NRPPA_MEASURED_RESULTS_VALUE_PR_GNB_RXTXTIMEDIFF +} nrppa_measured_results_value_pr; + +typedef struct nrppa_measured_results_value_s { + nrppa_measured_results_value_pr present; + nrppa_measured_results_value_u choice; +} nrppa_measured_results_value_t; + +typedef union nrppa_time_stamp_slot_index_c { + uint8_t scs_15; + uint8_t scs_30; + uint8_t scs_60; + uint8_t scs_120; +} nrppa_time_stamp_slot_index_u; + +typedef enum nrppa_time_stamp_slot_index_e { + NRPPA_TIME_STAMP_SLOT_INDEX_PR_NOTHING, + NRPPA_TIME_STAMP_SLOT_INDEX_PR_SCS_15, + NRPPA_TIME_STAMP_SLOT_INDEX_PR_SCS_30, + NRPPA_TIME_STAMP_SLOT_INDEX_PR_SCS_60, + NRPPA_TIME_STAMP_SLOT_INDEX_PR_SCS_120 +} nrppa_time_stamp_slot_index_pr; + +typedef struct nrppa_time_stamp_slot_index_s { + nrppa_time_stamp_slot_index_pr present; + nrppa_time_stamp_slot_index_u choice; +} nrppa_time_stamp_slot_index_t; + +typedef struct nrppa_time_stamp_s { + uint16_t system_frame_number; + nrppa_time_stamp_slot_index_t slot_index; +} nrppa_time_stamp_t; + +typedef struct nrppa_measurement_result_item_s { + nrppa_measured_results_value_t measured_results_value; + nrppa_time_stamp_t time_stamp; +} nrppa_measurement_result_item_t; + +typedef struct nrppa_measurement_result_s { + nrppa_measurement_result_item_t *measurement_result_item; + uint32_t measurement_result_item_length; +} nrppa_measurement_result_t; + +typedef struct nrppa_measurement_response_item_s { + nrppa_measurement_result_t measurement_result; + uint32_t trp_id; +} nrppa_measurement_response_item_t; + +typedef struct nrppa_measurement_response_list_s { + nrppa_measurement_response_item_t *measurement_response_item; + uint32_t measurement_response_list_length; +} nrppa_measurement_response_list_t; + typedef struct nrppa_trp_information_req_s { // IE 9.2.4 (mandatory) uint16_t transaction_id; @@ -693,4 +810,15 @@ typedef struct nrppa_measurement_req_s { nrppa_srs_configuration_t *srs_configuration; } nrppa_measurement_req_t; +typedef struct nrppa_measurement_resp_s { + // IE 9.2.4 (mandatory) + uint16_t transaction_id; + // (mandatory) + uint32_t lmf_measurement_id; + // (mandatory) + uint32_t ran_measurement_id; + // (optional) + nrppa_measurement_response_list_t *measurement_response_list; +} nrppa_measurement_resp_t; + #endif // NRPPA_MESSAGES_TYPES_H_ diff --git a/openair3/NRPPA/nrppa_gNB.c b/openair3/NRPPA/nrppa_gNB.c index 0da07e018e..a561c026fd 100644 --- a/openair3/NRPPA/nrppa_gNB.c +++ b/openair3/NRPPA/nrppa_gNB.c @@ -31,6 +31,7 @@ #include "nrppa_common.h" #include "nrppa_gNB_handlers.h" #include "nrppa_gNB_location_information_transfer.h" +#include "nrppa_gNB_measurement_information_transfer.h" void nrppa_gNB_init(void) { @@ -66,6 +67,9 @@ void *nrppa_gNB_process_itti_msg(void *notUsed) case NRPPA_POSITIONING_ACTIVATION_RESP: nrppa_gNB_positioning_activation_response(instance, received_msg); break; + case NRPPA_MEASUREMENT_RESP: + nrppa_gNB_measurement_response(instance, received_msg); + break; default: LOG_E(NRPPA, "Received unhandled message: %d:%s\n", ITTI_MSG_ID(received_msg), ITTI_MSG_NAME(received_msg)); break; diff --git a/openair3/NRPPA/nrppa_gNB_measurement_information_transfer.c b/openair3/NRPPA/nrppa_gNB_measurement_information_transfer.c index 02db797d81..afeacae4c7 100644 --- a/openair3/NRPPA/nrppa_gNB_measurement_information_transfer.c +++ b/openair3/NRPPA/nrppa_gNB_measurement_information_transfer.c @@ -714,6 +714,180 @@ void free_measurement_request(nrppa_measurement_req_t *msg) } } +static NRPPA_TrpMeasurementResult_t encode_measurement_results(nrppa_measurement_result_t *in_result) +{ + NRPPA_TrpMeasurementResult_t out_result = {0}; + for (int i = 0; i < in_result->measurement_result_item_length; i++) { + asn1cSequenceAdd(out_result.list, NRPPA_TrpMeasurementResultItem_t, out_item); + nrppa_measurement_result_item_t *in_item = &in_result->measurement_result_item[i]; + NRPPA_TrpMeasuredResultsValue_t *out_meas_res_val = &out_item->measuredResultsValue; + nrppa_measured_results_value_t *in_meas_res_val = &in_item->measured_results_value; + switch (in_meas_res_val->present) { + case NRPPA_MEASURED_RESULTS_VALUE_PR_NOTHING: + out_meas_res_val->present = NRPPA_TrpMeasuredResultsValue_PR_NOTHING; + break; + case NRPPA_MEASURED_RESULTS_VALUE_PR_UL_ANGLEOFARRIVAL: + out_meas_res_val->present = NRPPA_TrpMeasuredResultsValue_PR_uL_AngleOfArrival; + asn1cCalloc(out_meas_res_val->choice.uL_AngleOfArrival, out_ul_aoa); + nrppa_ul_aoa_t *in_ul_aoa = &in_meas_res_val->choice.ul_angle_of_arrival; + out_ul_aoa->azimuthAoA = in_ul_aoa->azimuth_aoa; + if (in_ul_aoa->zenith_aoa) { + asn1cCalloc(out_ul_aoa->zenithAoA, out_z_aoa); + *out_z_aoa = *in_ul_aoa->zenith_aoa; + } + break; + case NRPPA_MEASURED_RESULTS_VALUE_PR_UL_SRS_RSRP: + out_meas_res_val->present = NRPPA_TrpMeasuredResultsValue_PR_uL_SRS_RSRP; + out_meas_res_val->choice.uL_SRS_RSRP = in_meas_res_val->choice.ul_srs_rsrp; + break; + case NRPPA_MEASURED_RESULTS_VALUE_PR_UL_RTOA: + out_meas_res_val->present = NRPPA_TrpMeasuredResultsValue_PR_uL_RTOA; + asn1cCalloc(out_meas_res_val->choice.uL_RTOA, out_ul_rtoa); + nrppa_ul_rtoa_measurement_t *in_ul_rtoa = &in_meas_res_val->choice.ul_rtoa; + switch (in_ul_rtoa->present) { + case NRPPA_ULRTOAMEAS_PR_NOTHING: + out_ul_rtoa->uLRTOAmeas.present = NRPPA_ULRTOAMeas_PR_NOTHING; + break; + case NRPPA_ULRTOAMEAS_PR_K0: + out_ul_rtoa->uLRTOAmeas.present = NRPPA_ULRTOAMeas_PR_k0; + out_ul_rtoa->uLRTOAmeas.choice.k0 = in_ul_rtoa->choice.k0; + break; + case NRPPA_ULRTOAMEAS_PR_K1: + out_ul_rtoa->uLRTOAmeas.present = NRPPA_ULRTOAMeas_PR_k1; + out_ul_rtoa->uLRTOAmeas.choice.k1 = in_ul_rtoa->choice.k1; + break; + case NRPPA_ULRTOAMEAS_PR_K2: + out_ul_rtoa->uLRTOAmeas.present = NRPPA_ULRTOAMeas_PR_k2; + out_ul_rtoa->uLRTOAmeas.choice.k2 = in_ul_rtoa->choice.k2; + break; + case NRPPA_ULRTOAMEAS_PR_K3: + out_ul_rtoa->uLRTOAmeas.present = NRPPA_ULRTOAMeas_PR_k3; + out_ul_rtoa->uLRTOAmeas.choice.k3 = in_ul_rtoa->choice.k3; + break; + case NRPPA_ULRTOAMEAS_PR_K4: + out_ul_rtoa->uLRTOAmeas.present = NRPPA_ULRTOAMeas_PR_k4; + out_ul_rtoa->uLRTOAmeas.choice.k4 = in_ul_rtoa->choice.k4; + break; + case NRPPA_ULRTOAMEAS_PR_K5: + out_ul_rtoa->uLRTOAmeas.present = NRPPA_ULRTOAMeas_PR_k5; + out_ul_rtoa->uLRTOAmeas.choice.k5 = in_ul_rtoa->choice.k5; + break; + default: + AssertFatal(false, "illegal ul rtoa measure type\n"); + break; + } + break; + case NRPPA_MEASURED_RESULTS_VALUE_PR_GNB_RXTXTIMEDIFF: + out_meas_res_val->present = NRPPA_TrpMeasuredResultsValue_PR_gNB_RxTxTimeDiff; + asn1cCalloc(out_meas_res_val->choice.gNB_RxTxTimeDiff, out_rxtx_time_diff); + nrppa_gnb_rx_tx_time_diff_t *in_rxtx_time_diff = &in_meas_res_val->choice.gnb_rx_tx_time_diff; + switch (in_rxtx_time_diff->present) { + case NRPPA_GNBRXTXTIMEDIFFMEAS_PR_NOTHING: + out_rxtx_time_diff->rxTxTimeDiff.present = NRPPA_GNBRxTxTimeDiffMeas_PR_NOTHING; + break; + case NRPPA_GNBRXTXTIMEDIFFMEAS_PR_K0: + out_rxtx_time_diff->rxTxTimeDiff.present = NRPPA_GNBRxTxTimeDiffMeas_PR_k0; + out_rxtx_time_diff->rxTxTimeDiff.choice.k0 = in_rxtx_time_diff->choice.k0; + break; + case NRPPA_GNBRXTXTIMEDIFFMEAS_PR_K1: + out_rxtx_time_diff->rxTxTimeDiff.present = NRPPA_GNBRxTxTimeDiffMeas_PR_k1; + out_rxtx_time_diff->rxTxTimeDiff.choice.k1 = in_rxtx_time_diff->choice.k1; + break; + case NRPPA_GNBRXTXTIMEDIFFMEAS_PR_K2: + out_rxtx_time_diff->rxTxTimeDiff.present = NRPPA_GNBRxTxTimeDiffMeas_PR_k2; + out_rxtx_time_diff->rxTxTimeDiff.choice.k2 = in_rxtx_time_diff->choice.k2; + break; + case NRPPA_GNBRXTXTIMEDIFFMEAS_PR_K3: + out_rxtx_time_diff->rxTxTimeDiff.present = NRPPA_GNBRxTxTimeDiffMeas_PR_k3; + out_rxtx_time_diff->rxTxTimeDiff.choice.k3 = in_rxtx_time_diff->choice.k3; + break; + case NRPPA_GNBRXTXTIMEDIFFMEAS_PR_K4: + out_rxtx_time_diff->rxTxTimeDiff.present = NRPPA_GNBRxTxTimeDiffMeas_PR_k4; + out_rxtx_time_diff->rxTxTimeDiff.choice.k4 = in_rxtx_time_diff->choice.k4; + break; + case NRPPA_GNBRXTXTIMEDIFFMEAS_PR_K5: + out_rxtx_time_diff->rxTxTimeDiff.present = NRPPA_GNBRxTxTimeDiffMeas_PR_k5; + out_rxtx_time_diff->rxTxTimeDiff.choice.k5 = in_rxtx_time_diff->choice.k5; + break; + default: + AssertFatal(false, "illegal ul rtoa measure type\n"); + break; + } + break; + default: + AssertFatal(false, "illegal measured results type\n"); + break; + } + + NRPPA_TimeStamp_t *out_time_stamp = &out_item->timeStamp; + nrppa_time_stamp_t *in_time_stamp = &in_item->time_stamp; + out_time_stamp->systemFrameNumber = in_time_stamp->system_frame_number; + switch (in_time_stamp->slot_index.present) { + case NRPPA_TIME_STAMP_SLOT_INDEX_PR_NOTHING: + out_time_stamp->slotIndex.present = NRPPA_TimeStampSlotIndex_PR_NOTHING; + break; + case NRPPA_TIME_STAMP_SLOT_INDEX_PR_SCS_15: + out_time_stamp->slotIndex.present = NRPPA_TimeStampSlotIndex_PR_sCS_15; + out_time_stamp->slotIndex.choice.sCS_15 = in_time_stamp->slot_index.choice.scs_15; + break; + case NRPPA_TIME_STAMP_SLOT_INDEX_PR_SCS_30: + out_time_stamp->slotIndex.present = NRPPA_TimeStampSlotIndex_PR_sCS_30; + out_time_stamp->slotIndex.choice.sCS_30 = in_time_stamp->slot_index.choice.scs_30; + break; + case NRPPA_TIME_STAMP_SLOT_INDEX_PR_SCS_60: + out_time_stamp->slotIndex.present = NRPPA_TimeStampSlotIndex_PR_sCS_60; + out_time_stamp->slotIndex.choice.sCS_60 = in_time_stamp->slot_index.choice.scs_60; + break; + case NRPPA_TIME_STAMP_SLOT_INDEX_PR_SCS_120: + out_time_stamp->slotIndex.present = NRPPA_TimeStampSlotIndex_PR_sCS_120; + out_time_stamp->slotIndex.choice.sCS_120 = in_time_stamp->slot_index.choice.scs_120; + break; + default: + AssertFatal(false, "illegal slot index\n"); + break; + } + } + return out_result; +} + +NRPPA_TRP_MeasurementResponseList_t encode_trp_measurement_reponse_list(nrppa_measurement_response_list_t *in_list) +{ + NRPPA_TRP_MeasurementResponseList_t out_list = {0}; + for (int i = 0; i < in_list->measurement_response_list_length; i++) { + asn1cSequenceAdd(out_list.list, NRPPA_TRP_MeasurementResponseItem_t, out_item); + nrppa_measurement_response_item_t *in_item = &in_list->measurement_response_item[i]; + out_item->tRP_ID = in_item->trp_id; + out_item->measurementResult = encode_measurement_results(&in_item->measurement_result); + } + + return out_list; +} + +void free_measurement_resp(nrppa_measurement_resp_t *msg) +{ + if (msg->measurement_response_list) { + nrppa_measurement_response_list_t *list = msg->measurement_response_list; + uint32_t meas_resp_list_len = list->measurement_response_list_length; + for (int i = 0; i < meas_resp_list_len; i++) { + nrppa_measurement_response_item_t *meas_response_item = &list->measurement_response_item[i]; + nrppa_measurement_result_t *MeasurementResult = &meas_response_item->measurement_result; + uint32_t meas_result_length = MeasurementResult->measurement_result_item_length; + for (int j = 0; j < meas_result_length; j++) { + nrppa_measurement_result_item_t *item = &MeasurementResult->measurement_result_item[j]; + nrppa_measured_results_value_t *measuredResultsValue = &item->measured_results_value; + if (measuredResultsValue->present == NRPPA_MEASURED_RESULTS_VALUE_PR_UL_ANGLEOFARRIVAL) { + if (measuredResultsValue->choice.ul_angle_of_arrival.zenith_aoa) { + free(measuredResultsValue->choice.ul_angle_of_arrival.zenith_aoa); + } + } + } + free(MeasurementResult->measurement_result_item); + } + free(msg->measurement_response_list->measurement_response_item); + free(msg->measurement_response_list); + } +} + int nrppa_gNB_handle_measurement_request(nrppa_gnb_ue_info_t *nrppa_msg_info, const NRPPA_NRPPA_PDU_t *pdu) { DevAssert(pdu != NULL); @@ -872,3 +1046,98 @@ int nrppa_gNB_handle_measurement_request(nrppa_gnb_ue_info_t *nrppa_msg_info, co ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NRPPA_NRPPA_PDU, &pdu); return 0; } + +int nrppa_gNB_measurement_response(instance_t instance, MessageDef *msg_p) +{ + DevAssert(msg_p); + nrppa_measurement_resp_t *resp = &NRPPA_MEASUREMENT_RESP(msg_p); + nrppa_gNB_ue_context_t *ue_info = nrppa_detach_ue_context(resp->transaction_id); + + if (ue_info->gNB_ue_ngap_id != 0 && ue_info->amf_ue_ngap_id != 0) { + LOG_E(NRPPA, "Illegal gNB_ue_ngap_id %d and amf_ue_ngap_id %ld\n", ue_info->gNB_ue_ngap_id, ue_info->amf_ue_ngap_id); + free_measurement_resp(resp); + nrppa_free_ue_context(ue_info); + return -1; + } + + LOG_I(NRPPA, + "Received measurement response info from RRC with transaction_id %u and gNB_ue_ngap_id %u\n", + ue_info->transaction_id, + ue_info->gNB_ue_ngap_id); + + // Prepare NRPPA TRP Information transfer Response + NRPPA_NRPPA_PDU_t pdu = {0}; + + // IE: 9.2.3 Message Type : mandatory + pdu.present = NRPPA_NRPPA_PDU_PR_successfulOutcome; + asn1cCalloc(pdu.choice.successfulOutcome, head); + head->procedureCode = NRPPA_ProcedureCode_id_Measurement; + head->criticality = NRPPA_Criticality_reject; + head->value.present = NRPPA_SuccessfulOutcome__value_PR_MeasurementResponse; + + // IE 9.2.4 nrppatransactionID : mandatory + head->nrppatransactionID = resp->transaction_id; + NRPPA_MeasurementResponse_t *out = &head->value.choice.MeasurementResponse; + + // IE LMF Measurement ID : mandatory + { + asn1cSequenceAdd(out->protocolIEs.list, NRPPA_MeasurementResponse_IEs_t, ie); + ie->id = NRPPA_ProtocolIE_ID_id_LMF_Measurement_ID; + ie->criticality = NRPPA_Criticality_reject; + ie->value.present = NRPPA_MeasurementResponse_IEs__value_PR_Measurement_ID; + ie->value.choice.Measurement_ID = resp->lmf_measurement_id; + } + + // IE RAN Measurement ID : mandatory + { + asn1cSequenceAdd(out->protocolIEs.list, NRPPA_MeasurementResponse_IEs_t, ie); + ie->id = NRPPA_ProtocolIE_ID_id_RAN_Measurement_ID; + ie->criticality = NRPPA_Criticality_reject; + ie->value.present = NRPPA_MeasurementResponse_IEs__value_PR_Measurement_ID_1; + ie->value.choice.Measurement_ID_1 = resp->ran_measurement_id; + } + + // IE TRP Measurement Response List : mandatory + { + if (resp->measurement_response_list) { + asn1cSequenceAdd(out->protocolIEs.list, NRPPA_MeasurementResponse_IEs_t, ie); + ie->id = NRPPA_ProtocolIE_ID_id_TRP_MeasurementResponseList; + ie->criticality = NRPPA_Criticality_reject; + ie->value.present = NRPPA_MeasurementResponse_IEs__value_PR_TRP_MeasurementResponseList; + ie->value.choice.TRP_MeasurementResponseList = encode_trp_measurement_reponse_list(resp->measurement_response_list); + } + } + + free_measurement_resp(resp); + + LOG_I(NRPPA, "Calling encoder for Measurement Response \n"); + + if (LOG_DEBUGFLAG(DEBUG_ASN1)) { + xer_fprint(stdout, &asn_DEF_NRPPA_NRPPA_PDU, &pdu); + } + + // Encode NRPPA message + uint8_t *buffer = NULL; + uint32_t length = 0; + if (nrppa_gNB_encode_pdu(&pdu, &buffer, &length) < 0) { + LOG_E(NRPPA, "Failed to encode Uplink NRPPa Measurement Response\n"); + nrppa_free_ue_context(ue_info); + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NRPPA_NRPPA_PDU, &pdu); + return -1; + } + + MessageDef *msg = itti_alloc_new_message(TASK_NRPPA, 0, NGAP_UPLINKNONUEASSOCIATEDNRPPA); + ngap_uplink_non_ue_associated_nrppa_t *ULNRPPA = &NGAP_UPLINKNONUEASSOCIATEDNRPPA(msg); + + // Routing ID + ULNRPPA->routing_id = create_byte_array(ue_info->routing_id.len, ue_info->routing_id.buf); + + // NRPPa PDU + ULNRPPA->nrppa_pdu = create_byte_array(length, buffer); + + // Forward the NRPPA PDU to NGAP + itti_send_msg_to_task(TASK_NGAP, instance, msg); + nrppa_free_ue_context(ue_info); + free(buffer); + return length; +} diff --git a/openair3/NRPPA/nrppa_gNB_measurement_information_transfer.h b/openair3/NRPPA/nrppa_gNB_measurement_information_transfer.h index f154fc1ce8..da03403f4d 100644 --- a/openair3/NRPPA/nrppa_gNB_measurement_information_transfer.h +++ b/openair3/NRPPA/nrppa_gNB_measurement_information_transfer.h @@ -25,5 +25,8 @@ int nrppa_gNB_handle_measurement_request(nrppa_gnb_ue_info_t *nrppa_msg_info, const NRPPA_NRPPA_PDU_t *pdu); void decode_srs_carrier_list(nrppa_srs_carrier_list_t *out_list, const NRPPA_SRSCarrier_List_t *in_list); void free_measurement_request(nrppa_measurement_req_t *msg); +int nrppa_gNB_measurement_response(instance_t instance, MessageDef *msg_p); +NRPPA_TRP_MeasurementResponseList_t encode_trp_measurement_reponse_list(nrppa_measurement_response_list_t *in_list); +void free_measurement_resp(nrppa_measurement_resp_t *msg); #endif /* NRPPA_GNB_MEASUREMENT_INFORMATION_TRANSFER_H_ */ diff --git a/openair3/NRPPA/nrppa_includes.h b/openair3/NRPPA/nrppa_includes.h index 64c642587c..98e447d379 100644 --- a/openair3/NRPPA/nrppa_includes.h +++ b/openair3/NRPPA/nrppa_includes.h @@ -74,5 +74,10 @@ #include "NRPPA_TRP-MeasurementRequestItem.h" #include "NRPPA_TRPMeasurementQuantities-Item.h" #include "NRPPA_TRPMeasurementQuantitiesList-Item.h" +#include "NRPPA_TRP-MeasurementResponseList.h" +#include "NRPPA_TRP-MeasurementResponseItem.h" +#include "NRPPA_TrpMeasurementResultItem.h" +#include "NRPPA_UL-RTOAMeasurement.h" +#include "NRPPA_GNB-RxTxTimeDiff.h" #endif /* NRPPA_INCLUDE_H_ */ diff --git a/tests/nr-cu-nrppa/nr-cu-nrppa.c b/tests/nr-cu-nrppa/nr-cu-nrppa.c index 0edd0842f4..de784a3a16 100644 --- a/tests/nr-cu-nrppa/nr-cu-nrppa.c +++ b/tests/nr-cu-nrppa/nr-cu-nrppa.c @@ -32,6 +32,7 @@ #include "openair3/NAS/NR_UE/nr_nas_msg.h" #include "executables/nr-uesoftmodem.h" #include "openair3/NRPPA/nrppa_gNB_location_information_transfer.c" +#include "openair3/NRPPA/nrppa_gNB_measurement_information_transfer.h" RAN_CONTEXT_t RC; THREAD_STRUCT thread_struct; @@ -432,6 +433,82 @@ static nrppa_positioning_information_resp_t fill_position_information_resp(uint1 return resp; } +static nrppa_measurement_resp_t fill_measurement_response(uint16_t transaction_id, uint32_t lmf_measurement_id) +{ + positioning_config_t positioning_config = RCconfig_nr_positioning(); + nrppa_measurement_resp_t resp = {0}; + resp.transaction_id = transaction_id; + resp.lmf_measurement_id = lmf_measurement_id; + resp.ran_measurement_id = 1; + resp.measurement_response_list = calloc_or_fail(1, sizeof(*resp.measurement_response_list)); + uint32_t meas_response_list_len = positioning_config.num_trp; + resp.measurement_response_list->measurement_response_list_length = meas_response_list_len; + resp.measurement_response_list->measurement_response_item = + calloc_or_fail(meas_response_list_len, sizeof(*resp.measurement_response_list->measurement_response_item)); + for (int i = 0; i < meas_response_list_len; i++) { + nrppa_measurement_response_item_t *meas_response_item = &resp.measurement_response_list->measurement_response_item[i]; + meas_response_item->trp_id = positioning_config.trps[i].id; + + nrppa_measurement_result_t *MeasurementResult = &meas_response_item->measurement_result; + uint32_t meas_result_length = 4; + MeasurementResult->measurement_result_item_length = meas_result_length; + MeasurementResult->measurement_result_item = + calloc_or_fail(meas_result_length, sizeof(*MeasurementResult->measurement_result_item)); + + // Angle of arrival + nrppa_measurement_result_item_t *measurement_result_item = &MeasurementResult->measurement_result_item[0]; + nrppa_measured_results_value_t *measuredResultsValue = &measurement_result_item->measured_results_value; + measuredResultsValue->present = NRPPA_MEASURED_RESULTS_VALUE_PR_UL_ANGLEOFARRIVAL; + nrppa_ul_aoa_t *uL_AngleOfArrival = &measuredResultsValue->choice.ul_angle_of_arrival; + uL_AngleOfArrival->azimuth_aoa = 700 + i; + uL_AngleOfArrival->zenith_aoa = calloc_or_fail(1, sizeof(*uL_AngleOfArrival->zenith_aoa)); + *uL_AngleOfArrival->zenith_aoa = 450 + i; + + nrppa_time_stamp_t *timeStamp = &measurement_result_item->time_stamp; + timeStamp->system_frame_number = 100; + timeStamp->slot_index.present = NRPPA_TIME_STAMP_SLOT_INDEX_PR_SCS_30; + timeStamp->slot_index.choice.scs_30 = 15; + + // UL SRS RSRP + measurement_result_item = &MeasurementResult->measurement_result_item[1]; + measuredResultsValue = &measurement_result_item->measured_results_value; + measuredResultsValue->present = NRPPA_MEASURED_RESULTS_VALUE_PR_UL_SRS_RSRP; + measuredResultsValue->choice.ul_srs_rsrp = 100 + i; + + timeStamp = &measurement_result_item->time_stamp; + timeStamp->system_frame_number = 101; + timeStamp->slot_index.present = NRPPA_TIME_STAMP_SLOT_INDEX_PR_SCS_15; + timeStamp->slot_index.choice.scs_15 = 8; + + // UL RToA + measurement_result_item = &MeasurementResult->measurement_result_item[2]; + measuredResultsValue = &measurement_result_item->measured_results_value; + measuredResultsValue->present = NRPPA_MEASURED_RESULTS_VALUE_PR_UL_RTOA; + nrppa_ul_rtoa_measurement_t *uL_RTOA = &measuredResultsValue->choice.ul_rtoa; + uL_RTOA->present = NRPPA_ULRTOAMEAS_PR_K1; + uL_RTOA->choice.k1 = 98500 + i; + + timeStamp = &measurement_result_item->time_stamp; + timeStamp->system_frame_number = 102; + timeStamp->slot_index.present = NRPPA_TIME_STAMP_SLOT_INDEX_PR_SCS_60; + timeStamp->slot_index.choice.scs_60 = 31; + + // gNB RX-TX Time Diff + measurement_result_item = &MeasurementResult->measurement_result_item[3]; + measuredResultsValue = &measurement_result_item->measured_results_value; + measuredResultsValue->present = NRPPA_MEASURED_RESULTS_VALUE_PR_GNB_RXTXTIMEDIFF; + nrppa_gnb_rx_tx_time_diff_t *gNB_RxTxTimeDiff = &measuredResultsValue->choice.gnb_rx_tx_time_diff; + gNB_RxTxTimeDiff->present = NRPPA_GNBRXTXTIMEDIFFMEAS_PR_K3; + gNB_RxTxTimeDiff->choice.k3 = 98412 + i; + + timeStamp = &measurement_result_item->time_stamp; + timeStamp->system_frame_number = 103; + timeStamp->slot_index.present = NRPPA_TIME_STAMP_SLOT_INDEX_PR_SCS_120; + timeStamp->slot_index.choice.scs_120 = 70; + } + return resp; +} + // Initializing UE NAS Context with simulated SIM data nr_ue_nas_t *simulated_ue_nas = NULL; void init_ue_nas_context(void) @@ -589,6 +666,15 @@ void *rrc_gnb_task(void *args_p) itti_send_msg_to_task(TASK_NRPPA, 0, msg_p_resp); free_positioning_activation_request(req); break; + case NRPPA_MEASUREMENT_REQ: + nrppa_measurement_req_t *m_req = &NRPPA_MEASUREMENT_REQ(msg_p); + LOG_I(NR_RRC, "Received NRPPA_MEASUREMENT_REQ transaction_id %d\n", m_req->transaction_id); + msg_p_resp = itti_alloc_new_message(TASK_RRC_GNB, 0, NRPPA_MEASUREMENT_RESP); + NRPPA_MEASUREMENT_RESP(msg_p_resp) = fill_measurement_response(m_req->transaction_id, m_req->lmf_measurement_id); + LOG_I(NR_RRC, "Sending NRPPA_MEASUREMENT_RESP to TASK_NRPPA\n"); + itti_send_msg_to_task(TASK_NRPPA, 0, msg_p_resp); + free_measurement_request(m_req); + break; default: LOG_E(NR_RRC, "[gNB %ld] Received unexpected message %s\n", instance, msg_name_p); break; From 7de93489cf50ab4f7a30f615530a4cd20d2b8030 Mon Sep 17 00:00:00 2001 From: Rakesh Mundlamuri Date: Tue, 24 Feb 2026 21:08:57 +0530 Subject: [PATCH 31/44] Add README for the nr-cu-nrppa tester --- doc/README.md | 5 ++- tests/nr-cu-nrppa/README.md | 81 +++++++++++++++++++++++++++++++++++++ 2 files changed, 84 insertions(+), 2 deletions(-) create mode 100644 tests/nr-cu-nrppa/README.md diff --git a/doc/README.md b/doc/README.md index 8fc53eea24..13a9669f76 100644 --- a/doc/README.md +++ b/doc/README.md @@ -121,8 +121,9 @@ The other SDRs (AW2S, LimeSDR, ...) have no READMEs. ## Testing - [UnitTests.md](./UnitTests.md) explains the unit testing setup -- Component tests are under `tests/`. Currently, there is a simple CU-UP - tester, see the corresponding [README.md](../tests/nr-cuup/README.md). +- Component tests are under `tests/`. Currently, the following component tests are supported + - A simple CU-UP tester, see the corresponding [README.md](../tests/nr-cuup/README.md). + - A CU-NRPPA tester, see the corresponding [README.md](../tests/nr-cu-nrppa/README.md). - [TESTBenches.md](./TESTBenches.md) lists the CI setup and links to pipelines - The CI setup uses a [custom framework](../ci-scripts/README.md) to run end-to-end tests. diff --git a/tests/nr-cu-nrppa/README.md b/tests/nr-cu-nrppa/README.md new file mode 100644 index 0000000000..4ea780a20e --- /dev/null +++ b/tests/nr-cu-nrppa/README.md @@ -0,0 +1,81 @@ +This is a simple standalone tester for NRPPA and NGAP positioning messages. It connects to the AMF to perform NGAP and NRPPA encoding/decoding and validates the exchange of positioning data. + +[[_TOC_]] + +# Overview +From a schematic point of view, the tester and Core Network interaction looks like this: +``` + +-------+ +-------+ + | LMF |<--- HTTP POST---| User | + +-------+ +-------+ + | + | Nlmf + | + +-------+ + | AMF | + +-------+ + | + NGAP/NRPPA | + | + +-------+ + |tester | (nr-cu-nrppa-test) + +-------+ +``` +The tester is designed to validate the integration of NRPPA and NGAP messages required for 5G positioning (*3GPP 38.413 V16.0.0* and *3GPP 38.455 V16.7.1*). It acts as a simulated RAN node (like a CU) connecting to the 5G Core Network's AMF. + +The following messages are integrated and tested: +* **NGAP:** Uplink/Downlink UE Associated NRPPA Transport, Uplink/Downlink Non-UE Associated NRPPA Transport. +* **NRPPA:** TRP Information Request/Response, Positioning Information Request/Response, Positioning Activation Request/Response, Measurement Request/Response. + +A test scenario is fixed to these steps: +1. The 5G Core Network, specifically including the Location Management Function (LMF), is deployed via Docker. +2. The tester connects to the AMF and establishes the NGAP connection. +3. The user initiates a positioning procedure via a API call to the LMF. +4. The AMF and the tester exchange the required NGAP and NRPPA messages to determine location. + +# Usage +To run this test, you need to set up the Core Network and build the tester. + +**1. Core Network Deployment** + +Pull the required Docker images for the OAI 5G Core: + + docker pull oaisoftwarealliance/ims:latest + docker pull oaisoftwarealliance/oai-amf:develop + docker pull oaisoftwarealliance/oai-nrf:develop + docker pull oaisoftwarealliance/oai-smf:develop + docker pull oaisoftwarealliance/oai-udr:develop + docker pull oaisoftwarealliance/oai-upf:develop + docker pull oaisoftwarealliance/oai-udm:develop + docker pull oaisoftwarealliance/oai-ausf:develop + docker pull oaisoftwarealliance/oai-lmf:develop + +Deploy the network using the positioning compose file: + + cd doc/tutorial_resources/oai-cn5g + docker compose -f docker-compose-positioning.yaml up -d + +*(To undeploy later, run `docker compose -f docker-compose-positioning.yaml down -t 0`)* + +**2. Building the Tester** + +You can build the NRPPA tester like so: + + cd ~/openairinterface5g + mkdir build && cd build && cmake .. -GNinja && ninja nr-cu-nrppa-test + +**3. Running the Tester** + +Start the tester with the dedicated configuration file: + + LD_LIBRARY_PATH=. ./tests/nr-cu-nrppa/nr-cu-nrppa-test -O ../tests/nr-cu-nrppa/nr-nrppa-test.conf + +**4. Initiating the Procedure** + +Trigger the location determination by sending an HTTP POST request to the LMF: + + cd ~/openairinterface5g/doc/tutorial_resources/positioning/ + curl --http2-prior-knowledge -H "Content-Type: application/json" -d "@InputData.json" -X POST http://192.168.70.141:8080/nlmf-loc/v1/determine-location + +# Limitations +- The tester is a standalone validation tool (`nr-cu-nrppa-test`) and does not represent a fully integrated, end-to-end gNB positioning setup. From dafabe381c3e8584307e49df5aea022cf3d72575 Mon Sep 17 00:00:00 2001 From: Raghavendra Dinavahi Date: Thu, 12 Feb 2026 21:28:33 +0100 Subject: [PATCH 32/44] UE: update PDCCH config if MAC config changes without this fix, after sync is successful, RAR is not getting decoded. PDCCH area also changes as SSB offset can change. if MAC configuration changes. --- openair2/LAYER2/NR_MAC_UE/config_ue.c | 4 ++ openair2/LAYER2/NR_MAC_UE/mac_proto.h | 1 + .../NR_MAC_UE/nr_ue_dci_configuration.c | 63 +++++++++++-------- 3 files changed, 41 insertions(+), 27 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_UE/config_ue.c b/openair2/LAYER2/NR_MAC_UE/config_ue.c index 5d078cf941..5dcdf6a725 100644 --- a/openair2/LAYER2/NR_MAC_UE/config_ue.c +++ b/openair2/LAYER2/NR_MAC_UE/config_ue.c @@ -2106,6 +2106,10 @@ static void handle_reconfiguration_with_sync(NR_UE_MAC_INST_t *mac, configure_common_BWP_dl(mac, bwp_id, scc->downlinkConfigCommon->initialDownlinkBWP); if (scc->uplinkConfigCommon) configure_common_BWP_ul(mac, bwp_id, scc->uplinkConfigCommon->initialUplinkBWP); + + // Update PDCCH config as MAC configuration has changed + if (IS_SA_MODE(get_softmodem_params())) + update_pdcch_config(mac); } mac->state = UE_NOT_SYNC_RECONF; diff --git a/openair2/LAYER2/NR_MAC_UE/mac_proto.h b/openair2/LAYER2/NR_MAC_UE/mac_proto.h index 9ee1bfab28..e502d08f1f 100644 --- a/openair2/LAYER2/NR_MAC_UE/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_proto.h @@ -377,4 +377,5 @@ void nr_ue_sidelink_scheduler(nr_sidelink_indication_t *sl_ind, NR_UE_MAC_INST_t NR_SearchSpace_t *get_common_search_space(const NR_UE_MAC_INST_t *mac, const NR_SearchSpaceId_t ss_id); ssb_ro_preambles_t get_ssb_ro_preambles_4step(struct NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB *config); +void update_pdcch_config(NR_UE_MAC_INST_t *mac); #endif diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c index 8dbce0032c..43aab362f3 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c @@ -422,6 +422,38 @@ static bool monitor_dci_for_other_SI(NR_UE_MAC_INST_t *mac, return false; } +void update_pdcch_config(NR_UE_MAC_INST_t *mac) +{ + int scs = mac->current_DL_BWP ? mac->current_DL_BWP->scs : mac->numerology; + const int slots_per_frame = get_slots_per_frame_from_scs(scs); + int ssb_sc_offset_norm; + if (mac->ssb_subcarrier_offset < 24 && mac->frequency_range == FR1) + ssb_sc_offset_norm = mac->ssb_subcarrier_offset >> scs; + else + ssb_sc_offset_norm = mac->ssb_subcarrier_offset; + uint16_t ssb_offset_point_a = (mac->ssb_start_subcarrier - ssb_sc_offset_norm) / 12; + int ssb_start_symbol = get_ssb_start_symbol(mac->nr_band, scs, mac->mib_ssb); + get_type0_PDCCH_CSS_config_parameters(&mac->type0_PDCCH_CSS_config, + mac->mib_frame, + mac->mib, + slots_per_frame, + ssb_sc_offset_norm, + ssb_start_symbol, + scs, + mac->frequency_range, + mac->nr_band, + 273, // at this point UE in principle doesn't know the grid size (we assume the largest) + mac->mib_ssb, + 1, // If the UE is not configured with a periodicity, the UE assumes a periodicity of a half frame + ssb_offset_point_a); + if (mac->search_space_zero == NULL) + mac->search_space_zero = calloc(1, sizeof(*mac->search_space_zero)); + if (mac->coreset0 == NULL) + mac->coreset0 = calloc(1, sizeof(*mac->coreset0)); + fill_coresetZero(mac->coreset0, &mac->type0_PDCCH_CSS_config); + fill_searchSpaceZero(mac->search_space_zero, slots_per_frame, &mac->type0_PDCCH_CSS_config); +} + void ue_dci_configuration(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_request_t *dl_config, const frame_t frame, const int slot) { const NR_UE_DL_BWP_t *current_DL_BWP = mac->current_DL_BWP; @@ -430,37 +462,14 @@ void ue_dci_configuration(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_request_t *dl int scs = current_DL_BWP ? current_DL_BWP->scs : mac->numerology; const int slots_per_frame = get_slots_per_frame_from_scs(scs); if (mac->get_sib1) { - int ssb_sc_offset_norm; - if (mac->ssb_subcarrier_offset < 24 && mac->frequency_range == FR1) - ssb_sc_offset_norm = mac->ssb_subcarrier_offset >> scs; - else - ssb_sc_offset_norm = mac->ssb_subcarrier_offset; - uint16_t ssb_offset_point_a = (mac->ssb_start_subcarrier - ssb_sc_offset_norm) / 12; - int ssb_start_symbol = get_ssb_start_symbol(mac->nr_band, scs, mac->mib_ssb); - get_type0_PDCCH_CSS_config_parameters(&mac->type0_PDCCH_CSS_config, - mac->mib_frame, - mac->mib, - slots_per_frame, - ssb_sc_offset_norm, - ssb_start_symbol, - scs, - mac->frequency_range, - mac->nr_band, - 273, // at this point UE in principle doesn't know the grid size (we assume the largest) - mac->mib_ssb, - 1, // If the UE is not configured with a periodicity, the UE assumes a periodicity of a half frame - ssb_offset_point_a); - if (mac->search_space_zero == NULL) - mac->search_space_zero = calloc(1, sizeof(*mac->search_space_zero)); - if (mac->coreset0 == NULL) - mac->coreset0 = calloc(1, sizeof(*mac->coreset0)); - fill_coresetZero(mac->coreset0, &mac->type0_PDCCH_CSS_config); - fill_searchSpaceZero(mac->search_space_zero, slots_per_frame, &mac->type0_PDCCH_CSS_config); - if (is_ss_monitor_occasion(frame, slot, slots_per_frame, mac->search_space_zero)) { + update_pdcch_config(mac); + bool is_occasion = is_ss_monitor_occasion(frame, slot, slots_per_frame, mac->search_space_zero); + if (is_occasion) { LOG_D(NR_MAC_DCI, "Monitoring DCI for SIB1 in frame %d slot %d\n", frame, slot); config_dci_pdu(mac, dl_config, TYPE_SI_RNTI_, slot, mac->search_space_zero); } } + for (int i = 0; i < MAX_SI_GROUPS; i++) { if (!mac->get_otherSI[i]) continue; From b33424b7904fa61fc7cb072c32cf1dfa01628ea9 Mon Sep 17 00:00:00 2001 From: Jaroslava Fiedlerova Date: Wed, 26 Nov 2025 14:46:06 +0100 Subject: [PATCH 33/44] CI: Add script for BW configuration on WNC RU --- ci-scripts/scripts/set-wnc-bandwidth.sh | 93 +++++++++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 ci-scripts/scripts/set-wnc-bandwidth.sh diff --git a/ci-scripts/scripts/set-wnc-bandwidth.sh b/ci-scripts/scripts/set-wnc-bandwidth.sh new file mode 100644 index 0000000000..c52f30e388 --- /dev/null +++ b/ci-scripts/scripts/set-wnc-bandwidth.sh @@ -0,0 +1,93 @@ +#!/bin/bash + +if [ -z "$1" ]; then + echo "Usage: $0 [reboot]" + exit 1 +fi + +BANDWIDTH="$1" +DO_REBOOT="$2" +RU_IP="10.10.0.115" +HOST="root@$RU_IP" +LOGFILE="/tmp/radio_config_$(date +%Y%m%d_%H%M%S).log" + +echo "=== Starting at $(date) ===" | tee "$LOGFILE" +echo "Target bandwidth: $BANDWIDTH" | tee -a "$LOGFILE" +echo "Reboot before configuration: ${DO_REBOOT:-no}" | tee -a "$LOGFILE" + +if [ "$DO_REBOOT" == "reboot" ]; then + echo "=== Rebooting RU ($RU_IP) ... ===" | tee -a "$LOGFILE" + + expect < /dev/null 2>&1 +set timeout 10 +spawn ssh -tt $HOST + +expect "#" +send "reboot\r" +expect "Continue?" +send "Y\r" +# We expect disconnect now +expect eof +EOF + + echo "→ Waiting for $RU_IP SSH to go down..." | tee -a "$LOGFILE" + sleep 10 + + echo "→ Waiting for $RU_IP SSH port 22 to be open..." | tee -a "$LOGFILE" + while ! nc -zv $RU_IP 22 >/dev/null 2>&1; do + echo "SSH port 22 not open, waiting 5 seconds..." | tee -a "$LOGFILE" + sleep 5 + done + echo "✓ SSH port 22 is open on $RU_IP" | tee -a "$LOGFILE" +fi + +echo "=== Applying bandwidth configuration ===" | tee -a "$LOGFILE" + +expect < /dev/null 2>&1 +set timeout 10 +spawn ssh -tt $HOST + +expect "#" +send "radio disable\r" + +expect "#" +send "config\r" + +expect "(config)#" +send "radio 1\r" + +expect "(conf-rf 1)#" +send "bandwidth ${BANDWIDTH}\r" + +expect "(conf-rf 1)#" +send "exit\r" + +expect "(config)#" +send "exit\r" + +expect "#" +send "radio enable\r" + +expect "#" +send "show running-config\r" + +expect "#" +send "exit\r" +EOF + +echo "=== Checking bandwidth in running-config ===" | tee -a "$LOGFILE" + +FOUND_BW=$(grep -E "bandwidth[[:space:]]+[0-9]+" "$LOGFILE" \ + | tail -n 1 \ + | awk '{print $2}' \ + | tr -d '\r[:space:]') + +if [ "$FOUND_BW" -eq "$BANDWIDTH" ]; then + echo "✓ SUCCESS: Bandwidth correctly set to $FOUND_BW" | tee -a "$LOGFILE" + rm "$LOGFILE" + exit 0 +else + echo "✖ ERROR: Expected bandwidth $BANDWIDTH but found: $FOUND_BW" | tee -a "$LOGFILE" + exit 1 +fi + From ff358dde6f70a12f2a432d7010af3623a9458b38 Mon Sep 17 00:00:00 2001 From: Jaroslava Fiedlerova Date: Wed, 26 Nov 2025 14:48:04 +0100 Subject: [PATCH 34/44] CI: Add configuration and yaml files for new pipeline with Jetson --- ci-scripts/ci_infra.yaml | 16 ++ .../gnb-vnf.sa.band78.78prb.aerial.conf | 226 ++++++++++++++++ .../sa_b200_jetson_nrue/docker-compose.yml | 27 ++ .../aerial_l1_entrypoint.sh | 32 +++ .../cuphycontroller_P5G_WNC_GH.yaml | 243 ++++++++++++++++++ .../sa_gnb_aerial_30MHz/docker-compose.yaml | 67 +++++ 6 files changed, 611 insertions(+) create mode 100644 ci-scripts/conf_files/gnb-vnf.sa.band78.78prb.aerial.conf create mode 100644 ci-scripts/yaml_files/sa_b200_jetson_nrue/docker-compose.yml create mode 100755 ci-scripts/yaml_files/sa_gnb_aerial_30MHz/aerial_l1_entrypoint.sh create mode 100644 ci-scripts/yaml_files/sa_gnb_aerial_30MHz/cuphycontroller_P5G_WNC_GH.yaml create mode 100644 ci-scripts/yaml_files/sa_gnb_aerial_30MHz/docker-compose.yaml diff --git a/ci-scripts/ci_infra.yaml b/ci-scripts/ci_infra.yaml index 837f1edb82..00da44ed77 100644 --- a/ci-scripts/ci_infra.yaml +++ b/ci-scripts/ci_infra.yaml @@ -101,6 +101,14 @@ oc-cn5g-20897-aerial: Undeploy: "! scripts/oc-cn5g-undeploy.sh /opt/oai-cn5g-fed-develop-2025-jan oaicicd-core-for-nvidia-aerial" LogCollect: "! scripts/oc-cn5g-logcollect.sh /opt/oai-cn5g-fed-develop-2025-jan oaicicd-core-for-nvidia-aerial %%log_dir%%" +oc-cn5g-00104: + Host: gracehopper1-oai + NetworkScript: echo "inet 172.21.6.105" + RunIperf3Server: False + Deploy: "! scripts/oc-cn5g-deploy.sh /opt/oai-cn5g-fed-develop-00104 oaicicd-core-for-nvidia-aerial" + Undeploy: "! scripts/oc-cn5g-undeploy.sh /opt/oai-cn5g-fed-develop-00104 oaicicd-core-for-nvidia-aerial" + LogCollect: "! scripts/oc-cn5g-logcollect.sh /opt/oai-cn5g-fed-develop-00104 oaicicd-core-for-nvidia-aerial %%log_dir%%" + matix-cn5g: Host: matix NetworkScript: docker exec prod-trf-gen ip a show dev eth0 @@ -300,6 +308,14 @@ oai_ue_caracal: IF: oaitun_ue1 MTU: 1500 +oai_ue_jetson2: + Host: jetson2-oai + AttachScript: 'docker start oai-nr-ue' + DetachScript: 'docker stop oai-nr-ue' + NetworkScript: ip a show dev oaitun_ue1 + IF: oaitun_ue1 + MTU: 1500 + lte_oai_ue_carabe: Host: carabe NetworkScript: docker exec lte-b200-ue-fdd-10Mhz-tm1 ip a show dev oaitun_ue1 diff --git a/ci-scripts/conf_files/gnb-vnf.sa.band78.78prb.aerial.conf b/ci-scripts/conf_files/gnb-vnf.sa.band78.78prb.aerial.conf new file mode 100644 index 0000000000..12c0aba35c --- /dev/null +++ b/ci-scripts/conf_files/gnb-vnf.sa.band78.78prb.aerial.conf @@ -0,0 +1,226 @@ +Active_gNBs = ( "gNB-OAI"); +# Asn1_verbosity, choice in: none, info, annoying +Asn1_verbosity = "none"; + +nfapi = "AERIAL"; + +gNBs = +( + { + ////////// Identification parameters: + gNB_ID = 0xe00; + gNB_name = "gNB-OAI"; + + // Tracking area code, 0x0000 and 0xfffe are reserved values + tracking_area_code = 1; + plmn_list = ({mcc = 001; mnc = 04; mnc_length = 2; snssaiList = ({sst = 1;});}); + + nr_cellid = 12345678L; + + ////////// Physical parameters: + + pdsch_AntennaPorts_XP = 2; + pdsch_AntennaPorts_N1 = 2; + pusch_AntennaPorts = 2; + do_CSIRS = 0; + do_SRS = 0; + min_rxtxtime = 6; + + servingCellConfigCommon = ( + { + #spCellConfigCommon + + physCellId = 0; + +# downlinkConfigCommon + #frequencyInfoDL + # center frequency = 3350.01 MHz + # selected SSB frequency = 3349.92 MHz + absoluteFrequencySSB = 623328; + dl_frequencyBand = 78; + # frequency point A = 3300.87 MHz + dl_absoluteFrequencyPointA = 622398; + #scs-SpecificCarrierList + dl_offstToCarrier = 0; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + dl_subcarrierSpacing = 1; + dl_carrierBandwidth = 78; + #initialDownlinkBWP + #genericParameters + # this is RBstart=0,L=162 (275*(275-L+1))+(274-RBstart)) + initialDLBWPlocationAndBandwidth = 21175; + # +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + initialDLBWPsubcarrierSpacing = 1; + #pdcch-ConfigCommon + initialDLBWPcontrolResourceSetZero = 12; + initialDLBWPsearchSpaceZero = 0; + + #uplinkConfigCommon + #frequencyInfoUL + ul_frequencyBand = 78; + #scs-SpecificCarrierList + ul_offstToCarrier = 0; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + ul_subcarrierSpacing = 1; + ul_carrierBandwidth = 78; + pMax = 20; + #initialUplinkBWP + #genericParameters + initialULBWPlocationAndBandwidth = 21175; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + initialULBWPsubcarrierSpacing = 1; + #rach-ConfigCommon + #rach-ConfigGeneric + prach_ConfigurationIndex = 148;# testMAC 158; OAI gNB 98 +#prach_msg1_FDM +#0 = one, 1=two, 2=four, 3=eight + prach_msg1_FDM = 0; + prach_msg1_FrequencyStart = 0; + zeroCorrelationZoneConfig = 12; + preambleReceivedTargetPower = -96; +#preamblTransMax (0...10) = (3,4,5,6,7,8,10,20,50,100,200) + preambleTransMax = 6; +#powerRampingStep +# 0=dB0,1=dB2,2=dB4,3=dB6 + powerRampingStep = 1; +#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR +#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen + ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 4; +#one (0..15) 4,8,12,16,...60,64 + ssb_perRACH_OccasionAndCB_PreamblesPerSSB = 15; +#ra_ContentionResolutionTimer +#(0..7) 8,16,24,32,40,48,56,64 + ra_ContentionResolutionTimer = 7; + rsrp_ThresholdSSB = 19; +#prach-RootSequenceIndex_PR +#1 = 839, 2 = 139 + prach_RootSequenceIndex_PR = 2; + prach_RootSequenceIndex = 1; + # SCS for msg1, can only be 15 for 30 kHz < 6 GHz, takes precendence over the one derived from prach-ConfigIndex + # + msg1_SubcarrierSpacing = 1, +# restrictedSetConfig +# 0=unrestricted, 1=restricted type A, 2=restricted type B + restrictedSetConfig = 0, + + msg3_DeltaPreamble = 1; + p0_NominalWithGrant = -90; + +# pucch-ConfigCommon setup : +# pucchGroupHopping +# 0 = neither, 1= group hopping, 2=sequence hopping + pucchGroupHopping = 0; + hoppingId = 40; + p0_nominal = -90; + + ssb_PositionsInBurst_Bitmap = 1; + +# ssb_periodicityServingCell +# 0 = ms5, 1=ms10, 2=ms20, 3=ms40, 4=ms80, 5=ms160, 6=spare2, 7=spare1 + ssb_periodicityServingCell = 2; + +# dmrs_TypeA_position +# 0 = pos2, 1 = pos3 + dmrs_TypeA_Position = 0; + +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + subcarrierSpacing = 1; + + + #tdd-UL-DL-ConfigurationCommon +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + referenceSubcarrierSpacing = 1; + # pattern1 + # dl_UL_TransmissionPeriodicity + # 0=ms0p5, 1=ms0p625, 2=ms1, 3=ms1p25, 4=ms2, 5=ms2p5, 6=ms5, 7=ms10 + dl_UL_TransmissionPeriodicity = 6; #5; + nrofDownlinkSlots = 6; #3; + nrofDownlinkSymbols = 10; #6; + nrofUplinkSlots = 3; #1; + nrofUplinkSymbols = 0; + + ssPBCH_BlockPower = -25; + } + + ); + + + # ------- SCTP definitions + SCTP : + { + # Number of streams to use in input/output + SCTP_INSTREAMS = 2; + SCTP_OUTSTREAMS = 2; + }; + + + ////////// AMF parameters: + amf_ip_address = ({ ipv4 = "172.21.6.103"; }); + + + NETWORK_INTERFACES : + { + GNB_IPV4_ADDRESS_FOR_NG_AMF = "172.21.16.53"; + GNB_IPV4_ADDRESS_FOR_NGU = "172.21.16.53"; + GNB_PORT_FOR_S1U = 2152; # Spec 2152 + }; + + } +); + +MACRLCs = ( +{ + num_cc = 1; + remote_s_address = "127.0.0.1"; // pnf addr [!] + local_s_address = "127.0.0.2"; // vnf addr + local_s_portc = 50001; // vnf p5 port + remote_s_portc = 50000; // pnf p5 port [!] + local_s_portd = 50011; // vnf p7 port [!] + remote_s_portd = 50010; // pnf p7 port [!] + tr_s_preference = "aerial"; + tr_n_preference = "local_RRC"; + pusch_TargetSNRx10 = 180; # 150; + pucch_TargetSNRx10 = 180; #200; + ulsch_max_frame_inactivity = 10; + dl_max_mcs = 28; + ul_max_mcs = 28; +} +); + + +security = { + # preferred ciphering algorithms + # the first one of the list that an UE supports in chosen + # valid values: nea0, nea1, nea2, nea3 + ciphering_algorithms = ( "nea0" ); + + # preferred integrity algorithms + # the first one of the list that an UE supports in chosen + # valid values: nia0, nia1, nia2, nia3 + integrity_algorithms = ( "nia2", "nia0" ); + + # setting 'drb_ciphering' to "no" disables ciphering for DRBs, no matter + # what 'ciphering_algorithms' configures; same thing for 'drb_integrity' + drb_ciphering = "yes"; + drb_integrity = "no"; +}; + +log_config : +{ + global_log_level ="info"; + hw_log_level ="info"; + phy_log_level ="info"; + mac_log_level ="info"; + rlc_log_level ="info"; + pdcp_log_level ="info"; + rrc_log_level ="info"; + ngap_log_level ="debug"; + f1ap_log_level ="debug"; +} diff --git a/ci-scripts/yaml_files/sa_b200_jetson_nrue/docker-compose.yml b/ci-scripts/yaml_files/sa_b200_jetson_nrue/docker-compose.yml new file mode 100644 index 0000000000..0a35a3caaa --- /dev/null +++ b/ci-scripts/yaml_files/sa_b200_jetson_nrue/docker-compose.yml @@ -0,0 +1,27 @@ +services: + oai-nr-ue: + image: ${REGISTRY-oaisoftwarealliance/}${NRUE_IMG:-oai-nr-ue}:${TAG:-develop} + network_mode: host + container_name: oai-nr-ue + cap_drop: + - ALL + cap_add: + - NET_ADMIN # for interface bringup + - NET_RAW # for ping + - SYS_NICE # for performance + - IPC_LOCK # for memory locking + devices: + - /dev/net/tun:/dev/net/tun + - /dev/bus/usb/:/dev/bus/usb/ + environment: + TZ: Europe/Paris + USE_B2XX: 'yes' + USE_ADDITIONAL_OPTIONS: --usrp-args type=b200 -C 3350010000 -r 78 --numerology 1 --band 78 --ssb 345 --ue-fo-compensation --uicc0.imsi 001040000000001 --uicc0.pdu_sessions.[0].dnn oai.ipv4 -A 60 --thread-pool 5,6,7,8,9 --ue-txgain 15 --ue-rxgain 90 + cpuset: "3-11" + volumes: + - ../../conf_files/ue.sa.conf:/opt/oai-nr-ue/etc/nr-ue.conf + healthcheck: + test: /bin/bash -c "pgrep nr-uesoftmodem" + interval: 10s + timeout: 5s + retries: 5 diff --git a/ci-scripts/yaml_files/sa_gnb_aerial_30MHz/aerial_l1_entrypoint.sh b/ci-scripts/yaml_files/sa_gnb_aerial_30MHz/aerial_l1_entrypoint.sh new file mode 100755 index 0000000000..c8bac9eb3e --- /dev/null +++ b/ci-scripts/yaml_files/sa_gnb_aerial_30MHz/aerial_l1_entrypoint.sh @@ -0,0 +1,32 @@ +#!/bin/bash + +# Check if cuBB_SDK is defined, if not, use default path +cuBB_Path="${cuBB_SDK:-/opt/nvidia/cuBB}" + +cd "$cuBB_Path" || exit 1 + +# Restart MPS +# Export variables +export CUDA_DEVICE_MAX_CONNECTIONS=8 +export CUDA_MPS_PIPE_DIRECTORY=/var +export CUDA_MPS_LOG_DIRECTORY=/var + +# Stop existing MPS +echo quit | sudo -E nvidia-cuda-mps-control + +# Start MPS +sudo -E nvidia-cuda-mps-control -d +sudo -E echo start_server -uid 0 | sudo -E nvidia-cuda-mps-control + +# Start cuphycontroller_scf +# Check if an argument is provided +if [ $# -eq 0 ]; then + # No argument provided, use default value + argument="P5G_WNC_GH" +else + # Argument provided, use it + argument="$1" +fi + +sudo -E "$cuBB_Path"/build.$(uname -m)/cuPHY-CP/cuphycontroller/examples/cuphycontroller_scf "$argument" +sudo -E ./build.$(uname -m)/cuPHY-CP/gt_common_libs/nvIPC/tests/pcap/pcap_collect diff --git a/ci-scripts/yaml_files/sa_gnb_aerial_30MHz/cuphycontroller_P5G_WNC_GH.yaml b/ci-scripts/yaml_files/sa_gnb_aerial_30MHz/cuphycontroller_P5G_WNC_GH.yaml new file mode 100644 index 0000000000..d43e2b17ad --- /dev/null +++ b/ci-scripts/yaml_files/sa_gnb_aerial_30MHz/cuphycontroller_P5G_WNC_GH.yaml @@ -0,0 +1,243 @@ +# SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0 +# +# 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. + +aerial_sdk_version: 25-3-cubb +l2adapter_filename: l2_adapter_config_P5G_GH.yaml +aerial_metrics_backend_address: 127.0.0.1:8081 + +# CPU core shared by all low-priority threads +low_priority_core: 10 +enable_ptp_svc_monitoring: 0 +ptp_rms_threshold: 20 #ns +nic_tput_alert_threshold_mbps: 85000 + +cuphydriver_config: + standalone: 0 + validation: 0 + num_slots: 8 + log_level: DBG + profiler_sec: 0 + dpdk_thread: 10 + dpdk_verbose_logs: 0 + accu_tx_sched_res_ns: 500 + accu_tx_sched_disable: 0 #Flag applicable only for CX6-DX : BF3/CX7 HW and beyond support accurate send scheduling directly on timestamp, for CX6-DX this is implemented via software emulation + fh_stats_dump_cpu_core: -1 + pdump_client_thread: -1 + use_green_contexts: 0 + use_batched_memcpy: 0 # Experimental feature; requires >= CUDA 12.8 + mps_sm_pusch: 100 + mps_sm_pucch: 2 + mps_sm_prach: 2 + mps_sm_ul_order: 20 + mps_sm_pdsch: 102 + mps_sm_pdcch: 10 + mps_sm_pbch: 2 + mps_sm_gpu_comms: 16 + mps_sm_srs: 16 + pdsch_fallback: 0 + dpdk_file_prefix: cuphycontroller + nics: + - nic: '0000:01:00.0' + mtu: 9216 + cpu_mbufs: 196608 + uplane_tx_handles: 64 + txq_size: 8192 + rxq_size: 16384 + gpu: 0 + cus_port_failover: 0 + gpus: + - 0 + # Set GPUID to the GPU sharing the PCIe switch as NIC + # run nvidia-smi topo -m to find out which GPU + workers_ul: [4,5] + workers_dl: [6,7,8] + debug_worker: -1 + workers_sched_priority: 95 + prometheus_thread: -1 + start_section_id_srs: 3072 + start_section_id_prach: 2048 + enable_ul_cuphy_graphs: 1 + enable_dl_cuphy_graphs: 1 + ul_order_kernel_mode: 0 # 0: Ping-Pong, 1: dual CTA + ul_order_timeout_cpu_ns: 8000000 + ul_order_timeout_log_interval_ns: 1000000000 + ul_order_timeout_gpu_ns: 3000000 + ul_order_timeout_gpu_srs_ns: 5200000 + ul_srs_aggr3_task_launch_offset_ns: 500000 + ul_order_timeout_gpu_log_enable: 0 + ul_order_max_rx_pkts: 512 + ul_order_rx_pkts_timeout_ns: 100000 + cplane_disable: 0 + gpu_init_comms_dl: 1 + cell_group: 1 + cell_group_num: 1 + fix_beta_dl: 0 + bfw_beta_prescaler: 16384 + pusch_workCancelMode: 2 # set cuphyPuschStatPrms_t workCancelMode field to PUSCH_DEVICE_GRAPHS; this only sets the mode and does not cancel work; + # work cancellation (i.e., not launching some of the device graphs) can only occur after an explicit internal + # memory write is timely observed by a PUSCH graph. + pusch_sinr: 2 + pusch_rssi: 1 + pusch_tdi: 1 + pusch_cfo: 1 + pusch_dftsofdm: 0 + pusch_to: 1 + pusch_select_eqcoeffalgo: 3 + pusch_select_chestalgo: 1 + pusch_enable_perprgchest: 0 + pusch_tbsizecheck: 1 + pusch_deviceGraphLaunchEn: 1 + pusch_waitTimeOutPreEarlyHarqUs: 3000 + pusch_waitTimeOutPostEarlyHarqUs: 3000 + puxch_polarDcdrListSz: 8 + enable_cpu_task_tracing: 0 + enable_prepare_tracing: 0 + disable_empw: 0 #1=>Disables Multi packet WQE feature + cqe_tracer_config: + enable_dl_cqe_tracing: 0 + cqe_trace_cell_mask: 1 #[64 bit mask: Bit0->Cell0, Bit1->Cell1...] + cqe_trace_slot_mask: 196800 #[20 bit mask: Bit0->Slot0, Bit1->Slot1...] 196800=>All *6,*7 DL Slots + ul_rx_pkt_tracing_level: 0 + ul_rx_pkt_tracing_level_srs: 0 + pmu_metrics: 0 #Enable and select PMU metrics, 0=disabled, 1=General Counters (platform agnostic), 2=Topdown Metrics (Grace only), 3=Cache Metrics (Grace only) + enable_h2d_copy_thread: 1 + h2d_copy_thread_cpu_affinity : 11 + h2d_copy_thread_sched_priority : 95 #0->SCHED_OTHER, >0->Actual + split_ul_cuda_streams: 0 # 1=Put UL slot 4 and slot 5 on different streams for DDDSUUDDDD pattern + serialize_pucch_pusch: 0 # 1=Force serialization of PUSCH/PUCCH + # Note: for Early Harq (EH) order is PUSCH EH -> PUCCH -> PUSCH non EH + # for non-Early Harq order is PUCCH -> all PUSCH processing + aggr_obj_non_avail_th: 5 # Threshold for consecutive non-availability of Aggregated objects(UL/DL) or DL/UL buffers + dl_wait_th_ns: + - 500000 #H2D copy wait threshold + - 4000000 #cuPHY DL channel wait threshold + sendCPlane_timing_error_th_ns : 0 + sendCPlane_ulbfw_backoff_th_ns: 300000 # ULBFW must be completed by cplane send time - this is the backoff time + sendCPlane_dlbfw_backoff_th_ns: 300000 # DLBFW must be completed by cplane send time - this is the backoff time + pusch_forcedNumCsi2Bits: 0 + mMIMO_enable: 0 + enable_srs: 1 + ue_mode: 0 + mCh_segment_proc_enable: 0 + pusch_aggr_per_ctx: 3 + prach_aggr_per_ctx: 2 + pucch_aggr_per_ctx: 4 + srs_aggr_per_ctx: 3 + ul_input_buffer_per_cell: 10 + ul_input_buffer_per_cell_srs: 6 + max_harq_pools: 384 + max_harq_tx_count_bundled: 10 + max_harq_tx_count_non_bundled: 4 + ok_testbench_config: + enable_ok_tb: 0 + num_ok_tb_slot: 0 #Presently not used + max_ru_unhealthy_ul_slots: 100 + srs_chest_algo_type: 0 + srs_chest_tol2_normalization_algo_type: 1 + srs_chest_tol2_constant_scaler: 32768.0 + bfw_power_normalization_alg_selector: 1 + total_num_srs_chest_buffers: 6144 + send_static_bfw_wt_all_cplane: 1 + ul_pcap_capture_enable: 0 + ul_pcap_capture_thread_cpu_affinity: 10 + ul_pcap_capture_thread_sched_priority: 95 + pcap_logger_ul_cplane_enable: 0 + pcap_logger_dl_cplane_enable: 0 + pcap_logger_thread_cpu_affinity: 10 + pcap_logger_thread_sched_prio: 95 + pcap_logger_file_save_dir: ./ + dlc_bfw_enable_divide_per_cell: 0 # Enable/disable dividing DL BFW C-Plane transmission window among multiple cells in a slot + ulc_bfw_enable_divide_per_cell: 0 # Enable/disable dividing UL BFW C-Plane transmission window among multiple cells in a slot + dlc_alloc_cplane_bfw_txq: 0 # Allocates a second separate queue for BFW DL C-Plane transmission + ulc_alloc_cplane_bfw_txq: 1 # Allocates a second separate queue for BFW UL C-Plane transmission + #static beam id range + static_beam_id_start: 1 + static_beam_id_end: 16527 + #dynamic beam id range + dynamic_beam_id_start: 16528 #Dynamic beam ID start should be after static beam ID end + dynamic_beam_id_end: 32767 #15bit max value + bfw_c_plane_chaining_mode: 0 # 0: Default memcpy of BFW weights, 1: CPU mbuf chaining of BFW weights, 2: GPU mbuf chaining + enable_l1_param_sanity_check: 0 + pusch_nMaxLdpcHetConfigs: 32 + notify_ul_harq_buffer_release: 0 + + # data_config: + # datalake_core: 12 # This must be set for Data Lake and/or E3 Agent to be used + # datalake_db_write_enable: 1 # Enable/disable ClickHouse writes based on datalake_data_types + # datalake_samples: 1000000 + # datalake_address: localhost + # datalake_engine: "MergeTree() PRIMARY KEY (TsTaiNs)" + # # datalake_drop_tables: 0 # Set to 1 to drop Clickhouse tables at startup + # datalake_data_types: [fh, pusch, hest] # Data types to write to ClickHouse DB (all types always collected in memory for E3 Agent): + # fh = Fronthaul IQ samples,pusch = PUSCH/FAPI data, hest = channel estimates + # datalake_store_failed_pdu: 0 # Set to 1 to store PDU data even when CRC fails + # e3_agent_enable: 0 # Enable/disable E3 Agent and dApp capabilities + # num_rows_fh: 120 + # num_rows_pusch: 200 + # num_rows_hest: 140 + # e3_pub_port: 5555 # E3 publisher port for indication messages + # e3_rep_port: 5556 # E3 reply port for E3AP requests + # e3_sub_port: 5560 # E3 subscriber port for Manager messages + + cells: + - name: O-RU 0 + cell_id: 1 + ru_type: 1 + # set to 00:00:00:00:00:00 to use the MAC address of the NIC port to use + src_mac_addr: 00:00:00:00:00:00 + dst_mac_addr: e8:c7:cf:ad:12:0b #WNC n78 + nic: '0000:01:00.0' + vlan: 500 + pcp: 7 + txq_count_uplane: 1 + eAxC_id_ssb_pbch: [0, 1, 2, 3] + eAxC_id_pdcch: [0, 1, 2, 3] + eAxC_id_pdsch: [0, 1, 2, 3] + eAxC_id_csirs: [0, 1, 2, 3] + eAxC_id_pusch: [0, 1, 2, 3] + eAxC_id_pucch: [0, 1, 2, 3] + eAxC_id_srs: [8, 9, 10, 11] + eAxC_id_prach: [4, 5, 6, 7] + dl_iq_data_fmt: {comp_meth: 1, bit_width: 9} + ul_iq_data_fmt: {comp_meth: 1, bit_width: 9} + section_3_time_offset: 484 + fs_offset_dl: 10 + exponent_dl: 4 + ref_dl: 0 + fs_offset_ul: -5 + exponent_ul: 4 + max_amp_ul: 65504 + mu: 1 + T1a_max_up_ns: 280000 + T1a_max_cp_ul_ns: 405000 + Ta4_min_ns: 50000 + Ta4_max_ns: 331000 + Tcp_adv_dl_ns: 125000 + ul_u_plane_tx_offset_ns: 280000 + fh_len_range: 0 + pusch_prb_stride: 273 + prach_prb_stride: 12 + srs_prb_stride: 273 + pusch_ldpc_max_num_itr_algo_type: 1 + pusch_fixed_max_num_ldpc_itrs: 10 + pusch_ldpc_early_termination: 0 + pusch_ldpc_algo_index: 0 + pusch_ldpc_flags: 2 + pusch_ldpc_use_half: 1 + pusch_nMaxPrb: 273 + pusch_nMaxRx: 4 + ul_gain_calibration: 78.68 + lower_guard_bw: 845 + tv_pusch: cuPhyChEstCoeffs.h5 diff --git a/ci-scripts/yaml_files/sa_gnb_aerial_30MHz/docker-compose.yaml b/ci-scripts/yaml_files/sa_gnb_aerial_30MHz/docker-compose.yaml new file mode 100644 index 0000000000..7842077ab3 --- /dev/null +++ b/ci-scripts/yaml_files/sa_gnb_aerial_30MHz/docker-compose.yaml @@ -0,0 +1,67 @@ +services: + nv-cubb: + container_name: nv-cubb + deploy: + resources: + reservations: + devices: + - driver: nvidia + count: all + capabilities: + - gpu + network_mode: host + shm_size: 4096m + privileged: true + stdin_open: true + tty: true + volumes: + - /lib/modules:/lib/modules + - /dev/hugepages:/dev/hugepages + - /usr/src:/usr/src + - ./cuphycontroller_P5G_WNC_GH.yaml:/opt/nvidia/cuBB/cuPHY-CP/cuphycontroller/config/cuphycontroller_P5G_WNC_GH.yaml + - ./aerial_l1_entrypoint.sh:/opt/nvidia/cuBB/aerial_l1_entrypoint.sh + - /var/log/aerial:/var/log/aerial + - ../../../cmake_targets/share:/opt/cuBB/share + userns_mode: host + ipc: "shareable" + image: cubb-build:25-3 + environment: + - cuBB_SDK=/opt/nvidia/cuBB + command: bash -c "sudo rm -rf /tmp/phy.log && sudo chmod +x /opt/nvidia/cuBB/aerial_l1_entrypoint.sh && /opt/nvidia/cuBB/aerial_l1_entrypoint.sh" + healthcheck: + test: ["CMD-SHELL",'grep -q "L1 is ready!" /tmp/phy.log && echo 0 || echo 1'] + interval: 20s + timeout: 5s + retries: 5 + oai-gnb-aerial: + cpuset: "13-16" + image: ${REGISTRY-oaisoftwarealliance/}${GNB_IMG:-oai-gnb-aerial}:${TAG:-develop} + depends_on: + nv-cubb: + condition: service_healthy + cap_drop: + - ALL + cap_add: + - SYS_NICE + - IPC_LOCK + ipc: "container:nv-cubb" + environment: + USE_ADDITIONAL_OPTIONS: --log_config.global_log_options level,nocolor,utc_time + deploy: + resources: + reservations: + devices: + - driver: nvidia + count: all + capabilities: + - gpu + network_mode: host + shm_size: 4096m + volumes: + - ../../conf_files/gnb-vnf.sa.band78.78prb.aerial.conf:/opt/oai-gnb/etc/gnb.conf + container_name: oai-gnb-aerial + healthcheck: + test: /bin/bash -c "ps aux | grep -v grep | grep -c softmodem" + interval: 10s + timeout: 5s + retries: 5 From 63575e54bf04c6da79973569a9e0ef5a6577459d Mon Sep 17 00:00:00 2001 From: Jaroslava Fiedlerova Date: Wed, 26 Nov 2025 14:48:46 +0100 Subject: [PATCH 35/44] CI: Add XML file for RAN-SA-AERIAL-OAIUE-CN5G --- .../container_sa_b200_nrue_jetson.xml | 212 ++++++++++++++++++ 1 file changed, 212 insertions(+) create mode 100644 ci-scripts/xml_files/container_sa_b200_nrue_jetson.xml diff --git a/ci-scripts/xml_files/container_sa_b200_nrue_jetson.xml b/ci-scripts/xml_files/container_sa_b200_nrue_jetson.xml new file mode 100644 index 0000000000..610aa306d5 --- /dev/null +++ b/ci-scripts/xml_files/container_sa_b200_nrue_jetson.xml @@ -0,0 +1,212 @@ + + + JETSON-5G-NRUE + 30 MHz TDD SA JETSON + tasks + + DeployCoreNetwork + Initialize 5G Core + oc-cn5g-00104 + + + + Pull_Local_Registry + Pull Images from Local Registry + jetson2-oai + oai-nr-ue + armv8_ + + + + Pull_Local_Registry + Pull Images from Local Registry + gracehopper1-oai + oai-gnb-aerial + arm_ + + + + Create_Workspace + Create new Workspace + jetson2-oai + + + + Create_Workspace + Create new Workspace + gracehopper1-oai + + + + Custom_Script + Configure 30 MHz bandwidth on WNC RU + gracehopper1-oai + + 30 + + + + Deploy_Object + Deploy PNF/Nvidia CUBB in a container + gracehopper1-oai + ci-scripts/yaml_files/sa_gnb_aerial_30MHz + nv-cubb + + + + Deploy_Object + Deploy VNF in a container + gracehopper1-oai + ci-scripts/yaml_files/sa_gnb_aerial_30MHz + oai-gnb-aerial + + + + Deploy_Object + Deploy nrUE (TDD/Band78/40MHz/N310) in a container + ci-scripts/yaml_files/sa_b200_jetson_nrue + jetson2-oai + 3 + + + + Attach_UE + Attach OAIUE + oai_ue_jetson2 + + + + Custom_Command + Configure IP route + jetson2-oai + sudo ip route add 172.21.6.105 via 13.1.1.100 dev oaitun_ue1 + + + + Ping + Ping: 20pings in 20sec + oai_ue_jetson2 + oc-cn5g-00104 + -c 20 + 1 + 25 + + + + Iperf + iperf (UL/10Mbps/UDP)(30 sec) + -u -b 10M -t 30 -i 1 + oai_ue_jetson2 + oc-cn5g-00104 + 25 + 80 + + + + Iperf + iperf (DL/10Mbps/UDP)(30 sec) + -u -b 10M -t 30 -i 1 -R + oai_ue_jetson2 + oc-cn5g-00104 + 25 + 80 + + + + Iperf + iperf (UL/30Mbps/UDP)(30 sec) + true + -u -b 30M -t 30 -i 1 + oai_ue_jetson2 + oc-cn5g-00104 + 25 + 80 + + + + Iperf + iperf (DL/30Mbps/UDP)(30 sec) + true + -u -b 30M -t 30 -i 1 -R + oai_ue_jetson2 + oc-cn5g-00104 + 25 + 80 + + + + Undeploy_Object + true + Undeploy nr UE + jetson2-oai + ci-scripts/yaml_files/sa_b200_jetson_nrue + + oai-nr-ue + + + + + Undeploy_Object + true + Undeploy gNB + gracehopper1-oai + ci-scripts/yaml_files/sa_gnb_aerial_30MHz + + oai-gnb-aerial=RetxCheck=20,100,100,100 oai-gnb-aerial=EndsWithBye + + + + + Custom_Script + true + Configure 100 MHz bandwidth on WNC RU + gracehopper1-oai + + 100 + + + + Clean_Test_Server_Images + true + Clean Test Images on Test Server + gracehopper1-oai + oai-gnb-aerial + + + + Clean_Test_Server_Images + true + Clean Test Images on Test Server + jetson2-oai + oai-nr-ue + + + + UndeployCoreNetwork + true + Terminate 5G Core + oc-cn5g-00104 + + + From 356a905d5ac2c96770a5f9c9374a79fdc7d8cff5 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Mon, 2 Mar 2026 16:59:49 +0100 Subject: [PATCH 36/44] Remove RHEL and Rocky 8 from supported distributions --- cmake_targets/tools/build_helper | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/cmake_targets/tools/build_helper b/cmake_targets/tools/build_helper index d2a3c2b3b9..2652b29634 100755 --- a/cmake_targets/tools/build_helper +++ b/cmake_targets/tools/build_helper @@ -108,14 +108,6 @@ check_supported_distribution() { "debian11") return 0 ;; "debian12") return 0 ;; "fedora43") return 0 ;; - "rhel8.2") return 0 ;; - "rhel8.3") return 0 ;; - "rhel8.4") return 0 ;; - "rhel8.5") return 0 ;; - "rhel8.6") return 0 ;; - "rhel8.7") return 0 ;; - "rhel8.8") return 0 ;; - "rhel8.9") return 0 ;; "rhel9.0") return 0 ;; "rhel9.1") return 0 ;; "rhel9.2") return 0 ;; @@ -125,9 +117,6 @@ check_supported_distribution() { "rhel9.6") return 0 ;; "rhel9.7") return 0 ;; "centos9") return 0 ;; # CentOS stream - "rocky8.7") return 0 ;; - "rocky8.8") return 0 ;; - "rocky8.9") return 0 ;; "rocky9.1") return 0 ;; "rocky9.2") return 0 ;; "rocky9.3") return 0 ;; From 0e38bd239efb1ee65b6eebf984efbfe582a095be Mon Sep 17 00:00:00 2001 From: rmagueta Date: Wed, 25 Feb 2026 17:16:42 +0000 Subject: [PATCH 37/44] Use signed types for dB measurements to support negative values --- .../PHY/LTE_ESTIMATION/lte_eNB_measurements.c | 10 ++++---- .../PHY/LTE_ESTIMATION/lte_ue_measurements.c | 14 +++++------ openair1/PHY/LTE_TRANSPORT/prach.c | 4 ++-- openair1/PHY/LTE_TRANSPORT/transport_proto.h | 2 +- openair1/PHY/NR_TRANSPORT/pucch_rx.c | 2 +- .../PHY/NR_UE_ESTIMATION/nr_ue_measurements.c | 12 +++++----- openair1/PHY/NR_UE_TRANSPORT/csi_rx.c | 4 ++-- openair1/PHY/defs_UE.h | 14 +++++------ openair1/PHY/defs_eNB.h | 10 ++++---- openair1/PHY/defs_gNB.h | 8 +++---- openair1/PHY/defs_nr_UE.h | 12 +++++----- openair1/PHY/impl_defs_top_NB_IoT.h | 24 +++++++++---------- openair1/SCHED/prach_procedures.c | 9 +++---- openair1/SIMULATION/LTE_PHY/dlsim.c | 5 ++-- openair1/SIMULATION/LTE_PHY/prachsim.c | 2 +- openair1/SIMULATION/LTE_PHY/ulsim.c | 5 ++-- openair1/SIMULATION/NR_PHY/prachsim.c | 2 +- 17 files changed, 71 insertions(+), 68 deletions(-) diff --git a/openair1/PHY/LTE_ESTIMATION/lte_eNB_measurements.c b/openair1/PHY/LTE_ESTIMATION/lte_eNB_measurements.c index f1b26c8d4e..755c67435d 100644 --- a/openair1/PHY/LTE_ESTIMATION/lte_eNB_measurements.c +++ b/openair1/PHY/LTE_ESTIMATION/lte_eNB_measurements.c @@ -87,12 +87,12 @@ void lte_eNB_I0_measurements(PHY_VARS_eNB *eNB, measurements->n0_power[aarx] = ((k1*signal_energy(&common_vars->rxdata[aarx][(frame_parms->samples_per_tti<<1) -frame_parms->ofdm_symbol_size], frame_parms->ofdm_symbol_size)) + k2*measurements->n0_power[aarx])>>10; //measurements->n0_power[aarx] = (measurements->n0_power[aarx]) * 12*frame_parms->N_RB_DL)/(frame_parms->ofdm_symbol_size); - measurements->n0_power_dB[aarx] = (unsigned short) dB_fixed(measurements->n0_power[aarx]); + measurements->n0_power_dB[aarx] = dB_fixed(measurements->n0_power[aarx]); measurements->n0_power_tot += measurements->n0_power[aarx]; } - measurements->n0_power_tot_dB = (unsigned short) dB_fixed(measurements->n0_power_tot); + measurements->n0_power_tot_dB = dB_fixed(measurements->n0_power_tot); measurements->n0_power_tot_dBm = measurements->n0_power_tot_dB - eNB->rx_total_gain_dB; // printf("n0_power %d\n",measurements->n0_power_tot_dB); @@ -183,14 +183,14 @@ void lte_eNB_srs_measurements(PHY_VARS_eNB *eNB, measurements->rx_spatial_power[srs_id][0][aarx]<<=1; // because of noise only in odd samples - measurements->rx_spatial_power_dB[srs_id][0][aarx] = (unsigned short) dB_fixed(measurements->rx_spatial_power[srs_id][0][aarx]); + measurements->rx_spatial_power_dB[srs_id][0][aarx] = dB_fixed(measurements->rx_spatial_power[srs_id][0][aarx]); measurements->wideband_cqi[srs_id][aarx] = measurements->rx_spatial_power[srs_id][0][aarx]; // measurements->rx_power[UE_id][aarx]/=frame_parms->nb_antennas_tx; - measurements->wideband_cqi_dB[srs_id][aarx] = (unsigned short) dB_fixed(measurements->wideband_cqi[srs_id][aarx]); + measurements->wideband_cqi_dB[srs_id][aarx] = dB_fixed(measurements->wideband_cqi[srs_id][aarx]); rx_power += measurements->wideband_cqi[srs_id][aarx]; // measurements->rx_avg_power_dB[UE_id] += measurements->rx_power_dB[UE_id][aarx]; } @@ -206,7 +206,7 @@ void lte_eNB_srs_measurements(PHY_VARS_eNB *eNB, measurements->wideband_cqi_tot[srs_id] = dB_fixed2(rx_power,2*measurements->n0_power_tot); // times 2 since we have noise only in the odd carriers of the srs comb - measurements->rx_rssi_dBm[srs_id] = (int32_t)dB_fixed(rx_power_avg_eNB[srs_id])-eNB->rx_total_gain_dB; + measurements->rx_rssi_dBm[srs_id] = dB_fixed(rx_power_avg_eNB[srs_id])-eNB->rx_total_gain_dB; diff --git a/openair1/PHY/LTE_ESTIMATION/lte_ue_measurements.c b/openair1/PHY/LTE_ESTIMATION/lte_ue_measurements.c index 86af5fb81c..9abaeb789c 100644 --- a/openair1/PHY/LTE_ESTIMATION/lte_ue_measurements.c +++ b/openair1/PHY/LTE_ESTIMATION/lte_ue_measurements.c @@ -254,13 +254,13 @@ void ue_rrc_measurements(PHY_VARS_UE *ue, // ue->measurements.n0_power[aarx] += (((int32_t)rxF_pss[-64]*rxF_pss[-64])+((int32_t)rxF_pss[-63]*rxF_pss[-63])); // printf("pssm32 %d\n",ue->measurements.n0_power[aarx]); - ue->measurements.n0_power_dB[aarx] = (unsigned short) dB_fixed(ue->measurements.n0_power[aarx]/12); + ue->measurements.n0_power_dB[aarx] = dB_fixed(ue->measurements.n0_power[aarx]/12); ue->measurements.n0_power_tot /*+=*/ = ue->measurements.n0_power[aarx]; } //LOG_I(PHY,"Subframe %d RRC UE MEAS Noise Level %d \n", subframe, ue->measurements.n0_power_tot); - ue->measurements.n0_power_tot_dB = (unsigned short) dB_fixed(ue->measurements.n0_power_tot/(12*aarx)); + ue->measurements.n0_power_tot_dB = dB_fixed(ue->measurements.n0_power_tot/(12*aarx)); ue->measurements.n0_power_tot_dBm = ue->measurements.n0_power_tot_dB - ue->rx_total_gain_dB - dB_fixed(ue->frame_parms.ofdm_symbol_size); } else { LOG_E(PHY, "Not yet implemented: noise power calculation when prefix length == EXTENDED\n"); @@ -311,11 +311,11 @@ void ue_rrc_measurements(PHY_VARS_UE *ue, ue->measurements.n0_power[aarx] += (((int32_t)rxF_pss[-66]*rxF_pss[-66])+((int32_t)rxF_pss[-65]*rxF_pss[-65])); // ue->measurements.n0_power[aarx] += (((int32_t)rxF_pss[-64]*rxF_pss[-64])+((int32_t)rxF_pss[-63]*rxF_pss[-63])); // printf("pssm32 %d\n",ue->measurements.n0_power[aarx]); - ue->measurements.n0_power_dB[aarx] = (unsigned short) dB_fixed(ue->measurements.n0_power[aarx]/12); + ue->measurements.n0_power_dB[aarx] = dB_fixed(ue->measurements.n0_power[aarx]/12); ue->measurements.n0_power_tot /*+=*/ = ue->measurements.n0_power[aarx]; } - ue->measurements.n0_power_tot_dB = (unsigned short) dB_fixed(ue->measurements.n0_power_tot/(12*aarx)); + ue->measurements.n0_power_tot_dB = dB_fixed(ue->measurements.n0_power_tot/(12*aarx)); ue->measurements.n0_power_tot_dBm = ue->measurements.n0_power_tot_dB - ue->rx_total_gain_dB - dB_fixed(ue->frame_parms.ofdm_symbol_size); //LOG_I(PHY,"Subframe %d RRC UE MEAS Noise Level %d \n", subframe, ue->measurements.n0_power_tot); @@ -1034,7 +1034,7 @@ void lte_ue_measurements(PHY_VARS_UE *ue, if (ue->measurements.rx_spatial_power[eNB_id][aatx][aarx]<0) ue->measurements.rx_spatial_power[eNB_id][aatx][aarx] = 0; //ue->measurements.n0_power[aarx]; - ue->measurements.rx_spatial_power_dB[eNB_id][aatx][aarx] = (unsigned short) dB_fixed(ue->measurements.rx_spatial_power[eNB_id][aatx][aarx]); + ue->measurements.rx_spatial_power_dB[eNB_id][aatx][aarx] = dB_fixed(ue->measurements.rx_spatial_power[eNB_id][aatx][aarx]); if (aatx==0) ue->measurements.rx_power[eNB_id][aarx] = ue->measurements.rx_spatial_power[eNB_id][aatx][aarx]; @@ -1042,7 +1042,7 @@ void lte_ue_measurements(PHY_VARS_UE *ue, ue->measurements.rx_power[eNB_id][aarx] += ue->measurements.rx_spatial_power[eNB_id][aatx][aarx]; } //aatx - ue->measurements.rx_power_dB[eNB_id][aarx] = (unsigned short) dB_fixed(ue->measurements.rx_power[eNB_id][aarx]); + ue->measurements.rx_power_dB[eNB_id][aarx] = dB_fixed(ue->measurements.rx_power[eNB_id][aarx]); if (aarx==0) ue->measurements.rx_power_tot[eNB_id] = ue->measurements.rx_power[eNB_id][aarx]; @@ -1050,7 +1050,7 @@ void lte_ue_measurements(PHY_VARS_UE *ue, ue->measurements.rx_power_tot[eNB_id] += ue->measurements.rx_power[eNB_id][aarx]; } //aarx - ue->measurements.rx_power_tot_dB[eNB_id] = (unsigned short) dB_fixed(ue->measurements.rx_power_tot[eNB_id]); + ue->measurements.rx_power_tot_dB[eNB_id] = dB_fixed(ue->measurements.rx_power_tot[eNB_id]); } //eNB_id diff --git a/openair1/PHY/LTE_TRANSPORT/prach.c b/openair1/PHY/LTE_TRANSPORT/prach.c index 6cb2de68d2..e357825ac6 100644 --- a/openair1/PHY/LTE_TRANSPORT/prach.c +++ b/openair1/PHY/LTE_TRANSPORT/prach.c @@ -48,7 +48,7 @@ void rx_prach0(PHY_VARS_eNB *eNB, uint16_t *max_preamble, uint16_t *max_preamble_energy, uint16_t *max_preamble_delay, - uint16_t *avg_preamble_energy, + int16_t *avg_preamble_energy, uint16_t Nf, uint8_t tdd_mapindex, uint8_t br_flag, @@ -639,7 +639,7 @@ void rx_prach(PHY_VARS_eNB *eNB, uint16_t *max_preamble, uint16_t *max_preamble_energy, uint16_t *max_preamble_delay, - uint16_t *avg_preamble_energy, + int16_t *avg_preamble_energy, uint16_t Nf, uint8_t tdd_mapindex, uint8_t br_flag) { diff --git a/openair1/PHY/LTE_TRANSPORT/transport_proto.h b/openair1/PHY/LTE_TRANSPORT/transport_proto.h index 9cf09d7b52..7fad5aa5db 100644 --- a/openair1/PHY/LTE_TRANSPORT/transport_proto.h +++ b/openair1/PHY/LTE_TRANSPORT/transport_proto.h @@ -593,7 +593,7 @@ void rx_prach(PHY_VARS_eNB *phy_vars_eNB,RU_t *ru, uint16_t *max_preamble, uint16_t *max_preamble_energy, uint16_t *max_preamble_delay, - uint16_t *avg_preamble_energy, + int16_t *avg_preamble_energy, uint16_t Nf, uint8_t tdd_mapindex, uint8_t br_flag ); diff --git a/openair1/PHY/NR_TRANSPORT/pucch_rx.c b/openair1/PHY/NR_TRANSPORT/pucch_rx.c index 61bdce06b2..1a863ff1d6 100644 --- a/openair1/PHY/NR_TRANSPORT/pucch_rx.c +++ b/openair1/PHY/NR_TRANSPORT/pucch_rx.c @@ -1177,7 +1177,7 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB, uint64_t decodedPayload[nb_symbols]; memset(decodedPayload,0,sizeof(decodedPayload)); - uint8_t corr_dB; + int8_t corr_dB; int decoderState = 2; if (pucch2_levdB < gNB->measurements.n0_subband_power_avg_dB + (gNB->pucch0_thres / 10)) decoderState = 1; // assuming missed detection, only attempt to decode for polar case (with CRC) diff --git a/openair1/PHY/NR_UE_ESTIMATION/nr_ue_measurements.c b/openair1/PHY/NR_UE_ESTIMATION/nr_ue_measurements.c index 8a59470cbf..d3be8bd9e6 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/nr_ue_measurements.c +++ b/openair1/PHY/NR_UE_ESTIMATION/nr_ue_measurements.c @@ -73,7 +73,7 @@ void nr_ue_measurements(PHY_VARS_NR_UE *ue, cmax(frame_parms->nb_antennas_rx, 1), false); allocCast3D(rx_spatial_power_dB, - unsigned short, + short, ue->measurements.rx_spatial_power_dB, NUMBER_OF_CONNECTED_gNB_MAX, cmax(frame_parms->nb_antenna_ports_gNB, 1), @@ -96,16 +96,16 @@ void nr_ue_measurements(PHY_VARS_NR_UE *ue, if (rx_spatial_power[gNB_id][aatx][aarx] < 0) rx_spatial_power[gNB_id][aatx][aarx] = 0; - rx_spatial_power_dB[gNB_id][aatx][aarx] = (unsigned short)dB_fixed(rx_spatial_power[gNB_id][aatx][aarx]); + rx_spatial_power_dB[gNB_id][aatx][aarx] = dB_fixed(rx_spatial_power[gNB_id][aatx][aarx]); ue->measurements.rx_power[gNB_id][aarx] += rx_spatial_power[gNB_id][aatx][aarx]; } - ue->measurements.rx_power_dB[gNB_id][aarx] = (unsigned short) dB_fixed(ue->measurements.rx_power[gNB_id][aarx]); + ue->measurements.rx_power_dB[gNB_id][aarx] = dB_fixed(ue->measurements.rx_power[gNB_id][aarx]); ue->measurements.rx_power_tot[gNB_id] += ue->measurements.rx_power[gNB_id][aarx]; } - ue->measurements.rx_power_tot_dB[gNB_id] = (unsigned short) dB_fixed(ue->measurements.rx_power_tot[gNB_id]); + ue->measurements.rx_power_tot_dB[gNB_id] = dB_fixed(ue->measurements.rx_power_tot[gNB_id]); } @@ -565,12 +565,12 @@ void nr_ue_rrc_measurements(PHY_VARS_NR_UE *ue, } ue->measurements.n0_power[aarx] /= 2*k_length; - ue->measurements.n0_power_dB[aarx] = (unsigned short) dB_fixed(ue->measurements.n0_power[aarx]); + ue->measurements.n0_power_dB[aarx] = dB_fixed(ue->measurements.n0_power[aarx]); ue->measurements.n0_power_tot += ue->measurements.n0_power[aarx]; } - ue->measurements.n0_power_tot_dB = (unsigned short) dB_fixed(ue->measurements.n0_power_tot); + ue->measurements.n0_power_tot_dB = dB_fixed(ue->measurements.n0_power_tot); #ifdef DEBUG_MEAS_RRC const int psd_awgn = -174; diff --git a/openair1/PHY/NR_UE_TRANSPORT/csi_rx.c b/openair1/PHY/NR_UE_TRANSPORT/csi_rx.c index d8604d4570..069623b411 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/csi_rx.c +++ b/openair1/PHY/NR_UE_TRANSPORT/csi_rx.c @@ -581,7 +581,7 @@ int nr_csi_rs_pmi_estimation(const PHY_VARS_NR_UE *ue, const int16_t log2_re, uint8_t *i1, uint8_t *i2, - uint32_t *precoded_sinr_dB) + int32_t *precoded_sinr_dB) { const NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms; @@ -948,7 +948,7 @@ void nr_ue_csi_rs_procedures(PHY_VARS_NR_UE *ue, uint8_t i1[3] = {0}; uint8_t i2[1] = {0}; uint8_t cqi = 0; - uint32_t precoded_sinr_dB = 0; + int32_t precoded_sinr_dB = 0; // bit 3 in bitmap to indicate RI measurment if (csirs_config_pdu->measurement_bitmap & 8) { nr_csi_rs_pmi_estimation(ue, diff --git a/openair1/PHY/defs_UE.h b/openair1/PHY/defs_UE.h index 82cc747581..c6521e0c74 100644 --- a/openair1/PHY/defs_UE.h +++ b/openair1/PHY/defs_UE.h @@ -206,15 +206,15 @@ typedef struct { //! estimated noise power (linear) unsigned int n0_power[NB_ANTENNAS_RX]; //! estimated noise power (dB) - unsigned short n0_power_dB[NB_ANTENNAS_RX]; + short n0_power_dB[NB_ANTENNAS_RX]; //! total estimated noise power (linear) unsigned int n0_power_tot; //! total estimated noise power (dB) - unsigned short n0_power_tot_dB; + short n0_power_tot_dB; //! average estimated noise power (linear) unsigned int n0_power_avg; //! average estimated noise power (dB) - unsigned short n0_power_avg_dB; + short n0_power_avg_dB; //! total estimated noise power (dBm) short n0_power_tot_dBm; @@ -222,24 +222,24 @@ typedef struct { //! estimated received spatial signal power (linear) int rx_spatial_power[NUMBER_OF_CONNECTED_eNB_MAX][2][2]; //! estimated received spatial signal power (dB) - unsigned short rx_spatial_power_dB[NUMBER_OF_CONNECTED_eNB_MAX][2][2]; + short rx_spatial_power_dB[NUMBER_OF_CONNECTED_eNB_MAX][2][2]; /// estimated received signal power (sum over all TX antennas) //int wideband_cqi[NUMBER_OF_CONNECTED_eNB_MAX][NB_ANTENNAS_RX]; int rx_power[NUMBER_OF_CONNECTED_eNB_MAX][NB_ANTENNAS_RX]; /// estimated received signal power (sum over all TX antennas) //int wideband_cqi_dB[NUMBER_OF_CONNECTED_eNB_MAX][NB_ANTENNAS_RX]; - unsigned short rx_power_dB[NUMBER_OF_CONNECTED_eNB_MAX][NB_ANTENNAS_RX]; + short rx_power_dB[NUMBER_OF_CONNECTED_eNB_MAX][NB_ANTENNAS_RX]; /// estimated received signal power (sum over all TX/RX antennas) int rx_power_tot[NUMBER_OF_CONNECTED_eNB_MAX]; //NEW /// estimated received signal power (sum over all TX/RX antennas) - unsigned short rx_power_tot_dB[NUMBER_OF_CONNECTED_eNB_MAX]; //NEW + short rx_power_tot_dB[NUMBER_OF_CONNECTED_eNB_MAX]; //NEW //! estimated received signal power (sum of all TX/RX antennas, time average) int rx_power_avg[NUMBER_OF_CONNECTED_eNB_MAX]; //! estimated received signal power (sum of all TX/RX antennas, time average, in dB) - unsigned short rx_power_avg_dB[NUMBER_OF_CONNECTED_eNB_MAX]; + short rx_power_avg_dB[NUMBER_OF_CONNECTED_eNB_MAX]; /// SINR (sum of all TX/RX antennas, in dB) int wideband_cqi_tot[NUMBER_OF_CONNECTED_eNB_MAX]; diff --git a/openair1/PHY/defs_eNB.h b/openair1/PHY/defs_eNB.h index 441c7b8f96..ebb7013cc0 100644 --- a/openair1/PHY/defs_eNB.h +++ b/openair1/PHY/defs_eNB.h @@ -419,17 +419,17 @@ typedef struct { //! estimated noise power (linear) unsigned int n0_power[MAX_NUM_RU_PER_eNB]; //! estimated noise power (dB) - unsigned short n0_power_dB[MAX_NUM_RU_PER_eNB]; + short n0_power_dB[MAX_NUM_RU_PER_eNB]; //! total estimated noise power (linear) unsigned int n0_power_tot; //! estimated avg noise power (dB) - unsigned short n0_power_tot_dB; + short n0_power_tot_dB; //! estimated avg noise power (dB) short n0_power_tot_dBm; //! estimated avg noise power per RB per RX ant (lin) unsigned short n0_subband_power[MAX_NUM_RU_PER_eNB][100]; //! estimated avg noise power per RB per RX ant (dB) - unsigned short n0_subband_power_dB[MAX_NUM_RU_PER_eNB][100]; + short n0_subband_power_dB[MAX_NUM_RU_PER_eNB][100]; //! estimated avg noise power per RB (dB) short n0_subband_power_tot_dB[100]; //! estimated avg noise power per RB (dBm) @@ -440,7 +440,7 @@ typedef struct { //! estimated received spatial signal power (linear) unsigned int rx_spatial_power[NUMBER_OF_SRS_MAX][2][2]; //! estimated received spatial signal power (dB) - unsigned short rx_spatial_power_dB[NUMBER_OF_SRS_MAX][2][2]; + short rx_spatial_power_dB[NUMBER_OF_SRS_MAX][2][2]; //! estimated rssi (dBm) short rx_rssi_dBm[NUMBER_OF_SRS_MAX]; //! estimated correlation (wideband linear) between spatial channels (computed in dlsch_demodulation) @@ -453,7 +453,7 @@ typedef struct { /// Wideband CQI in dB (= SINR dB) int wideband_cqi_dB[NUMBER_OF_SRS_MAX][MAX_NUM_RU_PER_eNB]; /// Wideband CQI (sum of all RX antennas, in dB) - char wideband_cqi_tot[NUMBER_OF_SRS_MAX]; + int wideband_cqi_tot[NUMBER_OF_SRS_MAX]; /// Subband CQI per RX antenna and RB (= SINR) int subband_cqi[NUMBER_OF_SRS_MAX][MAX_NUM_RU_PER_eNB][100]; /// Total Subband CQI and RB (= SINR) diff --git a/openair1/PHY/defs_gNB.h b/openair1/PHY/defs_gNB.h index b1113517c6..92523d94ee 100644 --- a/openair1/PHY/defs_gNB.h +++ b/openair1/PHY/defs_gNB.h @@ -319,17 +319,17 @@ typedef struct { //! estimated noise power (linear) unsigned int n0_power[MAX_NUM_RU_PER_gNB]; //! estimated noise power (dB) - unsigned int n0_power_dB[MAX_NUM_RU_PER_gNB]; + int n0_power_dB[MAX_NUM_RU_PER_gNB]; //! total estimated noise power (linear) unsigned int n0_power_tot; //! estimated avg noise power (dB) - unsigned int n0_power_tot_dB; + int n0_power_tot_dB; //! estimated avg noise power per RB per RX ant (lin) fourDimArray_t *n0_subband_power; //! estimated avg subband noise power (dB) - unsigned int n0_subband_power_avg_dB; + int n0_subband_power_avg_dB; //! estimated avg subband noise power per antenna (dB) - unsigned int n0_subband_power_avg_perANT_dB[MAX_ANT]; + int n0_subband_power_avg_perANT_dB[MAX_ANT]; //! estimated avg noise power per RB (dB) int n0_subband_power_tot_dB[275]; /// PRACH background noise level diff --git a/openair1/PHY/defs_nr_UE.h b/openair1/PHY/defs_nr_UE.h index c14751a050..b6ad2f8750 100644 --- a/openair1/PHY/defs_nr_UE.h +++ b/openair1/PHY/defs_nr_UE.h @@ -147,15 +147,15 @@ typedef struct { //! estimated noise power (linear) unsigned int n0_power[NB_ANTENNAS_RX]; //! estimated noise power (dB) - unsigned short n0_power_dB[NB_ANTENNAS_RX]; + short n0_power_dB[NB_ANTENNAS_RX]; //! total estimated noise power (linear) unsigned int n0_power_tot; //! total estimated noise power (dB) - unsigned short n0_power_tot_dB; + short n0_power_tot_dB; //! average estimated noise power (linear) unsigned int n0_power_avg; //! average estimated noise power (dB) - unsigned short n0_power_avg_dB; + short n0_power_avg_dB; //! total estimated noise power (dBm) short n0_power_tot_dBm; @@ -168,17 +168,17 @@ typedef struct { /// estimated received signal power (sum over all TX antennas) int rx_power[NUMBER_OF_CONNECTED_gNB_MAX][NB_ANTENNAS_RX]; /// estimated received signal power (sum over all TX antennas) - unsigned short rx_power_dB[NUMBER_OF_CONNECTED_gNB_MAX][NB_ANTENNAS_RX]; + short rx_power_dB[NUMBER_OF_CONNECTED_gNB_MAX][NB_ANTENNAS_RX]; /// estimated received signal power (sum over all TX/RX antennas) int rx_power_tot[NUMBER_OF_CONNECTED_gNB_MAX]; //NEW /// estimated received signal power (sum over all TX/RX antennas) - unsigned short rx_power_tot_dB[NUMBER_OF_CONNECTED_gNB_MAX]; //NEW + short rx_power_tot_dB[NUMBER_OF_CONNECTED_gNB_MAX]; //NEW //! estimated received signal power (sum of all TX/RX antennas, time average) int rx_power_avg[NUMBER_OF_CONNECTED_gNB_MAX]; //! estimated received signal power (sum of all TX/RX antennas, time average, in dB) - unsigned short rx_power_avg_dB[NUMBER_OF_CONNECTED_gNB_MAX]; + short rx_power_avg_dB[NUMBER_OF_CONNECTED_gNB_MAX]; /// SINR (sum of all TX/RX antennas, in dB) int wideband_cqi_tot[NUMBER_OF_CONNECTED_gNB_MAX]; diff --git a/openair1/PHY/impl_defs_top_NB_IoT.h b/openair1/PHY/impl_defs_top_NB_IoT.h index 8d05e9a05e..4179a865b8 100644 --- a/openair1/PHY/impl_defs_top_NB_IoT.h +++ b/openair1/PHY/impl_defs_top_NB_IoT.h @@ -55,15 +55,15 @@ typedef struct { //! estimated noise power (linear) unsigned int n0_power[NB_ANTENNAS_RX]; //! estimated noise power (dB) - unsigned short n0_power_dB[NB_ANTENNAS_RX]; + short n0_power_dB[NB_ANTENNAS_RX]; //! total estimated noise power (linear) unsigned int n0_power_tot; //! total estimated noise power (dB) - unsigned short n0_power_tot_dB; + short n0_power_tot_dB; //! average estimated noise power (linear) unsigned int n0_power_avg; //! average estimated noise power (dB) - unsigned short n0_power_avg_dB; + short n0_power_avg_dB; //! total estimated noise power (dBm) short n0_power_tot_dBm; @@ -71,24 +71,24 @@ typedef struct { //! estimated received spatial signal power (linear) int rx_spatial_power[NUMBER_OF_CONNECTED_eNB_MAX][2][2]; //! estimated received spatial signal power (dB) - unsigned short rx_spatial_power_dB[NUMBER_OF_CONNECTED_eNB_MAX][2][2]; + short rx_spatial_power_dB[NUMBER_OF_CONNECTED_eNB_MAX][2][2]; /// estimated received signal power (sum over all TX antennas) //int wideband_cqi[NUMBER_OF_CONNECTED_eNB_MAX][NB_ANTENNAS_RX]; int rx_power[NUMBER_OF_CONNECTED_eNB_MAX][NB_ANTENNAS_RX]; /// estimated received signal power (sum over all TX antennas) //int wideband_cqi_dB[NUMBER_OF_CONNECTED_eNB_MAX][NB_ANTENNAS_RX]; - unsigned short rx_power_dB[NUMBER_OF_CONNECTED_eNB_MAX][NB_ANTENNAS_RX]; + short rx_power_dB[NUMBER_OF_CONNECTED_eNB_MAX][NB_ANTENNAS_RX]; /// estimated received signal power (sum over all TX/RX antennas) int rx_power_tot[NUMBER_OF_CONNECTED_eNB_MAX]; //NEW /// estimated received signal power (sum over all TX/RX antennas) - unsigned short rx_power_tot_dB[NUMBER_OF_CONNECTED_eNB_MAX]; //NEW + short rx_power_tot_dB[NUMBER_OF_CONNECTED_eNB_MAX]; //NEW //! estimated received signal power (sum of all TX/RX antennas, time average) int rx_power_avg[NUMBER_OF_CONNECTED_eNB_MAX]; //! estimated received signal power (sum of all TX/RX antennas, time average, in dB) - unsigned short rx_power_avg_dB[NUMBER_OF_CONNECTED_eNB_MAX]; + short rx_power_avg_dB[NUMBER_OF_CONNECTED_eNB_MAX]; /// SINR (sum of all TX/RX antennas, in dB) int wideband_cqi_tot[NUMBER_OF_CONNECTED_eNB_MAX]; @@ -141,17 +141,17 @@ typedef struct { //! estimated noise power (linear) unsigned int n0_power[NB_ANTENNAS_RX]; //! estimated noise power (dB) - unsigned short n0_power_dB[NB_ANTENNAS_RX]; + short n0_power_dB[NB_ANTENNAS_RX]; //! total estimated noise power (linear) unsigned int n0_power_tot; //! estimated avg noise power (dB) - unsigned short n0_power_tot_dB; + short n0_power_tot_dB; //! estimated avg noise power (dB) short n0_power_tot_dBm; //! estimated avg noise power per RB per RX ant (lin) unsigned short n0_subband_power[NB_ANTENNAS_RX][100]; //! estimated avg noise power per RB per RX ant (dB) - unsigned short n0_subband_power_dB[NB_ANTENNAS_RX][100]; + short n0_subband_power_dB[NB_ANTENNAS_RX][100]; //! estimated avg noise power per RB (dB) short n0_subband_power_tot_dB[100]; //! estimated avg noise power per RB (dBm) @@ -160,7 +160,7 @@ typedef struct { //! estimated received spatial signal power (linear) unsigned int rx_spatial_power[NUMBER_OF_UE_MAX][2][2]; //! estimated received spatial signal power (dB) - unsigned short rx_spatial_power_dB[NUMBER_OF_UE_MAX][2][2]; + short rx_spatial_power_dB[NUMBER_OF_UE_MAX][2][2]; //! estimated rssi (dBm) short rx_rssi_dBm[NUMBER_OF_UE_MAX]; //! estimated correlation (wideband linear) between spatial channels (computed in dlsch_demodulation) @@ -173,7 +173,7 @@ typedef struct { /// Wideband CQI in dB (= SINR dB) int wideband_cqi_dB[NUMBER_OF_UE_MAX][NB_ANTENNAS_RX]; /// Wideband CQI (sum of all RX antennas, in dB) - char wideband_cqi_tot[NUMBER_OF_UE_MAX]; + int wideband_cqi_tot[NUMBER_OF_UE_MAX]; /// Subband CQI per RX antenna and RB (= SINR) int subband_cqi[NUMBER_OF_UE_MAX][NB_ANTENNAS_RX][100]; /// Total Subband CQI and RB (= SINR) diff --git a/openair1/SCHED/prach_procedures.c b/openair1/SCHED/prach_procedures.c index 968a94eeb0..3c8dbe8d6e 100644 --- a/openair1/SCHED/prach_procedures.c +++ b/openair1/SCHED/prach_procedures.c @@ -47,11 +47,12 @@ extern int oai_nfapi_rach_ind(nfapi_rach_indication_t *rach_ind); -void prach_procedures(PHY_VARS_eNB *eNB, - int br_flag ) { - uint16_t max_preamble[4]={0},max_preamble_energy[4]={0},max_preamble_delay[4]={0},avg_preamble_energy[4]={0}; +void prach_procedures(PHY_VARS_eNB *eNB, int br_flag) +{ + uint16_t max_preamble[4] = {0}, max_preamble_energy[4] = {0}, max_preamble_delay[4] = {0}; + int16_t avg_preamble_energy[4] = {0}; uint16_t i; - int frame,subframe; + int frame, subframe; if (br_flag==1) { subframe = eNB->proc.subframe_prach_br; diff --git a/openair1/SIMULATION/LTE_PHY/dlsim.c b/openair1/SIMULATION/LTE_PHY/dlsim.c index a09b3558cb..9e334cb154 100644 --- a/openair1/SIMULATION/LTE_PHY/dlsim.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim.c @@ -520,7 +520,8 @@ int main(int argc, char **argv) { DCI_ALLOC_t da; DCI_ALLOC_t *dci_alloc = &da; unsigned int coded_bits_per_codeword=0,nsymb; //,tbs=0; - unsigned int tx_lev=0,tx_lev_dB=0,trials; + unsigned int tx_lev = 0, trials; + int tx_lev_dB = 0; unsigned int errs[4],errs2[4],round_trials[4],dci_errors[4];//,num_layers; memset(errs,0,4*sizeof(unsigned int)); memset(errs2,0,4*sizeof(unsigned int)); @@ -1494,7 +1495,7 @@ int main(int argc, char **argv) { eNB->frame_parms.samples_per_tti); } - tx_lev_dB = (unsigned int) dB_fixed(tx_lev); + tx_lev_dB = dB_fixed(tx_lev); if (n_frames==1) { printf("tx_lev = %u (%u dB)\n",tx_lev,tx_lev_dB); diff --git a/openair1/SIMULATION/LTE_PHY/prachsim.c b/openair1/SIMULATION/LTE_PHY/prachsim.c index 1b7f9e80e4..c1128f76a1 100644 --- a/openair1/SIMULATION/LTE_PHY/prachsim.c +++ b/openair1/SIMULATION/LTE_PHY/prachsim.c @@ -393,7 +393,7 @@ int main(int argc, char **argv) { subframe, 0); //Nf /* tx_lev_dB not used later, no need to set */ - //tx_lev_dB = (unsigned int) dB_fixed(tx_lev); + //tx_lev_dB = dB_fixed(tx_lev); LOG_M("txsig0_new.m","txs0", &txdata[0][subframe*frame_parms->samples_per_tti],frame_parms->samples_per_tti,1,1); //LOG_M("txsig1.m","txs1", txdata[1],FRAME_LENGTH_COMPLEX_SAMPLES,1,1); // multipath channel diff --git a/openair1/SIMULATION/LTE_PHY/ulsim.c b/openair1/SIMULATION/LTE_PHY/ulsim.c index 92b9d58f48..c85e07c99c 100644 --- a/openair1/SIMULATION/LTE_PHY/ulsim.c +++ b/openair1/SIMULATION/LTE_PHY/ulsim.c @@ -343,7 +343,8 @@ int main(int argc, char **argv) { unsigned short input_buffer_length; unsigned int ret; unsigned int coded_bits_per_codeword,nsymb; - unsigned int tx_lev = 0, tx_lev_dB = 0, trials, errs[6] = {0}, round_trials[4] = {0}; + unsigned int tx_lev = 0, trials, errs[6] = {0}, round_trials[4] = {0}; + int tx_lev_dB = 0; FILE *bler_fd=NULL; char bler_fname[512]; FILE *time_meas_fd=NULL; @@ -894,7 +895,7 @@ int main(int argc, char **argv) { // LOG_M("txsig1.m","txs1", txdata[1],FRAME_LENGTH_COMPLEX_SAMPLES,1,1); tx_lev = signal_energy(&txdata[0][0], OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES); - tx_lev_dB = (unsigned int) dB_fixed(tx_lev); + tx_lev_dB = dB_fixed(tx_lev); } iter_trials=0; diff --git a/openair1/SIMULATION/NR_PHY/prachsim.c b/openair1/SIMULATION/NR_PHY/prachsim.c index 4da1accfe8..b39aeed372 100644 --- a/openair1/SIMULATION/NR_PHY/prachsim.c +++ b/openair1/SIMULATION/NR_PHY/prachsim.c @@ -667,7 +667,7 @@ int main(int argc, char **argv){ generate_nr_prach(UE, 0, frame, slot, tx); /* tx_lev_dB not used later, no need to set */ - //tx_lev_dB = (unsigned int) dB_fixed(tx_lev); + //tx_lev_dB = dB_fixed(tx_lev); #ifdef NR_PRACH_DEBUG LOG_M("txsig0.m", "txs0", &txdata[0][subframe*frame_parms->samples_per_subframe], frame_parms->samples_per_subframe, 1, 1); From bc6963c58891b12e48fd01383946893006052cbf Mon Sep 17 00:00:00 2001 From: rmagueta Date: Tue, 10 Feb 2026 18:30:10 +0000 Subject: [PATCH 38/44] Fix dB_fixed() function 0 in dB is -INF, but since we're dealing with integer variables, we'll put 10*log10(2^-30) in the output, which corresponds to the symmetrical maximum output of the function. --- openair1/PHY/TOOLS/dB_routines.c | 64 ++++++++++++++++---------------- openair1/PHY/TOOLS/tools_defs.h | 2 +- 2 files changed, 33 insertions(+), 33 deletions(-) diff --git a/openair1/PHY/TOOLS/dB_routines.c b/openair1/PHY/TOOLS/dB_routines.c index 6d56e6d124..13172da86b 100644 --- a/openair1/PHY/TOOLS/dB_routines.c +++ b/openair1/PHY/TOOLS/dB_routines.c @@ -21,7 +21,7 @@ #include "tools_defs.h" -// Approximate 10*log10(x) in fixed point : x = 0...(2^32)-1 +// Approximate 10*log10(x) in fixed point : x = 0...(2^32)-1, where the output is truncated to 10*log10(2^30) = 90 dB static const int8_t dB_table[256] = { 0, 3, 5, 6, 7, 8, 8, 9, 10, 10, 10, 11, 11, 11, 12, 12, 12, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, @@ -131,60 +131,60 @@ int16_t dB_fixed_x10(uint32_t x) { int16_t dB_fixed_times10(uint32_t x) { - int16_t dB_power=0; + int16_t dB_power = 0; - if (x==0) { - dB_power = 0; - } else if ( (x&0xff000000) != 0 ) { - dB_power = dB_table_times10[((x>>24)&255)-1]; - dB_power += 3*dB_table_times10[255]; - } else if ( (x&0x00ff0000) != 0 ) { - dB_power = dB_table_times10[((x>>16)&255)-1]; - dB_power += 2*dB_table_times10[255]; - } else if ( (x&0x0000ff00) != 0 ) { - dB_power = dB_table_times10[((x>>8)&255)-1]; + if (x == 0) { + dB_power = -900; // 0 in dB is -INF, but since we're dealing with integer variables, we'll put 10*log10(2^-30) x 10 in the output + } else if ((x & 0xff000000) != 0) { + dB_power = dB_table_times10[((x >> 24) & 255) - 1]; + dB_power += 3 * dB_table_times10[255]; + } else if ((x & 0x00ff0000) != 0) { + dB_power = dB_table_times10[((x >> 16) & 255) - 1]; + dB_power += 2 * dB_table_times10[255]; + } else if ((x & 0x0000ff00) != 0) { + dB_power = dB_table_times10[((x >> 8) & 255) - 1]; dB_power += dB_table_times10[255]; } else { - dB_power = dB_table_times10[(x&255)-1]; + dB_power = dB_table_times10[(x & 255) - 1]; } if (dB_power > 900) - return(900); + return (900); return dB_power; } - int8_t dB_fixed(uint32_t x) { - int8_t dB_power=0; + int8_t dB_power = 0; - if (x==0) { - dB_power = 0; - } else if ( (x&0xff000000) != 0 ) { - dB_power = dB_table[((x>>24)&255)-1]; - dB_power += 3*dB_table[255]; - } else if ( (x&0x00ff0000) != 0 ) { - dB_power = dB_table[((x>>16)&255)-1]; - dB_power += 2*dB_table[255]; - } else if ( (x&0x0000ff00) != 0 ) { - dB_power = dB_table[((x>>8)&255)-1]; + if (x == 0) { + dB_power = -90; // 0 in dB is -INF, but since we're dealing with integer variables, we'll put 10*log10(2^-30) in the output + } else if ((x & 0xff000000) != 0) { + dB_power = dB_table[((x >> 24) & 255) - 1]; + dB_power += 3 * dB_table[255]; + } else if ((x & 0x00ff0000) != 0) { + dB_power = dB_table[((x >> 16) & 255) - 1]; + dB_power += 2 * dB_table[255]; + } else if ((x & 0x0000ff00) != 0) { + dB_power = dB_table[((x >> 8) & 255) - 1]; dB_power += dB_table[255]; } else { - dB_power = dB_table[(x&255)-1]; + dB_power = dB_table[(x & 255) - 1]; } if (dB_power > 90) - return(90); + return (90); return dB_power; } - -uint8_t dB_fixed64(uint64_t x) +int8_t dB_fixed64(uint64_t x) { - if ((x<(((uint64_t)1)<<32))) return(dB_fixed((uint32_t)x)); - else return(4*dB_table[255]+dB_fixed((uint32_t)(x>>32))); + if ((x < (((uint64_t)1) << 32))) + return (dB_fixed((uint32_t)x)); + else + return (4 * dB_table[255] + dB_fixed((uint32_t)(x >> 32))); } diff --git a/openair1/PHY/TOOLS/tools_defs.h b/openair1/PHY/TOOLS/tools_defs.h index 40f6ca46f6..abe2ded220 100644 --- a/openair1/PHY/TOOLS/tools_defs.h +++ b/openair1/PHY/TOOLS/tools_defs.h @@ -961,7 +961,7 @@ uint32_t angle(struct complex16 perrror); unsigned char factor2(unsigned int x); int8_t dB_fixed(uint32_t x); -uint8_t dB_fixed64(uint64_t x); +int8_t dB_fixed64(uint64_t x); int8_t dB_fixed2(uint32_t x,uint32_t y); int16_t dB_fixed_times10(uint32_t x); int16_t dB_fixed_x10(uint32_t x); From c9065df7f8c4cebb41ce9095bab8a41cba6b1f7b Mon Sep 17 00:00:00 2001 From: Jaroslava Fiedlerova Date: Tue, 2 Dec 2025 10:32:33 +0100 Subject: [PATCH 39/44] CI: Add test into Jenkinsfile-Gitlab-Container --- ci-scripts/Jenkinsfile-GitLab-Container | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/ci-scripts/Jenkinsfile-GitLab-Container b/ci-scripts/Jenkinsfile-GitLab-Container index e94f386e2e..85b6f18c18 100644 --- a/ci-scripts/Jenkinsfile-GitLab-Container +++ b/ci-scripts/Jenkinsfile-GitLab-Container @@ -795,6 +795,29 @@ pipeline { } } } + stage ("SA-AERIAL-OAIUE-CN5G") { + when { expression {do5Gtest || do5GUeTest} } + steps { + script { + triggerSlaveJob ('RAN-SA-AERIAL-OAIUE-CN5G', 'SA-AERIAL-OAIUE-CN5G') + } + } + post { + always { + script { + // Using a unique variable name for each test stage to avoid overwriting on a global variable + // due to parallel-time concurrency + saAERIALOAIUEStatus = finalizeSlaveJob('RAN-SA-AERIAL-OAIUE-CN5G') + } + } + failure { + script { + currentBuild.result = 'FAILURE' + failingStages += saAERIALOAIUEStatus + } + } + } + } stage ("SA-OAIUE-CN5G") { when { expression {do5Gtest || do5GUeTest} } steps { From f12a3f4d4569be632a141be12534bb5177ff995c Mon Sep 17 00:00:00 2001 From: Jaroslava Fiedlerova Date: Tue, 3 Mar 2026 11:23:01 +0100 Subject: [PATCH 40/44] CI: Set WNC BW in Aerial pipeline Since the setup script is available, use it to ensure the correct bandwidth configuration before each run. --- ci-scripts/xml_files/container_sa_aerial_quectel.xml | 9 +++++++++ .../xml_files/container_sa_aerial_quectel_ul_heavy.xml | 9 +++++++++ 2 files changed, 18 insertions(+) diff --git a/ci-scripts/xml_files/container_sa_aerial_quectel.xml b/ci-scripts/xml_files/container_sa_aerial_quectel.xml index 7282513bb8..cf545b1a1d 100644 --- a/ci-scripts/xml_files/container_sa_aerial_quectel.xml +++ b/ci-scripts/xml_files/container_sa_aerial_quectel.xml @@ -33,6 +33,15 @@ arm_ + + Custom_Script + true + Configure 100 MHz bandwidth on WNC RU + gracehopper1-oai + + 100 + + Detach_UE true diff --git a/ci-scripts/xml_files/container_sa_aerial_quectel_ul_heavy.xml b/ci-scripts/xml_files/container_sa_aerial_quectel_ul_heavy.xml index 8367316e3a..65b9eaa00e 100644 --- a/ci-scripts/xml_files/container_sa_aerial_quectel_ul_heavy.xml +++ b/ci-scripts/xml_files/container_sa_aerial_quectel_ul_heavy.xml @@ -33,6 +33,15 @@ arm_ + + Custom_Script + true + Configure 100 MHz bandwidth on WNC RU + gracehopper1-oai + + 100 + + Detach_UE true From e107f81d548c697a89480eb0f706c698fae913da Mon Sep 17 00:00:00 2001 From: Jaroslava Fiedlerova Date: Wed, 4 Mar 2026 22:06:32 +0100 Subject: [PATCH 41/44] CI: update documentation for CI setups Add information about the new CI setup and the RAN-SA-AERIAL-OAIUE-CN5G testing pipeline. --- doc/TESTBenches.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/doc/TESTBenches.md b/doc/TESTBenches.md index f91321012c..c48cdfe5d3 100644 --- a/doc/TESTBenches.md +++ b/doc/TESTBenches.md @@ -27,6 +27,7 @@ | groot | Groot | gNB (n77) | B210 (30AD30F) | | rocket | Rocket | gNB (n77) | B210 (31F8010) | | raspix | Raspix | COTS UE | Quectel RM520N | +| jetson1-oai | Jetson1-oai | nrUE | USRP B210 | > **Note:** The available resources, and their current usage, is indicated here: > - [Lockable resources of jenkins-oai](https://jenkins-oai.eurecom.fr/lockable-resources/): @@ -238,6 +239,10 @@ information on how the images are built. ~5G-NR - gracehopper1-oai - run channel simulation on CPU and GPU using test_channel_scalability +- [RAN-SA-AERIAL-OAIUE-CN5G](https://jenkins-oai.eurecom.fr/job/RAN-SA-AERIAL-OAIUE-CN5G/) + ~5G-NR ~nrUE + - 5G-NR SA test setup: OAI VNF + PNF/NVIDIA CUBB on gracehopper1-oai + WNC RU, OAIUE on jetson1-oai + B210, OAI CN5G + - OpenShift cluster for CN deployment and container images for gNB and UE deployment ### RAN-CI-NSA-Trigger From c90d7f7f2623c2aa759cc98ba1761cbe1a772689 Mon Sep 17 00:00:00 2001 From: Aswanth KC Date: Mon, 2 Mar 2026 22:45:12 -0500 Subject: [PATCH 42/44] fix: issue 911 - OAI gNB hangs when AMF connection goes down - Extended fix to support multiple UEs instead of single UE - Actions now trigger upon AMF reconnection Per 3GPP TS 123 502 V16.7.0 (2021-01) Section 4.2.6 (AN Release): When NG-AP signalling connection is lost due to (R)AN or AMF failure, AN release is performed locally by AMF or (R)AN without relying on signalling between (R)AN and AMF. This deactivates all UP connections. --- openair2/COMMON/ngap_messages_def.h | 1 + openair3/NGAP/ngap_gNB.c | 41 +++++++++++++++++++++++++ openair3/NGAP/ngap_gNB_defs.h | 2 ++ openair3/NGAP/ngap_gNB_handlers.c | 2 ++ openair3/NGAP/ngap_gNB_nas_procedures.c | 2 +- openair3/NGAP/ngap_gNB_ue_context.c | 30 ++++++++++++++++++ openair3/NGAP/ngap_gNB_ue_context.h | 1 + 7 files changed, 78 insertions(+), 1 deletion(-) diff --git a/openair2/COMMON/ngap_messages_def.h b/openair2/COMMON/ngap_messages_def.h index 09e893f874..36528357f1 100644 --- a/openair2/COMMON/ngap_messages_def.h +++ b/openair2/COMMON/ngap_messages_def.h @@ -73,6 +73,7 @@ MESSAGE_DEF(NGAP_HANDOVER_NOTIFY, MESSAGE_PRIORITY_MED, ngap_handover_notify_t, MESSAGE_DEF(NGAP_HANDOVER_CANCEL, MESSAGE_PRIORITY_MED, ngap_handover_cancel_t, ngap_handover_cancel) MESSAGE_DEF(NGAP_UL_RAN_STATUS_TRANSFER, MESSAGE_PRIORITY_MED, ngap_ran_status_transfer_t, ngap_ul_ran_status_transfer) MESSAGE_DEF(NGAP_DL_RAN_STATUS_TRANSFER, MESSAGE_PRIORITY_MED, ngap_ran_status_transfer_t, ngap_dl_ran_status_transfer) +MESSAGE_DEF(NGAP_RECONNECT_TIMER, MESSAGE_PRIORITY_MED, IttiMsgText, ngap_gNB_amf_data) /* NGAP -> RRC messages */ MESSAGE_DEF(NGAP_DOWNLINK_NAS , MESSAGE_PRIORITY_MED, ngap_downlink_nas_t , ngap_downlink_nas ) diff --git a/openair3/NGAP/ngap_gNB.c b/openair3/NGAP/ngap_gNB.c index 257ca25f1a..e8fee7f34a 100644 --- a/openair3/NGAP/ngap_gNB.c +++ b/openair3/NGAP/ngap_gNB.c @@ -93,6 +93,38 @@ uint32_t ngap_generate_gNB_id(void) return gNB_id; } +static void ngap_gNB_redial_amf(ngap_gNB_amf_data_t *amf_desc_p) +{ + NGAP_INFO("AMF cnx_id = %u\n", amf_desc_p->cnx_id); + NGAP_INFO("AMF state = %d\n", amf_desc_p->state); + /*reconnect with the amf */ + MessageDef *message_p = itti_alloc_new_message(TASK_NGAP, 0, SCTP_NEW_ASSOCIATION_REQ); + sctp_new_association_req_t *req = &message_p->ittiMsg.sctp_new_association_req; + + /*amf descriptor */ + req->port = NGAP_PORT_NUMBER; + req->ppid = NGAP_SCTP_PPID; + req->in_streams = amf_desc_p->in_streams; + req->out_streams = amf_desc_p->out_streams; + req->ulp_cnx_id = amf_desc_p->cnx_id; + + ngap_gNB_instance_t *inst = amf_desc_p->ngap_gNB_instance; + + memcpy(&req->remote_address, &amf_desc_p->amf_s1_ip, sizeof(req->remote_address)); + memcpy(&req->local_address, &inst->gNB_ng_ip, sizeof(req->local_address)); + + NGAP_INFO("[gNB %ld] Re-dial AMF cnx_id=%u (streams in=%u out=%u)\n", + inst->instance, + amf_desc_p->cnx_id, + req->in_streams, + req->out_streams); + + inst->ngap_amf_nb++; + inst->ngap_amf_pending_nb++; + + itti_send_msg_to_task(TASK_SCTP, inst->instance, message_p); +} + static void ngap_gNB_register_amf(ngap_gNB_instance_t *instance_p, net_ip_address_t *amf_ip_address, net_ip_address_t *local_ip_addr, @@ -550,6 +582,15 @@ void *ngap_gNB_process_itti_msg(void *notUsed) { ngap_gNB_handle_sctp_association_resp(instance, &received_msg->ittiMsg.sctp_new_association_resp); break; + case TIMER_HAS_EXPIRED: { + timer_has_expired_t *th = &received_msg->ittiMsg.timer_has_expired; + ngap_gNB_amf_data_t *amf_desc_p = (ngap_gNB_amf_data_t *)th->arg; + if (amf_desc_p) { + ngap_gNB_redial_amf(amf_desc_p); + } + break; + } + case SCTP_DATA_IND: ngap_gNB_handle_sctp_data_ind(&received_msg->ittiMsg.sctp_data_ind); break; diff --git a/openair3/NGAP/ngap_gNB_defs.h b/openair3/NGAP/ngap_gNB_defs.h index 1a1e5768ff..b7c5dc3f64 100644 --- a/openair3/NGAP/ngap_gNB_defs.h +++ b/openair3/NGAP/ngap_gNB_defs.h @@ -161,6 +161,8 @@ struct ngap_gNB_instance_s; /* This structure describes association of a gNB to a AMF */ typedef struct ngap_gNB_amf_data_s { + long t_reconnect; // ITTI timer id (or equivalent) + /* AMF descriptors tree, ordered by sctp assoc id */ RB_ENTRY(ngap_gNB_amf_data_s) entry; diff --git a/openair3/NGAP/ngap_gNB_handlers.c b/openair3/NGAP/ngap_gNB_handlers.c index 9113f850ca..be0361afbd 100644 --- a/openair3/NGAP/ngap_gNB_handlers.c +++ b/openair3/NGAP/ngap_gNB_handlers.c @@ -77,6 +77,8 @@ void ngap_handle_ng_setup_message(ngap_gNB_amf_data_t *amf_desc_p, int sctp_shut /* Decrease associated AMF number */ amf_desc_p->ngap_gNB_instance->ngap_amf_associated_nb --; } + /* Release UE context and start reconnection process*/ + ngap_release_ues_for_amf(amf_desc_p); /* If there are no more associated AMF, inform gNB app */ if (amf_desc_p->ngap_gNB_instance->ngap_amf_associated_nb == 0) { diff --git a/openair3/NGAP/ngap_gNB_nas_procedures.c b/openair3/NGAP/ngap_gNB_nas_procedures.c index 2d4bd3eefa..9e341494c6 100644 --- a/openair3/NGAP/ngap_gNB_nas_procedures.c +++ b/openair3/NGAP/ngap_gNB_nas_procedures.c @@ -59,7 +59,7 @@ #include "s1ap_messages_types.h" #include "xer_encoder.h" #include "ds/byte_array.h" - +#include "intertask_interface.h" /** @brief Selects the AMF instance for a given UE based on identity information. * It attempts to select an AMF using the following prioritized criteria: * 1. GUAMI, if provided and valid (via Region ID, Set ID, Pointer). diff --git a/openair3/NGAP/ngap_gNB_ue_context.c b/openair3/NGAP/ngap_gNB_ue_context.c index 994271d822..e50726380f 100644 --- a/openair3/NGAP/ngap_gNB_ue_context.c +++ b/openair3/NGAP/ngap_gNB_ue_context.c @@ -34,6 +34,8 @@ #include "common/utils/T/T.h" #include "ngap_common.h" #include "tree.h" +#include "intertask_interface.h" +#define SCTP_LOOKUP_TIMER_TIMEOUT_SEC 30 /* Tree of UE ordered by gNB_ue_ngap_id's * NO INSTANCE, the 32 bits id is large enough to handle all UEs, regardless the cell, gNB, ... @@ -92,3 +94,31 @@ struct ngap_gNB_ue_context_s *ngap_detach_ue_context(uint32_t gNB_ue_ngap_id) RB_REMOVE(ngap_ue_map, &ngap_ue_head, tmp); return tmp; } + +void ngap_release_ues_for_amf(ngap_gNB_amf_data_t *amf_desc_p) +{ + /* Release all UE contexts for this AMF */ + ngap_gNB_ue_context_t *ue = NULL; + ngap_gNB_ue_context_t *next = NULL; + RB_FOREACH_SAFE(ue, ngap_ue_map, &ngap_ue_head, next) { + if (ue->amf_ref == amf_desc_p) { + LOG_I(NGAP, "Releasing UE context: gNB UE NGAP ID: %u | AMF UE NGAP ID: %lu\n", ue->gNB_ue_ngap_id, ue->amf_ue_ngap_id); + MessageDef *msg_p = itti_alloc_new_message(TASK_NGAP, 0, NGAP_UE_CONTEXT_RELEASE_COMMAND); + NGAP_UE_CONTEXT_RELEASE_COMMAND(msg_p).gNB_ue_ngap_id = ue->gNB_ue_ngap_id; + itti_send_msg_to_task(TASK_RRC_GNB, amf_desc_p->ngap_gNB_instance->instance, msg_p); + } + } + /* Reset AMF connection and set reconnect timer */ + /* SCTP lookup timer */ + long tid; + int rc = timer_setup(SCTP_LOOKUP_TIMER_TIMEOUT_SEC, + 0, + TASK_NGAP, + amf_desc_p->ngap_gNB_instance->instance, + TIMER_ONE_SHOT, + amf_desc_p, + &tid); + if (rc == 0) { + amf_desc_p->t_reconnect = tid; + } +} diff --git a/openair3/NGAP/ngap_gNB_ue_context.h b/openair3/NGAP/ngap_gNB_ue_context.h index 8053e8f8c6..1ca458968f 100644 --- a/openair3/NGAP/ngap_gNB_ue_context.h +++ b/openair3/NGAP/ngap_gNB_ue_context.h @@ -74,6 +74,7 @@ typedef struct ngap_gNB_ue_context_s { } ngap_gNB_ue_context_t; void ngap_store_ue_context(const ngap_gNB_ue_context_t *ue_desc_p); +void ngap_release_ues_for_amf(ngap_gNB_amf_data_t *amf_desc_p); ngap_gNB_ue_context_t *ngap_get_ue_context(uint32_t gNB_ue_ngap_id); ngap_gNB_ue_context_t *ngap_get_ue_context_from_amf_ue_ngap_id(uint32_t amf_ue_ngap_id); From 1d69eb0e1ef6cc6f4856f9e441a77f40ca5c25f5 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Mon, 16 Feb 2026 09:12:44 +0100 Subject: [PATCH 43/44] Add T tracer to record configured events to database This extends the functionality provided by record in that it allows collection of data into a Clickhouse database, allowing aggregation of data from gNB and UE for functions like channel estimation for PUSCH transmissions that did not decode successfully at the gNB. It is intended to be used in conjunction with Aerial Data Lake but is not limited to it. Data access is simpler than in !3462, but could be improved using the metadata approach from !3462. The integration uses logfmt for fast logging, and a clickhouse DB client, both integrated using CPM. This change set also adds a docker-compose file for a UE on 100MHz, to be used with Aerial configurations, and builds the tracer for Aerial and nrUE docker files. --- .../sa_gnb_aerial/docker-compose-ue.yaml | 61 + common/utils/T/T_messages.txt | 2 +- common/utils/T/tracer/CMakeLists.txt | 54 + common/utils/T/tracer/Makefile | 12 +- common/utils/T/tracer/record_db.cpp | 1324 +++++++++++++++++ docker/Dockerfile.base.ubuntu | 2 + .../Dockerfile.build.fhi72.native_arm.ubuntu | 3 +- docker/Dockerfile.build.fhi72.ubuntu | 3 +- docker/Dockerfile.build.ubuntu | 26 +- docker/Dockerfile.gNB.aerial.ubuntu | 14 +- docker/Dockerfile.nrORU.fhi72.ubuntu | 6 - docker/Dockerfile.nrUE.ubuntu | 11 + 12 files changed, 1492 insertions(+), 26 deletions(-) create mode 100644 ci-scripts/yaml_files/sa_gnb_aerial/docker-compose-ue.yaml create mode 100644 common/utils/T/tracer/record_db.cpp diff --git a/ci-scripts/yaml_files/sa_gnb_aerial/docker-compose-ue.yaml b/ci-scripts/yaml_files/sa_gnb_aerial/docker-compose-ue.yaml new file mode 100644 index 0000000000..15f2f177f4 --- /dev/null +++ b/ci-scripts/yaml_files/sa_gnb_aerial/docker-compose-ue.yaml @@ -0,0 +1,61 @@ +services: + oai-nr-ue: + image: ${REGISTRY-oaisoftwarealliance/}${NRUE_IMG:-oai-nr-ue}:${UE_TAG:-${TAG:-develop}} + logging: + options: + max-file: "1" + network_mode: host + container_name: oai-nr-ue + privileged: true + cpuset: 4,6,8,10,12,14,16,18,20,22,24,26,28 + cap_drop: + - ALL + cap_add: + - NET_ADMIN # for interface bringup + - NET_RAW # for ping + - SYS_NICE # for performance + - IPC_LOCK # for memory locking + - SYS_PTRACE # for debugging + devices: + - /dev/net/tun:/dev/net/tun + ulimits: + core: -1 # for core dumps + #entrypoint: /bin/bash -c "sleep infinity" + environment: + TZ: UTC + #DISPLAY: $DISPLAY #Uncomment for GUI + USE_ADDITIONAL_OPTIONS: | + --thread-pool 4,6,8,10,12,14,16,18,20,22,24,26 + --usrp-args type=x4xx,addr=192.168.10.2,clock_source=external,time_source=external + --ssb 1478 -r 273 --numerology 1 --band 78 -C 3750000000 + --num-dl-actors 20 + --ue-nb-ant-tx 1 + --ue-nb-ant-rx 1 + --ue-rxgain 25 + --ue-txgain 13 + --uicc0.imsi 001010000000003 + --ue-fo-compensation -A 90 + --usrp-tx-thread-config 1 + --log_config.global_log_options level,nocolor,utc_time + # Unused options: + # --T_stdout 2 + # --imscope + # --ssb 1478 -r 273 --numerology 1 --band 78 -C 3750000000 + # --usrp-tx-thread-config 1 + # --log_config.mac_log_level debug + # --log_config.nr_mac_log_level debug + # --usrp-tx-thread-config 1 -d + # --ssb 194 -r 51 --numerology 1 --band 78 -C 3750000000 #20MHz + # --ssb 236 -r 106 --numerology 1 --band 78 -C 3750000000 #40MHz + volumes: + - ../../conf_files/ue.sa.conf:/opt/oai-nr-ue/etc/nr-ue.conf + # UL throughput is worse with 256-qam table + - ../../../targets/PROJECTS/GENERIC-NR-5GC/CONF/uecap_ports1.xml:/opt/oai-nr-ue/uecap_ports1.xml + #For GUI + - ${HOME}/.Xauthority:/root/.Xauthority:rw + - /tmp/.X11-unix:/tmp/.X11-unix + healthcheck: + test: /bin/bash -c "pgrep nr-uesoftmodem" + interval: 10s + timeout: 5s + retries: 5 diff --git a/common/utils/T/T_messages.txt b/common/utils/T/T_messages.txt index d2405f9033..18e98be0b6 100644 --- a/common/utils/T/T_messages.txt +++ b/common/utils/T/T_messages.txt @@ -1404,7 +1404,7 @@ ID = UE_PHY_PDCCH_ENERGY ID = UE_PHY_PDSCH_IQ DESC = UE PDSCH received IQ data GROUP = ALL:PHY:GRAPHIC:HEAVY:UE - FORMAT = int,eNB_ID : int,frame : int,subframe : int,nb_rb : int,N_RB_UL : int,symbols_per_tti : buffer,pusch_comp + FORMAT = int,eNB_ID : int,frame : int,subframe : int,nb_rb : int,N_RB_UL : int,symbols_per_tti : buffer,pdsch_comp ID = UE_PHY_PDSCH_ENERGY DESC = UE PDSCH 1 energy and threshold GROUP = ALL:PHY:GRAPHIC:HEAVY:UE diff --git a/common/utils/T/tracer/CMakeLists.txt b/common/utils/T/tracer/CMakeLists.txt index e347552d31..d64ea840a9 100644 --- a/common/utils/T/tracer/CMakeLists.txt +++ b/common/utils/T/tracer/CMakeLists.txt @@ -37,11 +37,65 @@ add_subdirectory(filter) add_subdirectory(logger) add_subdirectory(view) +# Option to enable record_db tracer tool with ClickHouse database support +add_boolean_option(T_RECORD_DB OFF "Compile record_db tracer tool with ClickHouse support" OFF) + +if(T_RECORD_DB) + # Save current BUILD_SHARED_LIBS setting + set(SAVED_BUILD_SHARED_LIBS ${BUILD_SHARED_LIBS}) + + # Configure options for clickhouse-cpp + set(BUILD_SHARED_LIBS ON CACHE BOOL "" FORCE) + + # Save current compiler flags and disable -Werror for zstd + set(SAVED_CMAKE_C_FLAGS "${CMAKE_C_FLAGS}") + + # Check if system zstd library is available + find_library(ZSTD_LIBRARY NAMES zstd) + if(ZSTD_LIBRARY) + # Use system zstd library to avoid building legacy zstd code with warnings + set(WITH_SYSTEM_ZSTD ON CACHE BOOL "" FORCE) + else() + # Fall back to bundled zstd and suppress warnings from legacy code + # https://github.com/ClickHouse/clickhouse-cpp/blob/master/contrib/zstd/zstd/legacy/zstd_v01.c#L1935 + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-maybe-uninitialized -Wno-uninitialized") + endif() + + CPMAddPackage( + NAME clickhouse-cpp + GITHUB_REPOSITORY ClickHouse/clickhouse-cpp + GIT_TAG master + ) + + # Restore original compiler flags and BUILD_SHARED_LIBS + set(CMAKE_C_FLAGS "${SAVED_CMAKE_C_FLAGS}") + set(BUILD_SHARED_LIBS ${SAVED_BUILD_SHARED_LIBS} CACHE BOOL "" FORCE) + + CPMAddPackage( + NAME fmtlog + GITHUB_REPOSITORY MengRao/fmtlog + GIT_TAG main + GIT_SHALLOW FALSE + ) + + add_executable(record_db record_db.cpp) + + target_include_directories(record_db PRIVATE ${fmtlog_SOURCE_DIR} ${fmtlog_SOURCE_DIR}/fmt/include) + target_link_libraries(record_db PRIVATE tracer_utils clickhouse-cpp-lib fmtlog-shared fmt) + +endif() # T_RECORD_DB + add_custom_target(T_tools) add_dependencies(T_tools record replay extract_config extract_input_subframe extract_output_subframe extract macpdu2wireshark multi textlog csv) + +# Add record_db to T_tools if it was built +if(TARGET record_db) + add_dependencies(T_tools record_db) +endif() + add_dependencies(nr-softmodem T_tools) add_dependencies(nr-uesoftmodem T_tools) add_dependencies(lte-softmodem T_tools) diff --git a/common/utils/T/tracer/Makefile b/common/utils/T/tracer/Makefile index cedf8fdbcf..5d0aed4029 100644 --- a/common/utils/T/tracer/Makefile +++ b/common/utils/T/tracer/Makefile @@ -1,18 +1,23 @@ CC=gcc +CXX=g++ CFLAGS=-Wall -g -pthread -DT_TRACER -I. -I../incgen +CXXFLAGS=-Wall -g -pthread -DT_TRACER -I. -I../incgen -std=c++11 #CFLAGS += -O3 -ffast-math -fomit-frame-pointer LIBS=-lm XLIBS=-lX11 -lpng -lXft -all: record replay extract_config textlog enb ue vcd macpdu2wireshark \ +all: record record_db replay extract_config textlog enb ue vcd macpdu2wireshark \ extract_input_subframe extract_output_subframe to_vcd extract multi \ gnb t_tracer_app_gnb t_tracer_app_ue gnb_mac csv record: utils.o record.o database.o configuration.o $(CC) $(CFLAGS) -o record $^ $(LIBS) +record_db: utils.o record_db.o database.o configuration.o + $(CXX) $(CXXFLAGS) -o record_db $^ $(LIBS) -lclickhouse-cpp-lib $(FMTLOG_LIBS) + replay: utils.o replay.o $(CC) $(CFLAGS) -o replay $^ $(LIBS) @@ -102,8 +107,11 @@ filter/filter.a: %.o: %.c $(CC) $(CFLAGS) -c -o $@ $< +%.o: %.cpp + $(CXX) $(CXXFLAGS) -c -o $@ $< + clean: - rm -f *.o core tracer_remote textlog enb ue vcd record replay + rm -f *.o core tracer_remote textlog enb ue vcd record record_db replay rm -f extract_config macpdu2wireshark extract_input_subframe rm -f extract_output_subframe to_vcd extract multi gnb rm -f t_tracer_app_gnb t_tracer_app_ue gnb_mac csv diff --git a/common/utils/T/tracer/record_db.cpp b/common/utils/T/tracer/record_db.cpp new file mode 100644 index 0000000000..b450f617db --- /dev/null +++ b/common/utils/T/tracer/record_db.cpp @@ -0,0 +1,1324 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "fmtlog.h" + +namespace ch = clickhouse; + +extern "C" { // For connect_to(), socket_send(), parse_database(), etc. +#include +#include +#include +#include +#include +#include "database.h" +#include "utils.h" +#include "../T_defs.h" +#include "configuration.h" +} + +const int MAX_QUERY_SIZE = 65536; +const char *DEFAULT_CLICKHOUSE_HOST = "localhost"; +const int DEFAULT_CLICKHOUSE_PORT = 9000; +const char *DEFAULT_CLICKHOUSE_DB = "oai"; + +// Buffer multiple rows per event type and insert when: +// 1. Buffer reaches BATCH_SIZE rows, OR +// 2. INSERT_INTERVAL_MS milliseconds have elapsed since last insert +// This reduces insertion time from ~30ms/event to <1ms/event amortized +const size_t BATCH_SIZE = 500; // Number of rows to buffer before inserting +const uint64_t INSERT_INTERVAL_MS = 500; // Insert every 500ms +const size_t BUFFER_SIZE = 10 * 1024 * 1024; // 10MB +const size_t BUFFER_MARGIN = 183'456; // UE_PHY_PDSCH_IQ size + +// 5G NR timing constants +const uint64_t NS_PER_SEC = 1000000000ULL; +const uint64_t FRAME_PERIOD_NS = 10000000ULL; // 10ms per frame +const int SFN_MAX = 1024; +// Duration of one full SFN cycle (1024 frames = 10.24 seconds) +const uint64_t SFN_CYCLE_NS = FRAME_PERIOD_NS * SFN_MAX; + +// TAI to UTC offset in seconds (37 leap seconds as of 2017) +// This may need to be updated when new leap seconds are added +const int TAI_UTC_OFFSET_SEC = 37; + +// GPS epoch is January 6, 1980 00:00:00 UTC +// Unix epoch is January 1, 1970 00:00:00 UTC +// Offset = 315964800 seconds +const uint64_t UNIX_TO_GPS_OFFSET_SEC = 315964800ULL; +const uint64_t UNIX_TO_GPS_OFFSET_NS = UNIX_TO_GPS_OFFSET_SEC * NS_PER_SEC; +const uint8_t UTC_TO_GPS_OFFSET_SEC = 18; // As of 2017, GPS time is 18 seconds ahead of UTC time. +const uint64_t UTC_TO_GPS_OFFSET_NS = UTC_TO_GPS_OFFSET_SEC * NS_PER_SEC; + +/** + * Calculate duration between two timestamps in nanoseconds + * Works with both std::chrono::high_resolution_clock::time_point and uint64_t nanosecond timestamps + */ +#define DURATION_NS(start, end) (std::chrono::duration_cast((end) - (start)).count()) +#define DURATION_US(start, end) (std::chrono::duration_cast((end) - (start)).count()) +#define DURATION_MS(start, end) (std::chrono::duration_cast((end) - (start)).count()) + +/** + * Calculate duration between two uint64_t nanosecond timestamps + */ +#define DURATION_NS_U64(end_ns, start_ns) ((int64_t)(end_ns) - (int64_t)(start_ns)) +/** + * Get slot duration in nanoseconds for a given numerology + * mu=0 (15kHz): 1ms, mu=1 (30kHz): 0.5ms, mu=2 (60kHz): 0.25ms, etc. + */ +inline uint64_t get_slot_duration_ns(int mu) +{ + static const uint64_t slot_durations_ns[] = { + 1000000, // mu=0: 1ms + 500000, // mu=1: 0.5ms + 250000, // mu=2: 0.25ms + 125000, // mu=3: 0.125ms + 62500 // mu=4: 0.0625ms + }; + if (mu < 0 || mu > 4) { + loge("Invalid numerology mu={}, using mu=0", mu); + return slot_durations_ns[0]; + } + return slot_durations_ns[mu]; +} + +/** + * Get number of slots per frame for a given numerology + */ +inline int get_slots_per_frame(int mu) +{ + static const int slots_per_frame[] = {10, 20, 40, 80, 160}; + if (mu < 0 || mu > 4) { + loge("Invalid numerology mu={}, using mu=0", mu); + return slots_per_frame[0]; + } + return slots_per_frame[mu]; +} + +/** + * Convert Unix/Linux time to GPS time + * + * @param unix_time_ns Unix time in nanoseconds since Unix epoch (Jan 1, 1970) + * @return GPS time in nanoseconds since GPS epoch (Jan 6, 1980) + */ +inline uint64_t unix_to_gps_ns(uint64_t unix_time_ns) +{ + return unix_time_ns - UNIX_TO_GPS_OFFSET_NS + UTC_TO_GPS_OFFSET_NS; +} + +/** + * Convert GPS time to Unix/Linux time + * + * @param gps_time_ns GPS time in nanoseconds since GPS epoch + * @return GPS time in nanoseconds since Unix epoch + */ +inline uint64_t gps_to_posix_ns(uint64_t gps_time_ns) +{ + return gps_time_ns + UNIX_TO_GPS_OFFSET_NS; +} + +/** + * Convert GPS time to Unix/Linux time + * + * @param gps_time_ns GPS time in nanoseconds since GPS epoch + * @return UTC time in nanoseconds since Unix epoch + */ +inline uint64_t gps_to_utc_ns(uint64_t gps_time_ns) +{ + return gps_to_posix_ns(gps_time_ns) - UTC_TO_GPS_OFFSET_NS; +} + +/** + * Calculate the absolute GPS timestamp for a given SFN and slot, given a close time reference in Unix time. + * + * @param sfn System Frame Number (0-1023) + * @param slot Slot number within the frame (depends on numerology) + * @param mu Numerology (0-4): 0=15kHz, 1=30kHz, 2=60kHz, 3=120kHz, 4=240kHz + * @param reference_utc_ns Reference UTC time in nanoseconds since Unix epoch + * @return UTC timestamp in nanoseconds when the SFN/slot was transmitted + */ +uint64_t calculate_sfn_slot_gps_time(int sfn, int slot, int mu, uint64_t reference_unix_ns) +{ + // Validate inputs + if (sfn < 0 || sfn >= SFN_MAX) { + loge("Invalid SFN={} (must be 0-1023)", sfn); + sfn = sfn % SFN_MAX; + return 0; + } + + int slots_per_frame = get_slots_per_frame(mu); + if (slot < 0 || slot >= slots_per_frame) { + loge("Invalid slot={} for mu={} (must be 0-{})", slot, mu, slots_per_frame - 1); + slot = slot % slots_per_frame; + } + // Nanoseconds since GPS epoch start, should be slightly larger than actual transmit time. + uint64_t reference_gps_ns = unix_to_gps_ns(reference_unix_ns); + + // Calculate the offset within one SFN cycle for the given SFN/slot + uint64_t slot_duration_ns = get_slot_duration_ns(mu); + uint64_t offset_in_cycle_ns = (sfn * FRAME_PERIOD_NS) + (slot * slot_duration_ns); + + // Find the number of complete SFN cycles since GPS epoch + // We'll use the reference time to determine which SFN cycle we're in + uint64_t cycles_since_epoch = reference_gps_ns / SFN_CYCLE_NS; + + // Calculate the base time for the current SFN cycle + uint64_t current_cycle_base_ns = cycles_since_epoch * SFN_CYCLE_NS; + + // Calculate the target time within this cycle + uint64_t gps_time_ns = current_cycle_base_ns + offset_in_cycle_ns; + + // Check if the GPS time is too far in the future (more than 1 second) + // If so, it probably occurred in the previous cycle + if (gps_time_ns > reference_gps_ns + NS_PER_SEC) { + gps_time_ns -= SFN_CYCLE_NS; + } + // Check if the target is too far in the past (more than 9.24 seconds) + // If so, it probably occurs in the next cycle + if (gps_time_ns < reference_gps_ns - (SFN_CYCLE_NS - NS_PER_SEC)) { + gps_time_ns += SFN_CYCLE_NS; + } + return gps_time_ns; +} + +void calculate_sfn_slot_from_gps(uint64_t gps_time_ns, int mu, int *sfn, int *slot) +{ + uint64_t phase_ns = gps_time_ns % SFN_CYCLE_NS; + + *sfn = phase_ns / FRAME_PERIOD_NS; // Truncate to integer + uint64_t position_in_frame_ns = phase_ns % FRAME_PERIOD_NS; // Remainder + + uint64_t slot_duration_ns = get_slot_duration_ns(mu); + *slot = position_in_frame_ns / slot_duration_ns; + + if (*sfn >= SFN_MAX) + *sfn = SFN_MAX - 1; + int max_slot = get_slots_per_frame(mu) - 1; + if (*slot > max_slot) + *slot = max_slot; +} + +void calculate_sfn_slot_from_unix(uint64_t unix_time_ns, int mu, int *sfn, int *slot) +{ + uint64_t gps_time_ns = unix_to_gps_ns(unix_time_ns); + calculate_sfn_slot_from_gps(gps_time_ns, mu, sfn, slot); +} + +void usage(void) +{ + printf( + "options:\n" + " -d this option is mandatory\n" + " -on turn log ON for given GROUP or ID\n" + " -off turn log OFF for given GROUP or ID\n" + " -ON turn all logs ON\n" + " -OFF turn all logs OFF\n" + " note: you may pass several -on/-off/-ON/-OFF,\n" + " they will be processed in order\n" + " by default, all is off\n" + " -ip connect to given IP address (default %s)\n" + " -p connect to given port (default %d)\n" + " -ch-host ClickHouse host (default %s)\n" + " -ch-port ClickHouse native port (default %d)\n" + " -ch-db ClickHouse database name (default %s)\n" + " -ch-user ClickHouse user (optional)\n" + " -ch-pass ClickHouse password (optional)\n" + " -ch-droptables drop the ClickHouse database before run\n" + " -debug enable debug logging\n", + DEFAULT_REMOTE_IP, + DEFAULT_REMOTE_PORT, + DEFAULT_CLICKHOUSE_HOST, + DEFAULT_CLICKHOUSE_PORT, + DEFAULT_CLICKHOUSE_DB); + exit(1); +} + +volatile int run = 1; + +static int socket_fd = -1; + +void force_stop(int x) +{ + logi("gently quit..."); + close(socket_fd); + socket_fd = -1; + run = 0; +} + +struct clickhouse_config_t { + std::string host; + int port; + std::string database; + std::string user; + std::string password; + std::unique_ptr client; + int drop_tables; +}; + +// Buffer management structures +struct DataBuffer { + uint8_t *buffer; // Large preallocated buffer + size_t buffer_size; // Total size of buffer + size_t current_offset; // Current write position in buffer + std::shared_ptr inner_col; // Reusable inner column for ClickHouse + std::shared_ptr offsets_col; // Reusable offsets column for ClickHouse (cumulative end offsets) + bool insert_now; + + DataBuffer(size_t size) : buffer_size(size - BUFFER_MARGIN), current_offset(0), insert_now(false) + { + buffer = (uint8_t *)malloc(size); + if (!buffer) { + throw std::bad_alloc(); + } + + // Create and reserve ClickHouse columns for reuse + inner_col = std::make_shared(); + auto &inner_data = inner_col->GetWritableData(); + inner_data.reserve(size); + + offsets_col = std::make_shared(); + offsets_col->Reserve(BATCH_SIZE); + } + + ~DataBuffer() + { + if (buffer) { + free(buffer); + buffer = nullptr; + } + } + + // Disable copy constructor and assignment operator + DataBuffer(const DataBuffer &) = delete; + DataBuffer &operator=(const DataBuffer &) = delete; + + // Copy data into buffer and return offset + size_t append(const void *data, size_t length) + { + if (current_offset + length > buffer_size) { + insert_now = true; // If this puts the buffer into the margin, insert it immediately + if (length > BUFFER_MARGIN) { + loge("DataBuffer full: current_offset={} length={} buffer_size={}", current_offset, length, buffer_size); + return (size_t)-1; + } // Else we have margin + } + + size_t offset = current_offset; + memcpy(buffer + current_offset, data, length); + current_offset += length; + + offsets_col->Append(current_offset); + + return offset; + } + + // Get pointer to data at a specific offset + const uint8_t *get_data(size_t offset) const + { + if (offset >= current_offset) { + return nullptr; + } + return buffer + offset; + } + + // Clear buffer for reuse + void clear() + { + current_offset = 0; + insert_now = false; + inner_col->Clear(); + offsets_col->Clear(); + } + + // Get number of entries + size_t entry_count() const + { + return offsets_col->Size(); + } + + // Get current usage + size_t usage() const + { + return current_offset; + } +}; + +struct EventBuffer { + std::vector columns; // Ordered list of columns + std::vector column_names; // Column names in same order + std::string event_table_name; + size_t row_count; + bool insert_now; + std::chrono::steady_clock::time_point last_insert_time; + database_event_format format; + std::string event_name; + bool has_frame_slot; + std::unordered_map> data_buffers; + + // Cached typed column pointers to avoid expensive As<> casts on every insert + std::shared_ptr ts_sw_col; + std::shared_ptr ts_tx_col; + std::vector> int_cols; + std::vector> ulong_cols; + std::vector> string_cols; + std::unordered_map field_idx_to_typed_col_idx; // Maps format field index to typed column index + + // Performance metrics + uint64_t last_column_build_duration_ns; + uint64_t last_block_append_duration_ns; + uint64_t last_insertion_duration_ns; + + // Statistics tracking + uint64_t total_rows; // Total rows inserted since start + uint64_t rows_since_print; // Rows since last print + + EventBuffer() + : row_count(0), + insert_now(false), + last_insert_time(std::chrono::steady_clock::now()), + has_frame_slot(false), + last_column_build_duration_ns(0), + last_block_append_duration_ns(0), + last_insertion_duration_ns(0), + total_rows(0), + rows_since_print(0) + { + } +}; + +// Global buffer map: event_id -> EventBuffer +std::unordered_map g_event_buffers; + +/* Convert T format type to ClickHouse type */ +const char *get_clickhouse_type(const char *t_type) +{ + if (strcmp(t_type, "int") == 0) + return "Int32"; + if (strcmp(t_type, "ulong") == 0) + return "UInt64"; + if (strcmp(t_type, "string") == 0) + return "String"; + if (strcmp(t_type, "buffer") == 0) + return "Array(UInt8)"; // Store as byte array + if (strncmp(t_type, "int", 3) == 0) + return "Int32"; + return "String"; // default +} + +/* Execute ClickHouse query */ +int clickhouse_execute(clickhouse_config_t *ch, const char *query) +{ + try { + ch->client->Execute(query); + return 0; + } catch (const std::exception &e) { + loge("ClickHouse query failed: {}", e.what()); + return -1; + } +} + +/* Initialize ClickHouse connection and create database */ +int clickhouse_init(clickhouse_config_t *ch) +{ + char query[1024]; + + try { + // Set connection options + ch::ClientOptions options; + options.SetHost(ch->host); + options.SetPort(ch->port); + + if (!ch->user.empty()) { + options.SetUser(ch->user); + } + if (!ch->password.empty()) { + options.SetPassword(ch->password); + } + + // Create client + ch->client = std::make_unique(options); + /* Handle drop database option */ + if (ch->drop_tables) { + logi("Dropping database: {}", ch->database.c_str()); + snprintf(query, sizeof(query), "DROP DATABASE IF EXISTS %s", ch->database.c_str()); + + if (clickhouse_execute(ch, query) != 0) { + loge("Failed to drop database {}", ch->database); + exit(1); + } + } + + // Create database if not exists + snprintf(query, sizeof(query), "CREATE DATABASE IF NOT EXISTS %s", ch->database.c_str()); + if (clickhouse_execute(ch, query) != 0) { + loge("Failed to create database"); + return -1; + } + + logi("ClickHouse connection initialized"); + return 0; + } catch (const std::exception &e) { + loge("Failed to create ClickHouse client: {}", e.what()); + return -1; + } +} + +/* Create table schema from database format */ +char *create_table_schema(char *schema_buf, const char *event_name, database_event_format format, const char *database) +{ + char *p = schema_buf; + bool has_frame = false; + bool has_slot = false; + int i; + + // Start CREATE TABLE statement + p += snprintf(p, + MAX_QUERY_SIZE - (p - schema_buf), + "CREATE TABLE IF NOT EXISTS %s.%s (\n TsSwNs DateTime64(9) DEFAULT now64(9)", + database, + event_name); + + for (i = 0; i < format.count; i++) { + if (strcmp(format.name[i], "frame") == 0) + has_frame = true; + if (strcmp(format.name[i], "slot") == 0) + has_slot = true; + if (strcmp(format.name[i], "subframe") == 0) + has_slot = true; + } + if (has_frame && has_slot) { + p += snprintf(p, MAX_QUERY_SIZE - (p - schema_buf), ",\n TsTxUtcNs DateTime64(9)"); + uint64_t timestamp_ns = std::chrono::system_clock::now().time_since_epoch().count() / NS_PER_SEC; + if (timestamp_ns > 1861920000) { + // 1861920000 -> 2029-01-01 00:00:00 + logw("WARNING: Linux time {} is greater than 2029-01-01 00:00:00.", timestamp_ns); + logw(" Check if a negative leap second has been announced and change UTC_TO_GPS_OFFSET_NS accordingly.", + timestamp_ns); + } + } + + // Add columns from format + for (i = 0; i < format.count; i++) { + const char *ch_type = get_clickhouse_type(format.type[i]); + p += snprintf(p, MAX_QUERY_SIZE - (p - schema_buf), ",\n %s %s", format.name[i], ch_type); + } + + p += snprintf(p, MAX_QUERY_SIZE - (p - schema_buf), "\n) ENGINE = Memory();"); + +#ifdef DB_DEBUG + logd("schema: {}", schema_buf); +#endif + return schema_buf; +} + +/* Initialize buffer for an event */ +void init_event_buffer(int event_id, void *database, const char *database_name) +{ + char *event_name = event_name_from_id(database, event_id); + database_event_format format = get_format(database, event_id); + + if (!event_name) + return; + + EventBuffer &buf = g_event_buffers[event_id]; + buf.event_name = std::string(event_name); + buf.event_table_name = std::string(database_name) + "." + event_name; + buf.format = format; + buf.row_count = 0; + buf.last_insert_time = std::chrono::steady_clock::now(); + + // Check if this event has frame/slot fields + buf.has_frame_slot = false; + bool has_frame = false; + bool has_slot = false; + for (int i = 0; i < format.count; i++) { + if (strcmp(format.name[i], "frame") == 0) + has_frame = true; + if (strcmp(format.name[i], "slot") == 0 || strcmp(format.name[i], "subframe") == 0) + has_slot = true; + } + buf.has_frame_slot = has_frame && has_slot; + + // Create TsSwNs column + auto ts_col = std::make_shared(9); + ts_col->Reserve(BATCH_SIZE); + buf.columns.push_back(ts_col); + buf.column_names.push_back("TsSwNs"); + buf.ts_sw_col = ts_col; // Cache typed pointer + + // Add data columns + for (int i = 0; i < format.count; i++) { + if (strcmp(format.type[i], "int") == 0) { + auto col = std::make_shared(); + col->Reserve(BATCH_SIZE); + buf.columns.push_back(col); + buf.column_names.push_back(format.name[i]); + buf.field_idx_to_typed_col_idx[i] = buf.int_cols.size(); + buf.int_cols.push_back(col); + } else if (strcmp(format.type[i], "ulong") == 0) { + auto col = std::make_shared(); + col->Reserve(BATCH_SIZE); + buf.columns.push_back(col); + buf.column_names.push_back(format.name[i]); + buf.field_idx_to_typed_col_idx[i] = buf.ulong_cols.size(); + buf.ulong_cols.push_back(col); + } else if (strcmp(format.type[i], "buffer") == 0) { + buf.data_buffers[i] = std::make_unique(BUFFER_SIZE); + + // Placeholder - array column will be created from DataBuffer at flush time + buf.columns.push_back(nullptr); + buf.column_names.push_back(format.name[i]); + + } else if (strcmp(format.type[i], "string") == 0) { + auto col = std::make_shared(); + col->Reserve(BATCH_SIZE); + buf.columns.push_back(col); + buf.column_names.push_back(format.name[i]); + buf.field_idx_to_typed_col_idx[i] = buf.string_cols.size(); + buf.string_cols.push_back(col); + } else { + // Default: treat as int + auto col = std::make_shared(); + col->Reserve(BATCH_SIZE); + buf.columns.push_back(col); + buf.column_names.push_back(format.name[i]); + buf.field_idx_to_typed_col_idx[i] = buf.int_cols.size(); + buf.int_cols.push_back(col); + } + } + + // Add TsTxUtcNs column if event has frame/slot + if (buf.has_frame_slot) { + auto gps_col = std::make_shared(9); + gps_col->Reserve(BATCH_SIZE); + buf.columns.push_back(gps_col); + buf.column_names.push_back("TsTxUtcNs"); + buf.ts_tx_col = gps_col; // Cache typed pointer + } + + logi("Initialized buffer for event_id:{:<4} name:{:<31} has_frame_slot:{} columns:{}", + event_id, + event_name, + buf.has_frame_slot, + buf.columns.size()); + + // Print sizes of buffer fields + for (int i = 0; i < format.count; i++) { + if (strcmp(format.type[i], "buffer") == 0) { + logd(" Buffer field '{}' size={} MB", format.name[i], BUFFER_SIZE / (1024 * 1024)); + } + } +} + +/* Create tables for enabled events */ +int create_tables(clickhouse_config_t *ch, void *database, int *is_on, int number_of_events) +{ + int i; + size_t longest_table_name = 0; + + for (i = 0; i < number_of_events; i++) { + if (!is_on[i]) + continue; + + char *event_name = event_name_from_id(database, i); + database_event_format format = get_format(database, i); + if (strlen(event_name) > longest_table_name) + longest_table_name = strlen(event_name); + + if (!event_name) + continue; + + logd("Creating table for event: {:<31}", event_name); + + char schema[MAX_QUERY_SIZE]; + create_table_schema(schema, event_name, format, ch->database.c_str()); + + if (clickhouse_execute(ch, schema) != 0) { + loge("Failed to create table {}", event_name); + return -1; + } + + // Initialize buffer for this event + init_event_buffer(i, database, ch->database.c_str()); + } + + return (int)longest_table_name; +} + +int insert_buffer(clickhouse_config_t *ch, int event_id) +{ + auto it = g_event_buffers.find(event_id); + if (it == g_event_buffers.end() || it->second.row_count == 0) { + return 0; // Nothing to flush + } + + EventBuffer &buf = it->second; + buf.insert_now = false; + + auto t_reconstruct_start = std::chrono::high_resolution_clock::now(); + size_t total_data_size = 0; + for (auto &dbuf_pair : buf.data_buffers) { + int field_idx = dbuf_pair.first; + DataBuffer *dbuf = dbuf_pair.second.get(); + int col_idx = field_idx + 1; // +1 because TsSwNs is at index 0 + + // Build the array column from the DataBuffer + size_t num_entries = dbuf->offsets_col->Size(); + + if (num_entries != buf.row_count) { + loge("DataBuffer entry count mismatch for field '{}': {} entries vs {} rows", + buf.format.name[field_idx], + num_entries, + buf.row_count); + } + + // Copy all data to the DataBuffer's inner column (space already reserved in constructor) + if (dbuf->current_offset > 0) { + auto &inner_data = dbuf->inner_col->GetWritableData(); + inner_data.resize(dbuf->current_offset); // Set size (doesn't reallocate since already reserved) + memcpy(inner_data.data(), dbuf->buffer, dbuf->current_offset); + } + + // Create the array column from DataBuffer's columns and store it + auto array_col = std::make_shared>(dbuf->inner_col, dbuf->offsets_col); + buf.columns[col_idx] = array_col; + + total_data_size += dbuf->current_offset; + } + auto t_reconstruct_end = std::chrono::high_resolution_clock::now(); + + ch::Block block; + for (size_t i = 0; i < buf.columns.size(); i++) { + if (buf.columns[i]) { + block.AppendColumn(buf.column_names[i], buf.columns[i]); + } else { + loge("Column '{}' at index {} is null when creating block", buf.column_names[i], i); + exit(1); + } + } + try { + auto t_insert_start = std::chrono::high_resolution_clock::now(); + ch->client->Insert(buf.event_table_name.c_str(), block); + auto t_insert_end = std::chrono::high_resolution_clock::now(); + + buf.last_column_build_duration_ns = DURATION_NS(t_reconstruct_start, t_reconstruct_end); + buf.last_block_append_duration_ns = DURATION_NS(t_reconstruct_end, t_insert_start); + buf.last_insertion_duration_ns = DURATION_NS(t_insert_start, t_insert_end); + + // Clear all columns and re-reserve (skip buffer-type columns which are rebuilt each time) + for (size_t i = 0; i < buf.columns.size(); i++) { + if (buf.columns[i]) { // Skip nullptr placeholders for buffer-type columns + auto col = std::const_pointer_cast(buf.columns[i]); + col->Clear(); + col->Reserve(BATCH_SIZE); + } + } + + // Reset buffer-type columns back to nullptr + for (auto &dbuf_pair : buf.data_buffers) { + int field_idx = dbuf_pair.first; + int col_idx = field_idx + 1; + buf.columns[col_idx] = nullptr; + } + + // Clear all DataBuffers + for (auto &pair : buf.data_buffers) { + pair.second->clear(); + } + + int rows = buf.row_count; + buf.row_count = 0; + buf.last_insert_time = std::chrono::steady_clock::now(); + + // Update statistics + buf.total_rows += rows; + buf.rows_since_print += rows; + + return rows; + } catch (const std::exception &e) { + loge("Failed to insert buffer for event {}: {}", buf.event_name, e.what()); + return -1; + } +} + +/* Flush all buffers to ClickHouse */ +int insert_all_buffers(clickhouse_config_t *ch) +{ + int errors = 0; + for (auto &pair : g_event_buffers) { + if (insert_buffer(ch, pair.first) <= 0) { + errors++; + } + } + return errors > 0 ? -1 : 0; +} + +/* Check if buffer should be inserted based on size or time */ +uint8_t should_insert(EventBuffer &buf) +{ + if (buf.row_count == 0) { + return 0; + } + + if (buf.row_count >= BATCH_SIZE) { + return 1; + } + + if (static_cast(DURATION_MS(buf.last_insert_time, std::chrono::steady_clock::now())) >= INSERT_INTERVAL_MS) { + return 2; + } + + if (buf.insert_now) { + return 3; + } + + return 0; +} + +int insert_event(clickhouse_config_t *ch, + void *database, + int event_id, + const char *event_data, + int data_length, + std::chrono::high_resolution_clock::time_point t_start) +{ + auto t_fn_start = std::chrono::high_resolution_clock::now(); + + // Get buffer for this event + auto it = g_event_buffers.find(event_id); + if (it == g_event_buffers.end()) { + loge("Buffer not found for event_id {}", event_id); + return -1; + } + + EventBuffer &buf = it->second; + database_event_format format = buf.format; + const char *event_name = buf.event_name.c_str(); + auto t_names_done = std::chrono::high_resolution_clock::now(); + + int16_t frame = -1; + int16_t slot = -1; + + try { + const char *data_ptr = event_data; + int remaining = data_length; + int buf_len = 0; + int i; + + auto t_append_start = std::chrono::high_resolution_clock::now(); + + // Append to TsSwNs column using cached pointer + buf.ts_sw_col->Append(std::chrono::system_clock::now().time_since_epoch().count()); + + // Process data columns + for (i = 0; i < format.count && remaining > 0; i++) { + if (strcmp(format.type[i], "int") == 0) { + int val = 0; + if (remaining >= 4) { + memcpy(&val, data_ptr, 4); + if (strcmp(format.name[i], "frame") == 0) + frame = val; + else if (strcmp(format.name[i], "slot") == 0) + slot = val; + else if (strcmp(format.name[i], "subframe") == 0) + slot = val; + data_ptr += 4; + remaining -= 4; + } + + int typed_col_idx = buf.field_idx_to_typed_col_idx[i]; + buf.int_cols[typed_col_idx]->Append(val); + + } else if (strcmp(format.type[i], "ulong") == 0) { + uint64_t val = 0; + if (remaining >= 8) { + memcpy(&val, data_ptr, 8); + data_ptr += 8; + remaining -= 8; + } + + int typed_col_idx = buf.field_idx_to_typed_col_idx[i]; + buf.ulong_cols[typed_col_idx]->Append(val); + + } else if (strcmp(format.type[i], "buffer") == 0) { + buf_len = 0; + const char *buf_data = nullptr; + + if (remaining >= 4) { + memcpy(&buf_len, data_ptr, 4); + data_ptr += 4; + remaining -= 4; + + if (buf_len > remaining) + buf_len = remaining; + if (buf_len > 0) + buf_data = data_ptr; + + data_ptr += buf_len; + remaining -= buf_len; + } + + auto it_dbuf = buf.data_buffers.find(i); + if (it_dbuf != buf.data_buffers.end()) { + size_t offset = it_dbuf->second->append(buf_data, buf_len); + + buf.insert_now |= it_dbuf->second->insert_now; + + if (offset == (size_t)-1) { + loge("DataBuffer full for field '{}', cannot append {} bytes", format.name[i], buf_len); + // Handle dropping tail for other columns and insert + } + } + } else if (strcmp(format.type[i], "string") == 0) { + std::string str_val; + if (remaining >= 4) { + int str_len; + memcpy(&str_len, data_ptr, 4); + data_ptr += 4; + remaining -= 4; + + if (str_len > remaining) + str_len = remaining; + if (str_len > 0) + str_val = std::string(data_ptr, str_len); + + data_ptr += str_len; + remaining -= str_len; + } + + int typed_col_idx = buf.field_idx_to_typed_col_idx[i]; + buf.string_cols[typed_col_idx]->Append(str_val); + + } else { + // Default: treat as int + int val = 0; + if (remaining >= 4) { + memcpy(&val, data_ptr, 4); + data_ptr += 4; + remaining -= 4; + } + + int typed_col_idx = buf.field_idx_to_typed_col_idx[i]; + buf.int_cols[typed_col_idx]->Append(val); + } + } + auto t_append_data_end = std::chrono::high_resolution_clock::now(); + + // Add TsTxUtcNs column if event has frame/slot + if (buf.has_frame_slot) { + uint64_t timestamp_ns = std::chrono::system_clock::now().time_since_epoch().count(); + uint64_t gps_elapsed_ns; + uint64_t transmit_time_in_utc_ns; + auto t_time_calc_start = std::chrono::high_resolution_clock::now(); + + if (frame == -1 || slot == -1) { // nr_ue_decode_BCCH_DL_SCH sets frame and slot to -1 + transmit_time_in_utc_ns = timestamp_ns; + } else { + gps_elapsed_ns = calculate_sfn_slot_gps_time(frame, slot, 1, timestamp_ns); + transmit_time_in_utc_ns = gps_to_utc_ns(gps_elapsed_ns); + + if (0) { + int check_frame, check_slot; + calculate_sfn_slot_from_unix(transmit_time_in_utc_ns, 1, &check_frame, &check_slot); + if (check_frame != frame || check_slot != slot) { + loge("ERROR1: sfn/slot check failed: {} {} {} {}", event_name, frame, slot, check_frame, check_slot); + } + } + + auto t_time_calc_end = std::chrono::high_resolution_clock::now(); + + int64_t ref_to_t0_offset_ns = (int64_t)timestamp_ns - (int64_t)transmit_time_in_utc_ns; + // Handle sign separately to properly display negative fractional seconds + const char *sign = (ref_to_t0_offset_ns < 0) ? "-" : " "; + int64_t abs_offset = (ref_to_t0_offset_ns < 0) ? -ref_to_t0_offset_ns : ref_to_t0_offset_ns; + int64_t offset_sec = abs_offset / NS_PER_SEC; + int64_t offset_ns = abs_offset % NS_PER_SEC; + + if (abs_offset > 50'000'000) { // 50ms + logi("{:<31} {:4d}.{:2d} TsSwNs={}.{:09} TsTxUtcNs={}.{:09} delta={}{}.{:09d}, {}", + event_name, + frame, + slot, + timestamp_ns / NS_PER_SEC, + timestamp_ns % NS_PER_SEC, + transmit_time_in_utc_ns / NS_PER_SEC, + transmit_time_in_utc_ns % NS_PER_SEC, + sign, + offset_sec, + offset_ns, + DURATION_NS(t_time_calc_start, t_time_calc_end)); + } + } + + // Append to TsTxUtcNs column using cached pointer + buf.ts_tx_col->Append(transmit_time_in_utc_ns); + } + auto t_append_ts_end = std::chrono::high_resolution_clock::now(); + + // Increment row count + buf.row_count++; + + // Check if we should insert this buffer + int rows = 0; + auto t_insert_start = std::chrono::high_resolution_clock::now(); + uint8_t insert = should_insert(buf); + auto t_insert_should_insert_end = std::chrono::high_resolution_clock::now(); + if (insert) { + rows = insert_buffer(ch, event_id); + } + auto t_insert_end = std::chrono::high_resolution_clock::now(); + + if (insert) { + if (DURATION_MS(t_insert_start, t_insert_end) > 5) { + logi("Slow Insert: {:<31} {:4d}.{:2d}: {:3d} {:3d} {:5d} {:4d} {:5d} {:4d} {:8d} (ns) {:3d} (ms) rows:{:3d} reason: {}", + event_name, + frame, + slot, + DURATION_NS(t_fn_start, t_names_done), + DURATION_NS(t_names_done, t_append_start), + DURATION_NS(t_append_start, t_append_data_end), + DURATION_NS(t_append_data_end, t_append_ts_end), + buf.last_column_build_duration_ns, + buf.last_block_append_duration_ns, + buf.last_insertion_duration_ns, + DURATION_MS(t_insert_start, t_insert_end), + rows, + insert); + } + } else if (DURATION_US(t_fn_start, t_insert_end) > 50) { + logd("Slow saving data: {:<31} {:4d}.{:2d}: {:3d} {:3d} {:5d} {:4d} {:5d} {:4d} {:8d} (ns) buf_len:{:3d} rows:{:3d} ---", + event_name, + frame, + slot, + DURATION_NS(t_fn_start, t_names_done), + DURATION_NS(t_names_done, t_append_start), + DURATION_NS(t_append_start, t_append_data_end), + DURATION_NS(t_append_data_end, t_append_ts_end), + DURATION_NS(t_append_ts_end, t_insert_start), + DURATION_NS(t_insert_start, t_insert_should_insert_end), + DURATION_NS(t_insert_should_insert_end, t_insert_end), + buf_len, + buf.row_count); + } + + return 0; + } catch (const std::exception &e) { + loge("Failed to insert event {}: {}", event_name, e.what()); + return -1; + } +} + +int main(int n, char **v) +{ + const char *default_database_filename = "T_messages.txt"; + char *database_filename = NULL; + void *database; + const char *ip = DEFAULT_REMOTE_IP; + int port = DEFAULT_REMOTE_PORT; + char **on_off_name; + int *on_off_action; + int on_off_n = 0; + int *is_on; + int number_of_events; + int i; + char mt; + int debug_mode = 0; + + clickhouse_config_t ch_config; + ch_config.drop_tables = 0; + ch_config.host = DEFAULT_CLICKHOUSE_HOST; + ch_config.port = DEFAULT_CLICKHOUSE_PORT; + ch_config.database = DEFAULT_CLICKHOUSE_DB; + + /* write on a socket fails if the other end is closed and we get SIGPIPE */ + if (signal(SIGPIPE, SIG_IGN) == SIG_ERR) + abort(); + + on_off_name = (char **)malloc(n * sizeof(char *)); + if (on_off_name == NULL) + abort(); + on_off_action = (int *)malloc(n * sizeof(int)); + if (on_off_action == NULL) + abort(); + + for (i = 1; i < n; i++) { + if (!strcmp(v[i], "-h") || !strcmp(v[i], "--help")) + usage(); + if (!strcmp(v[i], "-d")) { + if (i > n - 2) + usage(); + database_filename = v[++i]; + continue; + } + if (!strcmp(v[i], "-ip")) { + if (i > n - 2) + usage(); + ip = v[++i]; + continue; + } + if (!strcmp(v[i], "-p")) { + if (i > n - 2) + usage(); + port = atoi(v[++i]); + continue; + } + if (!strcmp(v[i], "-ch-host")) { + if (i > n - 2) + usage(); + ch_config.host = v[++i]; + continue; + } + if (!strcmp(v[i], "-ch-port")) { + if (i > n - 2) + usage(); + ch_config.port = atoi(v[++i]); + continue; + } + if (!strcmp(v[i], "-ch-db")) { + if (i > n - 2) + usage(); + ch_config.database = v[++i]; + continue; + } + if (!strcmp(v[i], "-ch-user")) { + if (i > n - 2) + usage(); + ch_config.user = v[++i]; + continue; + } + if (!strcmp(v[i], "-ch-pass")) { + if (i > n - 2) + usage(); + ch_config.password = v[++i]; + continue; + } + if (!strcmp(v[i], "-ch-droptables")) { + ch_config.drop_tables = 1; + continue; + } + if (!strcmp(v[i], "-debug")) { + debug_mode = 1; + continue; + } + if (!strcmp(v[i], "-on")) { + if (i > n - 2) + usage(); + on_off_name[on_off_n] = v[++i]; + on_off_action[on_off_n++] = 1; + logi("on: item: {}, on_off_name: {}, on_off_action: {}", v[i], on_off_name[on_off_n - 1], on_off_action[on_off_n - 1]); + continue; + } + if (!strcmp(v[i], "-off")) { + if (i > n - 2) + usage(); + on_off_name[on_off_n] = v[++i]; + on_off_action[on_off_n++] = 0; + continue; + } + if (!strcmp(v[i], "-ON")) { + on_off_name[on_off_n] = NULL; + on_off_action[on_off_n++] = 1; + continue; + } + if (!strcmp(v[i], "-OFF")) { + on_off_name[on_off_n] = NULL; + on_off_action[on_off_n++] = 0; + continue; + } + usage(); + } + + if (database_filename == NULL) { + logi("No database file provided, using default: {}", default_database_filename); + database_filename = strdup(default_database_filename); + } + + database = parse_database(database_filename); + + load_config_file(database_filename); + + number_of_events = number_of_ids(database); + logi("Number of events: {}", number_of_events); + is_on = (int *)calloc(number_of_events, sizeof(int)); + if (is_on == NULL) { + loge("aborting"); + abort(); + } + + for (i = 0; i < on_off_n; i++) { + on_off(database, on_off_name[i], is_on, on_off_action[i]); + } + + /* Initialize fmtlog for benchmarking */ + fmtlog::setLogLevel(debug_mode ? fmtlog::DBG : fmtlog::INF); + fmtlog::setThreadName("main"); + + /* Initialize ClickHouse */ + if (clickhouse_init(&ch_config) != 0) { + loge("Failed to initialize ClickHouse connection"); + exit(1); + } + + /* Create tables for enabled events */ + int longest_table_name = create_tables(&ch_config, database, is_on, number_of_events); + if (longest_table_name < 0) { + loge("Failed to create tables"); + exit(1); + } + + socket_fd = connect_to(const_cast(ip), port); + + /* activate selected traces */ + mt = 1; + if (socket_send(socket_fd, &mt, 1) == -1 || socket_send(socket_fd, &number_of_events, sizeof(int)) == -1 + || socket_send(socket_fd, is_on, number_of_events * sizeof(int)) == -1) + abort(); + + /* exit on ctrl+c and ctrl+z */ + if (signal(SIGQUIT, force_stop) == SIG_ERR) + abort(); + if (signal(SIGINT, force_stop) == SIG_ERR) + abort(); + if (signal(SIGTSTP, force_stop) == SIG_ERR) + abort(); + + OBUF ebuf = {.osize = 0, .omaxsize = 0, .obuf = NULL}; + + /* read messages */ + logi("Tables created, waiting for messages..."); + int poll_count = 0; + auto last_periodic_insert = std::chrono::steady_clock::now(); + auto last_stats_print = std::chrono::steady_clock::now(); + const uint64_t STATS_PRINT_INTERVAL_MS = 5000; // Print stats every 5 seconds + + while (run) { + int type; + int32_t length; + char *v; + int vpos = 0; + + // Poll fmtlog periodically to insert buffered logs + if (++poll_count % 10 == 0) { + fmtlog::poll(); + } + + // Periodic insert check (every 10 messages) + if (poll_count % 10 == 0) { + auto now = std::chrono::steady_clock::now(); + auto elapsed_ms = + static_cast(std::chrono::duration_cast(now - last_periodic_insert).count()); + + if (elapsed_ms >= INSERT_INTERVAL_MS) { + for (auto &pair : g_event_buffers) { + if (should_insert(pair.second)) { + insert_buffer(&ch_config, pair.first); + } + } + last_periodic_insert = now; + } + if (static_cast(DURATION_MS(last_stats_print, now)) >= STATS_PRINT_INTERVAL_MS) { + for (auto &pair : g_event_buffers) { + EventBuffer &buf = pair.second; + if (buf.rows_since_print > 0) + logi(" {:<31} rows: {:8d} total: {:10d}", buf.event_name, buf.rows_since_print, buf.total_rows); + buf.rows_since_print = 0; + } + last_stats_print = now; + logi(""); + } + } + + if (fullread(socket_fd, &length, 4) == -1) + goto read_error; + if (ebuf.omaxsize < length + 4) { + ebuf.omaxsize = (length + 4 + 65535) & ~65535; + ebuf.obuf = (char *)realloc(ebuf.obuf, ebuf.omaxsize); + if (ebuf.obuf == NULL) { + loge("out of memory"); + exit(1); + } + } + v = ebuf.obuf; + memcpy(v + vpos, &length, 4); + vpos += 4; +#ifdef T_SEND_TIME + if (length < (int32_t)sizeof(struct timespec)) + goto read_error; + if (fullread(socket_fd, v + vpos, sizeof(struct timespec)) == -1) + goto read_error; + // memcpy(v+vpos, &ts, sizeof(struct timespec)); + vpos += sizeof(struct timespec); + length -= sizeof(struct timespec); +#endif + if (length < (int32_t)sizeof(int)) + goto read_error; + if (fullread(socket_fd, &type, sizeof(int)) == -1) + goto read_error; + memcpy(v + vpos, &type, sizeof(int)); + vpos += sizeof(int); + length -= sizeof(int); + if (fullread(socket_fd, v + vpos, length) == -1) + goto read_error; + + auto t_start = std::chrono::high_resolution_clock::now(); + + if (type == -1) { + append_received_config_chunk(v + vpos, length); + } else if (type == -2) { + verify_config(); + } else if (type >= 0 && type < number_of_events && is_on[type]) { + if (insert_event(&ch_config, database, type, v + vpos, length, t_start) != 0) { + loge("Failed to insert event type {}", type); + } + } + } + +read_error: + // Flush all remaining buffers before exit + logi("Inserting all buffers before exit..."); + insert_all_buffers(&ch_config); + + // Print final statistics + size_t total_rows = 0; + for (const auto& pair : g_event_buffers) { + total_rows += pair.second.row_count; + } + logi("Final buffer state: {} events with {} uninserted rows", + g_event_buffers.size(), total_rows); + + // Client cleanup is automatic via std::unique_ptr + logi("Exiting..."); + + // Flush and close fmtlog + fmtlog::poll(); + fmtlog::closeLogFile(); + + return 0; +} diff --git a/docker/Dockerfile.base.ubuntu b/docker/Dockerfile.base.ubuntu index b0eb5c4d32..f13aa1f917 100644 --- a/docker/Dockerfile.base.ubuntu +++ b/docker/Dockerfile.base.ubuntu @@ -49,6 +49,8 @@ RUN apt-get update && \ bison \ flex \ m4 \ + # libzstd-dev for ClickHouse C++ library + libzstd-dev \ # python3-pip for conf template generation python3-pip \ wget \ diff --git a/docker/Dockerfile.build.fhi72.native_arm.ubuntu b/docker/Dockerfile.build.fhi72.native_arm.ubuntu index 96f50fa485..30c1df5962 100644 --- a/docker/Dockerfile.build.fhi72.native_arm.ubuntu +++ b/docker/Dockerfile.build.fhi72.native_arm.ubuntu @@ -81,8 +81,7 @@ RUN /bin/sh oaienv && \ --ninja --gNB \ --build-lib "telnetsrv enbscope uescope nrscope" \ -t oran_fhlib_5g --cmake-opt -Dxran_LOCATION=/opt/phy/fhi_lib/lib \ - --build-e2 --cmake-opt -DXAPP_MULTILANGUAGE=OFF --cmake-opt -DKPM_VERSION=$KPM_VERSION --cmake-opt -DE2AP_VERSION=$E2AP_VERSION \ - $BUILD_OPTION && \ + --build-e2 --cmake-opt -DXAPP_MULTILANGUAGE=OFF --cmake-opt -DKPM_VERSION=$KPM_VERSION --cmake-opt -DE2AP_VERSION=$E2AP_VERSION && \ # Mainly to see if the sanitize option was perfectly executed ldd ran_build/build/nr-softmodem && \ ldd ran_build/build/liboran_fhlib_5g.so && \ diff --git a/docker/Dockerfile.build.fhi72.ubuntu b/docker/Dockerfile.build.fhi72.ubuntu index 3d483618cd..63ec8a440e 100644 --- a/docker/Dockerfile.build.fhi72.ubuntu +++ b/docker/Dockerfile.build.fhi72.ubuntu @@ -71,8 +71,7 @@ RUN /bin/sh oaienv && \ --ninja --gNB --nrRU \ --build-lib "telnetsrv enbscope uescope nrscope" \ -t oran_fhlib_5g --cmake-opt -Dxran_LOCATION=/opt/phy/fhi_lib/lib \ - --build-e2 --cmake-opt -DKPM_VERSION=$KPM_VERSION --cmake-opt -DE2AP_VERSION=$E2AP_VERSION \ - $BUILD_OPTION && \ + --build-e2 --cmake-opt -DKPM_VERSION=$KPM_VERSION --cmake-opt -DE2AP_VERSION=$E2AP_VERSION && \ # Mainly to see if the sanitize option was perfectly executed ldd ran_build/build/nr-softmodem && \ ldd ran_build/build/liboran_fhlib_5g.so && \ diff --git a/docker/Dockerfile.build.ubuntu b/docker/Dockerfile.build.ubuntu index bc2ed577a6..b919a1aefc 100644 --- a/docker/Dockerfile.build.ubuntu +++ b/docker/Dockerfile.build.ubuntu @@ -42,15 +42,23 @@ RUN \ # Mount CPM package cache --mount=type=cache,target=/root/.cache/cpm/ \ /bin/sh oaienv && \ - mkdir -p cmake_targets/ran_build/build && \ - cd cmake_targets/ran_build/build && \ - cmake ../../../ -GNinja \ - -DENABLE_TELNETSRV=ON -DENABLE_ENBSCOPE=ON -DENABLE_UESCOPE=ON -DENABLE_NRSCOPE=ON \ - -DOAI_USRP=ON -DOAI_BLADERF=ON -DOAI_ETHERNET=ON -DOAI_VRTSIM_TAPS_CLIENT=ON \ - -DE2_AGENT=ON -DKPM_VERSION=KPM_V3_00 -DE2AP_VERSION=E2AP_V3 \ - -DAVX512=OFF && \ - # -DCMAKE_C_FLAGS=-Werror -DCMAKE_CXX_FLAGS=-Werror && \ - ninja + cd cmake_targets && \ + mkdir -p log && \ + ./build_oai -c --ninja \ + --eNB --gNB --RU --UE --nrUE \ + --build-lib "telnetsrv enbscope uescope nrscope" \ + -w USRP -t Ethernet -w BLADERF \ + --build-e2 --cmake-opt -DKPM_VERSION=$KPM_VERSION --cmake-opt -DE2AP_VERSION=$E2AP_VERSION \ + --cmake-opt -DOAI_VRTSIM_TAPS_CLIENT=ON \ + --noavx512 \ + --build-tool-opt -k10 \ + --cmake-opt -DT_RECORD_DB=ON \ + --cmake-opt -DCMAKE_C_FLAGS="-Werror" --cmake-opt -DCMAKE_CXX_FLAGS="-Werror" $BUILD_OPTION && \ + # Mainly to see if the sanitize option was perfectly executed + echo "---- ldd on executables ----" && \ + ldd ran_build/build/*softmodem* ran_build/build/nr-cuup ran_build/build/oairu && \ + echo "---- ldd on shared libraries ----" && \ + ldd ran_build/build/*.so ## Build FlexRIC for SM Models RUN \ diff --git a/docker/Dockerfile.gNB.aerial.ubuntu b/docker/Dockerfile.gNB.aerial.ubuntu index b79ab78fa8..20a453f652 100644 --- a/docker/Dockerfile.gNB.aerial.ubuntu +++ b/docker/Dockerfile.gNB.aerial.ubuntu @@ -55,13 +55,15 @@ RUN /bin/sh oaienv && \ cd cmake_targets && \ mkdir -p log && \ ./build_oai -c -w AERIAL --gNB --ninja --build-tool-opt -k10 \ - --cmake-opt -DCMAKE_C_FLAGS="-Werror" --cmake-opt -DCMAKE_CXX_FLAGS="-Werror" + --cmake-opt -DCMAKE_C_FLAGS="-Werror" --cmake-opt -DCMAKE_CXX_FLAGS="-Werror" \ + --cmake-opt -DT_RECORD_DB=ON #start from scratch for target executable FROM ubuntu:noble AS oai-gnb-aerial ENV DEBIAN_FRONTEND=noninteractive ENV TZ=Europe +ENV PATH="/opt/oai-gnb/bin:$PATH" RUN apt-get update && \ apt-get upgrade --yes && \ @@ -85,17 +87,20 @@ RUN apt-get update && \ WORKDIR /opt/oai-gnb/bin COPY --from=ran-build \ - /oai-ran/cmake_targets/ran_build/build/nr-softmodem ./ + /oai-ran/cmake_targets/ran_build/build/nr-softmodem \ + /oai-ran/cmake_targets/ran_build/build/common/utils/T/tracer/record* \ + ./ + COPY ./docker/scripts/gnb_entrypoint.sh ./entrypoint.sh COPY --from=ran-build \ /oai-ran/cmake_targets/ran_build/build/libparams_libconfig.so \ /oai-ran/cmake_targets/ran_build/build/libparams_yaml.so \ + /oai-ran/cmake_targets/ran_build/build/_deps*/fmtlog-build*/libfmtlog-shared*.so \ + /oai-ran/cmake_targets/ran_build/build/_deps*/clickhouse-cpp-build*/clickhouse/libclickhouse*.so \ /usr/local/lib/ -#copy files from nvIPC COPY --from=ran-build \ - /usr/local/lib/libfmtlog-shared.so \ /usr/local/lib/libnvlog.so \ /usr/local/lib/libnvipc.so \ /usr/local/lib/ @@ -113,5 +118,6 @@ WORKDIR /opt/oai-gnb COPY --from=ran-build /usr/local/bin/yq /usr/local/bin/yq COPY --from=ran-build /tini /tini +COPY --from=ran-build /oai-ran/common/utils/T/T_messages.txt ./ ENTRYPOINT ["/tini", "-v", "--", "/opt/oai-gnb/bin/entrypoint.sh"] CMD ["/opt/oai-gnb/bin/nr-softmodem"] diff --git a/docker/Dockerfile.nrORU.fhi72.ubuntu b/docker/Dockerfile.nrORU.fhi72.ubuntu index 0db881c734..9c4e1b3971 100644 --- a/docker/Dockerfile.nrORU.fhi72.ubuntu +++ b/docker/Dockerfile.nrORU.fhi72.ubuntu @@ -25,7 +25,6 @@ FROM ran-build-fhi72:latest AS ran-build #start from scratch for target executable FROM ubuntu:noble AS oai-nr-oru -ARG BUILD_OPTION ENV DEBIAN_FRONTEND=noninteractive ENV TZ=Europe @@ -50,11 +49,6 @@ RUN apt-get update && \ xz-utils \ libnuma-dev \ libyaml-cpp-dev && \ -# if the --sanitize option was used to build, additional packages are required - /bin/bash -c 'if [[ "$BUILD_OPTION" = "--sanitize" ]]; then DEBIAN_FRONTEND=noninteractive apt-get install --yes \ - libasan8 \ - libubsan1 \ - liblapacke; fi' && \ rm -rf /var/lib/apt/lists/* WORKDIR /opt/nr-oru/bin diff --git a/docker/Dockerfile.nrUE.ubuntu b/docker/Dockerfile.nrUE.ubuntu index 7c8b15d013..1cd151db53 100644 --- a/docker/Dockerfile.nrUE.ubuntu +++ b/docker/Dockerfile.nrUE.ubuntu @@ -35,6 +35,7 @@ FROM ubuntu:noble AS oai-nr-ue ARG BUILD_OPTION ENV DEBIAN_FRONTEND=noninteractive ENV TZ=Europe/Paris +ENV PATH="/opt/oai-nr-ue/bin:$PATH" RUN apt-get update && \ apt-get upgrade --yes && \ @@ -67,6 +68,7 @@ RUN apt-get update && \ iperf3 \ iperf \ libyaml-cpp-dev \ + libzstd1 \ libnanomsg5 && \ # if the --sanitize option was used to build, additional packages are required /bin/bash -c 'if [[ "$BUILD_OPTION" = "--sanitize" ]]; then DEBIAN_FRONTEND=noninteractive apt-get install --yes \ @@ -78,6 +80,7 @@ RUN apt-get update && \ WORKDIR /opt/oai-nr-ue/bin COPY --from=nr-ue-build \ /oai-ran/cmake_targets/ran_build/build/nr-uesoftmodem \ + /oai-ran/cmake_targets/ran_build/build/common/utils/T/tracer/record* \ ./ COPY ./docker/scripts/nr_ue_entrypoint.sh ./entrypoint.sh @@ -94,10 +97,17 @@ COPY --from=nr-ue-build \ /oai-ran/cmake_targets/ran_build/build/libtelnetsrv.so \ /oai-ran/cmake_targets/ran_build/build/libtelnetsrv_ciUE.so \ /oai-ran/cmake_targets/ran_build/build/libtelnetsrv_5Gue.so \ + /oai-ran/cmake_targets/ran_build/build/libnrscope.so \ + /oai-ran/cmake_targets/ran_build/build/libtelnetsrv.so \ /oai-ran/cmake_targets/ran_build/build/libparams_yaml.so \ /oai-ran/cmake_targets/ran_build/build/libvrtsim.so \ + # Wildcards so it doesn't fail if not present + /oai-ran/cmake_targets/ran_build/build/_deps*/fmtlog-build*/libfmtlog-shared*.so \ + /oai-ran/cmake_targets/ran_build/build/_deps*/clickhouse-cpp-build*/clickhouse/libclickhouse*.so \ /usr/local/lib/ +# /oai-ran/cmake_targets/ran_build/build/libimscope.so \ + # Now we are copying from builder-image the UHD files. COPY --from=nr-ue-base /usr/local/bin/uhd_find_devices /usr/local/bin COPY --from=nr-ue-base /usr/local/lib/libuhd.so.4.8.0 /usr/local/lib @@ -124,5 +134,6 @@ WORKDIR /opt/oai-nr-ue COPY --from=nr-ue-base /usr/local/bin/yq /usr/local/bin/yq COPY --from=nr-ue-base /tini /tini +COPY --from=nr-ue-build /oai-ran/common/utils/T/T_messages.txt ./ CMD ["/opt/oai-nr-ue/bin/nr-uesoftmodem"] ENTRYPOINT ["/tini", "-v", "--", "/opt/oai-nr-ue/bin/entrypoint.sh"] From 7d058eb0d08f6d102f53a3afacd260d8b0106e5b Mon Sep 17 00:00:00 2001 From: Bartosz Podrygajlo Date: Thu, 5 Mar 2026 16:08:15 +0100 Subject: [PATCH 44/44] Run nrue_ru_start in a high priority thread Launch a temporary high-priority thread to start the UE RU, ensuring radio library threads inherit this priority --- executables/nr-uesoftmodem.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/executables/nr-uesoftmodem.c b/executables/nr-uesoftmodem.c index 1631332e5e..df4088a87d 100644 --- a/executables/nr-uesoftmodem.c +++ b/executables/nr-uesoftmodem.c @@ -240,6 +240,13 @@ static void trigger_deregistration(int sig) } } +void *nrue_ru_start_thread(void *arg) +{ + (void)arg; + nrue_ru_start(); + return NULL; +} + int NB_UE_INST = 1; configmodule_interface_t *uniqCfg = NULL; nrLDPC_coding_interface_t nrLDPC_coding_interface = {0}; @@ -450,7 +457,11 @@ int main(int argc, char **argv) load_module_shlib("imscope_record", NULL, 0, PHY_vars_UE_g[0][0]); } - nrue_ru_start(); + // Launch a temporary high-priority thread to start the UE RU, ensuring radio library threads inherit this priority + pthread_t ru_start_thread; + threadCreate(&ru_start_thread, nrue_ru_start_thread, NULL, "ru_start_thread", -1, OAI_PRIORITY_RT_MAX); + int ret = pthread_join(ru_start_thread, NULL); + AssertFatal(ret == 0, "pthread_join error %d, errno %d (%s)\n", ret, errno, strerror(errno)); for (int inst = 0; inst < NB_UE_INST; inst++) { LOG_I(PHY,"Intializing UE Threads for instance %d ...\n", inst);