NR UE: fix reestablishment for NTN
During reestablishment the UE goes back to not synchronized state. While the synchronizatin is running, we trash frames using the function readFrame(). And when we successfully synchronize, we skip samples to align with the start of the frame using syncInFrame(). In rfsimulator mode, both of these functions send dummy data using the function dummyWrite(). Unfortunately, the writeTimestamp provided to that function was always assuming a duration from RX to TX of NR_UE_CAPABILITY_SLOT_RX_TO_TX. But in NTN mode, this value is changed when receiving SIB19. Therefore we have to consider this changed value instead of the static one.
This commit is contained in:
+21
-16
@@ -825,7 +825,8 @@ void dummyWrite(PHY_VARS_NR_UE *UE,openair0_timestamp timestamp, int writeBlockS
|
||||
AssertFatal(writeBlockSize == tmp, "");
|
||||
}
|
||||
|
||||
void readFrame(PHY_VARS_NR_UE *UE, openair0_timestamp *timestamp, bool toTrash) {
|
||||
void readFrame(PHY_VARS_NR_UE *UE, openair0_timestamp *timestamp, int duration_rx_to_tx, bool toTrash)
|
||||
{
|
||||
NR_DL_FRAME_PARMS *fp = &UE->frame_parms;
|
||||
// two frames for initial sync
|
||||
int num_frames = 2;
|
||||
@@ -853,7 +854,8 @@ void readFrame(PHY_VARS_NR_UE *UE, openair0_timestamp *timestamp, bool toTrash)
|
||||
AssertFatal(read_block_size == tmp, "");
|
||||
|
||||
if (IS_SOFTMODEM_RFSIM) {
|
||||
const openair0_timestamp writeTimestamp = *timestamp + fp->get_samples_slot_timestamp(slot, fp, NR_UE_CAPABILITY_SLOT_RX_TO_TX) - UE->N_TA_offset;
|
||||
const openair0_timestamp writeTimestamp =
|
||||
*timestamp + fp->get_samples_slot_timestamp(slot, fp, duration_rx_to_tx) - UE->N_TA_offset - UE->timing_advance;
|
||||
dummyWrite(UE, writeTimestamp, fp->get_samples_per_slot(slot, fp));
|
||||
}
|
||||
}
|
||||
@@ -864,7 +866,7 @@ void readFrame(PHY_VARS_NR_UE *UE, openair0_timestamp *timestamp, bool toTrash)
|
||||
free(rxp[i]);
|
||||
}
|
||||
|
||||
static void syncInFrame(PHY_VARS_NR_UE *UE, openair0_timestamp *timestamp, openair0_timestamp rx_offset)
|
||||
static void syncInFrame(PHY_VARS_NR_UE *UE, openair0_timestamp *timestamp, int duration_rx_to_tx, openair0_timestamp rx_offset)
|
||||
{
|
||||
NR_DL_FRAME_PARMS *fp = &UE->frame_parms;
|
||||
if (UE->sl_mode == 2)
|
||||
@@ -879,7 +881,8 @@ static void syncInFrame(PHY_VARS_NR_UE *UE, openair0_timestamp *timestamp, opena
|
||||
const int res = UE->rfdevice.trx_read_func(&UE->rfdevice, timestamp, (void **)UE->common_vars.rxdata, unitTransfer, fp->nb_antennas_rx);
|
||||
DevAssert(unitTransfer == res);
|
||||
if (IS_SOFTMODEM_RFSIM) {
|
||||
const openair0_timestamp writeTimestamp = *timestamp + fp->get_samples_slot_timestamp(slot, fp, NR_UE_CAPABILITY_SLOT_RX_TO_TX) - UE->N_TA_offset;
|
||||
const openair0_timestamp writeTimestamp =
|
||||
*timestamp + fp->get_samples_slot_timestamp(slot, fp, duration_rx_to_tx) - UE->N_TA_offset - UE->timing_advance;
|
||||
dummyWrite(UE, writeTimestamp, unitTransfer);
|
||||
}
|
||||
slot = (slot + 1) % fp->slots_per_subframe;
|
||||
@@ -965,6 +968,10 @@ void *UE_thread(void *arg)
|
||||
notifiedFIFO_t freeBlocks;
|
||||
initNotifiedFIFO_nothreadSafe(&freeBlocks);
|
||||
|
||||
double ntn_init_time_drift = get_nrUE_params()->ntn_init_time_drift;
|
||||
int ntn_koffset = 0;
|
||||
|
||||
int duration_rx_to_tx = NR_UE_CAPABILITY_SLOT_RX_TO_TX;
|
||||
int timing_advance = UE->timing_advance;
|
||||
UE->N_TA_offset = determine_N_TA_offset(UE);
|
||||
NR_UE_MAC_INST_t *mac = get_mac_inst(UE->Mod_id);
|
||||
@@ -988,13 +995,9 @@ void *UE_thread(void *arg)
|
||||
//warm up the RF board
|
||||
int64_t tmp;
|
||||
for (int i = 0; i < 50; i++)
|
||||
readFrame(UE, &tmp, true);
|
||||
readFrame(UE, &tmp, duration_rx_to_tx, true);
|
||||
}
|
||||
|
||||
double ntn_init_time_drift = get_nrUE_params()->ntn_init_time_drift;
|
||||
int ntn_koffset = 0;
|
||||
int duration_rx_to_tx = NR_UE_CAPABILITY_SLOT_RX_TO_TX;
|
||||
|
||||
while (!oai_exit) {
|
||||
if (syncRunning) {
|
||||
notifiedFIFO_elt_t *res = pollNotifiedFIFO(&nf);
|
||||
@@ -1034,11 +1037,11 @@ void *UE_thread(void *arg)
|
||||
*/
|
||||
const unsigned int sync_in_frames = UE->rfdevice.openair0_cfg->recplay_conf->u_f_sync;
|
||||
while (trashed_frames != sync_in_frames) {
|
||||
readFrame(UE, &sync_timestamp, true);
|
||||
readFrame(UE, &sync_timestamp, duration_rx_to_tx, true);
|
||||
trashed_frames += 2;
|
||||
}
|
||||
} else {
|
||||
readFrame(UE, &sync_timestamp, true);
|
||||
readFrame(UE, &sync_timestamp, duration_rx_to_tx, true);
|
||||
trashed_frames += ((UE->sl_mode == 2) ? SL_NR_PSBCH_REPETITION_IN_FRAMES : 2);
|
||||
}
|
||||
continue;
|
||||
@@ -1048,7 +1051,7 @@ void *UE_thread(void *arg)
|
||||
AssertFatal(!syncRunning, "At this point synchronization can't be running\n");
|
||||
|
||||
if (!UE->is_synchronized) {
|
||||
readFrame(UE, &sync_timestamp, false);
|
||||
readFrame(UE, &sync_timestamp, duration_rx_to_tx, false);
|
||||
notifiedFIFO_elt_t *Msg = newNotifiedFIFO_elt(sizeof(syncData_t), 0, &nf, UE_synch);
|
||||
syncData_t *syncMsg = (syncData_t *)NotifiedFifoData(Msg);
|
||||
*syncMsg = (syncData_t){0};
|
||||
@@ -1065,8 +1068,10 @@ void *UE_thread(void *arg)
|
||||
syncMsg->UE = UE;
|
||||
memset(&syncMsg->proc, 0, sizeof(syncMsg->proc));
|
||||
pushNotifiedFIFO(&UE->sync_actor.fifo, Msg);
|
||||
timing_advance = 0;
|
||||
UE->timing_advance = 0;
|
||||
if (ntn_koffset == 0) { // reset timing_advance for TN
|
||||
timing_advance = 0;
|
||||
UE->timing_advance = 0;
|
||||
}
|
||||
trashed_frames = 0;
|
||||
syncRunning = true;
|
||||
continue;
|
||||
@@ -1074,7 +1079,7 @@ void *UE_thread(void *arg)
|
||||
|
||||
if (stream_status == STREAM_STATUS_UNSYNC) {
|
||||
stream_status = STREAM_STATUS_SYNCING;
|
||||
syncInFrame(UE, &sync_timestamp, intialSyncOffset);
|
||||
syncInFrame(UE, &sync_timestamp, duration_rx_to_tx, intialSyncOffset);
|
||||
openair0_write_reorder_clear_context(&UE->rfdevice);
|
||||
if (get_nrUE_params()->time_sync_I)
|
||||
// ntn_init_time_drift is in µs/s, max_pos_acc * time_sync_I is in samples/frame
|
||||
@@ -1200,7 +1205,7 @@ void *UE_thread(void *arg)
|
||||
int writeBlockSize = fp->get_samples_per_slot((slot_nr + duration_rx_to_tx) % nb_slot_frame, fp) - iq_shift_to_apply;
|
||||
int new_timing_advance = UE->timing_advance;
|
||||
if (new_timing_advance != timing_advance) {
|
||||
writeBlockSize -= new_timing_advance- timing_advance;
|
||||
writeBlockSize -= new_timing_advance - timing_advance;
|
||||
timing_advance = new_timing_advance;
|
||||
}
|
||||
int new_N_TA_offset = determine_N_TA_offset(UE);
|
||||
|
||||
Reference in New Issue
Block a user