Merge remote-tracking branch 'origin/fix_ntn_reestablishment' into integration_2025_wk26 (!3360)
NR UE: fix reestablishment for NTN With these changes in place we should extend the NTN/GEO rfsim CI test to include reestablishment, too.
This commit is contained in:
@@ -195,6 +195,15 @@ gNBs =
|
||||
}
|
||||
);
|
||||
|
||||
rlc = {
|
||||
srb = {
|
||||
t_poll_retransmit = "ms2000"
|
||||
}
|
||||
drb_am = {
|
||||
t_poll_retransmit = "ms2000"
|
||||
}
|
||||
}
|
||||
|
||||
MACRLCs = (
|
||||
{
|
||||
num_cc = 1;
|
||||
|
||||
@@ -33,6 +33,11 @@
|
||||
000003
|
||||
020001
|
||||
020002
|
||||
040001
|
||||
020022
|
||||
040002
|
||||
020001
|
||||
020002
|
||||
100001
|
||||
222222
|
||||
</TestCaseRequestedList>
|
||||
@@ -98,6 +103,33 @@
|
||||
<ping_packetloss_threshold>5</ping_packetloss_threshold>
|
||||
</testCase>
|
||||
|
||||
<testCase id="040001">
|
||||
<class>Custom_Command</class>
|
||||
<desc>Trigger Reestablishment</desc>
|
||||
<node>cacofonix</node>
|
||||
<command>echo ci force_reestab | nc 192.168.71.140 9090 | grep -E 'Reset RLC counters of UE RNTI [0-9a-f]{4} to trigger reestablishment'</command>
|
||||
<command_fail>yes</command_fail>
|
||||
</testCase>
|
||||
|
||||
<testCase id="020022">
|
||||
<class>Ping</class>
|
||||
<desc>Ping ext-dn from NR-UE</desc>
|
||||
<id>rfsim5g_ue</id>
|
||||
<nodes>cacofonix</nodes>
|
||||
<svr_id>rfsim5g_ext_dn</svr_id>
|
||||
<svr_node>cacofonix</svr_node>
|
||||
<ping_args>-c 20 -i0.5 -w25</ping_args>
|
||||
<ping_packetloss_threshold>80</ping_packetloss_threshold>
|
||||
</testCase>
|
||||
|
||||
<testCase id="040002">
|
||||
<class>Custom_Command</class>
|
||||
<desc>Verify Reestablishment</desc>
|
||||
<node>cacofonix</node>
|
||||
<command>echo ci get_reestab_count | nc 192.168.71.140 9090 | grep -E 'UE RNTI [0-9a-f]{4} reestab 1'</command>
|
||||
<command_fail>yes</command_fail>
|
||||
</testCase>
|
||||
|
||||
<testCase id="100001">
|
||||
<class>Undeploy_Object</class>
|
||||
<always_exec>true</always_exec>
|
||||
|
||||
@@ -94,7 +94,9 @@ services:
|
||||
- ALL
|
||||
environment:
|
||||
USE_ADDITIONAL_OPTIONS: --rfsim --log_config.global_log_options level,nocolor,time
|
||||
ASAN_OPTIONS: detect_leaks=0
|
||||
--telnetsrv --telnetsrv.listenaddr 192.168.71.140
|
||||
--telnetsrv.shrmod ci
|
||||
ASAN_OPTIONS: detect_leaks=0:detect_odr_violation=0
|
||||
depends_on:
|
||||
- oai-ext-dn
|
||||
networks:
|
||||
|
||||
+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);
|
||||
|
||||
@@ -2466,13 +2466,13 @@ static void nr_ue_get_sdu_mac_ce_post(NR_UE_MAC_INST_t *mac,
|
||||
mac_ce_p->cur_ptr += size;
|
||||
}
|
||||
|
||||
uint32_t get_count_lcids_same_priority(uint8_t start, uint8_t total_active_lcids, nr_lcordered_info_t *lcid_ordered_array)
|
||||
static uint32_t get_count_lcids_same_priority(uint8_t start, uint8_t total_active_lcids, nr_lcordered_info_t *lcid_ordered_array[])
|
||||
{
|
||||
// count number of logical channels with same priority as curr_lcid
|
||||
uint8_t same_priority_count = 0;
|
||||
uint8_t curr_lcid = lcid_ordered_array[start].lcid;
|
||||
uint8_t curr_lcid = lcid_ordered_array[start]->lcid;
|
||||
for (uint8_t index = start; index < total_active_lcids; index++) {
|
||||
if (lcid_ordered_array[start].priority == lcid_ordered_array[index].priority) {
|
||||
if (lcid_ordered_array[start]->priority == lcid_ordered_array[index]->priority) {
|
||||
same_priority_count++;
|
||||
}
|
||||
}
|
||||
@@ -2520,11 +2520,13 @@ static long get_num_bytes_to_reqlc(NR_UE_MAC_INST_t *mac,
|
||||
return num_bytes_requested;
|
||||
}
|
||||
|
||||
bool get_dataavailability_buffers(uint8_t total_active_lcids, nr_lcordered_info_t *lcid_ordered_array, bool *data_status_lcbuffers)
|
||||
static bool get_dataavailability_buffers(uint8_t total_active_lcids,
|
||||
nr_lcordered_info_t *lcid_ordered_array[],
|
||||
bool *data_status_lcbuffers)
|
||||
{
|
||||
// check whether there is any data in the rlc buffer corresponding to active lcs
|
||||
for (uint8_t id = 0; id < total_active_lcids; id++) {
|
||||
int lcid = lcid_ordered_array[id].lcid;
|
||||
int lcid = lcid_ordered_array[id]->lcid;
|
||||
if (data_status_lcbuffers[lcid_buffer_index(lcid)]) {
|
||||
return true;
|
||||
}
|
||||
@@ -2532,17 +2534,20 @@ bool get_dataavailability_buffers(uint8_t total_active_lcids, nr_lcordered_info_
|
||||
return false;
|
||||
}
|
||||
|
||||
static uint select_logical_channels(NR_UE_MAC_INST_t *mac, nr_lcordered_info_t *active_lcids)
|
||||
static uint select_logical_channels(NR_UE_MAC_INST_t *mac, nr_lcordered_info_t *active_lcids[])
|
||||
{
|
||||
// (TODO: selection of logical channels for logical channel prioritization procedure as per 5.4.3.1.2 Selection of logical
|
||||
// channels, TS38.321)
|
||||
int nb = 0;
|
||||
// selection of logical channels with Bj > 0
|
||||
for (int i = 0; i < mac->lc_ordered_list.count; i++) {
|
||||
int lcid = mac->lc_ordered_list.array[i]->lcid;
|
||||
nr_lcordered_info_t *lc_info = mac->lc_ordered_list.array[i];
|
||||
if (lc_info->rb_suspended)
|
||||
continue;
|
||||
int lcid = lc_info->lcid;
|
||||
NR_LC_SCHEDULING_INFO *sched_info = get_scheduling_info_from_lcid(mac, lcid);
|
||||
if (sched_info->Bj > 0) {
|
||||
active_lcids[nb++] = *mac->lc_ordered_list.array[i];
|
||||
active_lcids[nb++] = lc_info;
|
||||
LOG_D(NR_MAC, "The available lcid is %d with total active channels count = %d\n", lcid, nb);
|
||||
}
|
||||
}
|
||||
@@ -2731,7 +2736,7 @@ static uint8_t nr_ue_get_sdu(NR_UE_MAC_INST_t *mac,
|
||||
LOG_E(NR_MAC, "Failed to init lcids_bj_pos: mac->lc_ordered_list.count = 0\n");
|
||||
return 0;
|
||||
}
|
||||
nr_lcordered_info_t lcids_bj_pos[mac->lc_ordered_list.count];
|
||||
nr_lcordered_info_t *lcids_bj_pos[mac->lc_ordered_list.count];
|
||||
int avail_lcids_count = select_logical_channels(mac, lcids_bj_pos);
|
||||
|
||||
// multiplex in the order of highest priority
|
||||
@@ -2752,7 +2757,7 @@ static uint8_t nr_ue_get_sdu(NR_UE_MAC_INST_t *mac,
|
||||
still space availble in the MAC PDU, then from the next run all the remaining data from the higher priority logical channel
|
||||
is placed in the MAC PDU before going on to next high priority logical channel
|
||||
*/
|
||||
int lcid = lcids_bj_pos[id].lcid;
|
||||
int lcid = lcids_bj_pos[id]->lcid;
|
||||
int idx = lcid_buffer_index(lcid);
|
||||
// skip the logical channel if no data in the buffer initially or the data in the buffer was zero because it was written in to
|
||||
// MAC PDU
|
||||
|
||||
@@ -276,7 +276,7 @@ void openair0_write_reorder_clear_context(openair0_device *device)
|
||||
re_order_t *ctx = &device->reOrder;
|
||||
if (!ctx->initDone)
|
||||
return;
|
||||
if (pthread_mutex_trylock(&ctx->mutex_write) == 0)
|
||||
if (pthread_mutex_trylock(&ctx->mutex_write) != 0)
|
||||
LOG_E(HW, "write_reorder_clear_context call while still writing on the device\n");
|
||||
pthread_mutex_destroy(&ctx->mutex_write);
|
||||
pthread_mutex_lock(&ctx->mutex_store);
|
||||
|
||||
Reference in New Issue
Block a user