From 5690aa0fe3700f5ca1e0a0dae14ccfbb51799da9 Mon Sep 17 00:00:00 2001 From: rakesh mundlamuri Date: Fri, 22 Aug 2025 15:46:42 +0530 Subject: [PATCH 01/10] first_half index correction in PRS channel estimation while copying memory Previously, we were using int16_t for the variable ch_tmp which was later harmonized to use c16_t while leaving <<1. This introduced the bug while accessing the address of the element at first_half of the ch_tmp variable. --- .../nr_dl_channel_estimation.c | 27 +++++-------------- 1 file changed, 6 insertions(+), 21 deletions(-) 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 6a49a17608..0d9399ce27 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c +++ b/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c @@ -315,10 +315,7 @@ int nr_prs_channel_estimation(uint8_t gNB_id, //Start pilot c16_t ch = c16MulConjShift(*pil, *rxF, 15); - multadd_real_vector_complex_scalar(fl, - ch, - ch_tmp, - 16); + multadd_real_vector_complex_scalar(fl, ch, ch_tmp, 16); // SNR & RSRP estimation rsrp += squaredMod(*rxF); @@ -331,10 +328,7 @@ int nr_prs_channel_estimation(uint8_t gNB_id, k = (k+prs_cfg->CombSize) % frame_params->ofdm_symbol_size; rxF = &rxdataF[rxAnt][l * frame_params->ofdm_symbol_size + k]; ch = c16MulConjShift(*pil, *rxF, 15); - multadd_real_vector_complex_scalar(fml, - ch, - ch_tmp, - 16); + multadd_real_vector_complex_scalar(fml, ch, ch_tmp, 16); // SNR & RSRP estimation rsrp += squaredMod(*rxF); @@ -352,10 +346,7 @@ int nr_prs_channel_estimation(uint8_t gNB_id, for(int pIdx = 2; pIdx < num_pilots-2; pIdx++) { c16_t ch = c16MulConjShift(*pil, *rxF, 15); - multadd_real_vector_complex_scalar(fmm, - ch, - ch_tmp, - 16); + multadd_real_vector_complex_scalar(fmm, ch, ch_tmp, 16); // SNR & RSRP estimation rsrp += squaredMod(*rxF); @@ -372,10 +363,7 @@ int nr_prs_channel_estimation(uint8_t gNB_id, //End pilot ch = c16MulConjShift(*pil, *rxF, 15); - multadd_real_vector_complex_scalar(fmr, - ch, - ch_tmp, - 16); + multadd_real_vector_complex_scalar(fmr, ch, ch_tmp, 16); // SNR & RSRP estimation rsrp += squaredMod(*rxF); @@ -388,10 +376,7 @@ int nr_prs_channel_estimation(uint8_t gNB_id, k = (k+prs_cfg->CombSize) % frame_params->ofdm_symbol_size; rxF = &rxdataF[rxAnt][l * frame_params->ofdm_symbol_size + k]; ch = c16MulConjShift(*pil, *rxF, 15); - multadd_real_vector_complex_scalar(fr, - ch, - ch_tmp, - 16); + multadd_real_vector_complex_scalar(fr, ch, ch_tmp, 16); // SNR & RSRP estimation rsrp += squaredMod(*rxF); @@ -437,7 +422,7 @@ int nr_prs_channel_estimation(uint8_t gNB_id, if(first_half > 0) memcpy((int16_t *)&chF_interpol[rxAnt][start_offset], &ch_tmp[0], first_half * sizeof(int32_t)); if(second_half > 0) - memcpy((int16_t *)&chF_interpol[rxAnt][0], &ch_tmp[first_half << 1], second_half * sizeof(int32_t)); + memcpy((int16_t *)&chF_interpol[rxAnt][0], &ch_tmp[first_half], second_half * sizeof(int32_t)); // Convert to time domain freq2time(NR_PRS_IDFT_OVERSAMP_FACTOR * frame_params->ofdm_symbol_size, From 825c6803adac44a3e4d3315f6b90a2df052e5f26 Mon Sep 17 00:00:00 2001 From: rakesh mundlamuri Date: Tue, 26 Aug 2025 12:59:50 +0530 Subject: [PATCH 02/10] harmonize IQ samples in prs channel estimation to use c16_t --- .../nr_dl_channel_estimation.c | 18 +++++++++--------- openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h | 2 +- 2 files changed, 10 insertions(+), 10 deletions(-) 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 0d9399ce27..45060eaacd 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c +++ b/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c @@ -47,12 +47,12 @@ #define NO_INTERP 1 /* Generic function to find the peak of channel estimation buffer */ -void peak_estimator(int32_t *buffer, int32_t buf_len, int32_t *peak_idx, int32_t *peak_val, int32_t mean_val) +void peak_estimator(c16_t *buffer, int32_t buf_len, int32_t *peak_idx, int32_t *peak_val, int32_t mean_val) { int32_t max_val = 0, max_idx = 0, abs_val = 0; for(int k = 0; k < buf_len; k++) { - abs_val = squaredMod(((c16_t*)buffer)[k]); + abs_val = squaredMod(buffer[k]); if(abs_val > max_val) { max_val = abs_val; @@ -83,8 +83,8 @@ int nr_prs_channel_estimation(uint8_t gNB_id, prs_config_t *prs_cfg = &ue->prs_vars[gNB_id]->prs_resource[rsc_id].prs_cfg; prs_meas_t **prs_meas = ue->prs_vars[gNB_id]->prs_resource[rsc_id].prs_meas; c16_t ch_tmp_buf[ ue->frame_parms.ofdm_symbol_size] __attribute__((aligned(32))); - int32_t chF_interpol[frame_params->nb_antennas_rx][NR_PRS_IDFT_OVERSAMP_FACTOR*ue->frame_parms.ofdm_symbol_size] __attribute__((aligned(32))); - int32_t chT_interpol[frame_params->nb_antennas_rx][NR_PRS_IDFT_OVERSAMP_FACTOR*ue->frame_parms.ofdm_symbol_size] __attribute__((aligned(32))); + c16_t chF_interpol[frame_params->nb_antennas_rx][NR_PRS_IDFT_OVERSAMP_FACTOR*ue->frame_parms.ofdm_symbol_size] __attribute__((aligned(32))); + c16_t chT_interpol[frame_params->nb_antennas_rx][NR_PRS_IDFT_OVERSAMP_FACTOR*ue->frame_parms.ofdm_symbol_size] __attribute__((aligned(32))); memset(ch_tmp_buf,0,sizeof(ch_tmp_buf)); memset(chF_interpol,0,sizeof(chF_interpol)); memset(chT_interpol,0,sizeof(chF_interpol)); @@ -420,9 +420,9 @@ int nr_prs_channel_estimation(uint8_t gNB_id, // Place PRS channel estimates in FFT shifted format if(first_half > 0) - memcpy((int16_t *)&chF_interpol[rxAnt][start_offset], &ch_tmp[0], first_half * sizeof(int32_t)); + memcpy(&chF_interpol[rxAnt][start_offset], &ch_tmp[0], first_half * sizeof(c16_t)); if(second_half > 0) - memcpy((int16_t *)&chF_interpol[rxAnt][0], &ch_tmp[first_half], second_half * sizeof(int32_t)); + memcpy(&chF_interpol[rxAnt][0], &ch_tmp[first_half], second_half * sizeof(c16_t)); // Convert to time domain freq2time(NR_PRS_IDFT_OVERSAMP_FACTOR * frame_params->ofdm_symbol_size, @@ -481,7 +481,7 @@ int nr_prs_channel_estimation(uint8_t gNB_id, // T tracer dump T(T_UE_PHY_INPUT_SIGNAL, T_INT(gNB_id), T_INT(proc->frame_rx), T_INT(proc->nr_slot_rx), - T_INT(rxAnt), T_BUFFER(&rxdataF[rxAnt][0], frame_params->samples_per_slot_wCP*sizeof(int32_t))); + T_INT(rxAnt), T_BUFFER(&rxdataF[rxAnt][0], frame_params->samples_per_slot_wCP*sizeof(c16_t))); T(T_UE_PHY_DL_CHANNEL_ESTIMATE_FREQ, T_INT(gNB_id), @@ -489,7 +489,7 @@ int nr_prs_channel_estimation(uint8_t gNB_id, T_INT(proc->frame_rx), T_INT(proc->nr_slot_rx), T_INT(rxAnt), - T_BUFFER(&chF_interpol[rxAnt][0], NR_PRS_IDFT_OVERSAMP_FACTOR * frame_params->ofdm_symbol_size * sizeof(int32_t))); + T_BUFFER(&chF_interpol[rxAnt][0], NR_PRS_IDFT_OVERSAMP_FACTOR * frame_params->ofdm_symbol_size * sizeof(c16_t))); T(T_UE_PHY_DL_CHANNEL_ESTIMATE, T_INT(gNB_id), @@ -497,7 +497,7 @@ int nr_prs_channel_estimation(uint8_t gNB_id, T_INT(proc->frame_rx), T_INT(proc->nr_slot_rx), T_INT(rxAnt), - T_BUFFER(&chT_interpol[rxAnt][0], NR_PRS_IDFT_OVERSAMP_FACTOR * frame_params->ofdm_symbol_size * sizeof(int32_t))); + T_BUFFER(&chT_interpol[rxAnt][0], NR_PRS_IDFT_OVERSAMP_FACTOR * frame_params->ofdm_symbol_size * sizeof(c16_t))); } return(0); diff --git a/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h b/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h index 85b8999118..d0d868197c 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h +++ b/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h @@ -39,7 +39,7 @@ int nr_prs_channel_estimation(uint8_t gNB_id, c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]); /* Generic function to find the peak of channel estimation buffer */ -void peak_estimator(int32_t *buffer, int32_t buf_len, int32_t *peak_idx, int32_t *peak_val, int32_t mean_val); +void peak_estimator(c16_t *buffer, int32_t buf_len, int32_t *peak_idx, int32_t *peak_val, int32_t mean_val); /*! \brief This function performs channel estimation including frequency and temporal interpolation From a72abe3cc8c25763859f28700fa523d0de41f429 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Fri, 19 Sep 2025 12:31:59 +0200 Subject: [PATCH 03/10] Refactor dl_toa setting to separate function --- .../NR_UE_ESTIMATION/nr_dl_channel_estimation.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) 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 45060eaacd..4151752f11 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c +++ b/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c @@ -71,6 +71,11 @@ void peak_estimator(c16_t *buffer, int32_t buf_len, int32_t *peak_idx, int32_t * } } +void set_prs_dl_toa(prs_meas_t *prs_meas, float dl_toa) +{ + prs_meas->dl_toa = dl_toa; +} + int nr_prs_channel_estimation(uint8_t gNB_id, uint8_t rsc_id, uint8_t rep_num, @@ -448,9 +453,9 @@ int nr_prs_channel_estimation(uint8_t gNB_id, prs_meas[rxAnt]->slot = proc->nr_slot_rx; prs_meas[rxAnt]->rxAnt_idx = rxAnt; prs_meas[rxAnt]->dl_aoa = rsc_id; - prs_meas[rxAnt]->dl_toa = prs_toa / (float)NR_PRS_IDFT_OVERSAMP_FACTOR; - if ((frame_params->ofdm_symbol_size - prs_meas[rxAnt]->dl_toa) < frame_params->ofdm_symbol_size / 2) - prs_meas[rxAnt]->dl_toa -= (frame_params->ofdm_symbol_size); + float dl_toa = prs_toa / (float)NR_PRS_IDFT_OVERSAMP_FACTOR; + if ((frame_params->ofdm_symbol_size - dl_toa) < frame_params->ofdm_symbol_size / 2) + dl_toa -= (frame_params->ofdm_symbol_size); LOG_I(PHY, "[gNB %d][rsc %d][Rx %d][sfn %d][slot %d] DL PRS ToA ==> %.1f / %d samples, peak channel power %.1f dBm, SNR %+.1f dB, rsrp %+.1f dBm\n", gNB_id, @@ -458,12 +463,14 @@ int nr_prs_channel_estimation(uint8_t gNB_id, rxAnt, proc->frame_rx, proc->nr_slot_rx, - prs_meas[rxAnt]->dl_toa, + dl_toa, frame_params->ofdm_symbol_size, ch_pwr_dbm, prs_meas[rxAnt]->snr, prs_meas[rxAnt]->rsrp_dBm); + set_prs_dl_toa(prs_meas[rxAnt], dl_toa); + #ifdef DEBUG_PRS_CHEST sprintf(filename, "%s%i%s", "PRSpilot_", rxAnt, ".m"); LOG_M(filename, "prs_loc", mod_prs, num_pilots, 1, 1); From b95b4c09d662f8bef48d67097e47a86380cf9f67 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Fri, 19 Sep 2025 12:34:26 +0200 Subject: [PATCH 04/10] Write DL ToA into circular buffer In a future commit, we will look up the maximum ToA over the last transmissions. Introduce a buffer in which we write the last 16 measurements. --- openair1/PHY/INIT/nr_init_ue.c | 2 ++ openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c | 5 ++++- openair1/PHY/defs_nr_common.h | 4 +++- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/openair1/PHY/INIT/nr_init_ue.c b/openair1/PHY/INIT/nr_init_ue.c index e617b08172..2dce10d9dc 100644 --- a/openair1/PHY/INIT/nr_init_ue.c +++ b/openair1/PHY/INIT/nr_init_ue.c @@ -157,6 +157,8 @@ void init_nr_prs_ue_vars(PHY_VARS_NR_UE *ue) for (int j=0; jnb_antennas_rx; j++) { prs_vars[idx]->prs_resource[k].prs_meas[j] = malloc16_clear(sizeof(prs_meas_t)); AssertFatal((prs_vars[idx]->prs_resource[k].prs_meas[j]!=NULL), "%s: PRS measurements malloc failed for gNB_id %d, rx_ant %d\n", __FUNCTION__, idx, j); + prs_meas_t *m = prs_vars[idx]->prs_resource[k].prs_meas[j]; + m->next_dl_toa = m->dl_toa; } } } 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 4151752f11..3af0937c48 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c +++ b/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c @@ -73,7 +73,10 @@ void peak_estimator(c16_t *buffer, int32_t buf_len, int32_t *peak_idx, int32_t * void set_prs_dl_toa(prs_meas_t *prs_meas, float dl_toa) { - prs_meas->dl_toa = dl_toa; + *prs_meas->next_dl_toa++ = dl_toa; + if (prs_meas->next_dl_toa >= prs_meas->dl_toa + sizeofArray(prs_meas->dl_toa)) + prs_meas->next_dl_toa = prs_meas->dl_toa; + LOG_D(NR_PHY, "next_dl_toa %p\n", prs_meas->next_dl_toa); } int nr_prs_channel_estimation(uint8_t gNB_id, diff --git a/openair1/PHY/defs_nr_common.h b/openair1/PHY/defs_nr_common.h index f4681020eb..b4d61d32f9 100644 --- a/openair1/PHY/defs_nr_common.h +++ b/openair1/PHY/defs_nr_common.h @@ -312,7 +312,9 @@ typedef struct { int32_t sfn; int8_t slot; int8_t rxAnt_idx; - float dl_toa; + // circular buffer to be able to read maximum of last estimations + float dl_toa[128]; // set through set_prs_dl_toa() + float *next_dl_toa; int32_t dl_aoa; float snr; float rsrp; From d682b6c5123012c3a356e71ba802141c28e49cd9 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Fri, 19 Sep 2025 12:44:37 +0200 Subject: [PATCH 05/10] Add function to read max DL ToA Protect with mutex to allow reading from another thread. --- openair1/PHY/INIT/nr_init_ue.c | 1 + .../nr_dl_channel_estimation.c | 18 ++++++++++++++++++ openair1/PHY/defs_nr_common.h | 3 +++ 3 files changed, 22 insertions(+) diff --git a/openair1/PHY/INIT/nr_init_ue.c b/openair1/PHY/INIT/nr_init_ue.c index 2dce10d9dc..7ab8a8863d 100644 --- a/openair1/PHY/INIT/nr_init_ue.c +++ b/openair1/PHY/INIT/nr_init_ue.c @@ -159,6 +159,7 @@ void init_nr_prs_ue_vars(PHY_VARS_NR_UE *ue) AssertFatal((prs_vars[idx]->prs_resource[k].prs_meas[j]!=NULL), "%s: PRS measurements malloc failed for gNB_id %d, rx_ant %d\n", __FUNCTION__, idx, j); prs_meas_t *m = prs_vars[idx]->prs_resource[k].prs_meas[j]; m->next_dl_toa = m->dl_toa; + pthread_mutex_init(&m->dl_toa_mtx, NULL); } } } 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 3af0937c48..de0b6d2b29 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c +++ b/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c @@ -73,10 +73,28 @@ void peak_estimator(c16_t *buffer, int32_t buf_len, int32_t *peak_idx, int32_t * void set_prs_dl_toa(prs_meas_t *prs_meas, float dl_toa) { + int rc = pthread_mutex_lock(&prs_meas->dl_toa_mtx); + AssertFatal(rc == 0, "pthread_mutex_lock() failed: errno %d, %s\n", errno, strerror(errno)); *prs_meas->next_dl_toa++ = dl_toa; if (prs_meas->next_dl_toa >= prs_meas->dl_toa + sizeofArray(prs_meas->dl_toa)) prs_meas->next_dl_toa = prs_meas->dl_toa; LOG_D(NR_PHY, "next_dl_toa %p\n", prs_meas->next_dl_toa); + rc = pthread_mutex_unlock(&prs_meas->dl_toa_mtx); + AssertFatal(rc == 0, "pthread_mutex_unlock() failed: errno %d, %s\n", errno, strerror(errno)); +} + +float get_prs_max_dl_toa(prs_meas_t *prs_meas) +{ + float max = 0.0f; + int rc = pthread_mutex_lock(&prs_meas->dl_toa_mtx); + AssertFatal(rc == 0, "pthread_mutex_lock() failed: errno %d, %s\n", errno, strerror(errno)); + for (int i = 0; i < sizeofArray(prs_meas->dl_toa); ++i) { + max = cmax(max, prs_meas->dl_toa[i]); + LOG_I(NR_PHY, "i %d dl_toa %.3f max %.3f\n", i, prs_meas->dl_toa[i], max); + } + rc = pthread_mutex_unlock(&prs_meas->dl_toa_mtx); + AssertFatal(rc == 0, "pthread_mutex_unlock() failed: errno %d, %s\n", errno, strerror(errno)); + return max; } int nr_prs_channel_estimation(uint8_t gNB_id, diff --git a/openair1/PHY/defs_nr_common.h b/openair1/PHY/defs_nr_common.h index b4d61d32f9..23972fc9f2 100644 --- a/openair1/PHY/defs_nr_common.h +++ b/openair1/PHY/defs_nr_common.h @@ -38,6 +38,8 @@ #include "impl_defs_nr.h" #include "PHY/CODING/nrPolar_tools/nr_polar_defs.h" +#include + #define MAX_NUM_SUBCARRIER_SPACING 5 #define NR_MAX_OFDM_SYMBOL_SIZE 8192 @@ -312,6 +314,7 @@ typedef struct { int32_t sfn; int8_t slot; int8_t rxAnt_idx; + pthread_mutex_t dl_toa_mtx; // protect reading of max from write // circular buffer to be able to read maximum of last estimations float dl_toa[128]; // set through set_prs_dl_toa() float *next_dl_toa; From 34e002a80063bbb05633971957290a3231f57da9 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Fri, 19 Sep 2025 12:59:01 +0200 Subject: [PATCH 06/10] Add get_max_dl_toa() for ciUE telnet module --- common/utils/telnetsrv/telnetsrv_ciUE.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/common/utils/telnetsrv/telnetsrv_ciUE.c b/common/utils/telnetsrv/telnetsrv_ciUE.c index 90e044ed86..88320a6ce0 100644 --- a/common/utils/telnetsrv/telnetsrv_ciUE.c +++ b/common/utils/telnetsrv/telnetsrv_ciUE.c @@ -37,6 +37,8 @@ #include "openair2/LAYER2/NR_MAC_UE/mac_defs.h" #include "openair2/LAYER2/NR_MAC_UE/mac_proto.h" #include "openair2/RRC/NR_UE/rrc_proto.h" +#include "openair1/PHY/phy_extern_nr_ue.h" +#include "openair1/PHY/defs_nr_common.h" #define TELNETSERVERCODE #include "telnetsrv.h" @@ -110,6 +112,26 @@ static int force_deregistration(char *buf, int debug, telnet_printfunc_t prnt) return 0; } +extern float get_prs_max_dl_toa(prs_meas_t *prs_meas); +static int get_dl_toa(char *buf, int debug, telnet_printfunc_t prnt) +{ + // TODO multiple antennas, resources, gNBs? + int gNB_id = 0; + int rsc_id = 0; + int ant = 0; + + PHY_VARS_NR_UE *UE = PHY_vars_UE_g[0][0]; + if (!UE || !UE->prs_vars[gNB_id]) + ERROR_MSG_RET("no UE/prs_vars found!\n"); + NR_PRS_RESOURCE_t *prs_res = &UE->prs_vars[gNB_id]->prs_resource[rsc_id]; + if (!prs_res->prs_meas || !prs_res->prs_meas[ant]) + ERROR_MSG_RET("prs_meas not initialized!\n"); + + float max = get_prs_max_dl_toa(prs_res->prs_meas[ant]); + prnt("UE max PRS DL ToA %.3f\n", max); + return 0; +} + /* Telnet shell command definitions */ static telnetshell_cmddef_t cicmds[] = { {"sync_state", "[UE_ID(int,opt)]", get_sync_state}, @@ -117,6 +139,7 @@ static telnetshell_cmddef_t cicmds[] = { {"force_RRC_IDLE", "", force_RRC_IDLE}, {"force_crnti_ra", "", force_crnti_ra}, {"deregistration", "", force_deregistration}, + {"get_max_dl_toa", "[ant]", get_dl_toa}, {"", "", NULL}, }; From 1dca20ba85cac8228bf44a34c492271685419a9c Mon Sep 17 00:00:00 2001 From: rakesh mundlamuri Date: Tue, 23 Sep 2025 14:34:09 +0530 Subject: [PATCH 07/10] Introduce a bash script to test PRS using estimated ToA Set RFsim (DL) distance and use PRS to estimate the new distance. This is verified by comparing the distance set in RFsim with the distance reported through ToA estimation at the UE. Note that since RFsim telnet output is asynchronous (it uses a queue internally), we use grep --max-count 1 to wait for the matching line, together with ncat --idle 0.3 to keep ncat open for some time. The --max-count option will terminate grep after the first occurrence. For this to work reliably, we need to use grep <(echo | ncat) as opposod to simply echo | ncat | grep, as the latter does not seem to reliably make grep exit after the occurrence. Co-authored-by: Robert Schmidt --- .../scripts/set-and-verify-distance-prs.sh | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100755 ci-scripts/scripts/set-and-verify-distance-prs.sh diff --git a/ci-scripts/scripts/set-and-verify-distance-prs.sh b/ci-scripts/scripts/set-and-verify-distance-prs.sh new file mode 100755 index 0000000000..e54c8897a2 --- /dev/null +++ b/ci-scripts/scripts/set-and-verify-distance-prs.sh @@ -0,0 +1,39 @@ +#!/bin/bash + +die() { echo -e "$@"; exit 1; } + +[[ -z "$1" ]] && die "Usage: $0 " + +IP=192.168.71.150 +PORT=8091 +distance=$1 + +set_and_verify_distance() { + local distance=$1 + echo "Testing PRS ToA estimation for distance: $distance m" + + # it sems that grep returns immediately with this syntax, but not echo | ncat | grep + # so prefer this to receive new distance immediately. We use --idle to keep + # ncat open for some additional time + local setdist_resp="$(grep --max-count 1 new_offset <(echo rfsimu setdistance rfsimu_channel_enB0 $distance | ncat --idle 1 ${IP} ${PORT}))" + echo "> response: ${setdist_resp}" + local gettoa_resp="$(echo ciUE get_max_dl_toa | ncat ${IP} ${PORT} | grep "UE max PRS DL ToA")" + echo "> response: ${gettoa_resp}" + + [[ "$setdist_resp" =~ new_offset\ ([0-9]+) ]] || die "Set ToA extraction failed for distance: $distance m\nLOG: $setdist_resp" + local set_toa="${BASH_REMATCH[1]}" + + [[ "$gettoa_resp" =~ UE\ max\ PRS\ DL\ ToA\ ([0-9]+) ]] || die "Estimated ToA extraction failed for distance: $distance m\nLOG: $gettoa_resp" + local est_toa="${BASH_REMATCH[1]}" + + [[ $set_toa == $est_toa ]] || die "PRS FAILURE for distance: $distance m\nActual ToA = $set_toa, Estimated ToA = $est_toa" + + echo "PRS SUCCESS for distance: $distance m" +} + +# Set distance to 0 initially and then set the actual distance +sleep 4 +set_and_verify_distance 0 + +sleep 4 +set_and_verify_distance $distance From 0d2212ca38e6da4dd4873de98d6a0f09bd278114 Mon Sep 17 00:00:00 2001 From: Jaroslava Fiedlerova Date: Wed, 24 Sep 2025 08:01:35 +0000 Subject: [PATCH 08/10] CI: Extend Custom_Script to accept arguments --- ci-scripts/cls_oaicitest.py | 4 ++-- ci-scripts/main.py | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/ci-scripts/cls_oaicitest.py b/ci-scripts/cls_oaicitest.py index 144bc24da6..485653851c 100644 --- a/ci-scripts/cls_oaicitest.py +++ b/ci-scripts/cls_oaicitest.py @@ -233,10 +233,10 @@ def Custom_Command(HTML, node, command): HTML.CreateHtmlTestRowQueue(command, status, message) return status == 'OK' or status == 'Warning' -def Custom_Script(HTML, node, script): +def Custom_Script(HTML, node, script, args): logging.info(f"Executing custom script on {node}") with cls_cmd.getConnection(node) as c: - ret = c.exec_script(script, 90) + ret = c.exec_script(script, 90, args) logging.debug(f"Custom_Script: {script} on node: {node} - return code {ret.returncode}, output:\n{ret.stdout}") status = 'OK' message = [ret.stdout] diff --git a/ci-scripts/main.py b/ci-scripts/main.py index ac4ac2c3be..ff0b9ddb18 100644 --- a/ci-scripts/main.py +++ b/ci-scripts/main.py @@ -328,9 +328,10 @@ def ExecuteActionWithParam(action, ctx): elif action == 'Custom_Script': node = test.findtext('node') script = test.findtext('script') + args = test.findtext('args') # Allow referencing repository workspace path in XML via %%workspace%% script = script.replace("%%workspace%%", CONTAINERS.eNBSourceCodePath) - success = cls_oaicitest.Custom_Script(HTML, node, script) + success = cls_oaicitest.Custom_Script(HTML, node, script, args) elif action == 'Pull_Cluster_Image': tag_prefix = test.findtext('tag_prefix') or "" From 871b813c12c89b8b1e54f22432bb211f43517939 Mon Sep 17 00:00:00 2001 From: Rakesh Mundlamuri Date: Mon, 3 Nov 2025 11:45:49 +0530 Subject: [PATCH 09/10] Modify the script with a retry logic for a failed test and print summary This commit inputs several distances at once and obtain the summary of successful and failed tests. We look for the number of successful tests that are geater than 0. We do that here since we sometimes dont receive a response for a telnet command from the rfsim although the command is applied. This is related to the queing telnet commands in the rfsim. The script for the distances 50, 100 and 150 are called as follows, ./set-and-verify-distance-prs.sh 50 100 150 The summary can be viewed as follows, ==================== SUMMARY ==================== Total tests run : 3 Successful tests: 3 Failed tests : 0 ================================================= --- .../scripts/set-and-verify-distance-prs.sh | 92 ++++++++++++++----- 1 file changed, 71 insertions(+), 21 deletions(-) diff --git a/ci-scripts/scripts/set-and-verify-distance-prs.sh b/ci-scripts/scripts/set-and-verify-distance-prs.sh index e54c8897a2..73012a4484 100755 --- a/ci-scripts/scripts/set-and-verify-distance-prs.sh +++ b/ci-scripts/scripts/set-and-verify-distance-prs.sh @@ -1,39 +1,89 @@ #!/bin/bash -die() { echo -e "$@"; exit 1; } - -[[ -z "$1" ]] && die "Usage: $0 " +[[ $# -lt 1 ]] && { echo "Usage: $0 "; exit 1; } +DISTANCES=("$@") IP=192.168.71.150 PORT=8091 -distance=$1 +NCAT_TIMEOUT=1 #s +SLEEP_WAIT=4 #s +MAX_RETRIES=3 set_and_verify_distance() { local distance=$1 echo "Testing PRS ToA estimation for distance: $distance m" - # it sems that grep returns immediately with this syntax, but not echo | ncat | grep + # it seems that grep returns immediately with this syntax, but not echo | ncat | grep # so prefer this to receive new distance immediately. We use --idle to keep # ncat open for some additional time - local setdist_resp="$(grep --max-count 1 new_offset <(echo rfsimu setdistance rfsimu_channel_enB0 $distance | ncat --idle 1 ${IP} ${PORT}))" + local setdist_resp="$(grep --max-count 1 new_offset <(echo rfsimu setdistance rfsimu_channel_enB0 $distance | ncat --idle ${NCAT_TIMEOUT} ${IP} ${PORT}))" echo "> response: ${setdist_resp}" - local gettoa_resp="$(echo ciUE get_max_dl_toa | ncat ${IP} ${PORT} | grep "UE max PRS DL ToA")" + + local gettoa_resp="$(echo "ciUE get_max_dl_toa" | ncat ${IP} ${PORT} | grep "UE max PRS DL ToA")" echo "> response: ${gettoa_resp}" - [[ "$setdist_resp" =~ new_offset\ ([0-9]+) ]] || die "Set ToA extraction failed for distance: $distance m\nLOG: $setdist_resp" - local set_toa="${BASH_REMATCH[1]}" - - [[ "$gettoa_resp" =~ UE\ max\ PRS\ DL\ ToA\ ([0-9]+) ]] || die "Estimated ToA extraction failed for distance: $distance m\nLOG: $gettoa_resp" - local est_toa="${BASH_REMATCH[1]}" - - [[ $set_toa == $est_toa ]] || die "PRS FAILURE for distance: $distance m\nActual ToA = $set_toa, Estimated ToA = $est_toa" - - echo "PRS SUCCESS for distance: $distance m" + [[ -z "$setdist_resp" || -z "$gettoa_resp" ]] && return 1 + + # Extract ToA values + [[ "$setdist_resp" =~ new_offset\ ([0-9]+) ]] && local set_toa="${BASH_REMATCH[1]}" || { echo "> Set ToA extraction failed for distance: $distance m"; return 1; } + + [[ "$gettoa_resp" =~ UE\ max\ PRS\ DL\ ToA\ ([0-9]+) ]] && local est_toa="${BASH_REMATCH[1]}" || { echo "> Estimated ToA extraction failed for distance: $distance m"; return 1; } + + # Compare extracted ToA values + [[ $set_toa == $est_toa ]] && echo "PRS SUCCESS for distance: $distance m" || { echo "PRS FAILURE for distance: $distance m (Actual ToA=$set_toa, Estimated ToA=$est_toa)" ; return 1; } + } -# Set distance to 0 initially and then set the actual distance -sleep 4 -set_and_verify_distance 0 +test_distance() { + local distance=$1 retries=0 -sleep 4 -set_and_verify_distance $distance + # retry loop incase we didn't receive the response + while (( retries < MAX_RETRIES )); do + echo " Attempt $((retries + 1))/$MAX_RETRIES" + + # Always reset to 0 m before testing target distance + if ! set_and_verify_distance 0; then + echo " Set distance 0 m failed during attempt $((retries + 1))" + else + sleep "$SLEEP_WAIT" + # Now test the actual target distance + if set_and_verify_distance "$distance"; then + return 0 + fi + fi + + ((retries++)) + if (( retries < MAX_RETRIES )); then + sleep "$SLEEP_WAIT" + else + echo " ERROR: No valid response after $MAX_RETRIES retries for distance: $distance m" + return 1 + fi + done +} + +num_success=0 +num_fail=0 + +for d in "${DISTANCES[@]}"; do + if test_distance "$d"; then + ((num_success++)) + else + ((num_fail++)) + fi + sleep "$SLEEP_WAIT" +done + +# ---- Summary ---- +echo +echo "==================== SUMMARY ====================" +echo "Total tests run : ${#DISTANCES[@]}" +echo "Successful tests: ${num_success}" +echo "Failed tests : ${num_fail}" +echo "=================================================" + +if [ $num_success -gt 0 ]; then + exit 0 +else + exit 1 +fi From c625a95042e110f9628f840f2a19eaca49ed33b3 Mon Sep 17 00:00:00 2001 From: Jaroslava Fiedlerova Date: Fri, 12 Sep 2025 12:55:22 +0200 Subject: [PATCH 10/10] CI: add rfsim test with PRS Use the bash script from a parent commit to verify PRS functionality. --- .../gnb.sa.band78.106prb.rfsim.prs.conf | 256 ++++++++++++++++++ .../conf_files/nrue.band78.106prb.prs.conf | 89 ++++++ .../xml_files/container_5g_rfsim_prs.xml | 100 +++++++ .../5g_rfsimulator_prs/docker-compose.yaml | 71 +++++ 4 files changed, 516 insertions(+) create mode 100644 ci-scripts/conf_files/gnb.sa.band78.106prb.rfsim.prs.conf create mode 100644 ci-scripts/conf_files/nrue.band78.106prb.prs.conf create mode 100644 ci-scripts/xml_files/container_5g_rfsim_prs.xml create mode 100644 ci-scripts/yaml_files/5g_rfsimulator_prs/docker-compose.yaml diff --git a/ci-scripts/conf_files/gnb.sa.band78.106prb.rfsim.prs.conf b/ci-scripts/conf_files/gnb.sa.band78.106prb.rfsim.prs.conf new file mode 100644 index 0000000000..3b6b591d85 --- /dev/null +++ b/ci-scripts/conf_files/gnb.sa.band78.106prb.rfsim.prs.conf @@ -0,0 +1,256 @@ +Active_gNBs = ( "gNB-OAI"); +# Asn1_verbosity, choice in: none, info, annoying +Asn1_verbosity = "none"; + +gNBs = +( + { + ////////// Identification parameters: + gNB_ID = 0xe00; + gNB_name = "gNB-OAI"; + + // Tracking area code, 0x0000 and 0xfffe are reserved values + tracking_area_code = 1; + + plmn_list = ({mcc = 208; mnc = 97; mnc_length = 2;}); + + ////////// Physical parameters: + + min_rxtxtime = 6; + + servingCellConfigCommon = ( + { + #spCellConfigCommon + + physCellId = 0; + +# downlinkConfigCommon + #frequencyInfoDL + # this is 3300.60 MHz + 53*12*30e-3 MHz = 3319.68 + absoluteFrequencySSB = 621312; + # this is 3300.60 MHz + dl_absoluteFrequencyPointA = 620040; + #scs-SpecificCarrierList + dl_offstToCarrier = 0; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + dl_subcarrierSpacing = 1; + dl_carrierBandwidth = 106; + #initialDownlinkBWP + #genericParameters + # this is RBstart=0,L=106 (275*(L-1))+RBstart + initialDLBWPlocationAndBandwidth = 28875; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + initialDLBWPsubcarrierSpacing = 1; + #pdcch-ConfigCommon + initialDLBWPcontrolResourceSetZero = 11; + 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 = 106; + pMax = 20; + #initialUplinkBWP + #genericParameters + initialULBWPlocationAndBandwidth = 28875; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + initialULBWPsubcarrierSpacing = 1; + #rach-ConfigCommon + #rach-ConfigGeneric + prach_ConfigurationIndex = 98; +#prach_msg1_FDM +#0 = one, 1=two, 2=four, 3=eight + prach_msg1_FDM = 0; + prach_msg1_FrequencyStart = 0; + zeroCorrelationZoneConfig = 12; + preambleReceivedTargetPower = -104; +#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=spar e1 + 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; + nrofDownlinkSlots = 7; + nrofDownlinkSymbols = 6; + nrofUplinkSlots = 2; + nrofUplinkSymbols = 4; + + 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 = "CI_MME_IP_ADDR"; }); + + NETWORK_INTERFACES : + { + + GNB_IPV4_ADDRESS_FOR_NG_AMF = "CI_GNB_IP_ADDR"; + GNB_IPV4_ADDRESS_FOR_NGU = "CI_GNB_IP_ADDR"; + GNB_PORT_FOR_S1U = 2152; # Spec 2152 + }; + + } +); + +MACRLCs = ( +{ + num_cc = 1; + tr_s_preference = "local_L1"; + tr_n_preference = "local_RRC"; + pusch_TargetSNRx10 = 200; + pucch_TargetSNRx10 = 200; +} +); + +prs_config = ( +{ + NumPRSResources = 1; + PRSResourceSetPeriod = [20, 2]; + SymbolStart = [7]; + NumPRSSymbols = [6]; + NumRB = 106; + RBOffset = 0; + CombSize = 4; + REOffset = [0]; + PRSResourceOffset = [0]; + PRSResourceRepetition = 1; + PRSResourceTimeGap = 1; + NPRS_ID = [0]; + MutingPattern1 = []; + MutingPattern2 = []; + MutingBitRepetition = 1; +} +); + +L1s = ( +{ + num_cc = 1; + tr_n_preference = "local_mac"; + prach_dtx_threshold = 120; +} +); + +RUs = ( +{ + local_rf = "yes" + nb_tx = 1 + nb_rx = 1 + att_tx = 0 + att_rx = 0; + bands = [78]; + max_pdschReferenceSignalPower = -27; + max_rxgain = 75; + sf_extension = 0; + eNB_instances = [0]; +} +); + + +rfsimulator : +{ + serveraddr = "server"; + serverport = 4043; + options = (); #("saviq"); or/and "chanmod" + modelname = "AWGN"; + IQfile = "/tmp/rfsimulator.iqs"; +}; + +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"; + f1ap_log_level = "debug"; +}; diff --git a/ci-scripts/conf_files/nrue.band78.106prb.prs.conf b/ci-scripts/conf_files/nrue.band78.106prb.prs.conf new file mode 100644 index 0000000000..1bf92fd0d6 --- /dev/null +++ b/ci-scripts/conf_files/nrue.band78.106prb.prs.conf @@ -0,0 +1,89 @@ +PRSs = +( + { + Active_gNBs = 1; + prs_config0 = ( + { + gNB_id = 0; + NumPRSResources = 1; + PRSResourceSetPeriod = [20, 2]; + SymbolStart = [7]; + NumPRSSymbols = [6]; + NumRB = 106; + RBOffset = 0; + CombSize = 4; + REOffset = [0]; + PRSResourceOffset = [0]; + PRSResourceRepetition = 1; + PRSResourceTimeGap = 1; + NPRS_ID = [0]; + MutingPattern1 = []; + MutingPattern2 = []; + MutingBitRepetition = 1; + } + ); + + prs_config1 = ( + { + gNB_id = 1; + NumPRSResources = 1; + PRSResourceSetPeriod = [20, 2]; + SymbolStart = [7]; + NumPRSSymbols = [6]; + NumRB = 106; + RBOffset = 0; + CombSize = 4; + REOffset = [0]; + PRSResourceOffset = [1]; + PRSResourceRepetition = 1; + PRSResourceTimeGap = 1; + NPRS_ID = [1]; + MutingPattern1 = []; + MutingPattern2 = []; + MutingBitRepetition = 1; + } + ); + + prs_config2 = ( + { + gNB_id = 2; + NumPRSResources = 1; + PRSResourceSetPeriod = [20, 2]; + SymbolStart = [7]; + NumPRSSymbols = [6]; + NumRB = 106; + RBOffset = 0; + CombSize = 4; + REOffset = [0]; + PRSResourceOffset = [2]; + PRSResourceRepetition = 1; + PRSResourceTimeGap = 1; + NPRS_ID = [2]; + MutingPattern1 = []; + MutingPattern2 = []; + MutingBitRepetition = 1; + } + ); + + prs_config3 = ( + { + gNB_id = 3; + NumPRSResources = 1; + PRSResourceSetPeriod = [20, 2]; + SymbolStart = [7]; + NumPRSSymbols = [6]; + NumRB = 106; + RBOffset = 0; + CombSize = 4; + REOffset = [0]; + PRSResourceOffset = [3]; + PRSResourceRepetition = 1; + PRSResourceTimeGap = 1; + NPRS_ID = [3]; + MutingPattern1 = []; + MutingPattern2 = []; + MutingBitRepetition = 1; + } + ); + } +); diff --git a/ci-scripts/xml_files/container_5g_rfsim_prs.xml b/ci-scripts/xml_files/container_5g_rfsim_prs.xml new file mode 100644 index 0000000000..456ae62c1a --- /dev/null +++ b/ci-scripts/xml_files/container_5g_rfsim_prs.xml @@ -0,0 +1,100 @@ + + + rfsim-5gnr-prs + Monolithic gNB with PRS + wrench + + 111111 + 800813 + 000012 + 000013 + 040001 + 040023 + 100011 + 222222 + + + + + Pull_Local_Registry + Pull Images from Local Registry + localhost + oai-gnb-asan oai-nr-ue-asan + + + + Create_Workspace + Create new Workspace + localhost + + + + Deploy_Object + Deploy OAI 5G gNB+UE RF sim SA + localhost + ci-scripts/yaml_files/5g_rfsimulator_prs + oai-gnb oai-nr-ue + + + + Attach_UE + Attach OAI UE (Wait for IP) + rfsim5g_ue + localhost + + + + IdleSleep + Sleep + 2 + + + + Custom_Script + true + Set and verify distance at 50, 100, 150 m + localhost + + 50 100 150 + + + + Undeploy_Object + true + Undeploy all OAI 5G stack + localhost + ci-scripts/yaml_files/5g_rfsimulator_prs + 30,100,100,100 + 30,100,100,100 + + + + Clean_Test_Server_Images + true + Clean Test Images on Test Server + localhost + oai-gnb-asan oai-nr-ue-asan + + + diff --git a/ci-scripts/yaml_files/5g_rfsimulator_prs/docker-compose.yaml b/ci-scripts/yaml_files/5g_rfsimulator_prs/docker-compose.yaml new file mode 100644 index 0000000000..c6b6c338de --- /dev/null +++ b/ci-scripts/yaml_files/5g_rfsimulator_prs/docker-compose.yaml @@ -0,0 +1,71 @@ +services: + oai-gnb: + image: ${REGISTRY-oaisoftwarealliance/}${GNB_IMG:-oai-gnb}:${TAG:-develop} + container_name: rfsim5g-oai-gnb + cap_drop: + - ALL + cap_add: + - NET_ADMIN # for interface bringup + - NET_RAW # for ping + environment: + USE_ADDITIONAL_OPTIONS: --phy-test --rfsim -E + --log_config.global_log_options level,nocolor,time + ASAN_OPTIONS: detect_leaks=0:detect_odr_violation=0 + networks: + public_net: + ipv4_address: 192.168.71.140 + devices: + - /dev/net/tun:/dev/net/tun + volumes: + - ../../conf_files/gnb.sa.band78.106prb.rfsim.prs.conf:/opt/oai-gnb/etc/gnb.conf + - rrc.config:/opt/oai-gnb/ + healthcheck: + test: /bin/bash -c "pgrep nr-softmodem" + interval: 10s + timeout: 5s + retries: 5 + + oai-nr-ue: + image: ${REGISTRY-oaisoftwarealliance/}${NRUE_IMG:-oai-nr-ue}:${TAG:-develop} + container_name: rfsim5g-oai-nr-ue + cap_drop: + - ALL + cap_add: + - NET_ADMIN # for interface bringup + - NET_RAW # for ping + environment: + USE_ADDITIONAL_OPTIONS: --phy-test --rfsim -E + --reconfig-file etc/rrc/reconfig.raw --rbconfig-file etc/rrc/rbconfig.raw + --rfsimulator.serveraddr 192.168.71.140 + --log_config.global_log_options level,nocolor,time + --telnetsrv --telnetsrv.listenaddr 192.168.71.150 --telnetsrv.listenport 8091 + --telnetsrv.shrmod ciUE + ASAN_OPTIONS: detect_leaks=0:detect_odr_violation=0 + devices: + - /dev/net/tun:/dev/net/tun + volumes: + - ../../conf_files/nrue.band78.106prb.prs.conf:/opt/oai-nr-ue/etc/nr-ue.conf + - rrc.config:/opt/oai-nr-ue/etc/rrc/ + depends_on: + - oai-gnb + networks: + public_net: + ipv4_address: 192.168.71.150 + healthcheck: + test: /bin/bash -c "pgrep nr-uesoftmodem" + interval: 10s + timeout: 5s + retries: 5 + +volumes: + rrc.config: + +networks: + public_net: + driver: bridge + name: rfsim5g-oai-public-net + ipam: + config: + - subnet: 192.168.71.128/26 + driver_opts: + com.docker.network.bridge.name: "rfsim5g-public"