Commit 8463ebf2 authored by Robert Schmidt's avatar Robert Schmidt

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
parents 3fac50a2 aa3a2098
......@@ -32,6 +32,11 @@
000003
020001
020002
040001
020022
040002
020001
020002
100001
222222
</TestCaseRequestedList>
......@@ -94,6 +99,33 @@
<ping_packetloss_threshold>5</ping_packetloss_threshold>
</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">
<class>Undeploy_Object</class>
<always_exec>true</always_exec>
......
......@@ -93,7 +93,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:
......
......@@ -355,7 +355,8 @@ These modes of operation are supported:
- Different TA adjustemt algorithms between SIB19 receptions:
- Autonomous TA adjustemt based on DL time tracking
- 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 polar encoder and decoder
* Encoder and decoder for short block
......
......@@ -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-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. |
| `--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. |
......
This diff is collapsed.
......@@ -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_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_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_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"
......
......@@ -51,9 +51,7 @@
#define FAPI_NR_DL_CONFIG_TYPE_CSI_RS 0x06
#define FAPI_NR_DL_CONFIG_TYPE_CSI_IM 0x07
#define FAPI_NR_CONFIG_TA_COMMAND 0x08
#define FAPI_NR_DL_NTN_CONFIG_PARAMS 0x09
#define FAPI_NR_DL_CONFIG_TYPES 0x09
#define FAPI_NR_DL_CONFIG_TYPES 0x08
#define FAPI_NR_CCE_REG_MAPPING_TYPE_INTERLEAVED 0x01
#define FAPI_NR_CCE_REG_MAPPING_TYPE_NON_INTERLEAVED 0x02
......
......@@ -569,10 +569,14 @@ typedef struct {
// orbital angular velocity in rad/ms
double omega;
// satellite position at epoch time
// satellite position vector at epoch time
position_t pos_sat_0;
// satellite position at 90° orbit
// satellite position vector at 90° orbit
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)
double N_common_ta_adj;
......@@ -583,7 +587,10 @@ typedef struct {
// cell scheduling offset expressed in terms of 15kHz SCS
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 {
uint8_t pdu_type;
......@@ -593,7 +600,6 @@ typedef struct {
fapi_nr_dl_config_csirs_pdu csirs_config_pdu;
fapi_nr_dl_config_csiim_pdu csiim_config_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;
......@@ -725,6 +731,7 @@ typedef struct {
fapi_nr_ssb_table_t ssb_table;
fapi_nr_tdd_table_t tdd_table;
fapi_nr_prach_config_t prach_config;
fapi_nr_ntn_config_t ntn_config;
} 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->ntn_config_message);
sl_ue_free(ue);
}
......
......@@ -119,7 +119,7 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue,
if (ue && ue->cont_fo_comp) {
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,
rx_offset,
rxdata_symb_ptr[aa],
......
......@@ -329,11 +329,6 @@ typedef struct UE_NR_SCAN_INFO_s {
int32_t freq_offset_Hz[3][10];
} 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
typedef struct PHY_VARS_NR_UE_s {
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
int cont_fo_comp; /// flag enabling the continuous frequency offset estimation and compensation
double freq_offset; /// currently compensated frequency offset
double freq_off_acc; /// accumulated frequency error (for PI controller)
double freq_offset; /// currently compensated DL frequency offset (without dl_Doppler_shift)
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 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 *dl_actors;
Actor_t *ul_actors;
ntn_config_message_t* ntn_config_message;
pthread_t main_thread;
pthread_t stat_thread;
} 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)
{
/* 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:
configure_ta_command(phy, &pdu->ta_command_pdu);
break;
case FAPI_NR_DL_NTN_CONFIG_PARAMS:
configure_ntn_params(phy, &pdu->ntn_config_command_pdu);
break;
default:
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
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
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_mag = sqrt(vel_sat_2);
// calculate angular velocity in rad/ms
const double omega = vel_mag / (radius * 1000);
double omega; // angular velocity in rad/ms
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
position_t pos_sat_90 = pos_sat;
if (vel_mag) {
const double scaling = radius / vel_mag;
// assuming circular orbit when satellite moves faster than 1000 m/s
// 1000 m/s are chosen because according to Wikipedia, this seems to be a reasonable minimal
// orbital velocity: https://en.wikipedia.org/wiki/Orbital_speed#Tangential_velocities_at_altitude
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};
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,
"Satellite angular velocity = %e rad/ms, sat_pos = {%f, %f, %f}, sat_pos_90 = {%f, %f, %f}\n",
omega,
"Satellite orbital radius %f m, pos_sat_0 = {%f, %f, %f}, pos_sat_90 = {%f, %f, %f}\n",
radius,
pos_sat.X,
pos_sat.Y,
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.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->pos_sat_0 = pos_sat;
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
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)
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_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
if (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->ntn_params_changed = true;
LOG_I(NR_MAC,
"SIB19 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",
"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",
ntn_ta->epoch_hfn,
ntn_ta->epoch_sfn,
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_drift,
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)
......@@ -553,7 +584,7 @@ static void config_common_ue(NR_UE_MAC_INST_t *mac, NR_ServingCellConfigCommon_t
// NTN Config
if (scc->ext2) {
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 {
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->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);
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) {
// update ntn_Config_r17 with received values
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)
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->if_module->synch_request(&mac->synch_request);
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,
......
......@@ -545,31 +545,6 @@ typedef struct {
A_SEQUENCE_OF(si_schedinfo_config_t) si_SchedInfo_list;
} 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 */
typedef struct NR_UE_MAC_INST_s {
module_id_t ue_id;
......@@ -633,8 +608,6 @@ typedef struct NR_UE_MAC_INST_s {
int p_Max;
int p_Max_alt;
ntn_timing_advance_componets_t ntn_ta;
long pdsch_HARQ_ACK_Codebook;
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;
} 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;
}
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);
}
......
......@@ -69,7 +69,7 @@ void nr_ue_init_mac(NR_UE_MAC_INST_t *mac)
mac->p_Max = INT_MIN;
mac->p_Max_alt = INT_MIN;
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);
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");
}
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;
}
......@@ -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;
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;
// 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;
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)) {
LOG_E(MAC, "Cannot schedule PUSCH\n");
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;
}
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)) {
LOG_E(MAC, "Cannot schedule PUSCH\n");
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 */
// 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;
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)
// 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.
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));
}
if (rnti_type != TYPE_RA_RNTI_ && rnti_type != TYPE_SI_RNTI_) {
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;
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",
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
const int tpc[] = {-1, 0, 1, 3};
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 */
// 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;
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;
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 "
"file (min_rxtxtime).\n",
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
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;
ul_time_alignment->ta_command = ta;
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;
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;
......@@ -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;
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);
// 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 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,
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;
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,
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 sched_slot = (slot + slot_offset) % n_slots_frame;
if (!is_ul_slot(sched_slot, &mac->frame_structure)) {
......@@ -1157,11 +1156,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)
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,
.module_id = mac->ue_id,
......@@ -1570,24 +1564,24 @@ int nr_ue_pusch_scheduler(const NR_UE_MAC_INST_t *mac,
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 "
"%ld in gNB config file or gNBs.[0].min_rxtxtime=%ld via command line.\n",
k2,
GET_DURATION_RX_TO_TX(&mac->ntn_ta, mu),
GET_DURATION_RX_TO_TX(&mac->ntn_ta, 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->phy_config.config_req.ntn_config, mu),
GET_DURATION_RX_TO_TX(&mac->phy_config.config_req.ntn_config, mu));
*slot_tx = (current_slot + k2 + delta) % slots_per_frame;
*frame_tx = (current_frame + (current_slot + k2 + delta) / slots_per_frame) % MAX_FRAME_NUMBER;
} 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 "
"gNB config file or gNBs.[0].min_rxtxtime=%ld via command line.\n",
k2,
GET_DURATION_RX_TO_TX(&mac->ntn_ta, mu),
GET_DURATION_RX_TO_TX(&mac->ntn_ta, 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->phy_config.config_req.ntn_config, 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
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;
add_slots++;
}
nr_timer_setup(&ra->response_window_timer,
ra->response_window_setup_time + add_slots + GET_DURATION_RX_TO_TX(&mac->ntn_ta, mac->current_DL_BWP->scs),
1);
add_slots += GET_DURATION_RX_TO_TX(&mac->phy_config.config_req.ntn_config, mac->current_DL_BWP->scs);
nr_timer_setup(&ra->response_window_timer, ra->response_window_setup_time + add_slots, 1);
nr_timer_start(&ra->response_window_timer);
} else if (ra->ra_type == RA_2_STEP) {
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
}
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)
{
NR_UL_TIME_ALIGNMENT_t *ul_time_alignment = &mac->ul_time_alignment;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment