Merge remote-tracking branch 'origin/multi-ue-test' into integration_2025_w35 (!3425)

RFSim test for 10 UEs/process

This MR adds a testcase and changes required to run 10 UEs in a single
process with RFSim

- Added deregistration for all connected UEs
- Refactored MAC/RRC instance handling
- made map_current_symbol thread safe
- made opeanir0_cfg thread safe and local
- Added 10UE/process testcase
This commit is contained in:
Robert Schmidt
2025-08-28 08:59:05 +02:00
31 changed files with 877 additions and 286 deletions
-1
View File
@@ -126,7 +126,6 @@ extern int32_t uplink_frequency_offset[MAX_NUM_CCs][4];
extern int oai_exit;
extern openair0_config_t openair0_cfg[MAX_CARDS];
extern pthread_cond_t sync_cond;
extern pthread_mutex_t sync_mutex;
extern int sync_var;
+24 -25
View File
@@ -414,7 +414,7 @@ static void UE_synch(void *arg) {
syncData_t *syncD = (syncData_t *)arg;
PHY_VARS_NR_UE *UE = syncD->UE;
UE->is_synchronized = 0;
openair0_config_t *cfg0 = &openair0_cfg[UE->rf_map.card];
openair0_config_t *cfg0 = &UE->openair0_cfg[UE->rf_map.card];
if (UE->target_Nid_cell != -1) {
LOG_W(NR_PHY, "Starting re-sync detection for target Nid_cell %i\n", UE->target_Nid_cell);
@@ -523,7 +523,7 @@ static void RU_write(nr_rxtx_thread_data_t *rxtxD, bool sl_tx_action, c16_t **tx
radio_tx_burst_flag_t flags = TX_BURST_INVALID;
if (UE->received_config_request) {
if (openair0_cfg[0].duplex_mode == duplex_mode_FDD || get_softmodem_params()->continuous_tx) {
if (UE->openair0_cfg[0].duplex_mode == duplex_mode_FDD || get_softmodem_params()->continuous_tx) {
flags = TX_BURST_MIDDLE;
// In case of Sidelink, USRP write needed only in case transmission
// needs to be done in this slot and not based on tdd ULDL configuration.
@@ -696,8 +696,8 @@ static int handle_sync_req_from_mac(PHY_VARS_NR_UE *UE)
if (dl_CarrierFreq != fp->dl_CarrierFreq || ul_CarrierFreq != fp->ul_CarrierFreq) {
fp->dl_CarrierFreq = dl_CarrierFreq;
fp->ul_CarrierFreq = ul_CarrierFreq;
nr_rf_card_config_freq(&openair0_cfg[UE->rf_map.card], ul_CarrierFreq, dl_CarrierFreq, 0);
UE->rfdevice.trx_set_freq_func(&UE->rfdevice, &openair0_cfg[0]);
nr_rf_card_config_freq(&UE->openair0_cfg[UE->rf_map.card], ul_CarrierFreq, dl_CarrierFreq, 0);
UE->rfdevice.trx_set_freq_func(&UE->rfdevice, &UE->openair0_cfg[UE->rf_map.card]);
init_symbol_rotation(fp);
}
@@ -731,12 +731,14 @@ static int UE_dl_preprocessing(PHY_VARS_NR_UE *UE,
fp = &UE->SL_UE_PHY_PARAMS.sl_frame_params;
// process what RRC thread sent to MAC
MessageDef *msg = NULL;
do {
itti_poll_msg(TASK_MAC_UE, &msg);
if (msg)
process_msg_rcc_to_mac(msg);
} while (msg);
notifiedFIFO_elt_t *elt = pollNotifiedFIFO(&get_mac_inst(UE->Mod_id)->input_nf);
if (!elt) {
break;
}
process_msg_rcc_to_mac(NotifiedFifoData(elt), UE->Mod_id);
delNotifiedFIFO_elt(elt);
} while (true);
if (UE->if_inst)
UE->if_inst->slot_indication(UE->Mod_id, false);
@@ -966,7 +968,7 @@ void *UE_thread(void *arg)
void *rxp[NB_ANTENNAS_RX];
enum stream_status_e stream_status = STREAM_STATUS_UNSYNC;
fapi_nr_config_request_t *cfg = &UE->nrUE_config;
int tmp = openair0_device_load(&(UE->rfdevice), &openair0_cfg[0]);
int tmp = openair0_device_load(&(UE->rfdevice), &UE->openair0_cfg[0]);
AssertFatal(tmp == 0, "Could not load the device\n");
NR_DL_FRAME_PARMS *fp = &UE->frame_parms;
sl_nr_phy_config_request_t *sl_cfg = NULL;
@@ -1032,12 +1034,10 @@ void *UE_thread(void *arg)
decoded_frame_rx = UE->SL_UE_PHY_PARAMS.sync_params.DFN;
else {
// We must wait the RRC layer decoded the MIB and sent us the frame number
MessageDef *msg = NULL;
itti_receive_msg(TASK_MAC_UE, &msg);
if (msg)
process_msg_rcc_to_mac(msg);
else
LOG_E(PHY, "It seems we arbort while trying to sync\n");
notifiedFIFO_elt_t *elt = pullNotifiedFIFO(&mac->input_nf);
AssertFatal(elt != NULL, "fifo error while waiting for MIB");
process_msg_rcc_to_mac(NotifiedFifoData(elt), UE->Mod_id);
delNotifiedFIFO_elt(elt);
decoded_frame_rx = mac->mib_frame;
}
LOG_A(PHY,
@@ -1284,20 +1284,19 @@ void *UE_thread(void *arg)
void init_NR_UE(int nb_inst, char *uecap_file, char *reconfig_file, char *rbconfig_file)
{
NR_UE_RRC_INST_t *rrc_inst = nr_rrc_init_ue(uecap_file, nb_inst, get_nrUE_params()->nb_antennas_tx);
NR_UE_MAC_INST_t *mac_inst = nr_l2_init_ue(nb_inst);
AssertFatal(mac_inst, "Couldn't allocate MAC module\n");
for (int instance_id = 0; instance_id < nb_inst; instance_id++) {
NR_UE_RRC_INST_t* rrc = nr_rrc_init_ue(uecap_file, instance_id, get_nrUE_params()->nb_antennas_tx);
NR_UE_MAC_INST_t *mac = nr_l2_init_ue(instance_id);
for (int i = 0; i < nb_inst; i++) {
NR_UE_MAC_INST_t *mac = get_mac_inst(i);
mac->if_module = nr_ue_if_module_init(i);
nr_rrc_set_mac_queue(instance_id, &mac->input_nf);
mac->if_module = nr_ue_if_module_init(instance_id);
AssertFatal(mac->if_module, "can not initialize IF module\n");
if (!IS_SA_MODE(get_softmodem_params()) && !get_softmodem_params()->sl_mode) {
init_nsa_message(&rrc_inst[i], reconfig_file, rbconfig_file);
nr_rlc_activate_srb0(mac_inst[i].crnti, NULL, send_srb0_rrc);
init_nsa_message(rrc, reconfig_file, rbconfig_file);
nr_rlc_activate_srb0(mac->crnti, NULL, send_srb0_rrc);
}
//TODO: Move this call to RRC
start_sidelink((&rrc_inst[i])->ue_id);
start_sidelink(instance_id);
}
}
+46 -43
View File
@@ -121,8 +121,6 @@ int32_t uplink_frequency_offset[MAX_NUM_CCs][4];
uint64_t sidelink_frequency[MAX_NUM_CCs][4];
// UE and OAI config variables
openair0_config_t openair0_cfg[MAX_CARDS];
int16_t node_synch_ref[MAX_NUM_CCs];
int otg_enabled;
double cpuf;
@@ -249,41 +247,42 @@ void set_options(int CC_id, PHY_VARS_NR_UE *UE){
}
static void init_openair0()
void init_openair0(PHY_VARS_NR_UE *ue)
{
int card;
int freq_off = 0;
NR_DL_FRAME_PARMS *frame_parms = &PHY_vars_UE_g[0][0]->frame_parms;
NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
bool is_sidelink = (get_softmodem_params()->sl_mode) ? true : false;
if (is_sidelink)
frame_parms = &PHY_vars_UE_g[0][0]->SL_UE_PHY_PARAMS.sl_frame_params;
frame_parms = &ue->SL_UE_PHY_PARAMS.sl_frame_params;
for (card=0; card<MAX_CARDS; card++) {
openair0_config_t *cfg = &ue->openair0_cfg[card];
uint64_t dl_carrier, ul_carrier;
openair0_cfg[card].configFilename = NULL;
openair0_cfg[card].sample_rate = frame_parms->samples_per_subframe * 1e3;
openair0_cfg[card].samples_per_frame = frame_parms->samples_per_frame;
cfg->configFilename = NULL;
cfg->sample_rate = frame_parms->samples_per_subframe * 1e3;
cfg->samples_per_frame = frame_parms->samples_per_frame;
if (frame_parms->frame_type==TDD)
openair0_cfg[card].duplex_mode = duplex_mode_TDD;
cfg->duplex_mode = duplex_mode_TDD;
else
openair0_cfg[card].duplex_mode = duplex_mode_FDD;
cfg->duplex_mode = duplex_mode_FDD;
openair0_cfg[card].Mod_id = 0;
openair0_cfg[card].num_rb_dl = frame_parms->N_RB_DL;
openair0_cfg[card].clock_source = get_softmodem_params()->clock_source;
openair0_cfg[card].time_source = get_softmodem_params()->timing_source;
openair0_cfg[card].tune_offset = get_softmodem_params()->tune_offset;
openair0_cfg[card].tx_num_channels = min(4, frame_parms->nb_antennas_tx);
openair0_cfg[card].rx_num_channels = min(4, frame_parms->nb_antennas_rx);
cfg->Mod_id = 0;
cfg->num_rb_dl = frame_parms->N_RB_DL;
cfg->clock_source = get_softmodem_params()->clock_source;
cfg->time_source = get_softmodem_params()->timing_source;
cfg->tune_offset = get_softmodem_params()->tune_offset;
cfg->tx_num_channels = min(4, frame_parms->nb_antennas_tx);
cfg->rx_num_channels = min(4, frame_parms->nb_antennas_rx);
LOG_I(PHY,
"HW: Configuring card %d, sample_rate %f, tx/rx num_channels %d/%d, duplex_mode %s\n",
card,
openair0_cfg[card].sample_rate,
openair0_cfg[card].tx_num_channels,
openair0_cfg[card].rx_num_channels,
duplex_mode_txt[openair0_cfg[card].duplex_mode]);
cfg->sample_rate,
cfg->tx_num_channels,
cfg->rx_num_channels,
duplex_mode_txt[cfg->duplex_mode]);
if (is_sidelink) {
dl_carrier = frame_parms->dl_CarrierFreq;
@@ -291,16 +290,18 @@ static void init_openair0()
} else
nr_get_carrier_frequencies(PHY_vars_UE_g[0][0], &dl_carrier, &ul_carrier);
nr_rf_card_config_freq(&openair0_cfg[card], ul_carrier, dl_carrier, freq_off);
nr_rf_card_config_freq(cfg, ul_carrier, dl_carrier, freq_off);
nr_rf_card_config_gain(&openair0_cfg[card], rx_gain_off);
nr_rf_card_config_gain(cfg, rx_gain_off);
openair0_cfg[card].configFilename = get_softmodem_params()->rf_config_file;
if (get_nrUE_params()->usrp_args) openair0_cfg[card].sdr_addrs = get_nrUE_params()->usrp_args;
if (get_nrUE_params()->tx_subdev) openair0_cfg[card].tx_subdev = get_nrUE_params()->tx_subdev;
if (get_nrUE_params()->rx_subdev) openair0_cfg[card].rx_subdev = get_nrUE_params()->rx_subdev;
cfg->configFilename = get_softmodem_params()->rf_config_file;
if (get_nrUE_params()->usrp_args)
cfg->sdr_addrs = get_nrUE_params()->usrp_args;
if (get_nrUE_params()->tx_subdev)
cfg->tx_subdev = get_nrUE_params()->tx_subdev;
if (get_nrUE_params()->rx_subdev)
cfg->rx_subdev = get_nrUE_params()->rx_subdev;
}
}
@@ -326,9 +327,11 @@ static void trigger_stop(int sig)
static void trigger_deregistration(int sig)
{
if (!stop_immediately && IS_SA_MODE(get_softmodem_params())) {
MessageDef *msg = itti_alloc_new_message(TASK_NAS_NRUE, 0, NAS_DEREGISTRATION_REQ);
NAS_DEREGISTRATION_REQ(msg).cause = AS_DETACH;
itti_send_msg_to_task(TASK_NAS_NRUE, 0, msg);
for (int ue_inst = 0; ue_inst < NB_UE_INST; ue_inst++) {
MessageDef *msg = itti_alloc_new_message(TASK_NAS_NRUE, ue_inst, NAS_DEREGISTRATION_REQ);
NAS_DEREGISTRATION_REQ(msg).cause = AS_DETACH;
itti_send_msg_to_task(TASK_NAS_NRUE, ue_inst, msg);
}
stop_immediately = true;
static const char m[] = "Press ^C again to trigger immediate shutdown\n";
__attribute__((unused)) int unused = write(STDOUT_FILENO, m, sizeof(m) - 1);
@@ -386,7 +389,6 @@ int main(int argc, char **argv)
}
//set_softmodem_sighandler();
CONFIG_SETRTFLAG(CONFIG_NOEXITONHELP);
memset(openair0_cfg,0,sizeof(openair0_config_t)*MAX_CARDS);
memset(tx_max_power,0,sizeof(int)*MAX_NUM_CCs);
// initialize logging
logInit();
@@ -425,12 +427,11 @@ int main(int argc, char **argv)
char *pckg = strdup(OAI_PACKAGE_VERSION);
LOG_I(HW, "Version: %s\n", pckg);
PHY_vars_UE_g = malloc(sizeof(*PHY_vars_UE_g) * NB_UE_INST);
PHY_vars_UE_g = calloc_or_fail(NB_UE_INST, sizeof(*PHY_vars_UE_g));
for (int inst = 0; inst < NB_UE_INST; inst++) {
PHY_vars_UE_g[inst] = malloc(sizeof(*PHY_vars_UE_g[inst]) * MAX_NUM_CCs);
PHY_vars_UE_g[inst] = calloc_or_fail(MAX_NUM_CCs, sizeof(*PHY_vars_UE_g[inst]));
for (int CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
PHY_vars_UE_g[inst][CC_id] = malloc(sizeof(*PHY_vars_UE_g[inst][CC_id]));
memset(PHY_vars_UE_g[inst][CC_id], 0, sizeof(*PHY_vars_UE_g[inst][CC_id]));
PHY_vars_UE_g[inst][CC_id] = calloc_or_fail(1, sizeof(*PHY_vars_UE_g[inst][CC_id]));
// All instances use the same coding interface
PHY_vars_UE_g[inst][CC_id]->nrLDPC_coding_interface = nrLDPC_coding_interface;
}
@@ -498,12 +499,14 @@ int main(int argc, char **argv)
get_softmodem_params()->numerology,
nr_band);
} else {
MessageDef *msg = NULL;
do {
itti_poll_msg(TASK_MAC_UE, &msg);
if (msg)
process_msg_rcc_to_mac(msg);
} while (msg);
do {
notifiedFIFO_elt_t *elt = pollNotifiedFIFO(&mac->input_nf);
if (!elt) {
break;
}
process_msg_rcc_to_mac(NotifiedFifoData(elt), inst);
delNotifiedFIFO_elt(elt);
} while (true);
fapi_nr_config_request_t *nrUE_config = &UE[CC_id]->nrUE_config;
nr_init_frame_parms_ue(&UE[CC_id]->frame_parms, nrUE_config, mac->nr_band);
}
@@ -538,10 +541,10 @@ int main(int argc, char **argv)
get_nrUE_params()->ofdm_offset_divisor);
sl_ue_phy_init(UE[CC_id]);
}
init_openair0(UE[CC_id]);
}
}
init_openair0();
lock_memory_to_ram();
if (IS_SOFTMODEM_DOSCOPE) {
+1
View File
@@ -5,6 +5,7 @@
#include "common/utils/threadPool/thread-pool.h"
#include "PHY/defs_nr_UE.h"
#define MAX_NUM_NR_UE_INST 32
extern int NB_UE_INST;
extern uint16_t ue_id_g;