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:
+25
-19
@@ -271,7 +271,7 @@ static client_info_t client_read_info(char *descriptor_file)
|
||||
return client_info;
|
||||
}
|
||||
|
||||
static int vrtsim_connect(openair0_device *device)
|
||||
static int vrtsim_connect(openair0_device_t *device)
|
||||
{
|
||||
vrtsim_state_t *vrtsim_state = (vrtsim_state_t *)device->priv;
|
||||
|
||||
@@ -332,7 +332,7 @@ static int vrtsim_connect(openair0_device *device)
|
||||
}
|
||||
|
||||
static int vrtsim_write_internal(vrtsim_state_t *vrtsim_state,
|
||||
openair0_timestamp timestamp,
|
||||
openair0_timestamp_t timestamp,
|
||||
c16_t *samples,
|
||||
int nsamps,
|
||||
int aarx,
|
||||
@@ -361,7 +361,7 @@ static int vrtsim_write_internal(vrtsim_state_t *vrtsim_state,
|
||||
|
||||
typedef struct {
|
||||
vrtsim_state_t *vrtsim_state;
|
||||
openair0_timestamp timestamp;
|
||||
openair0_timestamp_t timestamp;
|
||||
c16_t *samples[MAX_NUM_ANTENNAS_TX];
|
||||
int nsamps;
|
||||
int nbAnt;
|
||||
@@ -464,7 +464,7 @@ static void perform_channel_modelling(void *arg)
|
||||
}
|
||||
|
||||
static int vrtsim_write_with_chanmod(vrtsim_state_t *vrtsim_state,
|
||||
openair0_timestamp timestamp,
|
||||
openair0_timestamp_t timestamp,
|
||||
void **samplesVoid,
|
||||
int nsamps,
|
||||
int nbAnt,
|
||||
@@ -473,7 +473,7 @@ static int vrtsim_write_with_chanmod(vrtsim_state_t *vrtsim_state,
|
||||
// Sample history for channel impulse response
|
||||
static c16_t saved_samples[MAX_NUM_ANTENNAS_TX][SAVED_SAMPLES_LEN] __attribute__((aligned(32))) = {0};
|
||||
// Indicates what samples are saves in saved_samples
|
||||
static openair0_timestamp last_timestamp = 0;
|
||||
static openair0_timestamp_t last_timestamp = 0;
|
||||
const int batch_size = 4096;
|
||||
|
||||
AssertFatal(nbAnt <= MAX_NUM_ANTENNAS_TX, "Number of antennas %d exceeds maximum %d\n", nbAnt, MAX_NUM_ANTENNAS_TX);
|
||||
@@ -528,7 +528,12 @@ static int vrtsim_write_with_chanmod(vrtsim_state_t *vrtsim_state,
|
||||
return nsamps;
|
||||
}
|
||||
|
||||
static int vrtsim_write(openair0_device *device, openair0_timestamp timestamp, void **samplesVoid, int nsamps, int nbAnt, int flags)
|
||||
static int vrtsim_write(openair0_device_t *device,
|
||||
openair0_timestamp_t timestamp,
|
||||
void **samplesVoid,
|
||||
int nsamps,
|
||||
int nbAnt,
|
||||
int flags)
|
||||
{
|
||||
AssertFatal(nsamps > 0, "Number of samples must be greater than 0\n");
|
||||
AssertFatal(nbAnt > 0 && nbAnt <= MAX_NUM_ANTENNAS_TX,
|
||||
@@ -543,8 +548,8 @@ static int vrtsim_write(openair0_device *device, openair0_timestamp timestamp, v
|
||||
: vrtsim_write_internal(vrtsim_state, timestamp, (c16_t *)samplesVoid[0], nsamps, 0, flags, 0);
|
||||
}
|
||||
|
||||
static int vrtsim_write_beams(openair0_device *device,
|
||||
openair0_timestamp timestamp,
|
||||
static int vrtsim_write_beams(openair0_device_t *device,
|
||||
openair0_timestamp_t timestamp,
|
||||
void ***buff,
|
||||
int nsamps,
|
||||
int nb_antennas_tx,
|
||||
@@ -555,7 +560,7 @@ static int vrtsim_write_beams(openair0_device *device,
|
||||
return nsamps;
|
||||
}
|
||||
|
||||
static int vrtsim_read(openair0_device *device, openair0_timestamp *ptimestamp, void **samplesVoid, int nsamps, int nbAnt)
|
||||
static int vrtsim_read(openair0_device_t *device, openair0_timestamp_t *ptimestamp, void **samplesVoid, int nsamps, int nbAnt)
|
||||
{
|
||||
vrtsim_state_t *vrtsim_state = (vrtsim_state_t *)device->priv;
|
||||
if (shm_td_iq_channel_is_aborted(vrtsim_state->channel)) {
|
||||
@@ -594,7 +599,7 @@ static int vrtsim_read(openair0_device *device, openair0_timestamp *ptimestamp,
|
||||
return nsamps;
|
||||
}
|
||||
|
||||
static void vrtsim_end(openair0_device *device)
|
||||
static void vrtsim_end(openair0_device_t *device)
|
||||
{
|
||||
vrtsim_state_t *vrtsim_state = (vrtsim_state_t *)device->priv;
|
||||
if (vrtsim_state->role == ROLE_SERVER && vrtsim_state->run_timing_thread) {
|
||||
@@ -648,33 +653,34 @@ static void vrtsim_end(openair0_device *device)
|
||||
}
|
||||
}
|
||||
|
||||
static int vrtsim_stub(openair0_device *device)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
static int vrtsim_stub2(openair0_device *device, openair0_config_t *openair0_cfg)
|
||||
static int vrtsim_stub(openair0_device_t *device)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int vrtsim_set_freq(openair0_device *device, openair0_config_t *openair0_cfg)
|
||||
static int vrtsim_stub2(openair0_device_t *device, openair0_config_t *openair0_cfg)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int vrtsim_set_freq(openair0_device_t *device, openair0_config_t *openair0_cfg)
|
||||
{
|
||||
vrtsim_state_t *s = device->priv;
|
||||
s->rx_freq = openair0_cfg->rx_freq[0];
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int vrtsim_set_beams(openair0_device *device, uint64_t beam_map, openair0_timestamp timestamp)
|
||||
static int vrtsim_set_beams(openair0_device_t *device, uint64_t beam_map, openair0_timestamp_t timestamp)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int vrtsim_set_beams2(openair0_device *device, int *beam_ids, int num_beams, openair0_timestamp timestamp)
|
||||
static int vrtsim_set_beams2(openair0_device_t *device, int *beam_ids, int num_beams, openair0_timestamp_t timestamp)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
__attribute__((__visibility__("default"))) int device_init(openair0_device *device, openair0_config_t *openair0_cfg)
|
||||
__attribute__((__visibility__("default"))) int device_init(openair0_device_t *device, openair0_config_t *openair0_cfg)
|
||||
{
|
||||
randominit();
|
||||
vrtsim_state_t *vrtsim_state = calloc_or_fail(1, sizeof(vrtsim_state_t));
|
||||
|
||||
Reference in New Issue
Block a user