Merge remote-tracking branch 'origin/nr_ue_multiple_rf' into integration_2026_w05 (!3593)

NR UE: add support for multiple RF frontends

This MR adds basic support for multiple RF-frontends at the UE.
There are multiple reasons why we might want this:
1. There might be different antennas needed for different bands (e.g. NTN or
   TN antennas). These antennas might be connected to different RF-frontends.
   In case of Handover, the UE needs to dynamically switch between these
   RF-frontends.
2. Each rf-simulator connection carries baseband I/Q samples. To be able to
   perform a handover between two cells at different frequencies, there must
   be two rf-simulator connections, as the baseband channels should not
   interfere and thus cannot simply be added.
3. When we want to support multiple UE simulation within one instance of
   nr-uesoftmodem, and allow multiple cells and probably even handover between
   these cells, we need either:
   1. dedicated RF-frontends for each simulated UE, or
   2. dedicated RF-frontends for each connected cell and dynamically assign
      simulated UEs accordingly.

This MR implements what is needed for 1., 2. and 3.1.
This commit is contained in:
Jaroslava Fiedlerova
2026-01-28 20:19:48 +01:00
153 changed files with 1993 additions and 1082 deletions
@@ -41,7 +41,7 @@ At runtime, to successfully use LDPC accelerators (e.g., Xilinx T2/Intel ACCs),
Please refer to the dedicated documentation at [LDPC_OFFLOAD_SETUP.md](file://../../../../doc/LDPC_OFFLOAD_SETUP.md).
```
./nr-softmodem -O libconfig:gnb.band78.sa.fr1.106PRB.usrpb210.conf:dbgl5 --rfsim --rfsimulator.serveraddr server --log_config.gtpu_log_level info --loader.ldpc.shlibversion _aal --nrLDPC_coding_aal.dpdk_dev 01:00.0 --nrLDPC_coding_aal.dpdk_core_list 0-1
./nr-softmodem -O libconfig:gnb.band78.sa.fr1.106PRB.usrpb210.conf:dbgl5 --rfsim --rfsimulator.[0].serveraddr server --log_config.gtpu_log_level info --loader.ldpc.shlibversion _aal --nrLDPC_coding_aal.dpdk_dev 01:00.0 --nrLDPC_coding_aal.dpdk_core_list 0-1
```
`libldpc_aal.so` has its decoder and its encoder implemented in [nrLDPC_coding_aal.c](file://../nrLDPC_coding/nrLDPC_coding_aal/nrLDPC_coding_aal.c).
@@ -61,7 +61,7 @@ At runtime, to successfully use the xdma, you need to install vendor specific dr
Please refer to the dedicated documentation at [LDPC_XDMA_OFFLOAD_SETUP.md](file://../../../../doc/LDPC_XDMA_OFFLOAD_SETUP.md).
```
./nr-softmodem -O libconfig:gnb.band78.sa.fr1.106PRB.usrpb210.conf:dbgl5 --rfsim --rfsimulator.serveraddr server --log_config.gtpu_log_level info --loader.ldpc.shlibversion _xdma --nrLDPC_coding_xdma.num_threads_prepare 2
./nr-softmodem -O libconfig:gnb.band78.sa.fr1.106PRB.usrpb210.conf:dbgl5 --rfsim --rfsimulator.[0].serveraddr server --log_config.gtpu_log_level info --loader.ldpc.shlibversion _xdma --nrLDPC_coding_xdma.num_threads_prepare 2
```
`libldpc_xdma.so` has its decoder implemented in [nrLDPC_coding_xdma.c](file://../nrLDPC_coding/nrLDPC_coding_xdma/nrLDPC_coding_xdma.c).\
+14 -5
View File
@@ -320,7 +320,7 @@ uint32_t get_samples_symbol_timestamp(const NR_DL_FRAME_PARMS *fp, int slot, int
return get_samples_symbol_duration(fp, slot, 0, symbol);
}
uint32_t get_slot_from_timestamp(openair0_timestamp timestamp_rx, const NR_DL_FRAME_PARMS *fp)
uint32_t get_slot_from_timestamp(openair0_timestamp_t timestamp_rx, const NR_DL_FRAME_PARMS *fp)
{
timestamp_rx = timestamp_rx % fp->samples_per_frame;
if (timestamp_rx < fp->samples_per_slot0)
@@ -525,13 +525,20 @@ int nr_init_frame_parms_ue(NR_DL_FRAME_PARMS *fp,
return 0;
}
void nr_init_frame_parms_ue_sa(NR_DL_FRAME_PARMS *frame_parms, uint64_t downlink_frequency, int32_t delta_duplex, uint8_t mu, uint16_t nr_band) {
void nr_init_frame_parms_ue_sa(NR_DL_FRAME_PARMS *frame_parms, const nrUE_cell_params_t *cell)
{
const uint64_t downlink_frequency = cell->rf_frequency;
const int64_t delta_duplex = cell->rf_freq_offset;
const uint8_t mu = cell->numerology;
const int N_RB_DL = cell->N_RB_DL;
const int ssb_start_subcarrier = cell->ssb_start;
const uint16_t nr_band = cell->band;
LOG_I(PHY,"SA init parameters. DL freq %lu UL offset %d SSB numerology %d N_RB_DL %d\n",
LOG_I(PHY,"SA init parameters. DL freq %lu UL offset %ld SSB numerology %d N_RB_DL %d\n",
downlink_frequency,
delta_duplex,
mu,
frame_parms->N_RB_DL);
N_RB_DL);
frame_parms->numerology_index = mu;
frame_parms->dl_CarrierFreq = downlink_frequency;
@@ -539,6 +546,7 @@ void nr_init_frame_parms_ue_sa(NR_DL_FRAME_PARMS *frame_parms, uint64_t downlink
if (get_softmodem_params()->sl_mode == 0) {
frame_parms->freq_range = get_freq_range_from_freq(frame_parms->dl_CarrierFreq);
}
frame_parms->N_RB_DL = N_RB_DL;
frame_parms->N_RB_UL = frame_parms->N_RB_DL;
frame_parms->nr_band = nr_band;
@@ -564,8 +572,9 @@ void nr_init_frame_parms_ue_sa(NR_DL_FRAME_PARMS *frame_parms, uint64_t downlink
+ (frame_parms->symbols_per_slot * frame_parms->ofdm_symbol_size);
frame_parms->samples_per_frame = 10 * frame_parms->samples_per_subframe;
LOG_W(PHY, "samples_per_subframe %d/per second %d, wCP %d\n", frame_parms->samples_per_subframe, 1000*frame_parms->samples_per_subframe, frame_parms->samples_per_subframe_wCP);
frame_parms->ssb_start_subcarrier = ssb_start_subcarrier;
LOG_W(PHY, "samples_per_subframe %d/per second %d, wCP %d\n", frame_parms->samples_per_subframe, 1000*frame_parms->samples_per_subframe, frame_parms->samples_per_subframe_wCP);
}
void nr_dump_frame_parms(NR_DL_FRAME_PARMS *fp)
+1 -1
View File
@@ -28,7 +28,7 @@
int nr_get_ssb_start_symbol(const NR_DL_FRAME_PARMS *fp, uint8_t i_ssb);
void nr_init_frame_parms(nfapi_nr_config_request_scf_t *config, NR_DL_FRAME_PARMS *frame_parms);
int nr_init_frame_parms_ue(NR_DL_FRAME_PARMS *frame_parms, fapi_nr_config_request_t *config, uint16_t nr_band);
void nr_init_frame_parms_ue_sa(NR_DL_FRAME_PARMS *frame_parms, uint64_t downlink_frequency, int32_t uplink_frequency_offset, uint8_t mu, uint16_t nr_band);
void nr_init_frame_parms_ue_sa(NR_DL_FRAME_PARMS *frame_parms, const nrUE_cell_params_t *cell);
int nr_init_frame_parms_ue_sl(NR_DL_FRAME_PARMS *fp,
sl_nr_phy_config_request_t *config,
int threequarter_fs,
@@ -41,7 +41,7 @@ uint32_t ref_get_samples_slot_timestamp(NR_DL_FRAME_PARMS *fp, unsigned int slot
return samp_count;
}
uint32_t ref_get_slot_from_timestamp(openair0_timestamp ts, NR_DL_FRAME_PARMS *fp)
uint32_t ref_get_slot_from_timestamp(openair0_timestamp_t ts, NR_DL_FRAME_PARMS *fp)
{
uint32_t slot_idx = 0;
int samples_till_the_slot = get_samples_per_slot(slot_idx, fp) - 1;
@@ -75,7 +75,7 @@ void test_coherence_slot_api(NR_DL_FRAME_PARMS *fp)
EXPECT_EQ(get_samples_slot_timestamp(fp, slot), ref_get_samples_slot_timestamp(fp, slot));
}
openair0_timestamp ts = get_samples_per_slot(0, fp);
openair0_timestamp_t ts = get_samples_per_slot(0, fp);
// When timestamp is the last sample of the slot
EXPECT_EQ(get_slot_from_timestamp(ts - 1, fp), 0);
for (unsigned int slot = 0; slot < fp->slots_per_frame; slot++) {
@@ -174,4 +174,4 @@ int main(int argc, char **argv)
logInit();
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
}
@@ -46,6 +46,8 @@
#define CH_INTERP 0
#define NO_INTERP 1
extern openair0_config_t openair0_cfg[MAX_CARDS];
/* Generic function to find the peak of channel estimation buffer */
void peak_estimator(c16_t *buffer, int32_t buf_len, int32_t *peak_idx, int32_t *peak_val, int32_t mean_val)
{
@@ -461,12 +463,13 @@ int nr_prs_channel_estimation(uint8_t gNB_id,
// adjusting the rx_gains for channel peak power
ch_pwr_dbm = 10 * log10(ch_pwr) + 30 - SQ15_SQUARED_NORM_FACTOR_DB
- ((int)ue->openair0_cfg[0].rx_gain[0] - (int)ue->openair0_cfg[0].rx_gain_offset[0])
- ((int)openair0_cfg[ue->rf_map.card].rx_gain[0] - (int)openair0_cfg[ue->rf_map.card].rx_gain_offset[0])
- dB_fixed(frame_params->ofdm_symbol_size);
prs_meas[rxAnt]->rsrp_dBm = 10 * log10(prs_meas[rxAnt]->rsrp) + 30 - SQ15_SQUARED_NORM_FACTOR_DB
- ((int)ue->openair0_cfg[0].rx_gain[0] - (int)ue->openair0_cfg[0].rx_gain_offset[0])
- dB_fixed(ue->frame_parms.ofdm_symbol_size);
prs_meas[rxAnt]->rsrp_dBm =
10 * log10(prs_meas[rxAnt]->rsrp) + 30 - SQ15_SQUARED_NORM_FACTOR_DB
- ((int)openair0_cfg[ue->rf_map.card].rx_gain[0] - (int)openair0_cfg[ue->rf_map.card].rx_gain_offset[0])
- dB_fixed(ue->frame_parms.ofdm_symbol_size);
// prs measurements
prs_meas[rxAnt]->gNB_id = gNB_id;
@@ -154,10 +154,10 @@ void nr_pdsch_ptrs_processing(PHY_VARS_NR_UE *ue,
uint16_t rnti,
NR_UE_DLSCH_t dlsch[2]);
int nr_sl_psbch_rsrp_measurements(sl_nr_ue_phy_params_t *sl_phy_params,
int nr_sl_psbch_rsrp_measurements(PHY_VARS_NR_UE *ue,
sl_nr_ue_phy_params_t *sl_phy_params,
NR_DL_FRAME_PARMS *fp,
c16_t rxdataF[][fp->samples_per_slot_wCP],
bool use_SSS,
openair0_config_t *openair0_cfg);
bool use_SSS);
/** @}*/
#endif
@@ -51,6 +51,8 @@
//#define DEBUG_MEAS_UE
//#define DEBUG_RANK_EST
extern openair0_config_t openair0_cfg[MAX_CARDS];
void nr_ue_measurements(PHY_VARS_NR_UE *ue,
const UE_nr_rxtx_proc_t *proc,
int number_rbs,
@@ -133,9 +135,10 @@ void nr_ue_measurements(PHY_VARS_NR_UE *ue,
ue->measurements.n0_power_avg_dB = dB_fixed(ue->measurements.n0_power_avg);
ue->measurements.wideband_cqi_tot[gNB_id] = ue->measurements.rx_power_tot_dB[gNB_id] - ue->measurements.n0_power_tot_dB;
ue->measurements.wideband_cqi_avg[gNB_id] = ue->measurements.rx_power_avg_dB[gNB_id] - ue->measurements.n0_power_avg_dB;
ue->measurements.rx_rssi_dBm[gNB_id] = ue->measurements.rx_power_avg_dB[gNB_id] + 30 - SQ15_SQUARED_NORM_FACTOR_DB
- ((int)ue->openair0_cfg[0].rx_gain[0] - (int)ue->openair0_cfg[0].rx_gain_offset[0])
- dB_fixed(ue->frame_parms.ofdm_symbol_size);
ue->measurements.rx_rssi_dBm[gNB_id] =
ue->measurements.rx_power_avg_dB[gNB_id] + 30 - SQ15_SQUARED_NORM_FACTOR_DB
- ((int)openair0_cfg[ue->rf_map.card].rx_gain[0] - (int)openair0_cfg[ue->rf_map.card].rx_gain_offset[0])
- dB_fixed(ue->frame_parms.ofdm_symbol_size);
LOG_D(PHY, "[gNB %d] Slot %d, RSSI %d dB (%d dBm/RE), WBandCQI %d dB, rxPwrAvg %d, n0PwrAvg %d\n",
gNB_id,
@@ -242,7 +245,7 @@ void nr_ue_ssb_rsrp_measurements(PHY_VARS_NR_UE *ue,
uint32_t rsrp_avg = nr_ue_calculate_ssb_rsrp(fp, proc, rxdataF, symbol_offset, fp->ssb_start_subcarrier);
float rsrp_db_per_re = 10 * log10(rsrp_avg);
openair0_config_t *cfg0 = &ue->openair0_cfg[0];
openair0_config_t *cfg0 = &openair0_cfg[ue->rf_map.card];
if (rsrp_avg == 0)
ue->measurements.ssb_rsrp_dBm[ssb_index] = -200; // lower than any value to be reported per Table 10.1.6.1-1 of 38.133
@@ -488,9 +491,10 @@ 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_dBm = 10 * log10(neighboring_cell_info->ssb_rsrp) + 30 - SQ15_SQUARED_NORM_FACTOR_DB
- ((int)ue->openair0_cfg[0].rx_gain[0] - (int)ue->openair0_cfg[0].rx_gain_offset[0])
- dB_fixed(ue->frame_parms.ofdm_symbol_size);
neighboring_cell_info->ssb_rsrp_dBm =
10 * log10(neighboring_cell_info->ssb_rsrp) + 30 - SQ15_SQUARED_NORM_FACTOR_DB
- ((int)openair0_cfg[ue->rf_map.card].rx_gain[0] - (int)openair0_cfg[ue->rf_map.card].rx_gain_offset[0])
- dB_fixed(ue->frame_parms.ofdm_symbol_size);
// Send SS measurements to MAC
send_ssb_rsrp_meas(ue, proc, neighbor_cell->Nid_cell, neighboring_cell_info->ssb_rsrp_dBm, true, -1, 0.0);
@@ -522,8 +526,8 @@ void nr_ue_rrc_measurements(PHY_VARS_NR_UE *ue,
const uint8_t k_length = 8;
uint8_t l_sss = (ue->symbol_offset + 2) % ue->frame_parms.symbols_per_slot;
unsigned int ssb_offset = ue->frame_parms.first_carrier_offset + ue->frame_parms.ssb_start_subcarrier;
double rx_gain = ue->openair0_cfg[0].rx_gain[0];
double rx_gain_offset = ue->openair0_cfg[0].rx_gain_offset[0];
double rx_gain = openair0_cfg[ue->rf_map.card].rx_gain[0];
double rx_gain_offset = openair0_cfg[ue->rf_map.card].rx_gain_offset[0];
ue->measurements.n0_power_tot = 0;
@@ -592,11 +596,11 @@ void nr_ue_rrc_measurements(PHY_VARS_NR_UE *ue,
// Measurement units:
// - RSRP: W (dBW)
// returns RXgain to be adjusted based on target rx power (50db) - received digital power in db/RE
int nr_sl_psbch_rsrp_measurements(sl_nr_ue_phy_params_t *sl_phy_params,
int nr_sl_psbch_rsrp_measurements(PHY_VARS_NR_UE *ue,
sl_nr_ue_phy_params_t *sl_phy_params,
NR_DL_FRAME_PARMS *fp,
c16_t rxdataF[][fp->samples_per_slot_wCP],
bool use_SSS,
openair0_config_t *openair0_cfg)
bool use_SSS)
{
SL_NR_UE_PSBCH_t *psbch_rx = &sl_phy_params->psbch;
uint8_t numsym = (fp->Ncp) ? SL_NR_NUM_SYMBOLS_SSB_EXT_CP : SL_NR_NUM_SYMBOLS_SSB_NORMAL_CP;
@@ -629,9 +633,10 @@ int nr_sl_psbch_rsrp_measurements(sl_nr_ue_phy_params_t *sl_phy_params,
}
psbch_rx->rsrp_dB_per_RE = 10 * log10(rsrp / num_re);
psbch_rx->rsrp_dBm_per_RE = psbch_rx->rsrp_dB_per_RE + 30 - SQ15_SQUARED_NORM_FACTOR_DB
- ((int)openair0_cfg[0].rx_gain[0] - (int)openair0_cfg[0].rx_gain_offset[0])
- dB_fixed(fp->ofdm_symbol_size);
psbch_rx->rsrp_dBm_per_RE =
psbch_rx->rsrp_dB_per_RE + 30 - SQ15_SQUARED_NORM_FACTOR_DB
- ((int)openair0_cfg[ue->rf_map.card].rx_gain[0] - (int)openair0_cfg[ue->rf_map.card].rx_gain_offset[0])
- dB_fixed(fp->ofdm_symbol_size);
int adjust_rxgain = TARGET_RX_POWER - psbch_rx->rsrp_dB_per_RE;
+4 -1
View File
@@ -45,6 +45,8 @@
//#define NR_CSIRS_DEBUG
//#define NR_CSIIM_DEBUG
extern openair0_config_t openair0_cfg[MAX_CARDS];
void nr_det_A_MF_2x2(int32_t *a_mf_00,
int32_t *a_mf_01,
int32_t *a_mf_10,
@@ -237,7 +239,8 @@ static int nr_get_csi_rs_signal(const PHY_VARS_NR_UE *ue,
*rsrp = rsrp_sum/meas_count;
*rsrp_dBm = dB_fixed(*rsrp) + 30 - SQ15_SQUARED_NORM_FACTOR_DB
- ((int)ue->openair0_cfg[0].rx_gain[0] - (int)ue->openair0_cfg[0].rx_gain_offset[0]) - dB_fixed(ue->frame_parms.ofdm_symbol_size);
- ((int)openair0_cfg[ue->rf_map.card].rx_gain[0] - (int)openair0_cfg[ue->rf_map.card].rx_gain_offset[0])
- dB_fixed(ue->frame_parms.ofdm_symbol_size);
#ifdef NR_CSIRS_DEBUG
LOG_I(NR_PHY, "RSRP = %i (%i dBm)\n", *rsrp, *rsrp_dBm);
@@ -501,7 +501,7 @@ nr_initial_sync_t sl_nr_slss_search(PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc,
sync_params->DFN,
sync_params->slot_offset);
UE->adjust_rxgain = nr_sl_psbch_rsrp_measurements(sl_ue, frame_parms, rxdataF, false, UE->openair0_cfg);
UE->adjust_rxgain = nr_sl_psbch_rsrp_measurements(UE, sl_ue, frame_parms, rxdataF, false);
UE->init_sync_frame = sync_params->remaining_frames;
result.rx_offset = sync_params->rx_offset;
@@ -260,25 +260,13 @@ bool nr_search_ssb_common(nr_ssb_search_params_t *params);
@param dl_Carrier Pointer to DL carrier to be set
@param ul_Carrier Pointer to UL carrier to be set
*/
void nr_get_carrier_frequencies(PHY_VARS_NR_UE *ue,
uint64_t *dl_Carrier,
uint64_t *ul_Carrier);
/*!
\brief This function gets the carrier frequencies either from FP or command-line-set global variables, depending on the availability of the latter
@param ue Pointer to PHY UE
@param sl_Carrier Pointer to SL carrier to be set
*/
void nr_get_carrier_frequencies_sl(PHY_VARS_NR_UE *ue,
uint64_t *sl_Carrier);
void nr_get_carrier_frequencies(const PHY_VARS_NR_UE *ue, uint64_t *dl_Carrier, uint64_t *ul_Carrier);
/*!
\brief This function sets the OAI RF card rx/tx params
@param openair0_cfg Pointer OAI config for a specific card
@param rx_gain_off Rx gain offset
*/
void nr_rf_card_config_gain(openair0_config_t *openair0_cfg,
double rx_gain_off);
void nr_rf_card_config_gain(openair0_config_t *openair0_cfg);
void nr_rf_card_config_freq(openair0_config_t *openair0_cfg,
uint64_t ul_Carrier,
@@ -34,9 +34,9 @@
extern PHY_VARS_NR_UE ***PHY_vars_UE_g;
void nr_get_carrier_frequencies(PHY_VARS_NR_UE *ue, uint64_t *dl_carrier, uint64_t *ul_carrier){
NR_DL_FRAME_PARMS *fp = &ue->frame_parms;
void nr_get_carrier_frequencies(const PHY_VARS_NR_UE *ue, uint64_t *dl_carrier, uint64_t *ul_carrier)
{
const NR_DL_FRAME_PARMS *fp = &ue->frame_parms;
if (ue->if_freq!=0) {
*dl_carrier = ue->if_freq;
*ul_carrier = *dl_carrier + ue->if_freq_off;
@@ -47,12 +47,8 @@ void nr_get_carrier_frequencies(PHY_VARS_NR_UE *ue, uint64_t *dl_carrier, uint64
}
}
void nr_rf_card_config_gain(openair0_config_t *openair0_cfg,
double rx_gain_off){
void nr_rf_card_config_gain(openair0_config_t *openair0_cfg)
{
uint8_t mod_id = 0;
uint8_t cc_id = 0;
PHY_VARS_NR_UE *ue = PHY_vars_UE_g[mod_id][cc_id];
@@ -65,7 +61,7 @@ void nr_rf_card_config_gain(openair0_config_t *openair0_cfg,
if (tx_gain)
openair0_cfg->tx_gain[i] = tx_gain;
if (rx_gain)
openair0_cfg->rx_gain[i] = rx_gain - rx_gain_off;
openair0_cfg->rx_gain[i] = rx_gain;
openair0_cfg->autocal[i] = 1;
+3 -2
View File
@@ -18,7 +18,7 @@ typedef struct {
#define SquaredNorm(VaR) ((VaR).r*(VaR).r+(VaR).i*(VaR).i)
typedef struct {
void ** samplesRx;
openair0_device *rfdevice;
openair0_device_t *rfdevice;
} calibData_t;
typedef struct OAIgraph {
@@ -384,7 +384,8 @@ static void *scopeThread(void *arg) {
return NULL;
}
void CalibrationInitScope(void ** samplesRx,openair0_device *rfdevice) {
void CalibrationInitScope(void **samplesRx, openair0_device_t *rfdevice)
{
pthread_t forms_thread;
calibData_t *tmp = (calibData_t *)malloc_or_fail(sizeof(*tmp));
tmp->samplesRx=samplesRx;
+1 -1
View File
@@ -1,5 +1,5 @@
#ifndef CALIB_SCOPE_H
#define CALIB_SCOPE_H
void CalibrationInitScope(void ** samplesRx,openair0_device *rfdevice);
void CalibrationInitScope(void **samplesRx, openair0_device_t *rfdevice);
#endif
+2 -10
View File
@@ -110,14 +110,6 @@ int main(int argc, char **argv) {
.autocal={0},
//! Configuration file for LMS7002M
.configFilename="",
//! remote IP/MAC addr for Ethernet interface
.remote_addr="",
//! remote port number for Ethernet interface
.remote_port=0,
//! local IP/MAC addr for Ethernet interface (eNB/BBU, UE)
.my_addr=0,
//! local port number for Ethernet interface (eNB/BBU, UE)
.my_port=0,
//! record player configuration, definition in record_player.h
.recplay_mode=0,
.recplay_conf=NULL,
@@ -125,7 +117,7 @@ int main(int argc, char **argv) {
.samples_per_tti=0,
};
//-----------------------
openair0_device rfdevice= {
openair0_device_t rfdevice= {
/*!tx write thread*/
//.write_thread={0},
/*!brief Module ID of this device */
@@ -306,7 +298,7 @@ int main(int argc, char **argv) {
}
CalibrationInitScope(samplesRx, &rfdevice);
openair0_timestamp timestamp=0;
openair0_timestamp_t timestamp=0;
rfdevice.trx_start_func(&rfdevice);
while(!oai_exit) {
+11 -11
View File
@@ -222,7 +222,7 @@ typedef struct {
/// Context data structure for RX/TX portion of subframe processing
typedef struct {
/// timestamp transmitted to HW
openair0_timestamp timestamp_tx;
openair0_timestamp_t timestamp_tx;
/// subframe to act upon for transmission
int subframe_tx;
/// subframe to act upon for reception
@@ -273,9 +273,9 @@ typedef struct eNB_proc_NB_IoT_t_s {
/// thread index
int thread_index;
/// timestamp received from HW
openair0_timestamp timestamp_rx;
openair0_timestamp_t timestamp_rx;
/// timestamp to send to "slave rru"
openair0_timestamp timestamp_tx;
openair0_timestamp_t timestamp_tx;
/// subframe to act upon for reception
int subframe_rx;
/// symbol mask for IF4p5 reception per subframe
@@ -414,7 +414,7 @@ typedef struct {
/// index of the current UE RX/TX proc
int proc_id;
/// timestamp transmitted to HW
openair0_timestamp timestamp_tx;
openair0_timestamp_t timestamp_tx;
/// subframe to act upon for transmission
int subframe_tx;
/// subframe to act upon for reception
@@ -445,7 +445,7 @@ typedef struct {
/// Context data structure for eNB subframe processing
typedef struct {
/// Last RX timestamp
openair0_timestamp timestamp_rx;
openair0_timestamp_t timestamp_rx;
/// pthread attributes for main UE thread
pthread_attr_t attr_ue;
/// scheduling parameters for main UE thread
@@ -484,9 +484,9 @@ typedef struct PHY_VARS_eNB_NB_IoT_s {
eth_params_t eth_params_n;
/// Ethernet parameters for fronthaul interface (upper L1 to Radio head)
eth_params_t eth_params;
openair0_rf_map rf_map;
openair0_rf_map_t rf_map;
int abstraction_flag;
openair0_timestamp ts_offset;
openair0_timestamp_t ts_offset;
// indicator for synchronization state of eNB
int in_synch;
// indicator for master/slave (RRU)
@@ -672,8 +672,8 @@ typedef struct PHY_VARS_eNB_NB_IoT_s {
int32_t pusch_stats_BO[NUMBER_OF_UE_MAX][10240];
/// RF and Interface devices per CC
openair0_device rfdevice;
openair0_device ifdevice;
openair0_device_t rfdevice;
openair0_device_t ifdevice;
/// Pointer for ifdevice buffer struct
if_buffer_t ifbuffer;
@@ -731,7 +731,7 @@ typedef struct {
/// \brief Module ID indicator for this instance
uint8_t Mod_id;
/// \brief Mapping of CC_id antennas to cards
openair0_rf_map rf_map;
openair0_rf_map_t rf_map;
//uint8_t local_flag;
/// \brief Indicator of current run mode of UE (normal_txrx, rx_calib_ue, no_L2_connect, debug_prach)
runmode_NB_IoT_t mode;
@@ -956,7 +956,7 @@ typedef struct {
time_stats_t tx_prach;
/// RF and Interface devices per CC
openair0_device rfdevice;
openair0_device_t rfdevice;
time_stats_t dlsch_encoding_SIC_stats;
time_stats_t dlsch_scrambling_SIC_stats;
time_stats_t dlsch_modulation_SIC_stats;
+8 -8
View File
@@ -196,9 +196,9 @@ typedef struct RU_proc_t_s {
/// Pointer to associated RU descriptor
struct RU_t_s *ru;
/// timestamp received from HW
openair0_timestamp timestamp_rx;
openair0_timestamp_t timestamp_rx;
/// timestamp to send to "slave rru"
openair0_timestamp timestamp_tx;
openair0_timestamp_t timestamp_tx;
/// subframe (LTE) / slot (NR) to act upon for reception
int tti_rx;
/// subframe (LTE) / slot (NR) to act upon for transmission
@@ -354,7 +354,7 @@ typedef struct RU_proc_t_s {
/// subframe to act upon for transmission
int subframe_phy_tx;
/// timestamp to send to "slave rru"
openair0_timestamp timestamp_phy_tx;
openair0_timestamp_t timestamp_phy_tx;
/// pthread structure for RF TX thread
pthread_t pthread_rf_tx;
pthread_mutex_t mutex_rf_tx;
@@ -500,7 +500,7 @@ typedef struct RU_t_s {
/// "end of burst delay" used in TDD (unit: number of samples at 30.72MHz) (this is an expert option)
int end_of_burst_delay;
/// RF device descriptor
openair0_device rfdevice;
openair0_device_t rfdevice;
/// HW configuration
openair0_config_t openair0_cfg;
/// Number of NBs using this RU
@@ -510,9 +510,9 @@ typedef struct RU_t_s {
struct PHY_VARS_eNB_s *eNB_list[NUMBER_OF_eNB_MAX];
struct PHY_VARS_gNB_s *gNB_list[NUMBER_OF_gNB_MAX];
/// Mapping of antenna ports to RF chain index
openair0_rf_map rf_map;
openair0_rf_map_t rf_map;
/// IF device descriptor
openair0_device ifdevice;
openair0_device_t ifdevice;
/// Pointer for ifdevice buffer struct
if_buffer_t ifbuffer;
/// if prach processing is to be performed in RU
@@ -599,7 +599,7 @@ typedef struct RU_t_s {
/// sequence number for IF5
uint8_t seqno;
/// initial timestamp used as an offset make first real timestamp 0
openair0_timestamp ts_offset;
openair0_timestamp_t ts_offset;
/// Current state of the RU
rru_state_t state;
/// Command to do
@@ -758,7 +758,7 @@ typedef struct processingData_RU {
int frame_tx;
int slot_tx;
int next_slot;
openair0_timestamp timestamp_tx;
openair0_timestamp_t timestamp_tx;
RU_t *ru;
} processingData_RU_t;
#endif //__PHY_DEFS_RU__H__
+4 -4
View File
@@ -91,7 +91,7 @@ typedef struct {
/// Component Carrier index
uint8_t CC_id;
/// timestamp transmitted to HW
openair0_timestamp timestamp_tx;
openair0_timestamp_t timestamp_tx;
/// subframe to act upon for transmission
int subframe_tx;
/// subframe to act upon for reception
@@ -148,7 +148,7 @@ typedef struct {
/// Component Carrier index
uint8_t CC_id;
/// Last RX timestamp
openair0_timestamp timestamp_rx;
openair0_timestamp_t timestamp_rx;
/// pthread attributes for main UE thread
pthread_attr_t attr_ue;
/// scheduling parameters for main UE thread
@@ -550,7 +550,7 @@ typedef struct {
/// \brief Component carrier ID for this PHY instance
uint8_t CC_id;
/// \brief Mapping of CC_id antennas to cards
openair0_rf_map rf_map;
openair0_rf_map_t rf_map;
//uint8_t local_flag;
/// \brief Indicator of current run mode of UE (normal_txrx, rx_calib_ue, no_L2_connect, debug_prach)
runmode_t mode;
@@ -817,7 +817,7 @@ typedef struct {
int instance_cnt_timer;
/// RF and Interface devices per CC
openair0_device rfdevice;
openair0_device_t rfdevice;
void *scopeData;
} PHY_VARS_UE;
+4 -4
View File
@@ -218,8 +218,8 @@ typedef struct {
/// Component Carrier index
uint8_t CC_id;
/// timestamp transmitted to HW
openair0_timestamp timestamp_tx;
openair0_timestamp timestamp_rx;
openair0_timestamp_t timestamp_tx;
openair0_timestamp_t timestamp_rx;
/// subframe to act upon for transmission
int subframe_tx;
/// subframe to act upon for reception
@@ -285,9 +285,9 @@ typedef struct L1_proc_t_s {
/// thread index
int thread_index;
/// timestamp received from HW
openair0_timestamp timestamp_rx;
openair0_timestamp_t timestamp_rx;
/// timestamp to send to "slave rru"
openair0_timestamp timestamp_tx;
openair0_timestamp_t timestamp_tx;
/// subframe to act upon for reception
int subframe_rx;
/// subframe to act upon for PRACH
+5 -5
View File
@@ -288,7 +288,7 @@ typedef struct {
/// Component Carrier index
uint8_t CC_id;
/// timestamp transmitted to HW
openair0_timestamp timestamp_tx;
openair0_timestamp_t timestamp_tx;
/// slot to act upon for transmission
int slot_tx;
/// slot to act upon for reception
@@ -312,9 +312,9 @@ typedef struct gNB_L1_proc_t_s {
/// Component Carrier index
uint8_t CC_id;
/// timestamp received from HW
openair0_timestamp timestamp_rx;
openair0_timestamp_t timestamp_rx;
/// timestamp to send to "slave rru"
openair0_timestamp timestamp_tx;
openair0_timestamp_t timestamp_tx;
/// slot to act upon for reception
int slot_rx;
/// frame to act upon for reception
@@ -566,7 +566,7 @@ union ldpcReqUnion {
typedef struct processingData_L1 {
int frame_rx;
int slot_rx;
openair0_timestamp timestamp_tx;
openair0_timestamp_t timestamp_tx;
PHY_VARS_gNB *gNB;
notifiedFIFO_elt_t *elt;
} processingData_L1_t;
@@ -576,7 +576,7 @@ typedef struct processingData_L1tx {
int slot;
int frame_rx;
int slot_rx;
openair0_timestamp timestamp_tx;
openair0_timestamp_t timestamp_tx;
PHY_VARS_gNB *gNB;
} processingData_L1tx_t;
+31 -7
View File
@@ -113,7 +113,7 @@ typedef struct {
/// Component Carrier index
uint8_t CC_id;
/// Last RX timestamp
openair0_timestamp timestamp_rx;
openair0_timestamp_t timestamp_rx;
} UE_nr_proc_t;
typedef enum {
@@ -342,15 +342,42 @@ typedef struct UE_NR_SCAN_INFO_s {
int32_t freq_offset_Hz[3][10];
} UE_NR_SCAN_INFO_t;
typedef struct {
unsigned int nb_tx;
unsigned int nb_rx;
unsigned int att_tx;
unsigned int att_rx;
int max_rxgain;
char *sdr_addrs;
char *tx_subdev;
char *rx_subdev;
clock_source_t clock_source;
clock_source_t time_source;
double tune_offset;
uint64_t if_frequency;
int if_freq_offset;
int used_by_cell;
} nrUE_RU_params_t;
typedef struct {
int ru_id;
int band;
uint64_t rf_frequency;
int64_t rf_freq_offset;
int numerology;
int N_RB_DL;
int ssb_start;
int used_by_ue;
} nrUE_cell_params_t;
/// Top-level PHY Data Structure for UE
typedef struct PHY_VARS_NR_UE_s {
openair0_config_t openair0_cfg[MAX_CARDS];
/// \brief Module ID indicator for this instance
uint8_t Mod_id;
/// \brief Component carrier ID for this PHY instance
uint8_t CC_id;
/// \brief Mapping of CC_id antennas to cards
openair0_rf_map rf_map;
openair0_rf_map_t rf_map;
/// \brief Indicator that UE should perform band scanning
int UE_scan;
/// \brief Indicator that UE should perform coarse scanning around carrier
@@ -507,9 +534,6 @@ typedef struct PHY_VARS_NR_UE_s {
time_stats_t ue_ul_indication_stats;
nr_ue_phy_cpu_stat_t phy_cpu_stats;
/// RF and Interface devices per CC
openair0_device rfdevice;
/// Phase precompensation flag
bool no_phase_pre_comp;
@@ -540,7 +564,7 @@ typedef struct PHY_VARS_NR_UE_s {
} PHY_VARS_NR_UE;
typedef struct {
openair0_timestamp timestamp_tx;
openair0_timestamp_t timestamp_tx;
int gNB_id;
/// NR slot index within frame_tx [0 .. slots_per_frame - 1] to act upon for transmission
int nr_slot_tx;
+1 -1
View File
@@ -334,7 +334,7 @@ uint32_t get_samples_slot_duration(const NR_DL_FRAME_PARMS *fp, unsigned int sta
// Get timestamp of slot from start of frame
uint32_t get_samples_slot_timestamp(const NR_DL_FRAME_PARMS *fp, unsigned int slot);
// Get slot from timestamp
uint32_t get_slot_from_timestamp(openair0_timestamp timestamp_rx, const NR_DL_FRAME_PARMS *fp);
uint32_t get_slot_from_timestamp(openair0_timestamp_t timestamp_rx, const NR_DL_FRAME_PARMS *fp);
// Get number of samples in the slot
uint32_t get_samples_per_slot(int slot, const NR_DL_FRAME_PARMS *fp);
@@ -229,7 +229,7 @@ int psbch_pscch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr
sym = (sym == 0) ? 5 : sym + 1;
}
ue->adjust_rxgain = nr_sl_psbch_rsrp_measurements(sl_phy_params, fp, rxdataF, false, ue->openair0_cfg);
ue->adjust_rxgain = nr_sl_psbch_rsrp_measurements(ue, sl_phy_params, fp, rxdataF, false);
LOG_D(NR_PHY, " ------ Decode SL-MIB: frame.slot %d.%d ------ \n", frame_rx % 1024, nr_slot_rx);
+1 -1
View File
@@ -19,7 +19,7 @@
* contact@openairinterface.org
*/
openair0_device openair0;
openair0_device_t openair0;
int oai_exit=0;
void exit_function(const char* file, const char* function, const int line,const char* s, const int assert) {
-1
View File
@@ -67,7 +67,6 @@ uint8_t const nr_rv_round_map[4] = {0, 2, 3, 1};
// needed for some functions
PHY_VARS_NR_UE *PHY_vars_UE_g[1][1] = { { NULL } };
uint16_t n_rnti = 0x1234;
openair0_config_t openair0_cfg[MAX_CARDS];
static softmodem_params_t softmodem_params;
softmodem_params_t *get_softmodem_params(void) {
return &softmodem_params;
+1 -1
View File
@@ -932,7 +932,7 @@ int main(int argc, char **argv)
init_nr_ue_transport(UE);
UE_mac = nr_l2_init_ue(0);
UE_mac = nr_l2_init_ue(0, mu);
ue_init_config_request(UE_mac, get_slots_per_frame_from_scs(mu));
UE->if_inst = nr_ue_if_module_init(0);
-1
View File
@@ -77,7 +77,6 @@ PHY_VARS_NR_UE *UE;
RAN_CONTEXT_t RC;
RU_t *ru;
double cpuf;
openair0_config_t openair0_cfg[MAX_CARDS];
//uint8_t nfapi_mode=0;
uint64_t downlink_frequency[MAX_NUM_CCs][4];
int32_t uplink_frequency_offset[MAX_NUM_CCs][4];
-1
View File
@@ -54,7 +54,6 @@ THREAD_STRUCT thread_struct;
PHY_VARS_gNB *gNB;
PHY_VARS_NR_UE *UE;
RAN_CONTEXT_t RC;
openair0_config_t openair0_cfg[MAX_CARDS];
int32_t uplink_frequency_offset[MAX_NUM_CCs][4];
uint64_t downlink_frequency[MAX_NUM_CCs][4];
-1
View File
@@ -73,7 +73,6 @@ double cpuf;
// needed for some functions
PHY_VARS_NR_UE *PHY_vars_UE_g[1][1] = { { NULL } };
uint16_t n_rnti = 0x1234;
openair0_config_t openair0_cfg[MAX_CARDS];
void inc_ref_sched_response(int _)
{
+1 -1
View File
@@ -893,7 +893,7 @@ int main(int argc, char *argv[])
init_nr_ue_transport(UE);
//Configure UE
NR_UE_MAC_INST_t* UE_mac = nr_l2_init_ue(0);
NR_UE_MAC_INST_t* UE_mac = nr_l2_init_ue(0, mu);
ue_init_config_request(UE_mac, get_slots_per_frame_from_scs(mu));
@@ -123,17 +123,17 @@ Please refer to this documentation [telnetusage.md](../../../../common/utils/tel
When the `chanmod` option is enabled, the RF channel simulator with a channel modeling function is called. Add the following options to the command line to enable the channel model:
```bash
--rfsimulator.options chanmod
--rfsimulator.[0].options chanmod
```
Example run of OAI RFSIM on the same machine with activation of the channel model via command line:
gNB:
```bash
sudo ./nr-softmodem -O ../../../targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.conf --gNBs.[0].min_rxtxtime 6 --rfsim --rfsimulator.options chanmod --telnetsrv
sudo ./nr-softmodem -O ../../../targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.conf --gNBs.[0].min_rxtxtime 6 --rfsim --rfsimulator.[0].options chanmod --telnetsrv
```
UE:
```bash
sudo ./nr-uesoftmodem -r 106 --numerology 1 --band 78 -C 3619200000 --rfsim --rfsimulator.serveraddr 127.0.0.1 --uicc0.imsi 001010000000001 -O ../../../ci-scripts/conf_files/nrue.uicc.conf --rfsimulator.options chanmod
sudo ./nr-uesoftmodem -r 106 --numerology 1 --band 78 -C 3619200000 --rfsim --rfsimulator.[0].serveraddr 127.0.0.1 --uicc0.imsi 001010000000001 -O ../../../ci-scripts/conf_files/nrue.uicc.conf --rfsimulator.[0].options chanmod
```
where `@include "channelmod_rfsimu.conf"` has been added at the end of `ci-scripts/conf_files/channelmod_rfsimu.conf` which has been copied to `targets/PROJECTS/GENERIC-LTE-EPC/CONF/`.
@@ -175,7 +175,7 @@ Example usage, set the offset for the selected model of the selected `modellist`
e.g. with the softmodem:
```bash
sudo ./nr-softmodem -O ../../../targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.conf --gNBs.[0].min_rxtxtime 6 --rfsim --rfsimulator.options chanmod --telnetsrv --channelmod.modellist modellist_rfsimu_2 --channelmod.modellist_rfsimu_2.[1].offset 120
sudo ./nr-softmodem -O ../../../targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.conf --gNBs.[0].min_rxtxtime 6 --rfsim --rfsimulator.[0].options chanmod --telnetsrv --channelmod.modellist modellist_rfsimu_2 --channelmod.modellist_rfsimu_2.[1].offset 120
```
## Real time control and monitoring with telnet server
+2 -2
View File
@@ -328,8 +328,8 @@ typedef struct {
int RU_output_mask[NUMBER_OF_UE_MAX];
pthread_mutex_t RU_output_mutex[NUMBER_OF_UE_MAX];
pthread_mutex_t UE_output_mutex[NUMBER_OF_RU_MAX];
openair0_timestamp current_ru_rx_timestamp[NUMBER_OF_RU_MAX][MAX_NUM_CCs];
openair0_timestamp current_UE_rx_timestamp[MAX_MOBILES_PER_ENB][MAX_NUM_CCs];
openair0_timestamp_t current_ru_rx_timestamp[NUMBER_OF_RU_MAX][MAX_NUM_CCs];
openair0_timestamp_t current_UE_rx_timestamp[MAX_MOBILES_PER_ENB][MAX_NUM_CCs];
double ru_amp[NUMBER_OF_RU_MAX];
} sim_t;