Merge remote-tracking branch 'origin/ntn_continuous_sib19_updates' into integration_2025_w27 (!3398)
continuously update SIB19 information for rfsim NTN LEO scenarios Contains mainly these changes: - gNB: add function nr_update_sib19() allowing to update SIB19 information - rfsimulator: update SIB19 contents every frame for LEO channel simulations - NR UE: improve initial timing advance calculation from SIB19 Before, we only considered ta_Common_r17 and the SAT position from SIB19 to compute the initial timing advance value. This is good enough if the satellite does not move too fast (e.g. GEO satellite). Now we also consider ta_CommonDrift_r17, ta_CommonDriftVariant_r17 and the SAT velocity together with the epoch time from SIB19. This improves the accuracy of the initial TA computation, esp. for LEO satellite scenarios.
This commit is contained in:
@@ -60,3 +60,5 @@ MESSAGE_DEF(NR_RRC_MAC_CCCH_DATA_IND, MESSAGE_PRIORITY_MED_PLUS, NRRrcMacCcch
|
||||
MESSAGE_DEF(NR_RRC_MAC_BCCH_DATA_IND, MESSAGE_PRIORITY_MED_PLUS, NRRrcMacBcchDataInd, nr_rrc_mac_bcch_data_ind)
|
||||
MESSAGE_DEF(NR_RRC_MAC_SBCCH_DATA_IND, MESSAGE_PRIORITY_MED_PLUS, NRRrcMacSBcchDataInd, nr_rrc_mac_sbcch_data_ind)
|
||||
|
||||
// Message to GNB_APP to update SIB19 satellite position information
|
||||
MESSAGE_DEF(GNB_SAT_POSITION_UPDATE, MESSAGE_PRIORITY_MED, gnb_sat_position_update_t, gnb_sat_position_update)
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
|
||||
#include <LTE_DRX-Config.h>
|
||||
#include "OCTET_STRING.h"
|
||||
#include "NR_MAC_gNB/mac_config.h"
|
||||
|
||||
//-------------------------------------------------------------------------------------------//
|
||||
// Defines to access message fields.
|
||||
@@ -61,6 +62,8 @@
|
||||
|
||||
#define RRC_MAC_DRX_CONFIG_REQ(mSGpTR) (mSGpTR)->ittiMsg.rrc_mac_drx_config_req
|
||||
|
||||
#define GNB_SAT_POSITION_UPDATE(mSGpTR) (mSGpTR)->ittiMsg.gnb_sat_position_update
|
||||
|
||||
// Some constants from "LAYER2/MAC/defs.h"
|
||||
#define BCCH_SDU_SIZE (512)
|
||||
#define BCCH_SDU_MBMS_SIZE (512)
|
||||
|
||||
@@ -212,6 +212,11 @@ void *gNB_app_task(void *args_p)
|
||||
LOG_I(GNB_APP, " Received %s: timer_id %ld\n", msg_name, TIMER_HAS_EXPIRED(msg_p).timer_id);
|
||||
break;
|
||||
|
||||
case GNB_SAT_POSITION_UPDATE:
|
||||
LOG_I(GNB_APP, " Received GNB_SAT_POSITION_UPDATE message\n");
|
||||
nr_update_sib19(&GNB_SAT_POSITION_UPDATE(msg_p));
|
||||
break;
|
||||
|
||||
default:
|
||||
LOG_E(GNB_APP, "Received unexpected message %s\n", msg_name);
|
||||
break;
|
||||
|
||||
@@ -221,11 +221,18 @@ void prepare_scc(NR_ServingCellConfigCommon_t *scc)
|
||||
|
||||
scc->ext2->ntn_Config_r17->ephemerisInfo_r17 = calloc_or_fail(1, sizeof(*scc->ext2->ntn_Config_r17->ephemerisInfo_r17));
|
||||
scc->ext2->ntn_Config_r17->ta_Info_r17 = calloc_or_fail(1, sizeof(*scc->ext2->ntn_Config_r17->ta_Info_r17));
|
||||
scc->ext2->ntn_Config_r17->ta_Info_r17->ta_Common_r17 = -1;
|
||||
scc->ext2->ntn_Config_r17->ta_Info_r17->ta_CommonDrift_r17 = calloc_or_fail(1, sizeof(*scc->ext2->ntn_Config_r17->ta_Info_r17->ta_CommonDrift_r17));
|
||||
|
||||
scc->ext2->ntn_Config_r17->ephemerisInfo_r17->present = NR_EphemerisInfo_r17_PR_positionVelocity_r17;
|
||||
scc->ext2->ntn_Config_r17->ephemerisInfo_r17->choice.positionVelocity_r17 =
|
||||
calloc_or_fail(1, sizeof(*scc->ext2->ntn_Config_r17->ephemerisInfo_r17->choice.positionVelocity_r17));
|
||||
scc->ext2->ntn_Config_r17->ephemerisInfo_r17->choice.positionVelocity_r17->positionX_r17 = LONG_MAX;
|
||||
scc->ext2->ntn_Config_r17->ephemerisInfo_r17->choice.positionVelocity_r17->positionY_r17 = LONG_MAX;
|
||||
scc->ext2->ntn_Config_r17->ephemerisInfo_r17->choice.positionVelocity_r17->positionZ_r17 = LONG_MAX;
|
||||
scc->ext2->ntn_Config_r17->ephemerisInfo_r17->choice.positionVelocity_r17->velocityVX_r17 = LONG_MAX;
|
||||
scc->ext2->ntn_Config_r17->ephemerisInfo_r17->choice.positionVelocity_r17->velocityVY_r17 = LONG_MAX;
|
||||
scc->ext2->ntn_Config_r17->ephemerisInfo_r17->choice.positionVelocity_r17->velocityVZ_r17 = LONG_MAX;
|
||||
}
|
||||
void prepare_msgA_scc(NR_ServingCellConfigCommon_t *scc) {
|
||||
NR_BWP_UplinkCommon_t *initialUplinkBWP = scc->uplinkConfigCommon->initialUplinkBWP;
|
||||
|
||||
@@ -267,59 +267,104 @@ static void config_common_ue_sa(NR_UE_MAC_INST_t *mac, NR_ServingCellConfigCommo
|
||||
}
|
||||
|
||||
// computes round-trip-time between ue and sat based on SIB19 ephemeris data
|
||||
static double calculate_ue_sat_ta(const position_t *position_params, NR_PositionVelocity_r17_t *sat_pos)
|
||||
static void calculate_ue_sat_ta(const position_t *position_params,
|
||||
const NR_PositionVelocity_r17_t *sat_pos,
|
||||
ntn_timing_advance_componets_t *ntn_ta)
|
||||
{
|
||||
// get UE position coordinates
|
||||
double posx = position_params->positionX;
|
||||
double posy = position_params->positionY;
|
||||
double posz = position_params->positionZ;
|
||||
const position_t pos_ue = *position_params;
|
||||
|
||||
// get sat position coordinates
|
||||
double posx_0 = (double)sat_pos->positionX_r17 * 1.3;
|
||||
double posy_0 = (double)sat_pos->positionY_r17 * 1.3;
|
||||
double posz_0 = (double)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};
|
||||
|
||||
double distance = 2 * sqrt(pow(posx - posx_0, 2) + pow(posy - posy_0, 2) + pow(posz - posz_0, 2));
|
||||
double ta_ms = (distance / SPEED_OF_LIGHT) * 1000;
|
||||
// calculate directional vector from SAT to UE
|
||||
const position_t dir_sat_ue = {pos_ue.X - pos_sat.X, pos_ue.Y - pos_sat.Y, pos_ue.Z - pos_sat.Z};
|
||||
|
||||
return ta_ms;
|
||||
// calculate distance between SAT and UE
|
||||
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);
|
||||
|
||||
// get sat velocity vector
|
||||
const position_t vel_sat = {sat_pos->velocityVX_r17 * 0.06, sat_pos->velocityVY_r17 * 0.06, sat_pos->velocityVZ_r17 * 0.06};
|
||||
|
||||
// calculate SAT velocity towards UE
|
||||
double velocity = (vel_sat.X * dir_sat_ue.X + vel_sat.Y * dir_sat_ue.Y + vel_sat.Z * dir_sat_ue.Z) / distance;
|
||||
|
||||
ntn_ta->N_UE_TA_adj = (2 * distance / SPEED_OF_LIGHT) * 1e3; // in ms
|
||||
ntn_ta->N_UE_TA_drift = (2 * -velocity / SPEED_OF_LIGHT) * 1e6; // in µs/s
|
||||
}
|
||||
|
||||
// populate ntn_ta structure from mac
|
||||
void configure_ntn_ta(module_id_t module_id, ntn_timing_advance_componets_t *ntn_ta, NR_NTN_Config_r17_t *ntn_Config_r17)
|
||||
static void configure_ntn_ta(module_id_t module_id,
|
||||
ntn_timing_advance_componets_t *ntn_ta,
|
||||
const NR_NTN_Config_r17_t *ntn_Config_r17)
|
||||
{
|
||||
if (!ntn_Config_r17)
|
||||
return;
|
||||
|
||||
position_t position_params = {0};
|
||||
get_position_coordinates(module_id, &position_params);
|
||||
|
||||
// if ephemerisInfo_r17 present in SIB19
|
||||
NR_EphemerisInfo_r17_t *ephemeris_info = ntn_Config_r17->ephemerisInfo_r17;
|
||||
// epochTime_r17 must be present (this is assured by function `eval_epoch_time()`)
|
||||
const NR_EpochTime_r17_t *epoch_time_r17 = ntn_Config_r17->epochTime_r17;
|
||||
AssertFatal(epoch_time_r17, "epoch_time_r17 should not be NULL here\n");
|
||||
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) {
|
||||
NR_PositionVelocity_r17_t *position_velocity = ephemeris_info->choice.positionVelocity_r17;
|
||||
if (position_velocity
|
||||
&& (position_velocity->positionX_r17 != 0 || position_velocity->positionY_r17 != 0
|
||||
|| position_velocity->positionZ_r17 != 0)) {
|
||||
ntn_ta->N_UE_TA_adj = calculate_ue_sat_ta(&position_params, position_velocity);
|
||||
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");
|
||||
calculate_ue_sat_ta(&position_params, position_velocity, ntn_ta);
|
||||
} else {
|
||||
LOG_W(NR_MAC, "NR UE currently supports only ephemerisInfo_r17 of type positionVelocity_r17\n");
|
||||
ntn_ta->N_UE_TA_adj = 0;
|
||||
ntn_ta->N_UE_TA_drift = 0;
|
||||
}
|
||||
} else { // Need R - Release if not present
|
||||
ntn_ta->N_UE_TA_adj = 0;
|
||||
ntn_ta->N_UE_TA_drift = 0;
|
||||
}
|
||||
// if cellSpecificKoffset_r17 is present
|
||||
if (ntn_Config_r17->cellSpecificKoffset_r17) {
|
||||
|
||||
// handle cellSpecificKoffset_r17
|
||||
if (ntn_Config_r17->cellSpecificKoffset_r17)
|
||||
ntn_ta->cell_specific_k_offset = *ntn_Config_r17->cellSpecificKoffset_r17;
|
||||
}
|
||||
// Check if ta_Info_r17 is present and convert directly ta_Common_r17 (is in units of 4.072e-3 µs)
|
||||
else // Need R - Release if not present
|
||||
ntn_ta->cell_specific_k_offset = 0;
|
||||
|
||||
// Check if ta_Info_r17 is present and convert the time units
|
||||
if (ntn_Config_r17->ta_Info_r17) {
|
||||
// ta_Common_r17 (is in units of 4.072e-3 µs)
|
||||
ntn_ta->N_common_ta_adj = ntn_Config_r17->ta_Info_r17->ta_Common_r17 * 4.072e-6;
|
||||
// ta_CommonDrift_r17 (is in units of 0.2e-3 µs/s)
|
||||
if (ntn_Config_r17->ta_Info_r17->ta_CommonDrift_r17)
|
||||
ntn_ta->ntn_ta_commondrift = *ntn_Config_r17->ta_Info_r17->ta_CommonDrift_r17 * 0.2e-3;
|
||||
ntn_ta->N_common_ta_drift = *ntn_Config_r17->ta_Info_r17->ta_CommonDrift_r17 * 0.2e-3;
|
||||
else // Need R - Release if not present
|
||||
ntn_ta->N_common_ta_drift = 0;
|
||||
// ta_CommonDriftVariant_r17 (is in units of 0.2e-4 µs/s²)
|
||||
if (ntn_Config_r17->ta_Info_r17->ta_CommonDriftVariant_r17)
|
||||
ntn_ta->N_common_ta_drift_variant = *ntn_Config_r17->ta_Info_r17->ta_CommonDriftVariant_r17 * 0.2e-4;
|
||||
else // Need R - Release if not present
|
||||
ntn_ta->N_common_ta_drift_variant = 0;
|
||||
} else { // Need R - Release if not present
|
||||
ntn_ta->N_common_ta_adj = 0;
|
||||
ntn_ta->N_common_ta_drift = 0;
|
||||
ntn_ta->N_common_ta_drift_variant = 0;
|
||||
}
|
||||
|
||||
ntn_ta->ntn_params_changed = true;
|
||||
|
||||
LOG_D(NR_MAC,
|
||||
"SIB19 Rxd. k_offset:%ld, N_Common_Ta:%f,drift:%f,N_UE_TA:%f \n",
|
||||
"SIB19 Rxd. Epoch SFN: %d, Epoch Subframe: %d, k_offset: %ldms, N_Common_Ta: %fms, drift: %fµs/s, variant %fµs/s², N_UE_TA: %fms, drift: %fµs/s\n",
|
||||
ntn_ta->epoch_sfn,
|
||||
ntn_ta->epoch_subframe,
|
||||
ntn_ta->cell_specific_k_offset,
|
||||
ntn_ta->N_common_ta_adj,
|
||||
ntn_ta->ntn_ta_commondrift,
|
||||
ntn_ta->N_UE_TA_adj);
|
||||
ntn_ta->N_common_ta_drift,
|
||||
ntn_ta->N_common_ta_drift_variant,
|
||||
ntn_ta->N_UE_TA_adj,
|
||||
ntn_ta->N_UE_TA_drift);
|
||||
}
|
||||
|
||||
static void config_common_ue(NR_UE_MAC_INST_t *mac, NR_ServingCellConfigCommon_t *scc, int cc_idP)
|
||||
@@ -1875,10 +1920,8 @@ void nr_rrc_mac_config_other_sib(module_id_t module_id, NR_SIB19_r17_t *sib19, b
|
||||
|
||||
if (sib19) {
|
||||
// update ntn_Config_r17 with received values
|
||||
NR_NTN_Config_r17_t *ntn_Config_r17 = mac->sc_info.ntn_Config_r17;
|
||||
UPDATE_IE(ntn_Config_r17, sib19->ntn_Config_r17, NR_NTN_Config_r17_t);
|
||||
|
||||
configure_ntn_ta(mac->ue_id, &mac->ntn_ta, ntn_Config_r17);
|
||||
UPDATE_IE(mac->sc_info.ntn_Config_r17, sib19->ntn_Config_r17, NR_NTN_Config_r17_t);
|
||||
configure_ntn_ta(mac->ue_id, &mac->ntn_ta, mac->sc_info.ntn_Config_r17);
|
||||
}
|
||||
if (mac->state == UE_RECEIVING_SIB && can_start_ra)
|
||||
mac->state = UE_PERFORMING_RA;
|
||||
|
||||
@@ -528,12 +528,19 @@ typedef struct {
|
||||
} si_schedInfo_t;
|
||||
|
||||
typedef struct ntn_timing_advance_components {
|
||||
int epoch_sfn;
|
||||
int epoch_subframe;
|
||||
|
||||
// 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;
|
||||
// N_UE_TA_adj calculated round-trip-time between UE and SAT (ms)
|
||||
double N_UE_TA_adj;
|
||||
// drift rate of common ta in µs/s
|
||||
double ntn_ta_commondrift;
|
||||
// drift rate of N_UE_TA in µs/s
|
||||
double N_UE_TA_drift;
|
||||
// cell scheduling offset expressed in terms of 15kHz SCS
|
||||
long cell_specific_k_offset;
|
||||
|
||||
@@ -652,15 +659,20 @@ static inline int GET_NTN_UE_K_OFFSET(const ntn_timing_advance_componets_t *ntn_
|
||||
return (int)ntn_ta->cell_specific_k_offset << scs;
|
||||
}
|
||||
|
||||
static inline double GET_COMPLETE_TIME_ADVANCE_MS(const ntn_timing_advance_componets_t *ntn_ta)
|
||||
{
|
||||
return ntn_ta->N_common_ta_adj + ntn_ta->N_UE_TA_adj;
|
||||
}
|
||||
|
||||
static inline long GET_DURATION_RX_TO_TX(const ntn_timing_advance_componets_t *ntn_ta, int scs)
|
||||
{
|
||||
return NR_UE_CAPABILITY_SLOT_RX_TO_TX + (ntn_ta->cell_specific_k_offset << scs);
|
||||
}
|
||||
|
||||
static inline double get_total_TA_ms(const ntn_timing_advance_componets_t *ntn_ta)
|
||||
{
|
||||
return ntn_ta->N_common_ta_adj + ntn_ta->N_UE_TA_adj;
|
||||
}
|
||||
|
||||
static inline double get_total_TA_drift(const ntn_timing_advance_componets_t *ntn_ta)
|
||||
{
|
||||
return ntn_ta->N_common_ta_drift + ntn_ta->N_UE_TA_drift;
|
||||
}
|
||||
|
||||
/*@}*/
|
||||
#endif /*__LAYER2_MAC_DEFS_H__ */
|
||||
|
||||
@@ -818,7 +818,7 @@ static void setup_ra_response_window(RA_config_t *ra,
|
||||
|
||||
int ta_Common_slots = 0;
|
||||
if (ntn_Config_r17) {
|
||||
const double ta_Common_ms = GET_COMPLETE_TIME_ADVANCE_MS(ntn_ta);
|
||||
const double ta_Common_ms = get_total_TA_ms(ntn_ta);
|
||||
ta_Common_slots = (int)ceil(ta_Common_ms * slots_per_frame / 10);
|
||||
}
|
||||
|
||||
@@ -1066,7 +1066,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 double ta_Common_ms = GET_COMPLETE_TIME_ADVANCE_MS(&mac->ntn_ta);
|
||||
const double ta_Common_ms = get_total_TA_ms(&mac->ntn_ta);
|
||||
const int slots_per_ms = mac->frame_structure.numb_slots_frame / 10;
|
||||
|
||||
// start contention resolution timer
|
||||
|
||||
@@ -2848,11 +2848,14 @@ static uint8_t nr_ue_get_sdu(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)
|
||||
{
|
||||
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_sfn = mac->ntn_ta.epoch_sfn;
|
||||
ntn_config_command_pdu->epoch_subframe = mac->ntn_ta.epoch_subframe;
|
||||
ntn_config_command_pdu->cell_specific_k_offset = mac->ntn_ta.cell_specific_k_offset;
|
||||
ntn_config_command_pdu->ntn_ta_commondrift = mac->ntn_ta.ntn_ta_commondrift;
|
||||
ntn_config_command_pdu->N_common_ta_adj = mac->ntn_ta.N_common_ta_adj;
|
||||
ntn_config_command_pdu->N_UE_TA_adj = mac->ntn_ta.N_UE_TA_adj;
|
||||
ntn_config_command_pdu->ntn_total_time_advance_ms = mac->ntn_ta.N_common_ta_adj + mac->ntn_ta.N_UE_TA_adj;
|
||||
ntn_config_command_pdu->ntn_total_time_advance_ms = get_total_TA_ms(&mac->ntn_ta);
|
||||
ntn_config_command_pdu->ntn_total_time_advance_drift = get_total_TA_drift(&mac->ntn_ta);
|
||||
ntn_config_command_pdu->ntn_total_time_advance_drift_variant = mac->ntn_ta.N_common_ta_drift_variant;
|
||||
|
||||
dl_config->dl_config_list[dl_config->number_pdus].pdu_type = FAPI_NR_DL_NTN_CONFIG_PARAMS;
|
||||
dl_config->number_pdus += 1;
|
||||
}
|
||||
|
||||
@@ -927,6 +927,96 @@ bool nr_mac_configure_other_sib(gNB_MAC_INST *nrmac, int num_cu_sib, const f1ap_
|
||||
return true;
|
||||
}
|
||||
|
||||
bool nr_update_sib19(const gnb_sat_position_update_t *sat_position)
|
||||
{
|
||||
gNB_MAC_INST *nrmac = RC.nrmac[0];
|
||||
NR_COMMON_channels_t *cc = &nrmac->common_channels[0];
|
||||
NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon;
|
||||
|
||||
if (!scc || !scc->ext2 || !scc->ext2->ntn_Config_r17)
|
||||
return false;
|
||||
|
||||
const vector_t *pos = &sat_position->position;
|
||||
const vector_t *vel = &sat_position->velocity;
|
||||
|
||||
LOG_D(NR_MAC, "SFN = %d, SubFrame = %d\n", sat_position->sfn, sat_position->subframe);
|
||||
LOG_D(NR_MAC, "TA_Common: value %d, %f msec\n", sat_position->delay, sat_position->delay * 4.072e-6);
|
||||
LOG_D(NR_MAC, "TA_CommonDrift: value %d, = %f µsec/sec\n", sat_position->drift, sat_position->drift * 0.2e-3);
|
||||
LOG_D(NR_MAC, "TA_CommonDriftVariant: value %d, %f µsec/sec^2\n", sat_position->accel, sat_position->accel * 0.2e-4);
|
||||
LOG_D(NR_MAC, "SAT Position: values %d/%d/%d, %.3f/%3f/%3f metres in X/Y/Z\n", pos->X, pos->Y, pos->Z, pos->X * 1.3, pos->Y * 1.3, pos->Z * 1.3);
|
||||
LOG_D(NR_MAC, "SAT Velocity: values %d/%d/%d, %.3f/%3f/%3f m/s in X/Y/Z\n", vel->X, vel->Y, vel->Z, vel->X * 0.06, vel->Y * 0.06, vel->Z * 0.06);
|
||||
|
||||
NR_SCHED_LOCK(&nrmac->sched_lock);
|
||||
|
||||
if (!scc->ext2->ntn_Config_r17->epochTime_r17)
|
||||
scc->ext2->ntn_Config_r17->epochTime_r17 = calloc (1, sizeof(*scc->ext2->ntn_Config_r17->epochTime_r17));
|
||||
|
||||
NR_EpochTime_r17_t *epoch_time_r17 = scc->ext2->ntn_Config_r17->epochTime_r17;
|
||||
epoch_time_r17->sfn_r17 = sat_position->sfn;
|
||||
epoch_time_r17->subFrameNR_r17 = sat_position->subframe;
|
||||
|
||||
if (!scc->ext2->ntn_Config_r17->ta_Info_r17)
|
||||
scc->ext2->ntn_Config_r17->ta_Info_r17 = calloc(1, sizeof(*scc->ext2->ntn_Config_r17->ta_Info_r17));
|
||||
|
||||
NR_TA_Info_r17_t *sib19_ta_info = scc->ext2->ntn_Config_r17->ta_Info_r17;
|
||||
|
||||
// SIB19 provides Round trip delay on feeder link (between gNB and SAT).
|
||||
sib19_ta_info->ta_Common_r17 = sat_position->delay;
|
||||
|
||||
if (sat_position->drift) {
|
||||
if (!sib19_ta_info->ta_CommonDrift_r17)
|
||||
sib19_ta_info->ta_CommonDrift_r17 = calloc(1, sizeof(*sib19_ta_info->ta_CommonDrift_r17));
|
||||
*sib19_ta_info->ta_CommonDrift_r17 = sat_position->drift;
|
||||
} else
|
||||
free_and_zero(sib19_ta_info->ta_CommonDrift_r17);
|
||||
|
||||
if (sat_position->accel) {
|
||||
if (!sib19_ta_info->ta_CommonDriftVariant_r17)
|
||||
sib19_ta_info->ta_CommonDriftVariant_r17 = calloc(1, sizeof(*sib19_ta_info->ta_CommonDriftVariant_r17));
|
||||
*sib19_ta_info->ta_CommonDriftVariant_r17 = sat_position->accel;
|
||||
} else
|
||||
free_and_zero(sib19_ta_info->ta_CommonDriftVariant_r17);
|
||||
|
||||
// Currently PositionVelocity is supported and not yet the OrbitalParams
|
||||
if (!scc->ext2->ntn_Config_r17->ephemerisInfo_r17) {
|
||||
scc->ext2->ntn_Config_r17->ephemerisInfo_r17 = calloc(1, sizeof(*scc->ext2->ntn_Config_r17->ephemerisInfo_r17));
|
||||
scc->ext2->ntn_Config_r17->ephemerisInfo_r17->present = NR_EphemerisInfo_r17_PR_NOTHING;
|
||||
}
|
||||
if (scc->ext2->ntn_Config_r17->ephemerisInfo_r17->present == NR_EphemerisInfo_r17_PR_orbital_r17) {
|
||||
ASN_STRUCT_FREE(asn_DEF_NR_Orbital_r17, scc->ext2->ntn_Config_r17->ephemerisInfo_r17->choice.orbital_r17);
|
||||
scc->ext2->ntn_Config_r17->ephemerisInfo_r17->choice.orbital_r17 = NULL;
|
||||
scc->ext2->ntn_Config_r17->ephemerisInfo_r17->present = NR_EphemerisInfo_r17_PR_NOTHING;
|
||||
}
|
||||
if (!scc->ext2->ntn_Config_r17->ephemerisInfo_r17->choice.positionVelocity_r17)
|
||||
scc->ext2->ntn_Config_r17->ephemerisInfo_r17->choice.positionVelocity_r17 =
|
||||
calloc(1, sizeof(*scc->ext2->ntn_Config_r17->ephemerisInfo_r17->choice.positionVelocity_r17));
|
||||
|
||||
scc->ext2->ntn_Config_r17->ephemerisInfo_r17->present = NR_EphemerisInfo_r17_PR_positionVelocity_r17;
|
||||
NR_PositionVelocity_r17_t *sib19_PosVel = scc->ext2->ntn_Config_r17->ephemerisInfo_r17->choice.positionVelocity_r17;
|
||||
|
||||
sib19_PosVel->positionX_r17 = pos->X;
|
||||
sib19_PosVel->positionY_r17 = pos->Y;
|
||||
sib19_PosVel->positionZ_r17 = pos->Z;
|
||||
sib19_PosVel->velocityVX_r17 = vel->X;
|
||||
sib19_PosVel->velocityVY_r17 = vel->Y;
|
||||
sib19_PosVel->velocityVZ_r17 = vel->Z;
|
||||
|
||||
NR_SystemInformation_IEs_t *sysInfov17 = calloc(1, sizeof(*sysInfov17)); // for othersibs
|
||||
struct NR_SystemInformation_IEs__sib_TypeAndInfo__Member *type_du = calloc(1, sizeof(*type_du));
|
||||
type_du->present = NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib19_v1700;
|
||||
NR_SIB19_r17_t *sib19 = get_SIB19_NR(cc->ServingCellConfigCommon);
|
||||
type_du->choice.sib19_v1700 = sib19;
|
||||
add_sib_to_systeminformation(sysInfov17, type_du);
|
||||
|
||||
cc->other_sib_bcch_length[1] = encode_sysinfo_ie(sysInfov17, cc->other_sib_bcch_pdu[1], sizeof(cc->other_sib_bcch_pdu[1]));
|
||||
AssertFatal(cc->other_sib_bcch_length[1] > 0, "could not encode SIB19\n");
|
||||
ASN_STRUCT_FREE(asn_DEF_NR_SystemInformation_IEs, sysInfov17);
|
||||
|
||||
NR_SCHED_UNLOCK(&nrmac->sched_lock);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void prepare_du_configuration_update(gNB_MAC_INST *mac,
|
||||
f1ap_served_cell_info_t *info,
|
||||
NR_BCCH_BCH_Message_t *mib,
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
#ifndef __LAYER2_NR_MAC_CONFIG_H__
|
||||
#define __LAYER2_NR_MAC_CONFIG_H__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
typedef struct vector_s {
|
||||
int X;
|
||||
int Y;
|
||||
int Z;
|
||||
} vector_t;
|
||||
|
||||
// Format similar to values sent in SIB19
|
||||
typedef struct gnb_sat_position_update_s {
|
||||
int sfn;
|
||||
int subframe;
|
||||
uint32_t delay;
|
||||
int drift;
|
||||
uint32_t accel;
|
||||
vector_t position;
|
||||
vector_t velocity;
|
||||
} gnb_sat_position_update_t;
|
||||
|
||||
bool nr_update_sib19(const gnb_sat_position_update_t *sat_position);
|
||||
|
||||
#endif /*__LAYER2_NR_MAC_CONFIG_H__*/
|
||||
@@ -88,6 +88,7 @@
|
||||
|
||||
/* MAC */
|
||||
#include "LAYER2/NR_MAC_COMMON/nr_mac_common.h"
|
||||
#include "LAYER2/NR_MAC_gNB/mac_config.h"
|
||||
#include "NR_TAG.h"
|
||||
|
||||
/* Defs */
|
||||
|
||||
@@ -195,7 +195,7 @@ static void get_epochtime_from_sib19scheduling(NR_UE_RRC_SI_INFO *SI_info, int *
|
||||
int slot = slot_end_sib19_window % N;
|
||||
*subframe = ceil(slot / slots_per_subframe);
|
||||
|
||||
LOG_D(NR_RRC,
|
||||
LOG_I(NR_RRC,
|
||||
"Get EPOCHTIME: x:%d, N:%d, slot_endw:%d, frame:%d, subframe:%d , slot:%d\n",
|
||||
x,
|
||||
N,
|
||||
@@ -228,7 +228,7 @@ static int eval_epoch_time(NR_UE_RRC_SI_INFO *SI_info, NR_NTN_Config_r17_t *ntnc
|
||||
// after the frame where the message indicating the epochTime is received
|
||||
// i.e. Epochframe can be present or future SFN
|
||||
diff_frames = (epoch_frame - frame + 1024) % 1024; // According to 38.331 Epochtime is defined for serving cell like this
|
||||
LOG_D(NR_RRC, "Epoch frame %d, ahead by %d frames\n", epoch_frame, diff_frames);
|
||||
LOG_I(NR_RRC, "Epoch frame %d, ahead by %d frames\n", epoch_frame, diff_frames);
|
||||
return diff_frames;
|
||||
}
|
||||
|
||||
@@ -248,7 +248,7 @@ static int get_ntn_timervalues(NR_UE_RRC_SI_INFO *SI_info, NR_NTN_Config_r17_t *
|
||||
int expire_before_ms = ((val430 >= 120) ? 10000 : 2000);
|
||||
int diff = *val430_ms - expire_before_ms;
|
||||
int sib19_timer_ms = (diff > 0) ? diff : ((*val430_ms - sib19_periodicity_ms) > 0) ? (*val430_ms - sib19_periodicity_ms) : 0;
|
||||
LOG_D(NR_RRC, "val430:%d s, T430:%d ms, sib19_timer:%d ms\n", val430, *val430_ms, sib19_timer_ms);
|
||||
LOG_I(NR_RRC, "val430:%d s, T430:%d ms, sib19_timer:%d ms\n", val430, *val430_ms, sib19_timer_ms);
|
||||
return sib19_timer_ms;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user