Merge remote-tracking branch 'origin/nr_ue_sib19_doppler' into integration_2025_w52 (!3663)
NR UE: calculate DL and UL Doppler based on SIB19 information in NTN mode, fixing LEO reestablishment
This commit is contained in:
@@ -32,6 +32,11 @@
|
|||||||
000003
|
000003
|
||||||
020001
|
020001
|
||||||
020002
|
020002
|
||||||
|
040001
|
||||||
|
020022
|
||||||
|
040002
|
||||||
|
020001
|
||||||
|
020002
|
||||||
100001
|
100001
|
||||||
222222
|
222222
|
||||||
</TestCaseRequestedList>
|
</TestCaseRequestedList>
|
||||||
@@ -94,6 +99,33 @@
|
|||||||
<ping_packetloss_threshold>5</ping_packetloss_threshold>
|
<ping_packetloss_threshold>5</ping_packetloss_threshold>
|
||||||
</testCase>
|
</testCase>
|
||||||
|
|
||||||
|
<testCase id="040001">
|
||||||
|
<class>Custom_Command</class>
|
||||||
|
<desc>Trigger Reestablishment</desc>
|
||||||
|
<node>localhost</node>
|
||||||
|
<command>echo ci force_reestab | ncat 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>
|
||||||
|
<node>localhost</node>
|
||||||
|
<svr_id>rfsim5g_ext_dn</svr_id>
|
||||||
|
<svr_node>localhost</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>localhost</node>
|
||||||
|
<command>echo ci get_reestab_count | ncat 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">
|
<testCase id="100001">
|
||||||
<class>Undeploy_Object</class>
|
<class>Undeploy_Object</class>
|
||||||
<always_exec>true</always_exec>
|
<always_exec>true</always_exec>
|
||||||
|
|||||||
@@ -93,7 +93,9 @@ services:
|
|||||||
- ALL
|
- ALL
|
||||||
environment:
|
environment:
|
||||||
USE_ADDITIONAL_OPTIONS: --rfsim --log_config.global_log_options level,nocolor,time
|
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:
|
depends_on:
|
||||||
- oai-ext-dn
|
- oai-ext-dn
|
||||||
networks:
|
networks:
|
||||||
|
|||||||
+2
-1
@@ -355,7 +355,8 @@ These modes of operation are supported:
|
|||||||
- Different TA adjustemt algorithms between SIB19 receptions:
|
- Different TA adjustemt algorithms between SIB19 receptions:
|
||||||
- Autonomous TA adjustemt based on DL time tracking
|
- Autonomous TA adjustemt based on DL time tracking
|
||||||
- Standard compliant epoch time based TA adjustment including orbital propagation
|
- Standard compliant epoch time based TA adjustment including orbital propagation
|
||||||
- UL Doppler pre-compensation based on continuous DL FO estimation
|
- DL Doppler compensation based on ntn-Config-r17 information
|
||||||
|
- UL Doppler pre-compensation based on ntn-Config-r17 information and residual DL FO estimation
|
||||||
* Highly efficient 3GPP compliant LDPC encoder and decoder (BG1 and BG2 are supported)
|
* Highly efficient 3GPP compliant LDPC encoder and decoder (BG1 and BG2 are supported)
|
||||||
* Highly efficient 3GPP compliant polar encoder and decoder
|
* Highly efficient 3GPP compliant polar encoder and decoder
|
||||||
* Encoder and decoder for short block
|
* Encoder and decoder for short block
|
||||||
|
|||||||
+1
-1
@@ -135,7 +135,7 @@ Here are some useful command line options for the NR UE:
|
|||||||
|--------------------------|---------------------------------------------------------------------------------------------------------------|
|
|--------------------------|---------------------------------------------------------------------------------------------------------------|
|
||||||
| `--ue-scan-carrier` | Scan for cells in current bandwidth. This option can be used if the SSB position of the gNB is unknown. If multiple cells are detected, the UE will try to connect to the first cell. By default, this option is disabled and the UE attempts to only decode SSB given by `--ssb`. |
|
| `--ue-scan-carrier` | Scan for cells in current bandwidth. This option can be used if the SSB position of the gNB is unknown. If multiple cells are detected, the UE will try to connect to the first cell. By default, this option is disabled and the UE attempts to only decode SSB given by `--ssb`. |
|
||||||
| `--ue-fo-compensation` | Enables the initial frequency offset compensation at the UE. Useful when running over the air and/or without an external clock/time source. |
|
| `--ue-fo-compensation` | Enables the initial frequency offset compensation at the UE. Useful when running over the air and/or without an external clock/time source. |
|
||||||
| `--cont-fo-comp` | Enables the continuous frequency offset (FO) estimation and compensation. Parameter value `1` specifies that the main FO contribution comes from the local oscillator's (LO) accuracy. Parameter value `2` specifies that the main FO contribution comes from Doppler shift. |
|
| `--cont-fo-comp` | Enables the continuous frequency offset (FO) estimation and compensation. Parameter value `1` specifies that the main FO contribution comes from the local oscillator's (LO) accuracy. Parameter value `2` specifies that the main FO contribution comes from Doppler shift. Parameter value `3` specifies that no measured residual DL FO is considered for UL FO pre-compensation. |
|
||||||
| `--initial-fo` | Sets the known initial frequency offset. Useful especially with large Doppler frequency, e.g. LEO satellite. |
|
| `--initial-fo` | Sets the known initial frequency offset. Useful especially with large Doppler frequency, e.g. LEO satellite. |
|
||||||
| `--freq-sync-P` | Sets the coefficient for the Proportional part of the PI-controller for the continuous frequency offset compensation. Default value 0.01. |
|
| `--freq-sync-P` | Sets the coefficient for the Proportional part of the PI-controller for the continuous frequency offset compensation. Default value 0.01. |
|
||||||
| `--freq-sync-I` | Sets the coefficient for the Integrating part of the PI-controller for the continuous frequency offset compensation. Default value 0.001. |
|
| `--freq-sync-I` | Sets the coefficient for the Integrating part of the PI-controller for the continuous frequency offset compensation. Default value 0.001. |
|
||||||
|
|||||||
+184
-46
@@ -176,8 +176,7 @@ void init_nr_ue_vars(PHY_VARS_NR_UE *ue, uint8_t UE_id)
|
|||||||
ue->dci_thres = 0;
|
ue->dci_thres = 0;
|
||||||
ue->target_Nid_cell = -1;
|
ue->target_Nid_cell = -1;
|
||||||
|
|
||||||
ue->ntn_config_message = CALLOC(1, sizeof(*ue->ntn_config_message));
|
ue->nrUE_config.ntn_config.params_changed = false;
|
||||||
ue->ntn_config_message->update = false;
|
|
||||||
|
|
||||||
// initialize all signal buffers
|
// initialize all signal buffers
|
||||||
init_nr_ue_signal(ue, nb_connected_gNB);
|
init_nr_ue_signal(ue, nb_connected_gNB);
|
||||||
@@ -257,7 +256,7 @@ static void UE_synch(void *arg) {
|
|||||||
+ round((float)((ret.rx_offset << 1) % fp->samples_per_subframe) / fp->samples_per_slot0);
|
+ round((float)((ret.rx_offset << 1) % fp->samples_per_subframe) / fp->samples_per_slot0);
|
||||||
|
|
||||||
if (get_nrUE_params()->cont_fo_comp) {
|
if (get_nrUE_params()->cont_fo_comp) {
|
||||||
UE->freq_offset = freq_offset;
|
UE->freq_offset = freq_offset - UE->dl_Doppler_shift;
|
||||||
} else {
|
} else {
|
||||||
// rerun with new cell parameters and frequency-offset
|
// rerun with new cell parameters and frequency-offset
|
||||||
nr_rf_card_config_freq(cfg0, ul_carrier, dl_carrier, freq_offset);
|
nr_rf_card_config_freq(cfg0, ul_carrier, dl_carrier, freq_offset);
|
||||||
@@ -398,8 +397,15 @@ static void RU_write(nr_rxtx_thread_data_t *rxtxD, bool sl_tx_action, c16_t **tx
|
|||||||
double ul_freq_offset = -UE->freq_offset * ((double)fp->ul_CarrierFreq / (double)fp->dl_CarrierFreq);
|
double ul_freq_offset = -UE->freq_offset * ((double)fp->ul_CarrierFreq / (double)fp->dl_CarrierFreq);
|
||||||
if (get_nrUE_params()->cont_fo_comp == 2) // different from LO frequency error compensation, Doppler UL pre-compensation has to be negative
|
if (get_nrUE_params()->cont_fo_comp == 2) // different from LO frequency error compensation, Doppler UL pre-compensation has to be negative
|
||||||
ul_freq_offset = -ul_freq_offset;
|
ul_freq_offset = -ul_freq_offset;
|
||||||
|
else if (get_nrUE_params()->cont_fo_comp == 3) // do not consider residual DL FO for UL pre-compensation at all
|
||||||
|
ul_freq_offset = 0;
|
||||||
for (int i = 0; i < fp->nb_antennas_tx; i++)
|
for (int i = 0; i < fp->nb_antennas_tx; i++)
|
||||||
nr_fo_compensation(ul_freq_offset, fp->samples_per_subframe, writeTimestamp, txp[i], txp[i], writeBlockSize);
|
nr_fo_compensation(UE->ul_Doppler_shift + ul_freq_offset,
|
||||||
|
fp->samples_per_subframe,
|
||||||
|
writeTimestamp,
|
||||||
|
txp[i],
|
||||||
|
txp[i],
|
||||||
|
writeBlockSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
int tmp = openair0_write_reorder(&UE->rfdevice, writeTimestamp, (void **)txp, writeBlockSize, fp->nb_antennas_tx, flags);
|
int tmp = openair0_write_reorder(&UE->rfdevice, writeTimestamp, (void **)txp, writeBlockSize, fp->nb_antennas_tx, flags);
|
||||||
@@ -491,6 +497,8 @@ static uint64_t get_carrier_frequency(const int N_RB, const int mu, const uint32
|
|||||||
return carrier_freq;
|
return carrier_freq;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void apply_ntn_timing_advance_and_doppler(PHY_VARS_NR_UE *UE, const NR_DL_FRAME_PARMS *fp, int abs_subframe_tx);
|
||||||
|
|
||||||
static int handle_sync_req_from_mac(PHY_VARS_NR_UE *UE)
|
static int handle_sync_req_from_mac(PHY_VARS_NR_UE *UE)
|
||||||
{
|
{
|
||||||
NR_DL_FRAME_PARMS *fp = &UE->frame_parms;
|
NR_DL_FRAME_PARMS *fp = &UE->frame_parms;
|
||||||
@@ -515,6 +523,12 @@ static int handle_sync_req_from_mac(PHY_VARS_NR_UE *UE)
|
|||||||
init_symbol_rotation(fp);
|
init_symbol_rotation(fp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Apply Doppler based on NTN-Config for target cell
|
||||||
|
if (UE->nrUE_config.ntn_config.is_targetcell)
|
||||||
|
apply_ntn_timing_advance_and_doppler(UE, fp, -1);
|
||||||
|
// Apply NTN DL Doppler as initial FO
|
||||||
|
UE->initial_fo = UE->dl_Doppler_shift;
|
||||||
|
|
||||||
/* Clearing UE harq while DL actors are active causes race condition.
|
/* Clearing UE harq while DL actors are active causes race condition.
|
||||||
So we let the current execution to complete here.*/
|
So we let the current execution to complete here.*/
|
||||||
for (int i = 0; i < get_nrUE_params()->num_dl_actors; i++) {
|
for (int i = 0; i < get_nrUE_params()->num_dl_actors; i++) {
|
||||||
@@ -721,26 +735,81 @@ static inline int get_readBlockSize(uint16_t slot, NR_DL_FRAME_PARMS *fp) {
|
|||||||
return rem_samples + next_slot_first_symbol;
|
return rem_samples + next_slot_first_symbol;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define SPEED_OF_LIGHT 299792458
|
static void fix_ntn_epoch_hfn(PHY_VARS_NR_UE *UE, int hfn, int frame)
|
||||||
static inline void apply_ntn_timing_advance(PHY_VARS_NR_UE *UE, const NR_DL_FRAME_PARMS *fp, int abs_subframe_tx)
|
|
||||||
{
|
{
|
||||||
const fapi_nr_dl_ntn_config_command_pdu *ntn_config_params = &UE->ntn_config_message->ntn_config_params;
|
if (!UE->nrUE_config.ntn_config.is_targetcell)
|
||||||
|
return;
|
||||||
|
UE->nrUE_config.ntn_config.is_targetcell = false;
|
||||||
|
|
||||||
|
const int epoch_frame = UE->nrUE_config.ntn_config.epoch_sfn;
|
||||||
|
const int diff1 = (frame - epoch_frame + 1024) % 1024;
|
||||||
|
const int diff2 = (epoch_frame - frame + 1024) % 1024;
|
||||||
|
|
||||||
|
int *epoch_hfn = &UE->nrUE_config.ntn_config.epoch_hfn;
|
||||||
|
if (diff1 < diff2) { // epoch_frame in the past
|
||||||
|
LOG_I(PHY, "epoch is %d frames in the past\n", diff1);
|
||||||
|
if (epoch_frame <= frame)
|
||||||
|
*epoch_hfn = hfn;
|
||||||
|
else
|
||||||
|
*epoch_hfn = hfn - 1;
|
||||||
|
} else { // epoch_frame in the future
|
||||||
|
LOG_I(PHY, "epoch is %d frames in the future\n", diff2);
|
||||||
|
if (epoch_frame >= frame)
|
||||||
|
*epoch_hfn = hfn;
|
||||||
|
else
|
||||||
|
*epoch_hfn = hfn + 1;
|
||||||
|
}
|
||||||
|
LOG_I(PHY, "setting epoch_hfn = %d\n", *epoch_hfn);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define SPEED_OF_LIGHT 299792458
|
||||||
|
|
||||||
|
// calculate TA and Doppler based on the NTN-Config, if abs_subframe_tx < 0 then apply only Doppler
|
||||||
|
static void apply_ntn_timing_advance_and_doppler(PHY_VARS_NR_UE *UE, const NR_DL_FRAME_PARMS *fp, int abs_subframe_tx)
|
||||||
|
{
|
||||||
|
const fapi_nr_ntn_config_t *ntn_config_params = &UE->nrUE_config.ntn_config;
|
||||||
|
|
||||||
|
// Handle terrestrial networks
|
||||||
|
if (ntn_config_params->cell_specific_k_offset == 0) {
|
||||||
|
if (abs_subframe_tx >= 0)
|
||||||
|
UE->timing_advance_ntn = 0;
|
||||||
|
UE->dl_Doppler_shift = 0;
|
||||||
|
UE->ul_Doppler_shift = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const int abs_subframe_epoch = ntn_config_params->epoch_subframe
|
const int abs_subframe_epoch = ntn_config_params->epoch_subframe
|
||||||
+ ntn_config_params->epoch_sfn * 10
|
+ ntn_config_params->epoch_sfn * 10
|
||||||
+ ntn_config_params->epoch_hfn * 10240;
|
+ ntn_config_params->epoch_hfn * 10240;
|
||||||
const int ms_since_epoch = abs_subframe_tx - abs_subframe_epoch;
|
const int ms_since_epoch = abs_subframe_tx < 0 ? 0 : abs_subframe_tx - abs_subframe_epoch;
|
||||||
|
|
||||||
|
const position_t pos_sat_0 = ntn_config_params->pos_sat_0;
|
||||||
|
const position_t vel_sat_0 = ntn_config_params->vel_sat_0;
|
||||||
|
|
||||||
|
position_t pos_sat;
|
||||||
|
position_t vel_sat;
|
||||||
|
|
||||||
const double omega = ntn_config_params->omega;
|
const double omega = ntn_config_params->omega;
|
||||||
|
if (omega) {
|
||||||
const double cos_wt = cos(omega * ms_since_epoch);
|
const double cos_wt = cos(omega * ms_since_epoch);
|
||||||
const double sin_wt = sin(omega * ms_since_epoch);
|
const double sin_wt = sin(omega * ms_since_epoch);
|
||||||
|
|
||||||
const position_t pos_sat_0 = ntn_config_params->pos_sat_0;
|
|
||||||
const position_t pos_sat_90 = ntn_config_params->pos_sat_90;
|
const position_t pos_sat_90 = ntn_config_params->pos_sat_90;
|
||||||
const position_t pos_sat = {pos_sat_0.X * cos_wt + pos_sat_90.X * sin_wt,
|
pos_sat = (position_t){pos_sat_0.X * cos_wt + pos_sat_90.X * sin_wt,
|
||||||
pos_sat_0.Y * cos_wt + pos_sat_90.Y * sin_wt,
|
pos_sat_0.Y * cos_wt + pos_sat_90.Y * sin_wt,
|
||||||
pos_sat_0.Z * cos_wt + pos_sat_90.Z * sin_wt};
|
pos_sat_0.Z * cos_wt + pos_sat_90.Z * sin_wt};
|
||||||
|
|
||||||
|
const position_t vel_sat_90 = ntn_config_params->vel_sat_90;
|
||||||
|
vel_sat = (position_t){vel_sat_0.X * cos_wt + vel_sat_90.X * sin_wt,
|
||||||
|
vel_sat_0.Y * cos_wt + vel_sat_90.Y * sin_wt,
|
||||||
|
vel_sat_0.Z * cos_wt + vel_sat_90.Z * sin_wt};
|
||||||
|
} else {
|
||||||
|
pos_sat = (position_t){pos_sat_0.X + vel_sat_0.X * ms_since_epoch / 1000,
|
||||||
|
pos_sat_0.Y + vel_sat_0.Y * ms_since_epoch / 1000,
|
||||||
|
pos_sat_0.Z + vel_sat_0.Z * ms_since_epoch / 1000};
|
||||||
|
vel_sat = vel_sat_0;
|
||||||
|
}
|
||||||
|
|
||||||
position_t pos_ue = {0};
|
position_t pos_ue = {0};
|
||||||
get_position_coordinates(UE->Mod_id, &pos_ue);
|
get_position_coordinates(UE->Mod_id, &pos_ue);
|
||||||
|
|
||||||
@@ -750,6 +819,15 @@ static inline void apply_ntn_timing_advance(PHY_VARS_NR_UE *UE, const NR_DL_FRAM
|
|||||||
// calculate distance between SAT and UE
|
// calculate distance between SAT and UE
|
||||||
const double distance = sqrt(dir_sat_ue.X * dir_sat_ue.X + dir_sat_ue.Y * dir_sat_ue.Y + dir_sat_ue.Z * dir_sat_ue.Z);
|
const double distance = sqrt(dir_sat_ue.X * dir_sat_ue.X + dir_sat_ue.Y * dir_sat_ue.Y + dir_sat_ue.Z * dir_sat_ue.Z);
|
||||||
|
|
||||||
|
// calculate projected velocity from SAT towards UE
|
||||||
|
const double vel_sat_ue = (vel_sat.X * dir_sat_ue.X + vel_sat.Y * dir_sat_ue.Y + vel_sat.Z * dir_sat_ue.Z) / distance;
|
||||||
|
|
||||||
|
// calculate DL Doppler shift (moving source)
|
||||||
|
const double dl_Doppler_shift = (vel_sat_ue / (SPEED_OF_LIGHT - vel_sat_ue)) * fp->dl_CarrierFreq;
|
||||||
|
|
||||||
|
// calculate UL Doppler shift (moving target)
|
||||||
|
const double ul_Doppler_shift = (vel_sat_ue / SPEED_OF_LIGHT) * fp->ul_CarrierFreq;
|
||||||
|
|
||||||
// calculate round-trip-time (factor 2) between SAT and UE in ms (factor 1000)
|
// calculate round-trip-time (factor 2) between SAT and UE in ms (factor 1000)
|
||||||
const double N_UE_TA_adj = 2000 * distance / SPEED_OF_LIGHT;
|
const double N_UE_TA_adj = 2000 * distance / SPEED_OF_LIGHT;
|
||||||
|
|
||||||
@@ -757,36 +835,52 @@ static inline void apply_ntn_timing_advance(PHY_VARS_NR_UE *UE, const NR_DL_FRAM
|
|||||||
const double N_common_ta_drift = ntn_config_params->N_common_ta_drift;
|
const double N_common_ta_drift = ntn_config_params->N_common_ta_drift;
|
||||||
const double N_common_ta_drift_variant = ntn_config_params->N_common_ta_drift_variant;
|
const double N_common_ta_drift_variant = ntn_config_params->N_common_ta_drift_variant;
|
||||||
|
|
||||||
UE->timing_advance_ntn = (N_UE_TA_adj + N_common_ta_adj
|
if (abs_subframe_tx >= 0) {
|
||||||
+ N_common_ta_drift * ms_since_epoch / 1e6
|
UE->timing_advance_ntn = (N_UE_TA_adj + N_common_ta_adj + N_common_ta_drift * ms_since_epoch / 1e6
|
||||||
+ N_common_ta_drift_variant * ((int64_t)ms_since_epoch * ms_since_epoch) / 1e9)
|
+ N_common_ta_drift_variant * ((int64_t)ms_since_epoch * ms_since_epoch) / 1e9)
|
||||||
* fp->samples_per_subframe;
|
* fp->samples_per_subframe;
|
||||||
|
|
||||||
LOG_D(PHY,
|
|
||||||
"N_UE_TA_adj = %f ms, N_common_ta_adj = %f ms, N_common_ta_drift = %f µs/s, N_common_ta_drift_variant = %f µs/s², ms_since_epoch = %d ms, "
|
|
||||||
"computed timing_advance_ntn = %d samples\n",
|
|
||||||
N_UE_TA_adj,
|
|
||||||
N_common_ta_adj,
|
|
||||||
N_common_ta_drift,
|
|
||||||
N_common_ta_drift_variant,
|
|
||||||
ms_since_epoch,
|
|
||||||
UE->timing_advance_ntn);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void apply_ntn_config(PHY_VARS_NR_UE *UE,
|
UE->freq_offset -= dl_Doppler_shift - UE->dl_Doppler_shift;
|
||||||
|
UE->dl_Doppler_shift = dl_Doppler_shift;
|
||||||
|
UE->ul_Doppler_shift = ul_Doppler_shift;
|
||||||
|
|
||||||
|
if (abs_subframe_tx < 0) {
|
||||||
|
LOG_I(PHY,
|
||||||
|
"satellite velocity towards UE = %f m/s, DL Doppler shift = %f kHz, UL Doppler shift = %f kHz\n",
|
||||||
|
vel_sat_ue,
|
||||||
|
dl_Doppler_shift / 1000,
|
||||||
|
ul_Doppler_shift / 1000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// apply values based on the NTN-Config
|
||||||
|
static void apply_ntn_config(PHY_VARS_NR_UE *UE,
|
||||||
NR_DL_FRAME_PARMS *fp,
|
NR_DL_FRAME_PARMS *fp,
|
||||||
int hfn_rx,
|
int hfn_rx,
|
||||||
int frame_rx,
|
int frame_rx,
|
||||||
int slot_rx,
|
int slot_rx,
|
||||||
int *duration_rx_to_tx,
|
int *duration_rx_to_tx,
|
||||||
int *timing_advance,
|
int *timing_advance,
|
||||||
int *ntn_koffset)
|
int *ntn_koffset,
|
||||||
|
bool *ntn_targetcell)
|
||||||
{
|
{
|
||||||
if (UE->ntn_config_message->update) {
|
// return if there is no pending update
|
||||||
UE->ntn_config_message->update = false;
|
if (!UE->nrUE_config.ntn_config.params_changed)
|
||||||
|
return;
|
||||||
|
|
||||||
|
*ntn_targetcell = UE->nrUE_config.ntn_config.is_targetcell;
|
||||||
|
|
||||||
|
// skip update if it is for the target cell
|
||||||
|
if (UE->nrUE_config.ntn_config.is_targetcell)
|
||||||
|
return;
|
||||||
|
|
||||||
|
UE->nrUE_config.ntn_config.params_changed = false;
|
||||||
|
|
||||||
|
const fapi_nr_ntn_config_t *ntn_config_params = &UE->nrUE_config.ntn_config;
|
||||||
|
|
||||||
const int mu = fp->numerology_index;
|
const int mu = fp->numerology_index;
|
||||||
const int koffset = UE->ntn_config_message->ntn_config_params.cell_specific_k_offset;
|
const int koffset = ntn_config_params->cell_specific_k_offset;
|
||||||
|
|
||||||
*duration_rx_to_tx = NR_UE_CAPABILITY_SLOT_RX_TO_TX + (koffset << mu);
|
*duration_rx_to_tx = NR_UE_CAPABILITY_SLOT_RX_TO_TX + (koffset << mu);
|
||||||
if (koffset > *ntn_koffset)
|
if (koffset > *ntn_koffset)
|
||||||
@@ -796,8 +890,18 @@ static inline void apply_ntn_config(PHY_VARS_NR_UE *UE,
|
|||||||
*ntn_koffset = koffset;
|
*ntn_koffset = koffset;
|
||||||
|
|
||||||
const int abs_subframe_tx = 10240 * hfn_rx + 10 * frame_rx + ((slot_rx + *duration_rx_to_tx) >> mu);
|
const int abs_subframe_tx = 10240 * hfn_rx + 10 * frame_rx + ((slot_rx + *duration_rx_to_tx) >> mu);
|
||||||
apply_ntn_timing_advance(UE, fp, abs_subframe_tx);
|
apply_ntn_timing_advance_and_doppler(UE, fp, abs_subframe_tx);
|
||||||
}
|
|
||||||
|
LOG_I(PHY,
|
||||||
|
"k_offset: %dms, N_Common_Ta: %fms, drift: %fµs/s, variant: %fµs/s², "
|
||||||
|
"timing_advance_ntn: %d samples, DL Doppler shift: %fkHz, UL Doppler shift: %fkHz\n",
|
||||||
|
koffset << mu,
|
||||||
|
ntn_config_params->N_common_ta_adj,
|
||||||
|
ntn_config_params->N_common_ta_drift,
|
||||||
|
ntn_config_params->N_common_ta_drift_variant,
|
||||||
|
UE->timing_advance_ntn,
|
||||||
|
UE->dl_Doppler_shift / 1000,
|
||||||
|
UE->ul_Doppler_shift / 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
void *UE_thread(void *arg)
|
void *UE_thread(void *arg)
|
||||||
@@ -832,9 +936,15 @@ void *UE_thread(void *arg)
|
|||||||
notifiedFIFO_t freeBlocks;
|
notifiedFIFO_t freeBlocks;
|
||||||
initNotifiedFIFO_nothreadSafe(&freeBlocks);
|
initNotifiedFIFO_nothreadSafe(&freeBlocks);
|
||||||
|
|
||||||
double ntn_init_time_drift = get_nrUE_params()->ntn_init_time_drift;
|
const double ntn_init_time_drift = get_nrUE_params()->ntn_init_time_drift;
|
||||||
int ntn_koffset = 0;
|
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
|
||||||
|
UE->max_pos_acc = ntn_init_time_drift * 1e-6 * fp->samples_per_frame / get_nrUE_params()->time_sync_I;
|
||||||
|
else
|
||||||
|
UE->max_pos_acc = 0;
|
||||||
|
|
||||||
|
bool ntn_targetcell = false;
|
||||||
|
int ntn_koffset = 0;
|
||||||
int duration_rx_to_tx = NR_UE_CAPABILITY_SLOT_RX_TO_TX;
|
int duration_rx_to_tx = NR_UE_CAPABILITY_SLOT_RX_TO_TX;
|
||||||
int timing_advance = UE->timing_advance + UE->timing_advance_ntn;
|
int timing_advance = UE->timing_advance + UE->timing_advance_ntn;
|
||||||
UE->N_TA_offset = determine_N_TA_offset(UE);
|
UE->N_TA_offset = determine_N_TA_offset(UE);
|
||||||
@@ -930,10 +1040,6 @@ void *UE_thread(void *arg)
|
|||||||
syncMsg->UE = UE;
|
syncMsg->UE = UE;
|
||||||
memset(&syncMsg->proc, 0, sizeof(syncMsg->proc));
|
memset(&syncMsg->proc, 0, sizeof(syncMsg->proc));
|
||||||
pushNotifiedFIFO(&UE->sync_actor.fifo, Msg);
|
pushNotifiedFIFO(&UE->sync_actor.fifo, Msg);
|
||||||
if (ntn_koffset == 0) { // reset timing_advance for TN
|
|
||||||
timing_advance = 0;
|
|
||||||
UE->timing_advance = 0;
|
|
||||||
}
|
|
||||||
trashed_frames = 0;
|
trashed_frames = 0;
|
||||||
syncRunning = true;
|
syncRunning = true;
|
||||||
continue;
|
continue;
|
||||||
@@ -943,13 +1049,8 @@ void *UE_thread(void *arg)
|
|||||||
stream_status = STREAM_STATUS_SYNCING;
|
stream_status = STREAM_STATUS_SYNCING;
|
||||||
syncInFrame(UE, &sync_timestamp, duration_rx_to_tx, intialSyncOffset);
|
syncInFrame(UE, &sync_timestamp, duration_rx_to_tx, intialSyncOffset);
|
||||||
openair0_write_reorder_clear_context(&UE->rfdevice);
|
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
|
|
||||||
UE->max_pos_acc = ntn_init_time_drift * 1e-6 * fp->samples_per_frame / get_nrUE_params()->time_sync_I;
|
|
||||||
else
|
|
||||||
UE->max_pos_acc = 0;
|
|
||||||
shiftForNextFrame = -(UE->init_sync_frame + trashed_frames + 2) * UE->max_pos_acc * get_nrUE_params()->time_sync_I; // compensate for the time drift that happened during initial sync
|
shiftForNextFrame = -(UE->init_sync_frame + trashed_frames + 2) * UE->max_pos_acc * get_nrUE_params()->time_sync_I; // compensate for the time drift that happened during initial sync
|
||||||
LOG_D(PHY, "max_pos_acc = %d, shiftForNextFrame = %d\n", UE->max_pos_acc, shiftForNextFrame);
|
LOG_I(PHY, "max_pos_acc = %d, shiftForNextFrame = %d\n", UE->max_pos_acc, shiftForNextFrame);
|
||||||
// read in first symbol
|
// read in first symbol
|
||||||
AssertFatal(fp->ofdm_symbol_size + fp->nb_prefix_samples0
|
AssertFatal(fp->ofdm_symbol_size + fp->nb_prefix_samples0
|
||||||
== UE->rfdevice.trx_read_func(&UE->rfdevice,
|
== UE->rfdevice.trx_read_func(&UE->rfdevice,
|
||||||
@@ -961,12 +1062,35 @@ void *UE_thread(void *arg)
|
|||||||
// we have the decoded frame index in the return of the synch process
|
// we have the decoded frame index in the return of the synch process
|
||||||
// and we shifted above to the first slot of next frame
|
// and we shifted above to the first slot of next frame
|
||||||
decoded_frame_rx = (decoded_frame_rx + 1) % MAX_FRAME_NUMBER;
|
decoded_frame_rx = (decoded_frame_rx + 1) % MAX_FRAME_NUMBER;
|
||||||
|
const int prev_frame_rx = (absolute_slot / nb_slot_frame) % MAX_FRAME_NUMBER;
|
||||||
|
const int prev_hfn_rx = (absolute_slot / nb_slot_frame) / MAX_FRAME_NUMBER;
|
||||||
|
int decoded_hfn_rx = prev_hfn_rx;
|
||||||
|
if (decoded_frame_rx <= prev_frame_rx)
|
||||||
|
decoded_hfn_rx++;
|
||||||
// we do ++ first in the regular processing, so it will be begin of frame;
|
// we do ++ first in the regular processing, so it will be begin of frame;
|
||||||
absolute_slot = decoded_frame_rx * nb_slot_frame - 1;
|
absolute_slot = (decoded_hfn_rx * MAX_FRAME_NUMBER + decoded_frame_rx) * nb_slot_frame - 1;
|
||||||
if (UE->sl_mode == 2) {
|
if (UE->sl_mode == 2) {
|
||||||
// Set to the slot where the SL-SSB was decoded
|
// Set to the slot where the SL-SSB was decoded
|
||||||
absolute_slot += UE->SL_UE_PHY_PARAMS.sync_params.slot_offset;
|
absolute_slot += UE->SL_UE_PHY_PARAMS.sync_params.slot_offset;
|
||||||
}
|
}
|
||||||
|
// With the correct frame and slot numbers, we can now fix the UL timing
|
||||||
|
fix_ntn_epoch_hfn(UE, decoded_hfn_rx, decoded_frame_rx);
|
||||||
|
if (UE->nrUE_config.ntn_config.params_changed) {
|
||||||
|
apply_ntn_config(UE,
|
||||||
|
fp,
|
||||||
|
decoded_hfn_rx,
|
||||||
|
decoded_frame_rx,
|
||||||
|
0,
|
||||||
|
&duration_rx_to_tx,
|
||||||
|
&timing_advance,
|
||||||
|
&ntn_koffset,
|
||||||
|
&ntn_targetcell);
|
||||||
|
} else {
|
||||||
|
const int abs_subframe_tx = (absolute_slot + 1 + duration_rx_to_tx) / fp->slots_per_subframe;
|
||||||
|
apply_ntn_timing_advance_and_doppler(UE, fp, abs_subframe_tx);
|
||||||
|
ntn_targetcell = false;
|
||||||
|
}
|
||||||
|
UE->timing_advance = 0;
|
||||||
// We have resynchronized, maybe after RF loss so we need to purge any existing context
|
// We have resynchronized, maybe after RF loss so we need to purge any existing context
|
||||||
memset(tx_wait_for_dlsch, 0, sizeof(tx_wait_for_dlsch));
|
memset(tx_wait_for_dlsch, 0, sizeof(tx_wait_for_dlsch));
|
||||||
for (int i = 0; i < NUM_PROCESS_SLOT_TX_BARRIERS; i++) {
|
for (int i = 0; i < NUM_PROCESS_SLOT_TX_BARRIERS; i++) {
|
||||||
@@ -1026,9 +1150,10 @@ void *UE_thread(void *arg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Calculate new TA based on SIB19 information for each subframe in NTN mode, if "autonomous_ta" is not enabled
|
// Calculate new TA based on SIB19 information for each subframe in NTN mode, if "autonomous_ta" is not enabled
|
||||||
if (ntn_koffset && !get_nrUE_params()->autonomous_ta && (absolute_slot + duration_rx_to_tx) % fp->slots_per_subframe == 0) {
|
if (ntn_koffset && !ntn_targetcell && !get_nrUE_params()->autonomous_ta
|
||||||
|
&& (absolute_slot + duration_rx_to_tx) % fp->slots_per_subframe == 0) {
|
||||||
const int abs_subframe_tx = (absolute_slot + duration_rx_to_tx) / fp->slots_per_subframe;
|
const int abs_subframe_tx = (absolute_slot + duration_rx_to_tx) / fp->slots_per_subframe;
|
||||||
apply_ntn_timing_advance(UE, fp, abs_subframe_tx);
|
apply_ntn_timing_advance_and_doppler(UE, fp, abs_subframe_tx);
|
||||||
}
|
}
|
||||||
|
|
||||||
const int readBlockSize = get_readBlockSize(slot_nr, fp) - iq_shift_to_apply;
|
const int readBlockSize = get_readBlockSize(slot_nr, fp) - iq_shift_to_apply;
|
||||||
@@ -1081,6 +1206,11 @@ void *UE_thread(void *arg)
|
|||||||
writeBlockSize -= new_N_TA_offset - UE->N_TA_offset;
|
writeBlockSize -= new_N_TA_offset - UE->N_TA_offset;
|
||||||
UE->N_TA_offset = new_N_TA_offset;
|
UE->N_TA_offset = new_N_TA_offset;
|
||||||
}
|
}
|
||||||
|
if (writeBlockSize < 0) {
|
||||||
|
timing_advance += writeBlockSize - 1;
|
||||||
|
LOG_I(PHY, "writeBlockSize is %d, setting it to 1 and changing timing_advance to %d\n", writeBlockSize, timing_advance);
|
||||||
|
writeBlockSize = 1;
|
||||||
|
}
|
||||||
|
|
||||||
if (curMsg.proc.nr_slot_rx == 0)
|
if (curMsg.proc.nr_slot_rx == 0)
|
||||||
nr_ue_rrc_timer_trigger(UE->Mod_id, curMsg.proc.hfn_rx, curMsg.proc.frame_rx, curMsg.proc.gNB_id);
|
nr_ue_rrc_timer_trigger(UE->Mod_id, curMsg.proc.hfn_rx, curMsg.proc.frame_rx, curMsg.proc.gNB_id);
|
||||||
@@ -1099,7 +1229,15 @@ void *UE_thread(void *arg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// apply new NTN timing information
|
// apply new NTN timing information
|
||||||
apply_ntn_config(UE, fp, curMsg.proc.hfn_rx, curMsg.proc.frame_rx, curMsg.proc.nr_slot_rx, &duration_rx_to_tx, &timing_advance, &ntn_koffset);
|
apply_ntn_config(UE,
|
||||||
|
fp,
|
||||||
|
curMsg.proc.hfn_rx,
|
||||||
|
curMsg.proc.frame_rx,
|
||||||
|
curMsg.proc.nr_slot_rx,
|
||||||
|
&duration_rx_to_tx,
|
||||||
|
&timing_advance,
|
||||||
|
&ntn_koffset,
|
||||||
|
&ntn_targetcell);
|
||||||
|
|
||||||
// Start TX slot processing here. It runs in parallel with RX slot processing
|
// Start TX slot processing here. It runs in parallel with RX slot processing
|
||||||
// in current code, DURATION_RX_TO_TX constant is the limit to get UL data to encode from a RX slot
|
// in current code, DURATION_RX_TO_TX constant is the limit to get UL data to encode from a RX slot
|
||||||
@@ -1113,7 +1251,7 @@ void *UE_thread(void *arg)
|
|||||||
curMsgTx->absolute_deadline_us = absolute_deadline_us;
|
curMsgTx->absolute_deadline_us = absolute_deadline_us;
|
||||||
|
|
||||||
int slot = curMsgTx->proc.nr_slot_tx;
|
int slot = curMsgTx->proc.nr_slot_tx;
|
||||||
int slot_and_frame = slot + curMsgTx->proc.frame_tx * UE->frame_parms.slots_per_frame;
|
int slot_and_frame = slot + curMsgTx->proc.frame_tx * nb_slot_frame;
|
||||||
int next_tx_slot_and_frame = absolute_slot + duration_rx_to_tx + 1;
|
int next_tx_slot_and_frame = absolute_slot + duration_rx_to_tx + 1;
|
||||||
int wait_for_prev_slot = stream_status == STREAM_STATUS_SYNCED ? 1 : 0;
|
int wait_for_prev_slot = stream_status == STREAM_STATUS_SYNCED ? 1 : 0;
|
||||||
|
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ extern uint16_t ue_id_g;
|
|||||||
#define CONFIG_HLP_INITIAL_FO "Initially compensated DL frequency offset (e.g. known Doppler shift in NTN LEO scenario)\n"
|
#define CONFIG_HLP_INITIAL_FO "Initially compensated DL frequency offset (e.g. known Doppler shift in NTN LEO scenario)\n"
|
||||||
#define CONFIG_HLP_FREQ_SYNC_P "coefficient for Proportional part of continuous frequency offset compensation PI controller\n"
|
#define CONFIG_HLP_FREQ_SYNC_P "coefficient for Proportional part of continuous frequency offset compensation PI controller\n"
|
||||||
#define CONFIG_HLP_FREQ_SYNC_I "coefficient for Integrating part of continuous frequency offset compensation PI controller\n"
|
#define CONFIG_HLP_FREQ_SYNC_I "coefficient for Integrating part of continuous frequency offset compensation PI controller\n"
|
||||||
#define CONFIG_HLP_CONT_FO_COMP "Enable continuous frequency offset (FO) estimation and compensation and specify main FO source (1 = local oscillator, 2 = Doppler shift)\n"
|
#define CONFIG_HLP_CONT_FO_COMP "Enable continuous frequency offset (FO) estimation and (pre-)compensation and specify main FO source (1 = local oscillator, 2 = Doppler shift, 3 = Don't consider residual DL FO in UL FO pre-compensation)\n"
|
||||||
#define CONFIG_HLP_AGC "Rx Gain control used for UE\n"
|
#define CONFIG_HLP_AGC "Rx Gain control used for UE\n"
|
||||||
#define CONFIG_HLP_NUM_UL_ACTORS "Number of UL actors to use. Set to 0 to disable UL actor framework and do processing inline\n"
|
#define CONFIG_HLP_NUM_UL_ACTORS "Number of UL actors to use. Set to 0 to disable UL actor framework and do processing inline\n"
|
||||||
#define CONFIG_HLP_NUM_DL_ACTORS "Number of DL actors to use. Set to 0 to disable DL actor framework and do processing inline\n"
|
#define CONFIG_HLP_NUM_DL_ACTORS "Number of DL actors to use. Set to 0 to disable DL actor framework and do processing inline\n"
|
||||||
|
|||||||
@@ -51,9 +51,7 @@
|
|||||||
#define FAPI_NR_DL_CONFIG_TYPE_CSI_RS 0x06
|
#define FAPI_NR_DL_CONFIG_TYPE_CSI_RS 0x06
|
||||||
#define FAPI_NR_DL_CONFIG_TYPE_CSI_IM 0x07
|
#define FAPI_NR_DL_CONFIG_TYPE_CSI_IM 0x07
|
||||||
#define FAPI_NR_CONFIG_TA_COMMAND 0x08
|
#define FAPI_NR_CONFIG_TA_COMMAND 0x08
|
||||||
#define FAPI_NR_DL_NTN_CONFIG_PARAMS 0x09
|
#define FAPI_NR_DL_CONFIG_TYPES 0x08
|
||||||
#define FAPI_NR_DL_CONFIG_TYPES 0x09
|
|
||||||
|
|
||||||
|
|
||||||
#define FAPI_NR_CCE_REG_MAPPING_TYPE_INTERLEAVED 0x01
|
#define FAPI_NR_CCE_REG_MAPPING_TYPE_INTERLEAVED 0x01
|
||||||
#define FAPI_NR_CCE_REG_MAPPING_TYPE_NON_INTERLEAVED 0x02
|
#define FAPI_NR_CCE_REG_MAPPING_TYPE_NON_INTERLEAVED 0x02
|
||||||
|
|||||||
@@ -569,10 +569,14 @@ typedef struct {
|
|||||||
|
|
||||||
// orbital angular velocity in rad/ms
|
// orbital angular velocity in rad/ms
|
||||||
double omega;
|
double omega;
|
||||||
// satellite position at epoch time
|
// satellite position vector at epoch time
|
||||||
position_t pos_sat_0;
|
position_t pos_sat_0;
|
||||||
// satellite position at 90° orbit
|
// satellite position vector at 90° orbit
|
||||||
position_t pos_sat_90;
|
position_t pos_sat_90;
|
||||||
|
// satellite velocity vector at epoch time
|
||||||
|
position_t vel_sat_0;
|
||||||
|
// satellite velocity vector at 90° orbit
|
||||||
|
position_t vel_sat_90;
|
||||||
|
|
||||||
// N_common_ta_adj represents common round-trip-time between gNB and SAT received in SIB19 (ms)
|
// N_common_ta_adj represents common round-trip-time between gNB and SAT received in SIB19 (ms)
|
||||||
double N_common_ta_adj;
|
double N_common_ta_adj;
|
||||||
@@ -583,7 +587,10 @@ typedef struct {
|
|||||||
|
|
||||||
// cell scheduling offset expressed in terms of 15kHz SCS
|
// cell scheduling offset expressed in terms of 15kHz SCS
|
||||||
long cell_specific_k_offset;
|
long cell_specific_k_offset;
|
||||||
} fapi_nr_dl_ntn_config_command_pdu;
|
|
||||||
|
bool is_targetcell;
|
||||||
|
bool params_changed;
|
||||||
|
} fapi_nr_ntn_config_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint8_t pdu_type;
|
uint8_t pdu_type;
|
||||||
@@ -593,7 +600,6 @@ typedef struct {
|
|||||||
fapi_nr_dl_config_csirs_pdu csirs_config_pdu;
|
fapi_nr_dl_config_csirs_pdu csirs_config_pdu;
|
||||||
fapi_nr_dl_config_csiim_pdu csiim_config_pdu;
|
fapi_nr_dl_config_csiim_pdu csiim_config_pdu;
|
||||||
fapi_nr_ta_command_pdu ta_command_pdu;
|
fapi_nr_ta_command_pdu ta_command_pdu;
|
||||||
fapi_nr_dl_ntn_config_command_pdu ntn_config_command_pdu;
|
|
||||||
};
|
};
|
||||||
} fapi_nr_dl_config_request_pdu_t;
|
} fapi_nr_dl_config_request_pdu_t;
|
||||||
|
|
||||||
@@ -725,6 +731,7 @@ typedef struct {
|
|||||||
fapi_nr_ssb_table_t ssb_table;
|
fapi_nr_ssb_table_t ssb_table;
|
||||||
fapi_nr_tdd_table_t tdd_table;
|
fapi_nr_tdd_table_t tdd_table;
|
||||||
fapi_nr_prach_config_t prach_config;
|
fapi_nr_prach_config_t prach_config;
|
||||||
|
fapi_nr_ntn_config_t ntn_config;
|
||||||
|
|
||||||
} fapi_nr_config_request_t;
|
} fapi_nr_config_request_t;
|
||||||
|
|
||||||
|
|||||||
@@ -337,8 +337,6 @@ void term_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB)
|
|||||||
free_and_zero(ue->prs_vars[idx]);
|
free_and_zero(ue->prs_vars[idx]);
|
||||||
}
|
}
|
||||||
|
|
||||||
free_and_zero(ue->ntn_config_message);
|
|
||||||
|
|
||||||
sl_ue_free(ue);
|
sl_ue_free(ue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -119,7 +119,7 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue,
|
|||||||
|
|
||||||
if (ue && ue->cont_fo_comp) {
|
if (ue && ue->cont_fo_comp) {
|
||||||
start_meas_nr_ue_phy(ue, RX_FO_COMPENSATION_STATS);
|
start_meas_nr_ue_phy(ue, RX_FO_COMPENSATION_STATS);
|
||||||
nr_fo_compensation(ue->freq_offset,
|
nr_fo_compensation(ue->dl_Doppler_shift + ue->freq_offset,
|
||||||
frame_parms->samples_per_subframe,
|
frame_parms->samples_per_subframe,
|
||||||
rx_offset,
|
rx_offset,
|
||||||
rxdata_symb_ptr[aa],
|
rxdata_symb_ptr[aa],
|
||||||
|
|||||||
@@ -329,11 +329,6 @@ typedef struct UE_NR_SCAN_INFO_s {
|
|||||||
int32_t freq_offset_Hz[3][10];
|
int32_t freq_offset_Hz[3][10];
|
||||||
} UE_NR_SCAN_INFO_t;
|
} UE_NR_SCAN_INFO_t;
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
bool update;
|
|
||||||
fapi_nr_dl_ntn_config_command_pdu ntn_config_params;
|
|
||||||
} ntn_config_message_t;
|
|
||||||
|
|
||||||
/// Top-level PHY Data Structure for UE
|
/// Top-level PHY Data Structure for UE
|
||||||
typedef struct PHY_VARS_NR_UE_s {
|
typedef struct PHY_VARS_NR_UE_s {
|
||||||
openair0_config_t openair0_cfg[MAX_CARDS];
|
openair0_config_t openair0_cfg[MAX_CARDS];
|
||||||
@@ -462,8 +457,10 @@ typedef struct PHY_VARS_NR_UE_s {
|
|||||||
|
|
||||||
double initial_fo; /// initial frequency offset provided by the user
|
double initial_fo; /// initial frequency offset provided by the user
|
||||||
int cont_fo_comp; /// flag enabling the continuous frequency offset estimation and compensation
|
int cont_fo_comp; /// flag enabling the continuous frequency offset estimation and compensation
|
||||||
double freq_offset; /// currently compensated frequency offset
|
double freq_offset; /// currently compensated DL frequency offset (without dl_Doppler_shift)
|
||||||
double freq_off_acc; /// accumulated frequency error (for PI controller)
|
double freq_off_acc; /// accumulated DL frequency error (for PI controller)
|
||||||
|
double dl_Doppler_shift; /// calculated DL Doppler shift
|
||||||
|
double ul_Doppler_shift; /// calculated UL Doppler shift
|
||||||
|
|
||||||
/// Timing Advance updates variables
|
/// Timing Advance updates variables
|
||||||
/// Timing advance update computed from the TA command signalled from gNB
|
/// Timing advance update computed from the TA command signalled from gNB
|
||||||
@@ -525,7 +522,6 @@ typedef struct PHY_VARS_NR_UE_s {
|
|||||||
Actor_t sync_actor;
|
Actor_t sync_actor;
|
||||||
Actor_t *dl_actors;
|
Actor_t *dl_actors;
|
||||||
Actor_t *ul_actors;
|
Actor_t *ul_actors;
|
||||||
ntn_config_message_t* ntn_config_message;
|
|
||||||
pthread_t main_thread;
|
pthread_t main_thread;
|
||||||
pthread_t stat_thread;
|
pthread_t stat_thread;
|
||||||
} PHY_VARS_NR_UE;
|
} PHY_VARS_NR_UE;
|
||||||
|
|||||||
@@ -90,29 +90,6 @@ static void configure_dlsch(NR_UE_DLSCH_t *dlsch0,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void configure_ntn_params(PHY_VARS_NR_UE *ue, fapi_nr_dl_ntn_config_command_pdu* ntn_params_message)
|
|
||||||
{
|
|
||||||
if (!ue->ntn_config_message) {
|
|
||||||
ue->ntn_config_message = CALLOC(1, sizeof(*ue->ntn_config_message));
|
|
||||||
}
|
|
||||||
|
|
||||||
ue->ntn_config_message->ntn_config_params.epoch_hfn = ntn_params_message->epoch_hfn;
|
|
||||||
ue->ntn_config_message->ntn_config_params.epoch_sfn = ntn_params_message->epoch_sfn;
|
|
||||||
ue->ntn_config_message->ntn_config_params.epoch_subframe = ntn_params_message->epoch_subframe;
|
|
||||||
|
|
||||||
ue->ntn_config_message->ntn_config_params.omega = ntn_params_message->omega;
|
|
||||||
ue->ntn_config_message->ntn_config_params.pos_sat_0 = ntn_params_message->pos_sat_0;
|
|
||||||
ue->ntn_config_message->ntn_config_params.pos_sat_90 = ntn_params_message->pos_sat_90;
|
|
||||||
|
|
||||||
ue->ntn_config_message->ntn_config_params.N_common_ta_adj = ntn_params_message->N_common_ta_adj;
|
|
||||||
ue->ntn_config_message->ntn_config_params.N_common_ta_drift = ntn_params_message->N_common_ta_drift;
|
|
||||||
ue->ntn_config_message->ntn_config_params.N_common_ta_drift_variant = ntn_params_message->N_common_ta_drift_variant;
|
|
||||||
|
|
||||||
ue->ntn_config_message->ntn_config_params.cell_specific_k_offset = ntn_params_message->cell_specific_k_offset;
|
|
||||||
|
|
||||||
ue->ntn_config_message->update = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void configure_ta_command(PHY_VARS_NR_UE *ue, fapi_nr_ta_command_pdu *ta_command_pdu)
|
static void configure_ta_command(PHY_VARS_NR_UE *ue, fapi_nr_ta_command_pdu *ta_command_pdu)
|
||||||
{
|
{
|
||||||
/* Time Alignment procedure
|
/* Time Alignment procedure
|
||||||
@@ -229,9 +206,6 @@ static void nr_ue_scheduled_response_dl(NR_UE_MAC_INST_t *mac,
|
|||||||
case FAPI_NR_CONFIG_TA_COMMAND:
|
case FAPI_NR_CONFIG_TA_COMMAND:
|
||||||
configure_ta_command(phy, &pdu->ta_command_pdu);
|
configure_ta_command(phy, &pdu->ta_command_pdu);
|
||||||
break;
|
break;
|
||||||
case FAPI_NR_DL_NTN_CONFIG_PARAMS:
|
|
||||||
configure_ntn_params(phy, &pdu->ntn_config_command_pdu);
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
LOG_W(PHY, "unhandled dl pdu type %d \n", pdu->pdu_type);
|
LOG_W(PHY, "unhandled dl pdu type %d \n", pdu->pdu_type);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -263,7 +263,7 @@ static void config_common_ue_sa(NR_UE_MAC_INST_t *mac, NR_ServingCellConfigCommo
|
|||||||
}
|
}
|
||||||
|
|
||||||
// prepare data for orbit propagation based on SIB19 ephemeris data to be able to compute the round-trip-time between ue and sat
|
// prepare data for orbit propagation based on SIB19 ephemeris data to be able to compute the round-trip-time between ue and sat
|
||||||
static void prepare_ue_sat_ta(const NR_PositionVelocity_r17_t *sat_pos, ntn_timing_advance_componets_t *ntn_ta)
|
static void prepare_ue_sat_ta(const NR_PositionVelocity_r17_t *sat_pos, fapi_nr_ntn_config_t *ntn_ta)
|
||||||
{
|
{
|
||||||
// get sat position coordinates
|
// get sat position coordinates
|
||||||
const position_t pos_sat = {sat_pos->positionX_r17 * 1.3, sat_pos->positionY_r17 * 1.3, sat_pos->positionZ_r17 * 1.3};
|
const position_t pos_sat = {sat_pos->positionX_r17 * 1.3, sat_pos->positionY_r17 * 1.3, sat_pos->positionZ_r17 * 1.3};
|
||||||
@@ -279,19 +279,28 @@ static void prepare_ue_sat_ta(const NR_PositionVelocity_r17_t *sat_pos, ntn_timi
|
|||||||
const double vel_sat_2 = vel_sat.X * vel_sat.X + vel_sat.Y * vel_sat.Y + vel_sat.Z * vel_sat.Z;
|
const double vel_sat_2 = vel_sat.X * vel_sat.X + vel_sat.Y * vel_sat.Y + vel_sat.Z * vel_sat.Z;
|
||||||
const double vel_mag = sqrt(vel_sat_2);
|
const double vel_mag = sqrt(vel_sat_2);
|
||||||
|
|
||||||
// calculate angular velocity in rad/ms
|
double omega; // angular velocity in rad/ms
|
||||||
const double omega = vel_mag / (radius * 1000);
|
position_t pos_sat_90; // sat position vector in 90° orbit
|
||||||
|
position_t vel_sat_90; // sat velocity vector in 90° orbit
|
||||||
|
|
||||||
// calculate sat position in 90° orbit
|
// assuming circular orbit when satellite moves faster than 1000 m/s
|
||||||
position_t pos_sat_90 = pos_sat;
|
// 1000 m/s are chosen because according to Wikipedia, this seems to be a reasonable minimal
|
||||||
if (vel_mag) {
|
// orbital velocity: https://en.wikipedia.org/wiki/Orbital_speed#Tangential_velocities_at_altitude
|
||||||
const double scaling = radius / vel_mag;
|
if (vel_mag > 1000) {
|
||||||
|
omega = vel_mag / (radius * 1000);
|
||||||
|
double scaling = radius / vel_mag;
|
||||||
pos_sat_90 = (position_t){vel_sat.X * scaling, vel_sat.Y * scaling, vel_sat.Z * scaling};
|
pos_sat_90 = (position_t){vel_sat.X * scaling, vel_sat.Y * scaling, vel_sat.Z * scaling};
|
||||||
|
scaling = -vel_mag / radius;
|
||||||
|
vel_sat_90 = (position_t){pos_sat.X * scaling, pos_sat.Y * scaling, pos_sat.Z * scaling};
|
||||||
|
} else {
|
||||||
|
omega = 0;
|
||||||
|
pos_sat_90 = pos_sat;
|
||||||
|
vel_sat_90 = vel_sat;
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG_I(NR_MAC,
|
LOG_I(NR_MAC,
|
||||||
"Satellite angular velocity = %e rad/ms, sat_pos = {%f, %f, %f}, sat_pos_90 = {%f, %f, %f}\n",
|
"Satellite orbital radius %f m, pos_sat_0 = {%f, %f, %f}, pos_sat_90 = {%f, %f, %f}\n",
|
||||||
omega,
|
radius,
|
||||||
pos_sat.X,
|
pos_sat.X,
|
||||||
pos_sat.Y,
|
pos_sat.Y,
|
||||||
pos_sat.Z,
|
pos_sat.Z,
|
||||||
@@ -299,13 +308,30 @@ static void prepare_ue_sat_ta(const NR_PositionVelocity_r17_t *sat_pos, ntn_timi
|
|||||||
pos_sat_90.Y,
|
pos_sat_90.Y,
|
||||||
pos_sat_90.Z);
|
pos_sat_90.Z);
|
||||||
|
|
||||||
|
LOG_I(NR_MAC,
|
||||||
|
"Satellite velocity %f m/s, angular velocity = %e rad/ms, vel_sat_0 = {%f, %f, %f}, vel_sat_90 = {%f, %f, %f}\n",
|
||||||
|
vel_mag,
|
||||||
|
omega,
|
||||||
|
vel_sat.X,
|
||||||
|
vel_sat.Y,
|
||||||
|
vel_sat.Z,
|
||||||
|
vel_sat_90.X,
|
||||||
|
vel_sat_90.Y,
|
||||||
|
vel_sat_90.Z);
|
||||||
|
|
||||||
ntn_ta->omega = omega;
|
ntn_ta->omega = omega;
|
||||||
ntn_ta->pos_sat_0 = pos_sat;
|
ntn_ta->pos_sat_0 = pos_sat;
|
||||||
ntn_ta->pos_sat_90 = pos_sat_90;
|
ntn_ta->pos_sat_90 = pos_sat_90;
|
||||||
|
ntn_ta->vel_sat_0 = vel_sat;
|
||||||
|
ntn_ta->vel_sat_90 = vel_sat_90;
|
||||||
}
|
}
|
||||||
|
|
||||||
// populate ntn_ta structure from mac
|
// populate ntn_ta structure from mac
|
||||||
static void configure_ntn_ta(ntn_timing_advance_componets_t *ntn_ta, const NR_NTN_Config_r17_t *ntn_Config_r17, int hfn, int frame)
|
static void configure_ntn_ta(fapi_nr_ntn_config_t *ntn_ta,
|
||||||
|
const NR_NTN_Config_r17_t *ntn_Config_r17,
|
||||||
|
int hfn,
|
||||||
|
int frame,
|
||||||
|
bool is_targetcell)
|
||||||
{
|
{
|
||||||
if (!ntn_Config_r17)
|
if (!ntn_Config_r17)
|
||||||
return;
|
return;
|
||||||
@@ -320,25 +346,6 @@ static void configure_ntn_ta(ntn_timing_advance_componets_t *ntn_ta, const NR_NT
|
|||||||
ntn_ta->epoch_sfn = epoch_time_r17->sfn_r17;
|
ntn_ta->epoch_sfn = epoch_time_r17->sfn_r17;
|
||||||
ntn_ta->epoch_subframe = epoch_time_r17->subFrameNR_r17;
|
ntn_ta->epoch_subframe = epoch_time_r17->subFrameNR_r17;
|
||||||
|
|
||||||
// handle ephemerisInfo_r17
|
|
||||||
const NR_EphemerisInfo_r17_t *ephemeris_info = ntn_Config_r17->ephemerisInfo_r17;
|
|
||||||
if (ephemeris_info) {
|
|
||||||
if (ephemeris_info->present == NR_EphemerisInfo_r17_PR_positionVelocity_r17) {
|
|
||||||
const NR_PositionVelocity_r17_t *position_velocity = ephemeris_info->choice.positionVelocity_r17;
|
|
||||||
AssertFatal(position_velocity, "position_velocity should not be NULL here\n");
|
|
||||||
prepare_ue_sat_ta(position_velocity, ntn_ta);
|
|
||||||
} else {
|
|
||||||
LOG_W(NR_MAC, "NR UE currently supports only ephemerisInfo_r17 of type positionVelocity_r17\n");
|
|
||||||
ntn_ta->omega = 0;
|
|
||||||
ntn_ta->pos_sat_0 = (position_t){0, 0, 0};
|
|
||||||
ntn_ta->pos_sat_90 = (position_t){0, 0, 0};
|
|
||||||
}
|
|
||||||
} else { // Need R - Release if not present
|
|
||||||
ntn_ta->omega = 0;
|
|
||||||
ntn_ta->pos_sat_0 = (position_t){0, 0, 0};
|
|
||||||
ntn_ta->pos_sat_90 = (position_t){0, 0, 0};
|
|
||||||
}
|
|
||||||
|
|
||||||
// handle cellSpecificKoffset_r17
|
// handle cellSpecificKoffset_r17
|
||||||
if (ntn_Config_r17->cellSpecificKoffset_r17)
|
if (ntn_Config_r17->cellSpecificKoffset_r17)
|
||||||
ntn_ta->cell_specific_k_offset = *ntn_Config_r17->cellSpecificKoffset_r17;
|
ntn_ta->cell_specific_k_offset = *ntn_Config_r17->cellSpecificKoffset_r17;
|
||||||
@@ -365,11 +372,9 @@ static void configure_ntn_ta(ntn_timing_advance_componets_t *ntn_ta, const NR_NT
|
|||||||
ntn_ta->N_common_ta_drift_variant = 0;
|
ntn_ta->N_common_ta_drift_variant = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
ntn_ta->ntn_params_changed = true;
|
|
||||||
|
|
||||||
LOG_I(NR_MAC,
|
LOG_I(NR_MAC,
|
||||||
"SIB19 Rxd. Epoch HFN: %d, Epoch SFN: %d, Epoch Subframe: %d, k_offset: %ldms, "
|
"NTN Config Rxd. Epoch HFN: %d, Epoch SFN: %d, Epoch Subframe: %d, k_offset: %ldms, "
|
||||||
"N_Common_Ta: %fms, drift: %fµs/s, variant %fµs/s²\n",
|
"N_Common_Ta: %fms, drift: %fµs/s, variant: %fµs/s²\n",
|
||||||
ntn_ta->epoch_hfn,
|
ntn_ta->epoch_hfn,
|
||||||
ntn_ta->epoch_sfn,
|
ntn_ta->epoch_sfn,
|
||||||
ntn_ta->epoch_subframe,
|
ntn_ta->epoch_subframe,
|
||||||
@@ -377,6 +382,32 @@ static void configure_ntn_ta(ntn_timing_advance_componets_t *ntn_ta, const NR_NT
|
|||||||
ntn_ta->N_common_ta_adj,
|
ntn_ta->N_common_ta_adj,
|
||||||
ntn_ta->N_common_ta_drift,
|
ntn_ta->N_common_ta_drift,
|
||||||
ntn_ta->N_common_ta_drift_variant);
|
ntn_ta->N_common_ta_drift_variant);
|
||||||
|
|
||||||
|
// handle ephemerisInfo_r17
|
||||||
|
const NR_EphemerisInfo_r17_t *ephemeris_info = ntn_Config_r17->ephemerisInfo_r17;
|
||||||
|
if (ephemeris_info) {
|
||||||
|
if (ephemeris_info->present == NR_EphemerisInfo_r17_PR_positionVelocity_r17) {
|
||||||
|
const NR_PositionVelocity_r17_t *position_velocity = ephemeris_info->choice.positionVelocity_r17;
|
||||||
|
AssertFatal(position_velocity, "position_velocity should not be NULL here\n");
|
||||||
|
prepare_ue_sat_ta(position_velocity, ntn_ta);
|
||||||
|
} else {
|
||||||
|
LOG_W(NR_MAC, "NR UE currently supports only ephemerisInfo_r17 of type positionVelocity_r17\n");
|
||||||
|
ntn_ta->omega = 0;
|
||||||
|
ntn_ta->pos_sat_0 = (position_t){0, 0, 0};
|
||||||
|
ntn_ta->pos_sat_90 = (position_t){0, 0, 0};
|
||||||
|
ntn_ta->vel_sat_0 = (position_t){0, 0, 0};
|
||||||
|
ntn_ta->vel_sat_90 = (position_t){0, 0, 0};
|
||||||
|
}
|
||||||
|
} else { // Need R - Release if not present
|
||||||
|
ntn_ta->omega = 0;
|
||||||
|
ntn_ta->pos_sat_0 = (position_t){0, 0, 0};
|
||||||
|
ntn_ta->pos_sat_90 = (position_t){0, 0, 0};
|
||||||
|
ntn_ta->vel_sat_0 = (position_t){0, 0, 0};
|
||||||
|
ntn_ta->vel_sat_90 = (position_t){0, 0, 0};
|
||||||
|
}
|
||||||
|
|
||||||
|
ntn_ta->is_targetcell = is_targetcell;
|
||||||
|
ntn_ta->params_changed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void config_common_ue(NR_UE_MAC_INST_t *mac, NR_ServingCellConfigCommon_t *scc, int cc_idP, int hfn, int frame)
|
static void config_common_ue(NR_UE_MAC_INST_t *mac, NR_ServingCellConfigCommon_t *scc, int cc_idP, int hfn, int frame)
|
||||||
@@ -553,7 +584,7 @@ static void config_common_ue(NR_UE_MAC_INST_t *mac, NR_ServingCellConfigCommon_t
|
|||||||
// NTN Config
|
// NTN Config
|
||||||
if (scc->ext2) {
|
if (scc->ext2) {
|
||||||
UPDATE_IE(mac->sc_info.ntn_Config_r17, scc->ext2->ntn_Config_r17, NR_NTN_Config_r17_t);
|
UPDATE_IE(mac->sc_info.ntn_Config_r17, scc->ext2->ntn_Config_r17, NR_NTN_Config_r17_t);
|
||||||
configure_ntn_ta(&mac->ntn_ta, mac->sc_info.ntn_Config_r17, hfn, frame);
|
configure_ntn_ta(&mac->phy_config.config_req.ntn_config, mac->sc_info.ntn_Config_r17, hfn, frame, true);
|
||||||
} else {
|
} else {
|
||||||
asn1cFreeStruc(asn_DEF_NR_NTN_Config_r17, mac->sc_info.ntn_Config_r17);
|
asn1cFreeStruc(asn_DEF_NR_NTN_Config_r17, mac->sc_info.ntn_Config_r17);
|
||||||
}
|
}
|
||||||
@@ -1951,6 +1982,7 @@ void nr_rrc_mac_config_req_sib1(module_id_t module_id, int cc_idP, NR_SIB1_t *si
|
|||||||
mac->state = UE_PERFORMING_RA;
|
mac->state = UE_PERFORMING_RA;
|
||||||
|
|
||||||
mac->if_module->phy_config_request(&mac->phy_config);
|
mac->if_module->phy_config_request(&mac->phy_config);
|
||||||
|
mac->phy_config.config_req.ntn_config.params_changed = false;
|
||||||
ret = pthread_mutex_unlock(&mac->if_mutex);
|
ret = pthread_mutex_unlock(&mac->if_mutex);
|
||||||
AssertFatal(!ret, "mutex failed %d\n", ret);
|
AssertFatal(!ret, "mutex failed %d\n", ret);
|
||||||
}
|
}
|
||||||
@@ -1964,7 +1996,9 @@ void nr_rrc_mac_config_other_sib(module_id_t module_id, NR_SIB19_r17_t *sib19, i
|
|||||||
if (sib19) {
|
if (sib19) {
|
||||||
// update ntn_Config_r17 with received values
|
// update ntn_Config_r17 with received values
|
||||||
UPDATE_IE(mac->sc_info.ntn_Config_r17, sib19->ntn_Config_r17, NR_NTN_Config_r17_t);
|
UPDATE_IE(mac->sc_info.ntn_Config_r17, sib19->ntn_Config_r17, NR_NTN_Config_r17_t);
|
||||||
configure_ntn_ta(&mac->ntn_ta, mac->sc_info.ntn_Config_r17, hfn, frame);
|
configure_ntn_ta(&mac->phy_config.config_req.ntn_config, mac->sc_info.ntn_Config_r17, hfn, frame, false);
|
||||||
|
mac->if_module->phy_config_request(&mac->phy_config);
|
||||||
|
mac->phy_config.config_req.ntn_config.params_changed = false;
|
||||||
}
|
}
|
||||||
if (mac->state == UE_RECEIVING_SIB && can_start_ra)
|
if (mac->state == UE_RECEIVING_SIB && can_start_ra)
|
||||||
mac->state = UE_PERFORMING_RA;
|
mac->state = UE_PERFORMING_RA;
|
||||||
@@ -2027,6 +2061,7 @@ static void handle_reconfiguration_with_sync(NR_UE_MAC_INST_t *mac,
|
|||||||
mac->synch_request.synch_req.target_Nid_cell = mac->physCellId;
|
mac->synch_request.synch_req.target_Nid_cell = mac->physCellId;
|
||||||
mac->if_module->synch_request(&mac->synch_request);
|
mac->if_module->synch_request(&mac->synch_request);
|
||||||
mac->if_module->phy_config_request(&mac->phy_config);
|
mac->if_module->phy_config_request(&mac->phy_config);
|
||||||
|
mac->phy_config.config_req.ntn_config.params_changed = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void configure_physicalcellgroup(NR_UE_MAC_INST_t *mac,
|
static void configure_physicalcellgroup(NR_UE_MAC_INST_t *mac,
|
||||||
|
|||||||
@@ -545,31 +545,6 @@ typedef struct {
|
|||||||
A_SEQUENCE_OF(si_schedinfo_config_t) si_SchedInfo_list;
|
A_SEQUENCE_OF(si_schedinfo_config_t) si_SchedInfo_list;
|
||||||
} si_schedInfo_t;
|
} si_schedInfo_t;
|
||||||
|
|
||||||
typedef struct ntn_timing_advance_components {
|
|
||||||
int epoch_hfn;
|
|
||||||
int epoch_sfn;
|
|
||||||
int epoch_subframe;
|
|
||||||
|
|
||||||
// orbital angular velocity in rad/ms
|
|
||||||
double omega;
|
|
||||||
// satellite position at epoch time
|
|
||||||
position_t pos_sat_0;
|
|
||||||
// satellite position at 90° orbit
|
|
||||||
position_t pos_sat_90;
|
|
||||||
|
|
||||||
// N_common_ta_adj represents common round-trip-time between gNB and SAT received in SIB19 (ms)
|
|
||||||
double N_common_ta_adj;
|
|
||||||
// drift rate of common ta in µs/s
|
|
||||||
double N_common_ta_drift;
|
|
||||||
// change rate of common ta drift in µs/s²
|
|
||||||
double N_common_ta_drift_variant;
|
|
||||||
|
|
||||||
// cell scheduling offset expressed in terms of 15kHz SCS
|
|
||||||
long cell_specific_k_offset;
|
|
||||||
|
|
||||||
bool ntn_params_changed;
|
|
||||||
} ntn_timing_advance_componets_t;
|
|
||||||
|
|
||||||
/*!\brief Top level UE MAC structure */
|
/*!\brief Top level UE MAC structure */
|
||||||
typedef struct NR_UE_MAC_INST_s {
|
typedef struct NR_UE_MAC_INST_s {
|
||||||
module_id_t ue_id;
|
module_id_t ue_id;
|
||||||
@@ -633,8 +608,6 @@ typedef struct NR_UE_MAC_INST_s {
|
|||||||
int p_Max;
|
int p_Max;
|
||||||
int p_Max_alt;
|
int p_Max_alt;
|
||||||
|
|
||||||
ntn_timing_advance_componets_t ntn_ta;
|
|
||||||
|
|
||||||
long pdsch_HARQ_ACK_Codebook;
|
long pdsch_HARQ_ACK_Codebook;
|
||||||
|
|
||||||
NR_Type0_PDCCH_CSS_config_t type0_PDCCH_CSS_config;
|
NR_Type0_PDCCH_CSS_config_t type0_PDCCH_CSS_config;
|
||||||
@@ -675,12 +648,12 @@ typedef struct NR_UE_MAC_INST_s {
|
|||||||
notifiedFIFO_t input_nf;
|
notifiedFIFO_t input_nf;
|
||||||
} NR_UE_MAC_INST_t;
|
} NR_UE_MAC_INST_t;
|
||||||
|
|
||||||
static inline int GET_NTN_UE_K_OFFSET(const ntn_timing_advance_componets_t *ntn_ta, int scs)
|
static inline int GET_NTN_UE_K_OFFSET(const fapi_nr_ntn_config_t *ntn_ta, int scs)
|
||||||
{
|
{
|
||||||
return (int)ntn_ta->cell_specific_k_offset << scs;
|
return (int)ntn_ta->cell_specific_k_offset << scs;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline long GET_DURATION_RX_TO_TX(const ntn_timing_advance_componets_t *ntn_ta, int scs)
|
static inline long GET_DURATION_RX_TO_TX(const fapi_nr_ntn_config_t *ntn_ta, int scs)
|
||||||
{
|
{
|
||||||
return NR_UE_CAPABILITY_SLOT_RX_TO_TX + (ntn_ta->cell_specific_k_offset << scs);
|
return NR_UE_CAPABILITY_SLOT_RX_TO_TX + (ntn_ta->cell_specific_k_offset << scs);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ void nr_ue_init_mac(NR_UE_MAC_INST_t *mac)
|
|||||||
mac->p_Max = INT_MIN;
|
mac->p_Max = INT_MIN;
|
||||||
mac->p_Max_alt = INT_MIN;
|
mac->p_Max_alt = INT_MIN;
|
||||||
mac->msg3_C_RNTI = false;
|
mac->msg3_C_RNTI = false;
|
||||||
mac->ntn_ta.ntn_params_changed = false;
|
mac->phy_config.config_req.ntn_config.params_changed = false;
|
||||||
initNotifiedFIFO(&mac->input_nf);
|
initNotifiedFIFO(&mac->input_nf);
|
||||||
reset_mac_inst(mac);
|
reset_mac_inst(mac);
|
||||||
|
|
||||||
|
|||||||
@@ -813,7 +813,7 @@ static void setup_ra_response_window(NR_UE_MAC_INST_t *mac,
|
|||||||
LOG_E(NR_MAC, "RA-ResponseWindow need to be configured to a value lower than or equal to 10 ms\n");
|
LOG_E(NR_MAC, "RA-ResponseWindow need to be configured to a value lower than or equal to 10 ms\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
const int ntn_ue_koffset = GET_NTN_UE_K_OFFSET(&mac->ntn_ta, mac->current_UL_BWP->scs);
|
const int ntn_ue_koffset = GET_NTN_UE_K_OFFSET(&mac->phy_config.config_req.ntn_config, mac->current_UL_BWP->scs);
|
||||||
ra->response_window_setup_time = respwind_value + ntn_ue_koffset;
|
ra->response_window_setup_time = respwind_value + ntn_ue_koffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1027,7 +1027,7 @@ void nr_Msg3_transmitted(NR_UE_MAC_INST_t *mac, uint8_t CC_id, frame_t frameP, s
|
|||||||
{
|
{
|
||||||
RA_config_t *ra = &mac->ra;
|
RA_config_t *ra = &mac->ra;
|
||||||
NR_RACH_ConfigCommon_t *nr_rach_ConfigCommon = mac->current_UL_BWP->rach_ConfigCommon;
|
NR_RACH_ConfigCommon_t *nr_rach_ConfigCommon = mac->current_UL_BWP->rach_ConfigCommon;
|
||||||
const int ntn_ue_koffset = GET_NTN_UE_K_OFFSET(&mac->ntn_ta, mac->current_UL_BWP->scs);
|
const int ntn_ue_koffset = GET_NTN_UE_K_OFFSET(&mac->phy_config.config_req.ntn_config, mac->current_UL_BWP->scs);
|
||||||
const int slots_per_ms = mac->frame_structure.numb_slots_frame / 10;
|
const int slots_per_ms = mac->frame_structure.numb_slots_frame / 10;
|
||||||
|
|
||||||
// start contention resolution timer
|
// start contention resolution timer
|
||||||
|
|||||||
@@ -563,7 +563,7 @@ static int nr_ue_process_dci_ul_00(NR_UE_MAC_INST_t *mac,
|
|||||||
|
|
||||||
frame_t frame_tx;
|
frame_t frame_tx;
|
||||||
int slot_tx;
|
int slot_tx;
|
||||||
const int ntn_ue_koffset = GET_NTN_UE_K_OFFSET(&mac->ntn_ta, mac->current_UL_BWP->scs);
|
const int ntn_ue_koffset = GET_NTN_UE_K_OFFSET(&mac->phy_config.config_req.ntn_config, mac->current_UL_BWP->scs);
|
||||||
if (-1 == nr_ue_pusch_scheduler(mac, 0, frame, slot, &frame_tx, &slot_tx, tda_info.k2 + ntn_ue_koffset)) {
|
if (-1 == nr_ue_pusch_scheduler(mac, 0, frame, slot, &frame_tx, &slot_tx, tda_info.k2 + ntn_ue_koffset)) {
|
||||||
LOG_E(MAC, "Cannot schedule PUSCH\n");
|
LOG_E(MAC, "Cannot schedule PUSCH\n");
|
||||||
return -1;
|
return -1;
|
||||||
@@ -661,7 +661,7 @@ static int nr_ue_process_dci_ul_01(NR_UE_MAC_INST_t *mac,
|
|||||||
tda_info.k2 = csi_K2;
|
tda_info.k2 = csi_K2;
|
||||||
}
|
}
|
||||||
|
|
||||||
const int ntn_ue_koffset = GET_NTN_UE_K_OFFSET(&mac->ntn_ta, mac->current_UL_BWP->scs);
|
const int ntn_ue_koffset = GET_NTN_UE_K_OFFSET(&mac->phy_config.config_req.ntn_config, mac->current_UL_BWP->scs);
|
||||||
if (-1 == nr_ue_pusch_scheduler(mac, 0, frame, slot, &frame_tx, &slot_tx, tda_info.k2 + ntn_ue_koffset)) {
|
if (-1 == nr_ue_pusch_scheduler(mac, 0, frame, slot, &frame_tx, &slot_tx, tda_info.k2 + ntn_ue_koffset)) {
|
||||||
LOG_E(MAC, "Cannot schedule PUSCH\n");
|
LOG_E(MAC, "Cannot schedule PUSCH\n");
|
||||||
return -1;
|
return -1;
|
||||||
@@ -998,7 +998,7 @@ static int nr_ue_process_dci_dl_10(NR_UE_MAC_INST_t *mac,
|
|||||||
|
|
||||||
/* PDSCH_TO_HARQ_FEEDBACK_TIME_IND */
|
/* PDSCH_TO_HARQ_FEEDBACK_TIME_IND */
|
||||||
// according to TS 38.213 9.2.3
|
// according to TS 38.213 9.2.3
|
||||||
const int ntn_ue_koffset = GET_NTN_UE_K_OFFSET(&mac->ntn_ta, dlsch_pdu->SubcarrierSpacing);
|
const int ntn_ue_koffset = GET_NTN_UE_K_OFFSET(&mac->phy_config.config_req.ntn_config, dlsch_pdu->SubcarrierSpacing);
|
||||||
uint16_t feedback_ti = 0;
|
uint16_t feedback_ti = 0;
|
||||||
|
|
||||||
if (rnti_type == TYPE_RA_RNTI_) {
|
if (rnti_type == TYPE_RA_RNTI_) {
|
||||||
@@ -1006,17 +1006,17 @@ static int nr_ue_process_dci_dl_10(NR_UE_MAC_INST_t *mac,
|
|||||||
// that can process the MSG3. Also assume that RAR is sent in the same slot as DCI (k0 == 0)
|
// that can process the MSG3. Also assume that RAR is sent in the same slot as DCI (k0 == 0)
|
||||||
// This is not perfect as the MSG3 might end up being scheduled later, so we could be
|
// This is not perfect as the MSG3 might end up being scheduled later, so we could be
|
||||||
// halting the UL scheduler for a longer time than necessary.
|
// halting the UL scheduler for a longer time than necessary.
|
||||||
feedback_ti = max(1 + GET_DURATION_RX_TO_TX(&mac->ntn_ta, dlsch_pdu->SubcarrierSpacing),
|
feedback_ti = max(1 + GET_DURATION_RX_TO_TX(&mac->phy_config.config_req.ntn_config, dlsch_pdu->SubcarrierSpacing),
|
||||||
get_delta_for_k2(mac->current_UL_BWP->scs) + get_j_for_k2(mac->current_UL_BWP->scs));
|
get_delta_for_k2(mac->current_UL_BWP->scs) + get_j_for_k2(mac->current_UL_BWP->scs));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rnti_type != TYPE_RA_RNTI_ && rnti_type != TYPE_SI_RNTI_) {
|
if (rnti_type != TYPE_RA_RNTI_ && rnti_type != TYPE_SI_RNTI_) {
|
||||||
if (!get_FeedbackDisabled(mac->sc_info.downlinkHARQ_FeedbackDisabled_r17, dci->harq_pid.val)) {
|
if (!get_FeedbackDisabled(mac->sc_info.downlinkHARQ_FeedbackDisabled_r17, dci->harq_pid.val)) {
|
||||||
feedback_ti = 1 + dci->pdsch_to_harq_feedback_timing_indicator.val + ntn_ue_koffset;
|
feedback_ti = 1 + dci->pdsch_to_harq_feedback_timing_indicator.val + ntn_ue_koffset;
|
||||||
AssertFatal(feedback_ti >= GET_DURATION_RX_TO_TX(&mac->ntn_ta, dlsch_pdu->SubcarrierSpacing),
|
AssertFatal(feedback_ti >= GET_DURATION_RX_TO_TX(&mac->phy_config.config_req.ntn_config, dlsch_pdu->SubcarrierSpacing),
|
||||||
"PDSCH to HARQ feedback time (%d) needs to be higher than DURATION_RX_TO_TX (%ld).\n",
|
"PDSCH to HARQ feedback time (%d) needs to be higher than DURATION_RX_TO_TX (%ld).\n",
|
||||||
feedback_ti,
|
feedback_ti,
|
||||||
GET_DURATION_RX_TO_TX(&mac->ntn_ta, dlsch_pdu->SubcarrierSpacing));
|
GET_DURATION_RX_TO_TX(&mac->phy_config.config_req.ntn_config, dlsch_pdu->SubcarrierSpacing));
|
||||||
// set the harq status at MAC for feedback
|
// set the harq status at MAC for feedback
|
||||||
const int tpc[] = {-1, 0, 1, 3};
|
const int tpc[] = {-1, 0, 1, 3};
|
||||||
set_harq_status(mac,
|
set_harq_status(mac,
|
||||||
@@ -1312,16 +1312,16 @@ static int nr_ue_process_dci_dl_11(NR_UE_MAC_INST_t *mac,
|
|||||||
|
|
||||||
/* PDSCH_TO_HARQ_FEEDBACK_TIME_IND */
|
/* PDSCH_TO_HARQ_FEEDBACK_TIME_IND */
|
||||||
// according to TS 38.213 Table 9.2.3-1
|
// according to TS 38.213 Table 9.2.3-1
|
||||||
const int ntn_ue_koffset = GET_NTN_UE_K_OFFSET(&mac->ntn_ta, dlsch_pdu->SubcarrierSpacing);
|
const int ntn_ue_koffset = GET_NTN_UE_K_OFFSET(&mac->phy_config.config_req.ntn_config, dlsch_pdu->SubcarrierSpacing);
|
||||||
uint16_t feedback_ti = 0;
|
uint16_t feedback_ti = 0;
|
||||||
|
|
||||||
if (!get_FeedbackDisabled(mac->sc_info.downlinkHARQ_FeedbackDisabled_r17, dci->harq_pid.val)) {
|
if (!get_FeedbackDisabled(mac->sc_info.downlinkHARQ_FeedbackDisabled_r17, dci->harq_pid.val)) {
|
||||||
feedback_ti = pucch_Config->dl_DataToUL_ACK->list.array[dci->pdsch_to_harq_feedback_timing_indicator.val][0] + ntn_ue_koffset;
|
feedback_ti = pucch_Config->dl_DataToUL_ACK->list.array[dci->pdsch_to_harq_feedback_timing_indicator.val][0] + ntn_ue_koffset;
|
||||||
AssertFatal(feedback_ti >= GET_DURATION_RX_TO_TX(&mac->ntn_ta, dlsch_pdu->SubcarrierSpacing),
|
AssertFatal(feedback_ti >= GET_DURATION_RX_TO_TX(&mac->phy_config.config_req.ntn_config, dlsch_pdu->SubcarrierSpacing),
|
||||||
"PDSCH to HARQ feedback time (%d) needs to be higher than DURATION_RX_TO_TX (%ld). Min feedback time set in config "
|
"PDSCH to HARQ feedback time (%d) needs to be higher than DURATION_RX_TO_TX (%ld). Min feedback time set in config "
|
||||||
"file (min_rxtxtime).\n",
|
"file (min_rxtxtime).\n",
|
||||||
feedback_ti,
|
feedback_ti,
|
||||||
GET_DURATION_RX_TO_TX(&mac->ntn_ta, dlsch_pdu->SubcarrierSpacing));
|
GET_DURATION_RX_TO_TX(&mac->phy_config.config_req.ntn_config, dlsch_pdu->SubcarrierSpacing));
|
||||||
|
|
||||||
// set the harq status at MAC for feedback
|
// set the harq status at MAC for feedback
|
||||||
const int tpc[] = {-1, 0, 1, 3};
|
const int tpc[] = {-1, 0, 1, 3};
|
||||||
@@ -3620,7 +3620,7 @@ static void set_time_alignment(NR_UE_MAC_INST_t *mac, int ta, ta_type_t type, in
|
|||||||
NR_UL_TIME_ALIGNMENT_t *ul_time_alignment = &mac->ul_time_alignment;
|
NR_UL_TIME_ALIGNMENT_t *ul_time_alignment = &mac->ul_time_alignment;
|
||||||
ul_time_alignment->ta_command = ta;
|
ul_time_alignment->ta_command = ta;
|
||||||
ul_time_alignment->ta_apply = type;
|
ul_time_alignment->ta_apply = type;
|
||||||
const int ntn_ue_koffset = GET_NTN_UE_K_OFFSET(&mac->ntn_ta, mac->current_UL_BWP->scs);
|
const int ntn_ue_koffset = GET_NTN_UE_K_OFFSET(&mac->phy_config.config_req.ntn_config, mac->current_UL_BWP->scs);
|
||||||
const int n_slots_frame = mac->frame_structure.numb_slots_frame;
|
const int n_slots_frame = mac->frame_structure.numb_slots_frame;
|
||||||
ul_time_alignment->frame = (frame + (slot + ntn_ue_koffset) / n_slots_frame) % MAX_FRAME_NUMBER;
|
ul_time_alignment->frame = (frame + (slot + ntn_ue_koffset) / n_slots_frame) % MAX_FRAME_NUMBER;
|
||||||
ul_time_alignment->slot = (slot + ntn_ue_koffset) % n_slots_frame;
|
ul_time_alignment->slot = (slot + ntn_ue_koffset) % n_slots_frame;
|
||||||
@@ -4095,7 +4095,7 @@ static void handle_rar_reception(NR_UE_MAC_INST_t *mac, NR_MAC_RAR *rar, frame_t
|
|||||||
}
|
}
|
||||||
frame_t frame_tx = 0;
|
frame_t frame_tx = 0;
|
||||||
int slot_tx = 0;
|
int slot_tx = 0;
|
||||||
const int ntn_ue_koffset = GET_NTN_UE_K_OFFSET(&mac->ntn_ta, mac->current_UL_BWP->scs);
|
const int ntn_ue_koffset = GET_NTN_UE_K_OFFSET(&mac->phy_config.config_req.ntn_config, mac->current_UL_BWP->scs);
|
||||||
int ret = nr_ue_pusch_scheduler(mac, 1, frame, slot, &frame_tx, &slot_tx, tda_info.k2 + ntn_ue_koffset);
|
int ret = nr_ue_pusch_scheduler(mac, 1, frame, slot, &frame_tx, &slot_tx, tda_info.k2 + ntn_ue_koffset);
|
||||||
|
|
||||||
// TA command
|
// TA command
|
||||||
|
|||||||
@@ -59,7 +59,6 @@
|
|||||||
|
|
||||||
static void nr_ue_prach_scheduler(NR_UE_MAC_INST_t *mac, frame_t frameP, slot_t slotP);
|
static void nr_ue_prach_scheduler(NR_UE_MAC_INST_t *mac, frame_t frameP, slot_t slotP);
|
||||||
static void schedule_ta_command(fapi_nr_dl_config_request_t *dl_config, NR_UE_MAC_INST_t *mac);
|
static void schedule_ta_command(fapi_nr_dl_config_request_t *dl_config, NR_UE_MAC_INST_t *mac);
|
||||||
static void schedule_ntn_config_command(fapi_nr_dl_config_request_t *dl_config, NR_UE_MAC_INST_t *mac);
|
|
||||||
|
|
||||||
static void nr_ue_fill_phr(NR_UE_MAC_INST_t *mac,
|
static void nr_ue_fill_phr(NR_UE_MAC_INST_t *mac,
|
||||||
NR_SINGLE_ENTRY_PHR_MAC_CE *phr,
|
NR_SINGLE_ENTRY_PHR_MAC_CE *phr,
|
||||||
@@ -1056,10 +1055,10 @@ void nr_ue_aperiodic_srs_scheduling(NR_UE_MAC_INST_t *mac, long resource_trigger
|
|||||||
}
|
}
|
||||||
|
|
||||||
int scs = mac->current_UL_BWP->scs;
|
int scs = mac->current_UL_BWP->scs;
|
||||||
AssertFatal(slot_offset > GET_DURATION_RX_TO_TX(&mac->ntn_ta, scs),
|
AssertFatal(slot_offset > GET_DURATION_RX_TO_TX(&mac->phy_config.config_req.ntn_config, scs),
|
||||||
"Slot offset between DCI and aperiodic SRS (%d) needs to be higher than DURATION_RX_TO_TX (%ld)\n",
|
"Slot offset between DCI and aperiodic SRS (%d) needs to be higher than DURATION_RX_TO_TX (%ld)\n",
|
||||||
slot_offset,
|
slot_offset,
|
||||||
GET_DURATION_RX_TO_TX(&mac->ntn_ta, scs));
|
GET_DURATION_RX_TO_TX(&mac->phy_config.config_req.ntn_config, scs));
|
||||||
int n_slots_frame = mac->frame_structure.numb_slots_frame;
|
int n_slots_frame = mac->frame_structure.numb_slots_frame;
|
||||||
int sched_slot = (slot + slot_offset) % n_slots_frame;
|
int sched_slot = (slot + slot_offset) % n_slots_frame;
|
||||||
if (!is_ul_slot(sched_slot, &mac->frame_structure)) {
|
if (!is_ul_slot(sched_slot, &mac->frame_structure)) {
|
||||||
@@ -1158,11 +1157,6 @@ void nr_ue_dl_scheduler(NR_UE_MAC_INST_t *mac, nr_downlink_indication_t *dl_info
|
|||||||
if (mac->ul_time_alignment.ta_apply != no_ta)
|
if (mac->ul_time_alignment.ta_apply != no_ta)
|
||||||
schedule_ta_command(dl_config, mac);
|
schedule_ta_command(dl_config, mac);
|
||||||
|
|
||||||
if (mac->ntn_ta.ntn_params_changed) {
|
|
||||||
mac->ntn_ta.ntn_params_changed = false;
|
|
||||||
schedule_ntn_config_command(dl_config, mac);
|
|
||||||
}
|
|
||||||
|
|
||||||
nr_scheduled_response_t scheduled_response = {.dl_config = dl_config,
|
nr_scheduled_response_t scheduled_response = {.dl_config = dl_config,
|
||||||
.module_id = mac->ue_id,
|
.module_id = mac->ue_id,
|
||||||
.CC_id = dl_info->cc_id,
|
.CC_id = dl_info->cc_id,
|
||||||
@@ -1570,24 +1564,24 @@ int nr_ue_pusch_scheduler(const NR_UE_MAC_INST_t *mac,
|
|||||||
|
|
||||||
delta = get_delta_for_k2(mu);
|
delta = get_delta_for_k2(mu);
|
||||||
|
|
||||||
AssertFatal((k2 + delta) > GET_DURATION_RX_TO_TX(&mac->ntn_ta, mu),
|
AssertFatal((k2 + delta) > GET_DURATION_RX_TO_TX(&mac->phy_config.config_req.ntn_config, mu),
|
||||||
"Slot offset (%ld) for Msg3 needs to be higher than DURATION_RX_TO_TX (%ld). Please set min_rxtxtime at least to "
|
"Slot offset (%ld) for Msg3 needs to be higher than DURATION_RX_TO_TX (%ld). Please set min_rxtxtime at least to "
|
||||||
"%ld in gNB config file or gNBs.[0].min_rxtxtime=%ld via command line.\n",
|
"%ld in gNB config file or gNBs.[0].min_rxtxtime=%ld via command line.\n",
|
||||||
k2,
|
k2,
|
||||||
GET_DURATION_RX_TO_TX(&mac->ntn_ta, mu),
|
GET_DURATION_RX_TO_TX(&mac->phy_config.config_req.ntn_config, mu),
|
||||||
GET_DURATION_RX_TO_TX(&mac->ntn_ta, mu),
|
GET_DURATION_RX_TO_TX(&mac->phy_config.config_req.ntn_config, mu),
|
||||||
GET_DURATION_RX_TO_TX(&mac->ntn_ta, mu));
|
GET_DURATION_RX_TO_TX(&mac->phy_config.config_req.ntn_config, mu));
|
||||||
|
|
||||||
*slot_tx = (current_slot + k2 + delta) % slots_per_frame;
|
*slot_tx = (current_slot + k2 + delta) % slots_per_frame;
|
||||||
*frame_tx = (current_frame + (current_slot + k2 + delta) / slots_per_frame) % MAX_FRAME_NUMBER;
|
*frame_tx = (current_frame + (current_slot + k2 + delta) / slots_per_frame) % MAX_FRAME_NUMBER;
|
||||||
} else {
|
} else {
|
||||||
AssertFatal(k2 >= GET_DURATION_RX_TO_TX(&mac->ntn_ta, mu),
|
AssertFatal(k2 >= GET_DURATION_RX_TO_TX(&mac->phy_config.config_req.ntn_config, mu),
|
||||||
"Slot offset K2 (%ld) needs to be higher than DURATION_RX_TO_TX (%ld). Please set min_rxtxtime at least to %ld in "
|
"Slot offset K2 (%ld) needs to be higher than DURATION_RX_TO_TX (%ld). Please set min_rxtxtime at least to %ld in "
|
||||||
"gNB config file or gNBs.[0].min_rxtxtime=%ld via command line.\n",
|
"gNB config file or gNBs.[0].min_rxtxtime=%ld via command line.\n",
|
||||||
k2,
|
k2,
|
||||||
GET_DURATION_RX_TO_TX(&mac->ntn_ta, mu),
|
GET_DURATION_RX_TO_TX(&mac->phy_config.config_req.ntn_config, mu),
|
||||||
GET_DURATION_RX_TO_TX(&mac->ntn_ta, mu),
|
GET_DURATION_RX_TO_TX(&mac->phy_config.config_req.ntn_config, mu),
|
||||||
GET_DURATION_RX_TO_TX(&mac->ntn_ta, mu));
|
GET_DURATION_RX_TO_TX(&mac->phy_config.config_req.ntn_config, mu));
|
||||||
|
|
||||||
if (k2 < 0) { // This can happen when a false DCI is received
|
if (k2 < 0) { // This can happen when a false DCI is received
|
||||||
LOG_W(PHY, "%d.%d. Received k2 %ld\n", current_frame, current_slot, k2);
|
LOG_W(PHY, "%d.%d. Received k2 %ld\n", current_frame, current_slot, k2);
|
||||||
@@ -2210,9 +2204,8 @@ static void nr_ue_prach_scheduler(NR_UE_MAC_INST_t *mac, frame_t frameP, slot_t
|
|||||||
next_slot = temp_slot;
|
next_slot = temp_slot;
|
||||||
add_slots++;
|
add_slots++;
|
||||||
}
|
}
|
||||||
nr_timer_setup(&ra->response_window_timer,
|
add_slots += GET_DURATION_RX_TO_TX(&mac->phy_config.config_req.ntn_config, mac->current_DL_BWP->scs);
|
||||||
ra->response_window_setup_time + add_slots + GET_DURATION_RX_TO_TX(&mac->ntn_ta, mac->current_DL_BWP->scs),
|
nr_timer_setup(&ra->response_window_timer, ra->response_window_setup_time + add_slots, 1);
|
||||||
1);
|
|
||||||
nr_timer_start(&ra->response_window_timer);
|
nr_timer_start(&ra->response_window_timer);
|
||||||
} else if (ra->ra_type == RA_2_STEP) {
|
} else if (ra->ra_type == RA_2_STEP) {
|
||||||
NR_MsgA_PUSCH_Resource_r16_t *msgA_PUSCH_Resource =
|
NR_MsgA_PUSCH_Resource_r16_t *msgA_PUSCH_Resource =
|
||||||
@@ -2844,28 +2837,6 @@ static uint8_t nr_ue_get_sdu(NR_UE_MAC_INST_t *mac,
|
|||||||
return mac_ce_info.num_sdus > 0; // success if we got at least one sdu
|
return mac_ce_info.num_sdus > 0; // success if we got at least one sdu
|
||||||
}
|
}
|
||||||
|
|
||||||
static void schedule_ntn_config_command(fapi_nr_dl_config_request_t *dl_config, NR_UE_MAC_INST_t *mac)
|
|
||||||
{
|
|
||||||
fapi_nr_dl_ntn_config_command_pdu *ntn_config_command_pdu = &dl_config->dl_config_list[dl_config->number_pdus].ntn_config_command_pdu;
|
|
||||||
|
|
||||||
ntn_config_command_pdu->epoch_hfn = mac->ntn_ta.epoch_hfn;
|
|
||||||
ntn_config_command_pdu->epoch_sfn = mac->ntn_ta.epoch_sfn;
|
|
||||||
ntn_config_command_pdu->epoch_subframe = mac->ntn_ta.epoch_subframe;
|
|
||||||
|
|
||||||
ntn_config_command_pdu->omega = mac->ntn_ta.omega;
|
|
||||||
ntn_config_command_pdu->pos_sat_0 = mac->ntn_ta.pos_sat_0;
|
|
||||||
ntn_config_command_pdu->pos_sat_90 = mac->ntn_ta.pos_sat_90;
|
|
||||||
|
|
||||||
ntn_config_command_pdu->N_common_ta_adj = mac->ntn_ta.N_common_ta_adj;
|
|
||||||
ntn_config_command_pdu->N_common_ta_drift = mac->ntn_ta.N_common_ta_drift;
|
|
||||||
ntn_config_command_pdu->N_common_ta_drift_variant = mac->ntn_ta.N_common_ta_drift_variant;
|
|
||||||
|
|
||||||
ntn_config_command_pdu->cell_specific_k_offset = mac->ntn_ta.cell_specific_k_offset;
|
|
||||||
|
|
||||||
dl_config->dl_config_list[dl_config->number_pdus].pdu_type = FAPI_NR_DL_NTN_CONFIG_PARAMS;
|
|
||||||
dl_config->number_pdus += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void schedule_ta_command(fapi_nr_dl_config_request_t *dl_config, NR_UE_MAC_INST_t *mac)
|
static void schedule_ta_command(fapi_nr_dl_config_request_t *dl_config, NR_UE_MAC_INST_t *mac)
|
||||||
{
|
{
|
||||||
NR_UL_TIME_ALIGNMENT_t *ul_time_alignment = &mac->ul_time_alignment;
|
NR_UL_TIME_ALIGNMENT_t *ul_time_alignment = &mac->ul_time_alignment;
|
||||||
|
|||||||
Reference in New Issue
Block a user