From 06c0374ec809a4793c3db1c23d0f1186fa78d009 Mon Sep 17 00:00:00 2001 From: Roberto Rosca Date: Mon, 2 Sep 2024 16:59:22 +0300 Subject: [PATCH 01/12] Added UE support for position coordinates taken from conf files --- CMakeLists.txt | 1 + executables/nr-ue.c | 2 ++ executables/position_interface.c | 33 +++++++++++++++++ executables/position_interface.h | 38 ++++++++++++++++++++ openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c | 8 +++-- targets/PROJECTS/GENERIC-NR-5GC/CONF/ue.conf | 6 ++++ 6 files changed, 86 insertions(+), 2 deletions(-) create mode 100644 executables/position_interface.c create mode 100644 executables/position_interface.h diff --git a/CMakeLists.txt b/CMakeLists.txt index e6147ce3fb..681c727dfc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2079,6 +2079,7 @@ add_executable(nr-uesoftmodem ${rrc_h} ${s1ap_h} ${OPENAIR_DIR}/executables/nr-uesoftmodem.c + ${OPENAIR_DIR}/executables/position_interface.c ${OPENAIR_DIR}/executables/nr-ue.c ${OPENAIR_DIR}/executables/softmodem-common.c ${OPENAIR_DIR}/radio/COMMON/common_lib.c diff --git a/executables/nr-ue.c b/executables/nr-ue.c index e2882b4224..49deb85456 100644 --- a/executables/nr-ue.c +++ b/executables/nr-ue.c @@ -41,6 +41,7 @@ #include "PHY/MODULATION/nr_modulation.h" #include "instrumentation.h" #include "common/utils/threadPool/notified_fifo.h" +#include "position_interface.h" /* * NR SLOT PROCESSING SEQUENCE @@ -157,6 +158,7 @@ void init_nr_ue_vars(PHY_VARS_NR_UE *ue, uint8_t UE_id) ue->target_Nid_cell = -1; ue->timing_advance = ue->frame_parms.samples_per_subframe * get_nrUE_params()->ntn_ta_common; + check_position(UE_id); // initialize all signal buffers init_nr_ue_signal(ue, nb_connected_gNB); diff --git a/executables/position_interface.c b/executables/position_interface.c new file mode 100644 index 0000000000..3d6bbe3094 --- /dev/null +++ b/executables/position_interface.c @@ -0,0 +1,33 @@ +#include "position_interface.h" + +extern uint16_t NB_UE_INST; +static position_t **positionArray = 0; + +position_t *check_position(int Mod_id) +{ + AssertFatal(Mod_id < NB_UE_INST, "Mod_id must be less than NB_UE_INST. Mod_id:%d NB_UE_INST:%d", Mod_id, NB_UE_INST); + if (positionArray == NULL) { + positionArray = (position_t **)calloc(1, sizeof(position_t *) * NB_UE_INST); + } + if (!positionArray[Mod_id]) { + char positionName[64]; + sprintf(positionName, "position%d", Mod_id); + positionArray[Mod_id] = (void *)init_position(positionName); + } + return (position_t *)positionArray[Mod_id]; +} + +position_t *init_position(char *sectionName) +{ + position_t *position = (position_t *)calloc(sizeof(position_t), 1); + paramdef_t position_params[] = POSITION_CONFIG_PARAMS_DEF; + int ret = config_get(config_get_if(), position_params, sizeofArray(position_params), sectionName); + AssertFatal(ret >= 0, "configuration couldn't be performed for position name: %s", sectionName); + + return position; +} + +position_t *get_position(int Mod_id) +{ + return positionArray[Mod_id]; +} \ No newline at end of file diff --git a/executables/position_interface.h b/executables/position_interface.h new file mode 100644 index 0000000000..a645961f7e --- /dev/null +++ b/executables/position_interface.h @@ -0,0 +1,38 @@ +#ifndef __POSITION_INTERFACE__H__ +#define __POSITION_INTERFACE__H__ + +#include +#include +#include "PHY/defs_nr_UE.h" +#include "executables/nr-uesoftmodem.h" + +/* position configuration parameters name */ +#define CONFIG_STRING_POSITION_X "x" +#define CONFIG_STRING_POSITION_Y "y" +#define CONFIG_STRING_POSITION_Z "z" + +#define HELP_STRING_POSITION "Postion coordinates (x, y, z) config params" + +// Position parameters config +/*----------------------------------------------------------------------------------------------------------------------------------------------------*/ +/* position configuration parameters */ +/* optname helpstr paramflags XXXptr defXXXval type numelt */ +/*----------------------------------------------------------------------------------------------------------------------------------------------------*/ +// clang-format off +#define POSITION_CONFIG_PARAMS_DEF { \ + {CONFIG_STRING_POSITION_X, HELP_STRING_POSITION, 0, .dblptr=&(position->positionX), .defuintval=0, TYPE_DOUBLE, 0}, \ + {CONFIG_STRING_POSITION_Y, HELP_STRING_POSITION, 0, .dblptr=&(position->positionY), .defuintval=0, TYPE_DOUBLE, 0}, \ + {CONFIG_STRING_POSITION_Z, HELP_STRING_POSITION, 0, .dblptr=&(position->positionZ), .defuintval=0, TYPE_DOUBLE, 0} \ +} +// clang-format on + +typedef struct { + double positionX; + double positionY; + double positionZ; +} position_t; + +position_t *check_position(int Mod_id); +position_t *init_position(char *sectionName); +position_t *get_position(int Mod_id); +#endif \ No newline at end of file diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c index 3eabec0249..dd98495fe0 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c @@ -41,10 +41,14 @@ #include #include "openair2/LAYER2/RLC/rlc.h" +#include "nr-uesoftmodem.h" + static double get_ta_Common_ms(NR_NTN_Config_r17_t *ntn_Config_r17) { - if (ntn_Config_r17 && ntn_Config_r17->ta_Info_r17) - return ntn_Config_r17->ta_Info_r17->ta_Common_r17 * 4.072e-6; // ta_Common_r17 is in units of 4.072e-3 µs + if (ntn_Config_r17 && ntn_Config_r17->ta_Info_r17) { + // ta_Common_r17 is in units of 4.072e-3 µs + return (ntn_Config_r17->ta_Info_r17->ta_Common_r17 * 4.072e-6 + get_nrUE_params()->ntn_ta_common) * 2; + } return 0.0; } diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/ue.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/ue.conf index 545b44f888..955b7b1253 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/ue.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/ue.conf @@ -6,3 +6,9 @@ dnn= "oai"; nssai_sst=1; nssai_sd=1; } + +position0 = { + x = 0.0; + y = 0.0; + z = 6371400.0; +} \ No newline at end of file From 698ff73c7f2e8baa2aa6f746091365d2c9e478fb Mon Sep 17 00:00:00 2001 From: Roberto Rosca Date: Mon, 16 Sep 2024 14:51:55 +0300 Subject: [PATCH 02/12] Added SIB19 related calculations on UE --- openair2/LAYER2/NR_MAC_UE/config_ue.c | 40 ++++++++++++++++++++++---- openair2/LAYER2/NR_MAC_UE/main_ue_nr.c | 23 --------------- openair2/RRC/NR_UE/rrc_UE.c | 7 +++-- 3 files changed, 39 insertions(+), 31 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_UE/config_ue.c b/openair2/LAYER2/NR_MAC_UE/config_ue.c index b430727955..fb027c2083 100644 --- a/openair2/LAYER2/NR_MAC_UE/config_ue.c +++ b/openair2/LAYER2/NR_MAC_UE/config_ue.c @@ -31,6 +31,7 @@ */ #define _GNU_SOURCE +#define SPEED_OF_LIGHT 299792458 //#include "mac_defs.h" #include @@ -41,6 +42,7 @@ #include "executables/softmodem-common.h" #include "SCHED_NR/phy_frame_config_nr.h" #include "oai_asn1.h" +#include "executables/position_interface.h" void set_tdd_config_nr_ue(fapi_nr_tdd_table_t *tdd_table, int mu, @@ -1746,15 +1748,43 @@ void nr_rrc_mac_config_req_sib1(module_id_t module_id, AssertFatal(!ret, "mutex failed %d\n", ret); } -void nr_rrc_mac_config_req_sib19_r17(module_id_t module_id, - NR_SIB19_r17_t *sib19_r17) +// computes delay between ue and sat based on SIB19 ephemeris data +static double calculate_ue_sat_ta(position_t *position_params, struct NR_PositionVelocity_r17 *sat_pos) +{ + // get UE position coordinates + double posx = position_params->positionX; + double posy = position_params->positionY; + double posz = position_params->positionZ; + + // 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; + + double distance = sqrt(pow(posx - posx_0, 2) + pow(posy - posy_0, 2) + pow(posz - posz_0, 2)); + // this computation will ensure 3 decimal precision + double ta_ms = round(((distance / SPEED_OF_LIGHT) * 1000) * 1000.0) / 1000.0; + + return ta_ms; +} + +void nr_rrc_mac_config_req_sib19_r17(module_id_t module_id, NR_SIB19_r17_t *sib19_r17) { NR_UE_MAC_INST_t *mac = get_mac_inst(module_id); - // ntn-Config-r17 - UPDATE_IE(mac->sc_info.ntn_Config_r17, sib19_r17->ntn_Config_r17, NR_NTN_Config_r17_t); + // ntn-Config-r17 deep copy into mac + asn_copy(&asn_DEF_NR_NTN_Config_r17, (void **)&mac->sc_info.ntn_Config_r17, sib19_r17->ntn_Config_r17); - // TODO handle other SIB19 elements + // if ephemerisInfo_r17 present in SIB19 + if (mac->sc_info.ntn_Config_r17->ephemerisInfo_r17 && mac->sc_info.ntn_Config_r17->ephemerisInfo_r17->choice.positionVelocity_r17 + && (mac->sc_info.ntn_Config_r17->ephemerisInfo_r17->choice.positionVelocity_r17->positionX_r17 != 0 + || mac->sc_info.ntn_Config_r17->ephemerisInfo_r17->choice.positionVelocity_r17->positionY_r17 != 0 + || mac->sc_info.ntn_Config_r17->ephemerisInfo_r17->choice.positionVelocity_r17->positionZ_r17 != 0)) { + get_nrUE_params()->ntn_ta_common = + calculate_ue_sat_ta(get_position(module_id), mac->sc_info.ntn_Config_r17->ephemerisInfo_r17->choice.positionVelocity_r17); + } + + get_nrUE_params()->ntn_koffset = *mac->sc_info.ntn_Config_r17->cellSpecificKoffset_r17; } static void handle_reconfiguration_with_sync(NR_UE_MAC_INST_t *mac, diff --git a/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c b/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c index 76dd88d07d..064fcc4e78 100644 --- a/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c +++ b/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c @@ -86,29 +86,6 @@ void nr_ue_init_mac(NR_UE_MAC_INST_t *mac) mac->pucch_power_control_initialized = false; mac->pusch_power_control_initialized = false; - - // Fake SIB19 reception for NTN - // TODO: remove this and implement the actual SIB19 reception instead! - if (get_nrUE_params()->ntn_koffset || get_nrUE_params()->ntn_ta_common || get_nrUE_params()->ntn_ta_commondrift) { - NR_SIB19_r17_t *sib19_r17 = calloc(1, sizeof(*sib19_r17)); - sib19_r17->ntn_Config_r17 = calloc(1, sizeof(*sib19_r17->ntn_Config_r17)); - - // NTN cellSpecificKoffset-r17 - if (get_nrUE_params()->ntn_koffset) { - asn1cCallocOne(sib19_r17->ntn_Config_r17->cellSpecificKoffset_r17, get_nrUE_params()->ntn_koffset); - } - - // NTN ta-Common-r17 - if (get_nrUE_params()->ntn_ta_common || get_nrUE_params()->ntn_ta_commondrift) { - sib19_r17->ntn_Config_r17->ta_Info_r17 = calloc(1, sizeof(*sib19_r17->ntn_Config_r17->ta_Info_r17)); - sib19_r17->ntn_Config_r17->ta_Info_r17->ta_Common_r17 = get_nrUE_params()->ntn_ta_common / 4.072e-6; // ta-Common-r17 is in units of 4.072e-3 µs, ntn_ta_common is in ms - if (get_nrUE_params()->ntn_ta_commondrift) - asn1cCallocOne(sib19_r17->ntn_Config_r17->ta_Info_r17->ta_CommonDrift_r17, get_nrUE_params()->ntn_ta_commondrift / 0.2e-3); // is in units of 0.2e-3 µs/s, ntn_ta_commondrift is in µs/s - } - - nr_rrc_mac_config_req_sib19_r17(mac->ue_id, sib19_r17); - asn1cFreeStruc(asn_DEF_NR_SIB19_r17, sib19_r17); - } } void nr_ue_mac_default_configs(NR_UE_MAC_INST_t *mac) diff --git a/openair2/RRC/NR_UE/rrc_UE.c b/openair2/RRC/NR_UE/rrc_UE.c index b46da32374..70708625f7 100644 --- a/openair2/RRC/NR_UE/rrc_UE.c +++ b/openair2/RRC/NR_UE/rrc_UE.c @@ -165,7 +165,7 @@ static void set_DRB_status(NR_UE_RRC_INST_t *rrc, NR_DRB_Identity_t drb_id, NR_R rrc->status_DRBs[drb_id - 1] = status; } -static void nr_decode_SI(NR_UE_RRC_SI_INFO *SI_info, NR_SystemInformation_t *si) +static void nr_decode_SI(NR_UE_RRC_SI_INFO *SI_info, NR_SystemInformation_t *si, instance_t ue_id) { VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_UE_DECODE_SI, VCD_FUNCTION_IN); @@ -241,6 +241,7 @@ static void nr_decode_SI(NR_UE_RRC_SI_INFO *SI_info, NR_SystemInformation_t *si) SI_info->SInfo_r17.sib19_validity = true; if (g_log->log_component[NR_RRC].level >= OAILOG_DEBUG) xer_fprint(stdout, &asn_DEF_NR_SIB19_r17, (const void *)typeandinfo->choice.sib19_v1700); + nr_rrc_mac_config_req_sib19_r17(ue_id, typeandinfo->choice.sib19_v1700); nr_timer_start(&SI_info->SInfo_r17.sib19_timer); break; default: @@ -386,7 +387,7 @@ static void nr_rrc_process_reconfiguration_v1530(NR_UE_RRC_INST_t *rrc, NR_RRCRe SEQUENCE_free(&asn_DEF_NR_SystemInformation, si, 1); } else { LOG_I(NR_RRC, "[UE %ld] Decoding dedicatedSystemInformationDelivery\n", rrc->ue_id); - nr_decode_SI(SI_info, si); + nr_decode_SI(SI_info, si, rrc->ue_id); } } if (rec_1530->otherConfig) { @@ -895,7 +896,7 @@ static int8_t nr_rrc_ue_decode_NR_BCCH_DL_SCH_Message(NR_UE_RRC_INST_t *rrc, case NR_BCCH_DL_SCH_MessageType__c1_PR_systemInformation: LOG_I(NR_RRC, "[UE %ld] Decoding SI\n", rrc->ue_id); NR_SystemInformation_t *si = bcch_message->message.choice.c1->choice.systemInformation; - nr_decode_SI(SI_info, si); + nr_decode_SI(SI_info, si, rrc->ue_id); break; case NR_BCCH_DL_SCH_MessageType__c1_PR_NOTHING: default: From f88c47ba3ec561b16c8d7b9a211cb31516105e03 Mon Sep 17 00:00:00 2001 From: Roberto Rosca Date: Wed, 25 Sep 2024 09:28:04 +0300 Subject: [PATCH 03/12] Adding first layer timing advance - Added new structure to hold timing advance parameters - Made SIB19 related calculation to save to this struct - Modified in ra to get ta struct values --- executables/nr-ue.c | 2 +- openair2/LAYER2/NR_MAC_UE/config_ue.c | 13 ++++++++++--- openair2/LAYER2/NR_MAC_UE/mac_defs.h | 9 +++++++++ openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c | 11 ++++------- 4 files changed, 24 insertions(+), 11 deletions(-) diff --git a/executables/nr-ue.c b/executables/nr-ue.c index 49deb85456..993701fb11 100644 --- a/executables/nr-ue.c +++ b/executables/nr-ue.c @@ -156,7 +156,7 @@ void init_nr_ue_vars(PHY_VARS_NR_UE *ue, uint8_t UE_id) ue->if_inst = nr_ue_if_module_init(UE_id); ue->dci_thres = 0; ue->target_Nid_cell = -1; - ue->timing_advance = ue->frame_parms.samples_per_subframe * get_nrUE_params()->ntn_ta_common; + ue->timing_advance = ue->frame_parms.samples_per_subframe * 2 * get_nrUE_params()->ntn_ta_common; check_position(UE_id); // initialize all signal buffers diff --git a/openair2/LAYER2/NR_MAC_UE/config_ue.c b/openair2/LAYER2/NR_MAC_UE/config_ue.c index fb027c2083..7d9a1a40a1 100644 --- a/openair2/LAYER2/NR_MAC_UE/config_ue.c +++ b/openair2/LAYER2/NR_MAC_UE/config_ue.c @@ -1775,16 +1775,23 @@ void nr_rrc_mac_config_req_sib19_r17(module_id_t module_id, NR_SIB19_r17_t *sib1 // ntn-Config-r17 deep copy into mac asn_copy(&asn_DEF_NR_NTN_Config_r17, (void **)&mac->sc_info.ntn_Config_r17, sib19_r17->ntn_Config_r17); + // populate ntn_ta structure from mac // if ephemerisInfo_r17 present in SIB19 if (mac->sc_info.ntn_Config_r17->ephemerisInfo_r17 && mac->sc_info.ntn_Config_r17->ephemerisInfo_r17->choice.positionVelocity_r17 && (mac->sc_info.ntn_Config_r17->ephemerisInfo_r17->choice.positionVelocity_r17->positionX_r17 != 0 || mac->sc_info.ntn_Config_r17->ephemerisInfo_r17->choice.positionVelocity_r17->positionY_r17 != 0 || mac->sc_info.ntn_Config_r17->ephemerisInfo_r17->choice.positionVelocity_r17->positionZ_r17 != 0)) { - get_nrUE_params()->ntn_ta_common = + mac->ntn_ta.N_UE_TA_adj = calculate_ue_sat_ta(get_position(module_id), mac->sc_info.ntn_Config_r17->ephemerisInfo_r17->choice.positionVelocity_r17); } - - get_nrUE_params()->ntn_koffset = *mac->sc_info.ntn_Config_r17->cellSpecificKoffset_r17; + // if cellSpecificKoffset_r17 is present + if (sib19_r17->ntn_Config_r17->cellSpecificKoffset_r17) { + mac->ntn_ta.cell_specific_k_offset = *sib19_r17->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) + if (sib19_r17->ntn_Config_r17->ta_Info_r17) { + mac->ntn_ta.N_common_ta_adj = sib19_r17->ntn_Config_r17->ta_Info_r17->ta_Common_r17 * 4.072e-6; + } } static void handle_reconfiguration_with_sync(NR_UE_MAC_INST_t *mac, diff --git a/openair2/LAYER2/NR_MAC_UE/mac_defs.h b/openair2/LAYER2/NR_MAC_UE/mac_defs.h index 51b9c29058..7c8f37175f 100644 --- a/openair2/LAYER2/NR_MAC_UE/mac_defs.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_defs.h @@ -554,6 +554,13 @@ typedef struct { A_SEQUENCE_OF(si_schedinfo_config_t) si_SchedInfo_list; } si_schedInfo_t; +typedef struct ntn_timing_advance_components { +// N_common_ta_adj and N_UE_TA_adj are in ms +double N_common_ta_adj; +double N_UE_TA_adj; +long cell_specific_k_offset; +} ntn_timing_advance_componets_t; + /*!\brief Top level UE MAC structure */ typedef struct NR_UE_MAC_INST_s { module_id_t ue_id; @@ -623,6 +630,8 @@ typedef struct NR_UE_MAC_INST_s { int p_Max_alt; int n_ta_offset; // -1 not present, otherwise value to be applied + ntn_timing_advance_componets_t ntn_ta; + long pdsch_HARQ_ACK_Codebook; NR_Type0_PDCCH_CSS_config_t type0_PDCCH_CSS_config; diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c index dd98495fe0..98f1d7a9e8 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c @@ -40,16 +40,13 @@ #include #include "openair2/LAYER2/RLC/rlc.h" +#include "openair2/LAYER2/NR_MAC_UE/mac_defs.h" #include "nr-uesoftmodem.h" -static double get_ta_Common_ms(NR_NTN_Config_r17_t *ntn_Config_r17) +static double get_ta_Common_ms(const ntn_timing_advance_componets_t* ntn_ta) { - if (ntn_Config_r17 && ntn_Config_r17->ta_Info_r17) { - // ta_Common_r17 is in units of 4.072e-3 µs - return (ntn_Config_r17->ta_Info_r17->ta_Common_r17 * 4.072e-6 + get_nrUE_params()->ntn_ta_common) * 2; - } - return 0.0; + return (ntn_ta->N_common_ta_adj + ntn_ta->N_UE_TA_adj) * 2; } int16_t get_prach_tx_power(NR_UE_MAC_INST_t *mac) @@ -625,7 +622,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_ta_Common_ms(mac->sc_info.ntn_Config_r17); + const double ta_Common_ms = get_ta_Common_ms(&mac->ntn_ta); const int mu = mac->current_UL_BWP->scs; const int slots_per_ms = nr_slots_per_frame[mu] / 10; From 486f4f5f966c59187a7000b2215af8fbb7fedf62 Mon Sep 17 00:00:00 2001 From: Roberto Rosca Date: Thu, 26 Sep 2024 15:47:54 +0300 Subject: [PATCH 04/12] Adding second layer timing advance - Renamed position coordinates function (better readability) - Introduced large timing advance compensation mechanism --- executables/nr-ue.c | 44 ++++++++++++++++---- executables/position_interface.c | 9 ++-- executables/position_interface.h | 4 +- openair1/PHY/defs_nr_UE.h | 5 ++- openair2/LAYER2/NR_MAC_UE/config_ue.c | 10 +++-- openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c | 2 +- 6 files changed, 54 insertions(+), 20 deletions(-) diff --git a/executables/nr-ue.c b/executables/nr-ue.c index 993701fb11..7704d59a7d 100644 --- a/executables/nr-ue.c +++ b/executables/nr-ue.c @@ -43,6 +43,8 @@ #include "common/utils/threadPool/notified_fifo.h" #include "position_interface.h" +extern unsigned int NTN_UE_Koffset; + /* * NR SLOT PROCESSING SEQUENCE * @@ -156,9 +158,8 @@ void init_nr_ue_vars(PHY_VARS_NR_UE *ue, uint8_t UE_id) ue->if_inst = nr_ue_if_module_init(UE_id); ue->dci_thres = 0; ue->target_Nid_cell = -1; - ue->timing_advance = ue->frame_parms.samples_per_subframe * 2 * get_nrUE_params()->ntn_ta_common; - check_position(UE_id); + config_position_coordinates(UE_id); // initialize all signal buffers init_nr_ue_signal(ue, nb_connected_gNB); @@ -552,7 +553,7 @@ void processSlotTX(void *arg) int slots_per_frame = (UE->sl_mode == 2) ? UE->SL_UE_PHY_PARAMS.sl_frame_params.slots_per_frame : UE->frame_parms.slots_per_frame; - int next_slot = (proc->nr_slot_tx + 1) % slots_per_frame; + int next_slot = (proc->nr_slot_tx + 1 + proc->nr_slot_tx_offset) % slots_per_frame; dynamic_barrier_join(&UE->process_slot_tx_barriers[next_slot]); RU_write(rxtxD, sl_tx_action); free(rxtxD); @@ -827,7 +828,15 @@ void *UE_thread(void *arg) readFrame(UE, &tmp, true); } + double ntn_ta_common = (mac->ntn_ta.N_common_ta_adj + mac->ntn_ta.N_UE_TA_adj) * 2; + int ntn_koffset = mac->ntn_ta.cell_specific_k_offset; + + int duration_rx_to_tx = DURATION_RX_TO_TX; + int nr_slot_tx_offset = 0; + bool update_ntn_system_information = false; + while (!oai_exit) { + nr_slot_tx_offset = 0; if (syncRunning) { notifiedFIFO_elt_t *res = pollNotifiedFIFO(&nf); @@ -935,14 +944,31 @@ void *UE_thread(void *arg) absolute_slot++; TracyCFrameMark; + if (update_ntn_system_information) { + update_ntn_system_information = false; + int ta_offset = + UE->frame_parms.samples_per_subframe * 2 * (mac->ntn_ta.N_common_ta_adj + mac->ntn_ta.N_UE_TA_adj - ntn_ta_common); + + UE->timing_advance += ta_offset; + timing_advance = ntn_koffset * 7680; + ntn_ta_common = mac->ntn_ta.N_common_ta_adj + mac->ntn_ta.N_UE_TA_adj; + } + + if (ntn_koffset != mac->ntn_ta.cell_specific_k_offset && ntn_ta_common != mac->ntn_ta.N_common_ta_adj) { + ntn_koffset = mac->ntn_ta.cell_specific_k_offset; + NTN_UE_Koffset = ntn_koffset; + update_ntn_system_information = true; + nr_slot_tx_offset = mac->ntn_ta.cell_specific_k_offset % nb_slot_frame; + } + int slot_nr = absolute_slot % nb_slot_frame; nr_rxtx_thread_data_t curMsg = {0}; curMsg.UE=UE; // update thread index for received subframe curMsg.proc.nr_slot_rx = slot_nr; - curMsg.proc.nr_slot_tx = (absolute_slot + DURATION_RX_TO_TX) % nb_slot_frame; + curMsg.proc.nr_slot_tx = (absolute_slot + duration_rx_to_tx) % nb_slot_frame; curMsg.proc.frame_rx = (absolute_slot / nb_slot_frame) % MAX_FRAME_NUMBER; - curMsg.proc.frame_tx = ((absolute_slot + DURATION_RX_TO_TX) / nb_slot_frame) % MAX_FRAME_NUMBER; + curMsg.proc.frame_tx = ((absolute_slot + duration_rx_to_tx) / nb_slot_frame) % MAX_FRAME_NUMBER; if (UE->received_config_request) { if (UE->sl_mode) { curMsg.proc.rx_slot_type = sl_nr_ue_slot_select(sl_cfg, curMsg.proc.nr_slot_rx, TDD); @@ -995,11 +1021,11 @@ void *UE_thread(void *arg) } // use previous timing_advance value to compute writeTimestamp - const openair0_timestamp writeTimestamp = rx_timestamp + fp->get_samples_slot_timestamp(slot_nr, fp, DURATION_RX_TO_TX) + const openair0_timestamp writeTimestamp = rx_timestamp + fp->get_samples_slot_timestamp(slot_nr, fp, duration_rx_to_tx) - firstSymSamp - UE->N_TA_offset - timing_advance; // but use current UE->timing_advance value to compute writeBlockSize - int writeBlockSize = fp->get_samples_per_slot((slot_nr + DURATION_RX_TO_TX) % nb_slot_frame, fp) - iq_shift_to_apply; + int writeBlockSize = fp->get_samples_per_slot((slot_nr + duration_rx_to_tx) % nb_slot_frame, fp) - iq_shift_to_apply; if (UE->timing_advance != timing_advance) { writeBlockSize -= UE->timing_advance - timing_advance; timing_advance = UE->timing_advance; @@ -1025,6 +1051,7 @@ void *UE_thread(void *arg) curMsgTx->proc.timestamp_tx = writeTimestamp; curMsgTx->UE = UE; curMsgTx->stream_status = stream_status; + curMsgTx->proc.nr_slot_tx_offset = nr_slot_tx_offset; int sync_to_previous_thread = stream_status == STREAM_STATUS_SYNCED ? 1 : 0; int slot = curMsgTx->proc.nr_slot_tx; @@ -1034,6 +1061,9 @@ void *UE_thread(void *arg) curMsgTx); stream_status = STREAM_STATUS_SYNCED; tx_wait_for_dlsch[slot] = 0; + if (duration_rx_to_tx != DURATION_RX_TO_TX) { + duration_rx_to_tx = DURATION_RX_TO_TX; + } } return NULL; diff --git a/executables/position_interface.c b/executables/position_interface.c index 3d6bbe3094..c2cd0b09ca 100644 --- a/executables/position_interface.c +++ b/executables/position_interface.c @@ -3,7 +3,7 @@ extern uint16_t NB_UE_INST; static position_t **positionArray = 0; -position_t *check_position(int Mod_id) +void config_position_coordinates(int Mod_id) { AssertFatal(Mod_id < NB_UE_INST, "Mod_id must be less than NB_UE_INST. Mod_id:%d NB_UE_INST:%d", Mod_id, NB_UE_INST); if (positionArray == NULL) { @@ -12,18 +12,17 @@ position_t *check_position(int Mod_id) if (!positionArray[Mod_id]) { char positionName[64]; sprintf(positionName, "position%d", Mod_id); - positionArray[Mod_id] = (void *)init_position(positionName); + positionArray[Mod_id] = (void *) init_position_coordinates(positionName); } - return (position_t *)positionArray[Mod_id]; } -position_t *init_position(char *sectionName) +position_t *init_position_coordinates(char *sectionName) { position_t *position = (position_t *)calloc(sizeof(position_t), 1); paramdef_t position_params[] = POSITION_CONFIG_PARAMS_DEF; int ret = config_get(config_get_if(), position_params, sizeofArray(position_params), sectionName); AssertFatal(ret >= 0, "configuration couldn't be performed for position name: %s", sectionName); - + return position; } diff --git a/executables/position_interface.h b/executables/position_interface.h index a645961f7e..7edda34970 100644 --- a/executables/position_interface.h +++ b/executables/position_interface.h @@ -32,7 +32,7 @@ typedef struct { double positionZ; } position_t; -position_t *check_position(int Mod_id); -position_t *init_position(char *sectionName); +void config_position_coordinates(int Mod_id); +position_t *init_position_coordinates(char *sectionName); position_t *get_position(int Mod_id); #endif \ No newline at end of file diff --git a/openair1/PHY/defs_nr_UE.h b/openair1/PHY/defs_nr_UE.h index 774309831c..b5ef2b4c85 100644 --- a/openair1/PHY/defs_nr_UE.h +++ b/openair1/PHY/defs_nr_UE.h @@ -394,7 +394,6 @@ typedef struct PHY_VARS_NR_UE_s { uint8_t prs_active_gNBs; NR_DL_UE_HARQ_t dl_harq_processes[2][NR_MAX_DLSCH_HARQ_PROCESSES]; NR_UL_UE_HARQ_t ul_harq_processes[NR_MAX_ULSCH_HARQ_PROCESSES]; - //Paging parameters uint32_t IMSImod1024; uint32_t PF; @@ -540,6 +539,10 @@ typedef struct { int gNB_id; /// NR slot index within frame_tx [0 .. slots_per_frame - 1] to act upon for transmission int nr_slot_tx; + /// NR slot index tx offset to resume + /// in case of NTN, tx_offset can be changed dynamically via SIB19 + /// we need to notify the right tx thread slot based on TX offset change + int nr_slot_tx_offset; int rx_slot_type; /// NR slot index within frame_rx [0 .. slots_per_frame - 1] to act upon for transmission int nr_slot_rx; diff --git a/openair2/LAYER2/NR_MAC_UE/config_ue.c b/openair2/LAYER2/NR_MAC_UE/config_ue.c index 7d9a1a40a1..1400548665 100644 --- a/openair2/LAYER2/NR_MAC_UE/config_ue.c +++ b/openair2/LAYER2/NR_MAC_UE/config_ue.c @@ -1777,10 +1777,12 @@ void nr_rrc_mac_config_req_sib19_r17(module_id_t module_id, NR_SIB19_r17_t *sib1 // populate ntn_ta structure from mac // if ephemerisInfo_r17 present in SIB19 - if (mac->sc_info.ntn_Config_r17->ephemerisInfo_r17 && mac->sc_info.ntn_Config_r17->ephemerisInfo_r17->choice.positionVelocity_r17 - && (mac->sc_info.ntn_Config_r17->ephemerisInfo_r17->choice.positionVelocity_r17->positionX_r17 != 0 - || mac->sc_info.ntn_Config_r17->ephemerisInfo_r17->choice.positionVelocity_r17->positionY_r17 != 0 - || mac->sc_info.ntn_Config_r17->ephemerisInfo_r17->choice.positionVelocity_r17->positionZ_r17 != 0)) { + struct NR_EphemerisInfo_r17 *ephemeris_info = mac->sc_info.ntn_Config_r17->ephemerisInfo_r17; + struct NR_PositionVelocity_r17 *position_velocity = mac->sc_info.ntn_Config_r17->ephemerisInfo_r17->choice.positionVelocity_r17; + + if (ephemeris_info && position_velocity + && (position_velocity->positionX_r17 != 0 || position_velocity->positionY_r17 != 0 + || position_velocity->positionZ_r17 != 0)) { mac->ntn_ta.N_UE_TA_adj = calculate_ue_sat_ta(get_position(module_id), mac->sc_info.ntn_Config_r17->ephemerisInfo_r17->choice.positionVelocity_r17); } diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c index 98f1d7a9e8..e30b69f6be 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c @@ -923,7 +923,7 @@ void nr_get_RA_window(NR_UE_MAC_INST_t *mac) NR_RACH_ConfigCommon_t *setup = mac->current_UL_BWP->rach_ConfigCommon; AssertFatal(&setup->rach_ConfigGeneric != NULL, "In %s: FATAL! rach_ConfigGeneric is NULL...\n", __FUNCTION__); - const double ta_Common_ms = get_ta_Common_ms(mac->sc_info.ntn_Config_r17); + const double ta_Common_ms = get_ta_Common_ms(&mac->ntn_ta); const int mu = mac->current_DL_BWP->scs; const int slots_per_ms = nr_slots_per_frame[mu] / 10; From bd7fb492fd9b32eb3326cd660d5de94126051fd2 Mon Sep 17 00:00:00 2001 From: Roberto Rosca Date: Thu, 3 Oct 2024 12:36:26 +0300 Subject: [PATCH 05/12] Removed SIB19 related UE arguments - Removed ntn_koffset, ntn_ta_common, ntn_ta_commondrift arguments in order to be used directly from SIB19 - Removed global NTN_UE_Koffset variable and it's use - Introduced getter functions for ntn related parameters --- CMakeLists.txt | 4 +++ executables/nr-ue.c | 33 +++++++++-------- executables/nr-uesoftmodem.c | 6 ---- executables/nr-uesoftmodem.h | 9 ----- executables/position_interface.c | 2 +- executables/position_interface.h | 2 +- openair1/PHY/impl_defs_top.h | 18 ++-------- openair2/LAYER2/NR_MAC_UE/config_ue.c | 38 +++++++++++--------- openair2/LAYER2/NR_MAC_UE/mac_defs.h | 11 ++++-- openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c | 10 ++---- openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c | 31 +++++++--------- openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c | 28 +++++++-------- targets/PROJECTS/GENERIC-NR-5GC/CONF/ue.conf | 2 +- 13 files changed, 85 insertions(+), 109 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 681c727dfc..b7b245ab76 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1942,6 +1942,7 @@ target_link_libraries(lte-softmodem PRIVATE target_link_libraries(lte-softmodem PRIVATE pthread m CONFIG_LIB rt sctp) target_link_libraries(lte-softmodem PRIVATE ${T_LIB}) target_link_libraries(lte-softmodem PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs) +target_link_libraries(lte-softmodem PRIVATE ${blas_LIBRARIES} ${cblas_LIBRARIES} ${lapacke_LIBRARIES} ${lapack_LIBRARIES}) if(E2_AGENT) target_compile_definitions(lte-softmodem PRIVATE ${E2AP_VERSION} ${KPM_VERSION} E2_AGENT) @@ -1997,6 +1998,7 @@ target_link_libraries(lte-uesoftmodem PRIVATE target_link_libraries(lte-uesoftmodem PRIVATE pthread m CONFIG_LIB rt sctp) target_link_libraries(lte-uesoftmodem PRIVATE ${T_LIB}) target_link_libraries(lte-uesoftmodem PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs) +target_link_libraries(lte-uesoftmodem PRIVATE ${blas_LIBRARIES} ${cblas_LIBRARIES} ${lapacke_LIBRARIES} ${lapack_LIBRARIES}) # force the generation of ASN.1 so that we don't need to wait during the build target_link_libraries(lte-uesoftmodem PRIVATE @@ -2217,6 +2219,7 @@ target_link_libraries(nr_pucchsim PRIVATE target_link_libraries(nr_pucchsim PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs) add_executable(nr_dlsim + ${OPENAIR_DIR}/executables/position_interface.c ${OPENAIR1_DIR}/SIMULATION/NR_PHY/dlsim.c ${OPENAIR1_DIR}/SIMULATION/NR_PHY/nr_dummy_functions.c ${OPENAIR_DIR}/executables/softmodem-common.c @@ -2252,6 +2255,7 @@ target_link_libraries(nr_ulschsim PRIVATE target_link_libraries(nr_ulschsim PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs) add_executable(nr_ulsim + ${OPENAIR_DIR}/executables/position_interface.c ${OPENAIR1_DIR}/SIMULATION/NR_PHY/ulsim.c ${OPENAIR1_DIR}/SIMULATION/NR_PHY/nr_dummy_functions.c ${OPENAIR_DIR}/executables/softmodem-common.c diff --git a/executables/nr-ue.c b/executables/nr-ue.c index 7704d59a7d..a70e9edd4e 100644 --- a/executables/nr-ue.c +++ b/executables/nr-ue.c @@ -43,8 +43,6 @@ #include "common/utils/threadPool/notified_fifo.h" #include "position_interface.h" -extern unsigned int NTN_UE_Koffset; - /* * NR SLOT PROCESSING SEQUENCE * @@ -828,12 +826,13 @@ void *UE_thread(void *arg) readFrame(UE, &tmp, true); } - double ntn_ta_common = (mac->ntn_ta.N_common_ta_adj + mac->ntn_ta.N_UE_TA_adj) * 2; - int ntn_koffset = mac->ntn_ta.cell_specific_k_offset; + double ntn_ta_common = GET_COMPLETE_TIME_ADVANCE_MS(mac); + int ntn_koffset = GET_NTN_UE_K_OFFSET(mac, 0); - int duration_rx_to_tx = DURATION_RX_TO_TX; + int duration_rx_to_tx = GET_DURATION_RX_TO_TX(mac); int nr_slot_tx_offset = 0; bool update_ntn_system_information = false; + bool apply_duration_next_run = false; while (!oai_exit) { nr_slot_tx_offset = 0; @@ -907,7 +906,7 @@ void *UE_thread(void *arg) openair0_write_reorder_clear_context(&UE->rfdevice); if (get_nrUE_params()->time_sync_I) // ntn_ta_commondrift is in µs/s, max_pos_acc * time_sync_I is in samples/frame - UE->max_pos_acc = get_nrUE_params()->ntn_ta_commondrift * 1e-6 * fp->samples_per_frame / get_nrUE_params()->time_sync_I; + UE->max_pos_acc = mac->ntn_ta.ntn_ta_commondrift * 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 @@ -946,17 +945,15 @@ void *UE_thread(void *arg) if (update_ntn_system_information) { update_ntn_system_information = false; - int ta_offset = - UE->frame_parms.samples_per_subframe * 2 * (mac->ntn_ta.N_common_ta_adj + mac->ntn_ta.N_UE_TA_adj - ntn_ta_common); + int ta_offset = UE->frame_parms.samples_per_subframe * (GET_COMPLETE_TIME_ADVANCE_MS(mac) - ntn_ta_common); UE->timing_advance += ta_offset; - timing_advance = ntn_koffset * 7680; - ntn_ta_common = mac->ntn_ta.N_common_ta_adj + mac->ntn_ta.N_UE_TA_adj; + ntn_ta_common = GET_COMPLETE_TIME_ADVANCE_MS(mac); + ntn_koffset = GET_NTN_UE_K_OFFSET(mac, 0); + timing_advance = ntn_koffset * (UE->frame_parms.samples_per_subframe >> mac->current_UL_BWP->scs); } - if (ntn_koffset != mac->ntn_ta.cell_specific_k_offset && ntn_ta_common != mac->ntn_ta.N_common_ta_adj) { - ntn_koffset = mac->ntn_ta.cell_specific_k_offset; - NTN_UE_Koffset = ntn_koffset; + if (ntn_koffset != (GET_NTN_UE_K_OFFSET(mac, 0)) && ntn_ta_common != GET_COMPLETE_TIME_ADVANCE_MS(mac)) { update_ntn_system_information = true; nr_slot_tx_offset = mac->ntn_ta.cell_specific_k_offset % nb_slot_frame; } @@ -1061,8 +1058,14 @@ void *UE_thread(void *arg) curMsgTx); stream_status = STREAM_STATUS_SYNCED; tx_wait_for_dlsch[slot] = 0; - if (duration_rx_to_tx != DURATION_RX_TO_TX) { - duration_rx_to_tx = DURATION_RX_TO_TX; + // apply new duration next run to avoid thread dead lock + if (apply_duration_next_run) { + duration_rx_to_tx = GET_DURATION_RX_TO_TX(mac); + apply_duration_next_run = false; + } + + if (duration_rx_to_tx != GET_DURATION_RX_TO_TX(mac)) { + apply_duration_next_run = true; } } diff --git a/executables/nr-uesoftmodem.c b/executables/nr-uesoftmodem.c index ff8a7f7fa8..3d6a4ae0a8 100644 --- a/executables/nr-uesoftmodem.c +++ b/executables/nr-uesoftmodem.c @@ -129,9 +129,6 @@ int otg_enabled; double cpuf; uint32_t N_RB_DL = 106; -// NTN cellSpecificKoffset-r17, but in slots for DL SCS -unsigned int NTN_UE_Koffset = 0; - int create_tasks_nrue(uint32_t ue_nb) { LOG_D(NR_RRC, "%s(ue_nb:%d)\n", __FUNCTION__, ue_nb); itti_wait_ready(1); @@ -518,9 +515,6 @@ int main(int argc, char **argv) } } - // NTN cellSpecificKoffset-r17, but in slots for DL SCS - NTN_UE_Koffset = nrUE_params.ntn_koffset << PHY_vars_UE_g[0][0]->frame_parms.numerology_index; - init_openair0(); lock_memory_to_ram(); diff --git a/executables/nr-uesoftmodem.h b/executables/nr-uesoftmodem.h index 40ff2075a5..74aa64affe 100644 --- a/executables/nr-uesoftmodem.h +++ b/executables/nr-uesoftmodem.h @@ -12,9 +12,6 @@ #define CONFIG_HLP_MAX_LDPC_ITERATIONS "Maximum LDPC decoder iterations\n" #define CONFIG_HLP_TIME_SYNC_P "coefficient for Proportional part of time sync PI controller\n" #define CONFIG_HLP_TIME_SYNC_I "coefficient for Integrating part of time sync PI controller\n" -#define CONFIG_HLP_NTN_KOFFSET "NTN cellSpecificKoffset-r17 (number of slots for a given subcarrier spacing of 15 kHz)\n" -#define CONFIG_HLP_NTN_TA_COMMON "NTN ta-Common, but given in ms\n" -#define CONFIG_HLP_NTN_TA_COMMONDRIFT "NTN ta-CommonDrift, but given in µs/s\n" #define CONFIG_HLP_AUTONOMOUS_TA "Autonomously update TA based on DL drift (useful if main contribution to DL drift is movement, e.g. LEO satellite)\n" #define CONFIG_HLP_AGC "Rx Gain control used for UE\n" @@ -67,9 +64,6 @@ {"num-ues", NULL, 0, .iptr=&(NB_UE_INST), .defuintval=1, TYPE_INT, 0}, \ {"time-sync-P", CONFIG_HLP_TIME_SYNC_P, 0, .dblptr=&(nrUE_params.time_sync_P), .defdblval=0.5, TYPE_DOUBLE, 0}, \ {"time-sync-I", CONFIG_HLP_TIME_SYNC_I, 0, .dblptr=&(nrUE_params.time_sync_I), .defdblval=0.0, TYPE_DOUBLE, 0}, \ - {"ntn-koffset", CONFIG_HLP_NTN_KOFFSET, 0, .uptr=&(nrUE_params.ntn_koffset), .defuintval=0, TYPE_UINT, 0}, \ - {"ntn-ta-common", CONFIG_HLP_NTN_TA_COMMON, 0, .dblptr=&(nrUE_params.ntn_ta_common), .defdblval=0.0, TYPE_DOUBLE, 0}, \ - {"ntn-ta-commondrift", CONFIG_HLP_NTN_TA_COMMONDRIFT, 0, .dblptr=&(nrUE_params.ntn_ta_commondrift), .defdblval=0.0, TYPE_DOUBLE, 0}, \ {"autonomous-ta", CONFIG_HLP_AUTONOMOUS_TA, PARAMFLAG_BOOL, .iptr=&(nrUE_params.autonomous_ta), .defintval=0, TYPE_INT, 0}, \ {"agc", CONFIG_HLP_AGC, PARAMFLAG_BOOL, .iptr=&(nrUE_params.agc), .defintval=0, TYPE_INT, 0}, \ } @@ -94,9 +88,6 @@ typedef struct { int ldpc_offload_flag; double time_sync_P; double time_sync_I; - unsigned int ntn_koffset; - double ntn_ta_common; - double ntn_ta_commondrift; int autonomous_ta; int agc; char *usrp_args; diff --git a/executables/position_interface.c b/executables/position_interface.c index c2cd0b09ca..885859014d 100644 --- a/executables/position_interface.c +++ b/executables/position_interface.c @@ -26,7 +26,7 @@ position_t *init_position_coordinates(char *sectionName) return position; } -position_t *get_position(int Mod_id) +position_t *get_position_coordinates(int Mod_id) { return positionArray[Mod_id]; } \ No newline at end of file diff --git a/executables/position_interface.h b/executables/position_interface.h index 7edda34970..dce6656689 100644 --- a/executables/position_interface.h +++ b/executables/position_interface.h @@ -34,5 +34,5 @@ typedef struct { void config_position_coordinates(int Mod_id); position_t *init_position_coordinates(char *sectionName); -position_t *get_position(int Mod_id); +position_t *get_position_coordinates(int Mod_id); #endif \ No newline at end of file diff --git a/openair1/PHY/impl_defs_top.h b/openair1/PHY/impl_defs_top.h index 24f1599873..27384532c5 100644 --- a/openair1/PHY/impl_defs_top.h +++ b/openair1/PHY/impl_defs_top.h @@ -276,20 +276,6 @@ /* - between reception of un uplink grant and its related transmission (k2) */ #define NR_UE_CAPABILITY_SLOT_RX_TO_TX (3) -/* When the OAI UE receives RX slot N, it starts sending TX slot N+DURATION_RX_TO_TX. - * Therefore DURATION_RX_TO_TX must not be larger than the minimum k1 and k2 values (NR_UE_CAPABILITY_SLOT_RX_TO_TX). - * In case of NTN, the propagation delay is so large, that the TX slot needs to be transmitted far in advance. - * Therefore, the NTN_UE_Koffset is added to DURATION_RX_TO_TX. - * - * Note: currently, the UE requires this to be a constant. - * But in case of NTN, Koffset is only known after receiving SIB19. - * Therefore, support should be added to allow changing DURATION_RX_TO_TX on reception of SIB19 (via FAPI-like interface). - * E.g. no transmission before successful reception of SIB19, and re-sync with disabled transmission if Koffset changes. - * When this has been implemented, the global variable NTN_UE_Koffset should be removed, too. - */ -extern unsigned int NTN_UE_Koffset; -#define DURATION_RX_TO_TX (NR_UE_CAPABILITY_SLOT_RX_TO_TX + NTN_UE_Koffset) - #define NR_MAX_ULSCH_HARQ_PROCESSES (NR_MAX_HARQ_PROCESSES) /* cf 38.214 6.1 UE procedure for receiving the physical uplink shared channel */ #define NR_MAX_DLSCH_HARQ_PROCESSES (NR_MAX_HARQ_PROCESSES) /* cf 38.214 5.1 UE procedure for receiving the physical downlink shared channel */ #endif @@ -317,6 +303,6 @@ typedef struct { #include "common/openairinterface5g_limits.h" #include "assertions.h" -#endif //__PHY_IMPLEMENTATION_DEFS_H__ -/**@} +#endif //__PHY_IMPLEMENTATION_DEFS_H__ +/**@} */ diff --git a/openair2/LAYER2/NR_MAC_UE/config_ue.c b/openair2/LAYER2/NR_MAC_UE/config_ue.c index 1400548665..6edbb55914 100644 --- a/openair2/LAYER2/NR_MAC_UE/config_ue.c +++ b/openair2/LAYER2/NR_MAC_UE/config_ue.c @@ -33,7 +33,7 @@ #define _GNU_SOURCE #define SPEED_OF_LIGHT 299792458 -//#include "mac_defs.h" +#include "mac_defs.h" #include #include "NR_MAC_UE/mac_proto.h" #include "NR_MAC-CellGroupConfig.h" @@ -254,7 +254,7 @@ static void config_common_ue(NR_UE_MAC_INST_t *mac, mac->phy_config.Mod_id = mac->ue_id; mac->phy_config.CC_id = cc_idP; - + // carrier config LOG_D(MAC, "[UE %d] Entering UE Config Common\n", mac->ue_id); @@ -1771,28 +1771,32 @@ static double calculate_ue_sat_ta(position_t *position_params, struct NR_Positio void nr_rrc_mac_config_req_sib19_r17(module_id_t module_id, NR_SIB19_r17_t *sib19_r17) { NR_UE_MAC_INST_t *mac = get_mac_inst(module_id); + struct NR_NTN_Config_r17 *ntn_Config_r17 = mac->sc_info.ntn_Config_r17; - // ntn-Config-r17 deep copy into mac - asn_copy(&asn_DEF_NR_NTN_Config_r17, (void **)&mac->sc_info.ntn_Config_r17, sib19_r17->ntn_Config_r17); + // update ntn_Config_r17 with received values + UPDATE_IE(ntn_Config_r17, sib19_r17->ntn_Config_r17, NR_NTN_Config_r17_t); // populate ntn_ta structure from mac // if ephemerisInfo_r17 present in SIB19 - struct NR_EphemerisInfo_r17 *ephemeris_info = mac->sc_info.ntn_Config_r17->ephemerisInfo_r17; - struct NR_PositionVelocity_r17 *position_velocity = mac->sc_info.ntn_Config_r17->ephemerisInfo_r17->choice.positionVelocity_r17; - - if (ephemeris_info && position_velocity - && (position_velocity->positionX_r17 != 0 || position_velocity->positionY_r17 != 0 - || position_velocity->positionZ_r17 != 0)) { - mac->ntn_ta.N_UE_TA_adj = - calculate_ue_sat_ta(get_position(module_id), mac->sc_info.ntn_Config_r17->ephemerisInfo_r17->choice.positionVelocity_r17); + struct NR_EphemerisInfo_r17 *ephemeris_info = ntn_Config_r17->ephemerisInfo_r17; + if (ephemeris_info) { + struct NR_PositionVelocity_r17 *position_velocity = ntn_Config_r17->ephemerisInfo_r17->choice.positionVelocity_r17; + if (position_velocity + && (position_velocity->positionX_r17 != 0 || position_velocity->positionY_r17 != 0 + || position_velocity->positionZ_r17 != 0)) { + mac->ntn_ta.N_UE_TA_adj = calculate_ue_sat_ta(get_position_coordinates(module_id), position_velocity); + } } // if cellSpecificKoffset_r17 is present - if (sib19_r17->ntn_Config_r17->cellSpecificKoffset_r17) { - mac->ntn_ta.cell_specific_k_offset = *sib19_r17->ntn_Config_r17->cellSpecificKoffset_r17; + if (ntn_Config_r17->cellSpecificKoffset_r17) { + mac->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) - if (sib19_r17->ntn_Config_r17->ta_Info_r17) { - mac->ntn_ta.N_common_ta_adj = sib19_r17->ntn_Config_r17->ta_Info_r17->ta_Common_r17 * 4.072e-6; + if (ntn_Config_r17->ta_Info_r17) { + mac->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) + mac->ntn_ta.ntn_ta_commondrift = *ntn_Config_r17->ta_Info_r17->ta_CommonDrift_r17 * 0.2e-3; } } @@ -2638,4 +2642,4 @@ void nr_rrc_mac_config_req_cg(module_id_t module_id, ue_init_config_request(mac, mac->current_DL_BWP->scs); ret = pthread_mutex_unlock(&mac->if_mutex); AssertFatal(!ret, "mutex failed %d\n", ret); -} +} \ No newline at end of file diff --git a/openair2/LAYER2/NR_MAC_UE/mac_defs.h b/openair2/LAYER2/NR_MAC_UE/mac_defs.h index 7c8f37175f..8f211e2215 100644 --- a/openair2/LAYER2/NR_MAC_UE/mac_defs.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_defs.h @@ -485,7 +485,6 @@ typedef struct nr_lcordered_info_s { bool lc_SRMask; } nr_lcordered_info_t; - typedef struct { uint8_t payload[NR_CCCH_PAYLOAD_SIZE_MAX]; } __attribute__ ((__packed__)) NR_CCCH_PDU; @@ -555,9 +554,13 @@ typedef struct { } si_schedInfo_t; typedef struct ntn_timing_advance_components { -// N_common_ta_adj and N_UE_TA_adj are in ms +// N_common_ta_adj represents common propagation delay received in SIB19 (ms) double N_common_ta_adj; +// N_UE_TA_adj calculated propagation delay from UE and SAT (ms) double N_UE_TA_adj; +// drift rate of common ta in µs/s +double ntn_ta_commondrift; +// cell scheduling offset expressed in terms of 15kHz SCS long cell_specific_k_offset; } ntn_timing_advance_componets_t; @@ -670,5 +673,9 @@ typedef struct NR_UE_MAC_INST_s { ue_mac_stats_t stats; } NR_UE_MAC_INST_t; +#define GET_NTN_UE_K_OFFSET(mac, scs) (mac->ntn_ta.cell_specific_k_offset << scs) +#define GET_COMPLETE_TIME_ADVANCE_MS(mac) ((mac)->ntn_ta.N_common_ta_adj + (mac)->ntn_ta.N_UE_TA_adj * 2) +#define GET_DURATION_RX_TO_TX(mac) (NR_UE_CAPABILITY_SLOT_RX_TO_TX + (mac)->ntn_ta.cell_specific_k_offset) + /*@}*/ #endif /*__LAYER2_MAC_DEFS_H__ */ diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c index e30b69f6be..45b1cf6320 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c @@ -42,12 +42,6 @@ #include "openair2/LAYER2/RLC/rlc.h" #include "openair2/LAYER2/NR_MAC_UE/mac_defs.h" -#include "nr-uesoftmodem.h" - -static double get_ta_Common_ms(const ntn_timing_advance_componets_t* ntn_ta) -{ - return (ntn_ta->N_common_ta_adj + ntn_ta->N_UE_TA_adj) * 2; -} int16_t get_prach_tx_power(NR_UE_MAC_INST_t *mac) { @@ -622,7 +616,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_ta_Common_ms(&mac->ntn_ta); + const double ta_Common_ms = GET_COMPLETE_TIME_ADVANCE_MS(mac); const int mu = mac->current_UL_BWP->scs; const int slots_per_ms = nr_slots_per_frame[mu] / 10; @@ -923,7 +917,7 @@ void nr_get_RA_window(NR_UE_MAC_INST_t *mac) NR_RACH_ConfigCommon_t *setup = mac->current_UL_BWP->rach_ConfigCommon; AssertFatal(&setup->rach_ConfigGeneric != NULL, "In %s: FATAL! rach_ConfigGeneric is NULL...\n", __FUNCTION__); - const double ta_Common_ms = get_ta_Common_ms(&mac->ntn_ta); + const double ta_Common_ms = GET_COMPLETE_TIME_ADVANCE_MS(mac); const int mu = mac->current_DL_BWP->scs; const int slots_per_ms = nr_slots_per_frame[mu] / 10; diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c index 5808cf3dcb..3f1077bb9a 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c @@ -147,13 +147,6 @@ static nr_dci_format_t nr_extract_dci_info(NR_UE_MAC_INST_t *mac, const uint8_t *dci_pdu, const int slot); -static int get_NTN_UE_Koffset(NR_NTN_Config_r17_t *ntn_Config_r17, int scs) -{ - if (ntn_Config_r17 && ntn_Config_r17->cellSpecificKoffset_r17) - return *ntn_Config_r17->cellSpecificKoffset_r17 << scs; - return 0; -} - int get_rnti_type(const NR_UE_MAC_INST_t *mac, const uint16_t rnti) { const RA_config_t *ra = &mac->ra; @@ -506,7 +499,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_Koffset(mac->sc_info.ntn_Config_r17, mac->current_UL_BWP->scs); + const int ntn_ue_koffset = GET_NTN_UE_K_OFFSET(mac, 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; @@ -604,7 +597,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_Koffset(mac->sc_info.ntn_Config_r17, mac->current_UL_BWP->scs); + const int ntn_ue_koffset = GET_NTN_UE_K_OFFSET(mac, 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; @@ -921,14 +914,14 @@ 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_Koffset(mac->sc_info.ntn_Config_r17, dlsch_pdu->SubcarrierSpacing); + const int ntn_ue_koffset = GET_NTN_UE_K_OFFSET(mac, dlsch_pdu->SubcarrierSpacing); const uint16_t feedback_ti = 1 + dci->pdsch_to_harq_feedback_timing_indicator.val + ntn_ue_koffset; if (rnti_type != TYPE_RA_RNTI_ && rnti_type != TYPE_SI_RNTI_) { - AssertFatal(feedback_ti > DURATION_RX_TO_TX, - "PDSCH to HARQ feedback time (%d) needs to be higher than DURATION_RX_TO_TX (%d).\n", + AssertFatal(feedback_ti > GET_DURATION_RX_TO_TX(mac), + "PDSCH to HARQ feedback time (%d) needs to be higher than DURATION_RX_TO_TX (%ld).\n", feedback_ti, - DURATION_RX_TO_TX); + GET_DURATION_RX_TO_TX(mac)); // set the harq status at MAC for feedback const int tpc[] = {-1, 0, 1, 3}; set_harq_status(mac, @@ -1266,14 +1259,14 @@ 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_Koffset(mac->sc_info.ntn_Config_r17, dlsch_pdu->SubcarrierSpacing); + const int ntn_ue_koffset = GET_NTN_UE_K_OFFSET(mac, dlsch_pdu->SubcarrierSpacing); const uint16_t feedback_ti = pucch_Config->dl_DataToUL_ACK->list.array[dci->pdsch_to_harq_feedback_timing_indicator.val][0] + ntn_ue_koffset; - AssertFatal(feedback_ti > DURATION_RX_TO_TX, - "PDSCH to HARQ feedback time (%d) needs to be higher than DURATION_RX_TO_TX (%d). Min feedback time set in config " + AssertFatal(feedback_ti > GET_DURATION_RX_TO_TX(mac), + "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, - DURATION_RX_TO_TX); + GET_DURATION_RX_TO_TX(mac)); // set the harq status at MAC for feedback const int tpc[] = {-1, 0, 1, 3}; @@ -3453,7 +3446,7 @@ static void set_time_alignment(NR_UE_MAC_INST_t *mac, int ta, ta_type_t type, in ul_time_alignment->ta_command = ta; ul_time_alignment->ta_apply = type; - const int ntn_ue_koffset = get_NTN_UE_Koffset(mac->sc_info.ntn_Config_r17, mac->current_UL_BWP->scs); + const int ntn_ue_koffset = GET_NTN_UE_K_OFFSET(mac, mac->current_UL_BWP->scs); const int n_slots_frame = nr_slots_per_frame[mac->current_UL_BWP->scs]; 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; @@ -4108,7 +4101,7 @@ static void nr_ue_process_rar(NR_UE_MAC_INST_t *mac, nr_downlink_indication_t *d LOG_E(MAC, "Cannot schedule Msg3. Something wrong in TDA information\n"); return; } - const int ntn_ue_koffset = get_NTN_UE_Koffset(mac->sc_info.ntn_Config_r17, mac->current_UL_BWP->scs); + const int ntn_ue_koffset = GET_NTN_UE_K_OFFSET(mac, mac->current_UL_BWP->scs); ret = nr_ue_pusch_scheduler(mac, is_Msg3, frame, slot, &frame_tx, &slot_tx, tda_info.k2 + ntn_ue_koffset); // TA command diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c index 0e9b26c773..44bcedc435 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c @@ -1266,9 +1266,9 @@ void nr_ue_aperiodic_srs_scheduling(NR_UE_MAC_INST_t *mac, long resource_trigger return; } - AssertFatal(slot_offset > DURATION_RX_TO_TX, - "Slot offset between DCI and aperiodic SRS (%d) needs to be higher than DURATION_RX_TO_TX (%d)\n", - slot_offset, DURATION_RX_TO_TX); + AssertFatal(slot_offset > GET_DURATION_RX_TO_TX(mac), + "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)); int n_slots_frame = nr_slots_per_frame[current_UL_BWP->scs]; int sched_slot = (slot + slot_offset) % n_slots_frame; NR_TDD_UL_DL_ConfigCommon_t *tdd_config = mac->tdd_UL_DL_ConfigurationCommon; @@ -1732,7 +1732,7 @@ static uint8_t nr_locate_BsrIndexByBufferSize(const uint32_t *table, int size, i // PUSCH scheduler: // - Calculate the slot in which ULSCH should be scheduled. This is current slot + K2, // - where K2 is the offset between the slot in which UL DCI is received and the slot -// - in which ULSCH should be scheduled. K2 is configured in RRC configuration. +// - in which ULSCH should be scheduled. K2 is configured in RRC configuration. // PUSCH Msg3 scheduler: // - scheduled by RAR UL grant according to 8.3 of TS 38.213 // Note: Msg3 tx in the uplink symbols of mixed slot @@ -1772,24 +1772,24 @@ int nr_ue_pusch_scheduler(const NR_UE_MAC_INST_t *mac, AssertFatal(1 == 0, "Invalid numerology %i\n", mu); } - AssertFatal((k2 + delta) > DURATION_RX_TO_TX, - "Slot offset (%ld) for Msg3 needs to be higher than DURATION_RX_TO_TX (%d). Please set min_rxtxtime at least to %d in gNB config file or gNBs.[0].min_rxtxtime=%d via command line.\n", + AssertFatal((k2 + delta) > GET_DURATION_RX_TO_TX(mac), + "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, - DURATION_RX_TO_TX, - DURATION_RX_TO_TX, - DURATION_RX_TO_TX); + GET_DURATION_RX_TO_TX(mac), + GET_DURATION_RX_TO_TX(mac), + GET_DURATION_RX_TO_TX(mac)); *slot_tx = (current_slot + k2 + delta) % nr_slots_per_frame[mu]; *frame_tx = (current_frame + (current_slot + k2 + delta) / nr_slots_per_frame[mu]) % MAX_FRAME_NUMBER; } else { - AssertFatal(k2 > DURATION_RX_TO_TX, - "Slot offset K2 (%ld) needs to be higher than DURATION_RX_TO_TX (%d). Please set min_rxtxtime at least to %d in gNB config file or gNBs.[0].min_rxtxtime=%d via command line.\n", + AssertFatal(k2 > GET_DURATION_RX_TO_TX(mac), + "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, - DURATION_RX_TO_TX, - DURATION_RX_TO_TX, - DURATION_RX_TO_TX); + GET_DURATION_RX_TO_TX(mac), + GET_DURATION_RX_TO_TX(mac), + GET_DURATION_RX_TO_TX(mac)); 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); diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/ue.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/ue.conf index 955b7b1253..115104e8f1 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/ue.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/ue.conf @@ -10,5 +10,5 @@ nssai_sd=1; position0 = { x = 0.0; y = 0.0; - z = 6371400.0; + z = 6377900.0; } \ No newline at end of file From be618b069ed09fe7ccc19aebc9738dc4dd68bf74 Mon Sep 17 00:00:00 2001 From: Roberto Rosca Date: Mon, 18 Nov 2024 16:23:28 +0200 Subject: [PATCH 06/12] Added message-based communication between L2 and L1 regarding NTN configuration parameters --- executables/nr-ue.c | 30 +++++++-------- executables/position_interface.c | 21 ++++++++++ executables/position_interface.h | 21 ++++++++++ .../nfapi/public_inc/fapi_nr_ue_constants.h | 4 +- .../nfapi/public_inc/fapi_nr_ue_interface.h | 14 +++++++ openair1/PHY/INIT/nr_init_ue.c | 2 + openair1/PHY/defs_nr_UE.h | 8 ++++ openair1/SCHED_NR_UE/fapi_nr_ue_l1.c | 16 ++++++++ openair2/LAYER2/NR_MAC_UE/config_ue.c | 11 ++++-- openair2/LAYER2/NR_MAC_UE/mac_defs.h | 35 +++++++++++------ openair2/LAYER2/NR_MAC_UE/main_ue_nr.c | 1 + openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c | 4 +- openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c | 20 +++++----- openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c | 38 ++++++++++++++----- .../gnb.sa.band66.fr1.25PRB.usrpx300.conf | 2 +- 15 files changed, 173 insertions(+), 54 deletions(-) diff --git a/executables/nr-ue.c b/executables/nr-ue.c index a70e9edd4e..2536e90060 100644 --- a/executables/nr-ue.c +++ b/executables/nr-ue.c @@ -157,6 +157,9 @@ void init_nr_ue_vars(PHY_VARS_NR_UE *ue, uint8_t UE_id) ue->dci_thres = 0; ue->target_Nid_cell = -1; + ue->ntn_config_message = CALLOC(1, sizeof(*ue->ntn_config_message)); + ue->ntn_config_message->update = false; + config_position_coordinates(UE_id); // initialize all signal buffers init_nr_ue_signal(ue, nb_connected_gNB); @@ -826,13 +829,12 @@ void *UE_thread(void *arg) readFrame(UE, &tmp, true); } - double ntn_ta_common = GET_COMPLETE_TIME_ADVANCE_MS(mac); - int ntn_koffset = GET_NTN_UE_K_OFFSET(mac, 0); + double ntn_ta_common = 0; + int ntn_koffset = 0; - int duration_rx_to_tx = GET_DURATION_RX_TO_TX(mac); + int duration_rx_to_tx = NR_UE_CAPABILITY_SLOT_RX_TO_TX; int nr_slot_tx_offset = 0; bool update_ntn_system_information = false; - bool apply_duration_next_run = false; while (!oai_exit) { nr_slot_tx_offset = 0; @@ -945,17 +947,18 @@ void *UE_thread(void *arg) if (update_ntn_system_information) { update_ntn_system_information = false; - int ta_offset = UE->frame_parms.samples_per_subframe * (GET_COMPLETE_TIME_ADVANCE_MS(mac) - ntn_ta_common); + int ta_offset = UE->frame_parms.samples_per_subframe * (UE->ntn_config_message->ntn_config_params.ntn_total_time_advance_ms - ntn_ta_common); UE->timing_advance += ta_offset; - ntn_ta_common = GET_COMPLETE_TIME_ADVANCE_MS(mac); - ntn_koffset = GET_NTN_UE_K_OFFSET(mac, 0); + ntn_ta_common = UE->ntn_config_message->ntn_config_params.ntn_total_time_advance_ms; + ntn_koffset = UE->ntn_config_message->ntn_config_params.cell_specific_k_offset; timing_advance = ntn_koffset * (UE->frame_parms.samples_per_subframe >> mac->current_UL_BWP->scs); } - if (ntn_koffset != (GET_NTN_UE_K_OFFSET(mac, 0)) && ntn_ta_common != GET_COMPLETE_TIME_ADVANCE_MS(mac)) { + if (UE->ntn_config_message->update) { + UE->ntn_config_message->update = false; update_ntn_system_information = true; - nr_slot_tx_offset = mac->ntn_ta.cell_specific_k_offset % nb_slot_frame; + nr_slot_tx_offset = UE->ntn_config_message->ntn_config_params.cell_specific_k_offset % nb_slot_frame; } int slot_nr = absolute_slot % nb_slot_frame; @@ -1059,13 +1062,8 @@ void *UE_thread(void *arg) stream_status = STREAM_STATUS_SYNCED; tx_wait_for_dlsch[slot] = 0; // apply new duration next run to avoid thread dead lock - if (apply_duration_next_run) { - duration_rx_to_tx = GET_DURATION_RX_TO_TX(mac); - apply_duration_next_run = false; - } - - if (duration_rx_to_tx != GET_DURATION_RX_TO_TX(mac)) { - apply_duration_next_run = true; + if (update_ntn_system_information) { + duration_rx_to_tx = NR_UE_CAPABILITY_SLOT_RX_TO_TX + UE->ntn_config_message->ntn_config_params.cell_specific_k_offset; } } diff --git a/executables/position_interface.c b/executables/position_interface.c index 885859014d..4aecf16604 100644 --- a/executables/position_interface.c +++ b/executables/position_interface.c @@ -1,3 +1,24 @@ +/* + * 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 + */ + #include "position_interface.h" extern uint16_t NB_UE_INST; diff --git a/executables/position_interface.h b/executables/position_interface.h index dce6656689..6fd80819e4 100644 --- a/executables/position_interface.h +++ b/executables/position_interface.h @@ -1,3 +1,24 @@ +/* + * 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 __POSITION_INTERFACE__H__ #define __POSITION_INTERFACE__H__ diff --git a/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_constants.h b/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_constants.h index 1094e82fa7..37b661afb9 100644 --- a/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_constants.h +++ b/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_constants.h @@ -51,7 +51,9 @@ #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_CONFIG_TYPES 0x08 +#define FAPI_NR_DL_NTN_CONFIG_PARAMS 0x09 +#define FAPI_NR_DL_CONFIG_TYPES 0x09 + #define FAPI_NR_CCE_REG_MAPPING_TYPE_INTERLEAVED 0x01 #define FAPI_NR_CCE_REG_MAPPING_TYPE_NON_INTERLEAVED 0x02 diff --git a/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h b/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h index d0d9fc9093..b8228778b6 100644 --- a/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h +++ b/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h @@ -555,6 +555,19 @@ typedef struct { bool is_rar; } fapi_nr_ta_command_pdu; +typedef struct { + // N_common_ta_adj represents common propagation delay received in SIB19 (ms) + double N_common_ta_adj; + // N_UE_TA_adj calculated propagation delay from UE and SAT (ms) + double N_UE_TA_adj; + // drift rate of common ta in µs/s + double ntn_ta_commondrift; + // cell scheduling offset expressed in terms of 15kHz SCS + long cell_specific_k_offset; + + double ntn_total_time_advance_ms; +} fapi_nr_dl_ntn_config_command_pdu; + typedef struct { uint8_t pdu_type; union { @@ -563,6 +576,7 @@ 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; diff --git a/openair1/PHY/INIT/nr_init_ue.c b/openair1/PHY/INIT/nr_init_ue.c index 677401ae47..1c5be50f3f 100644 --- a/openair1/PHY/INIT/nr_init_ue.c +++ b/openair1/PHY/INIT/nr_init_ue.c @@ -338,6 +338,8 @@ 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); } diff --git a/openair1/PHY/defs_nr_UE.h b/openair1/PHY/defs_nr_UE.h index b5ef2b4c85..2db8530a99 100644 --- a/openair1/PHY/defs_nr_UE.h +++ b/openair1/PHY/defs_nr_UE.h @@ -322,6 +322,11 @@ 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 { /// \brief Module ID indicator for this instance @@ -532,6 +537,9 @@ typedef struct PHY_VARS_NR_UE_s { sl_nr_ue_phy_params_t SL_UE_PHY_PARAMS; Actor_t sync_actor; Actor_t dl_actors[NUM_DL_ACTORS]; + + ntn_config_message_t* ntn_config_message; + } PHY_VARS_NR_UE; typedef struct { diff --git a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c index dc2db2d2ea..4ab9167c0a 100644 --- a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c +++ b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c @@ -326,6 +326,19 @@ 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.cell_specific_k_offset = ntn_params_message->cell_specific_k_offset; + 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.ntn_ta_commondrift = ntn_params_message->ntn_ta_commondrift; + ue->ntn_config_message->ntn_config_params.ntn_total_time_advance_ms = ntn_params_message->ntn_total_time_advance_ms; + 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 @@ -451,6 +464,9 @@ 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); } diff --git a/openair2/LAYER2/NR_MAC_UE/config_ue.c b/openair2/LAYER2/NR_MAC_UE/config_ue.c index 6edbb55914..95a08b113c 100644 --- a/openair2/LAYER2/NR_MAC_UE/config_ue.c +++ b/openair2/LAYER2/NR_MAC_UE/config_ue.c @@ -1771,16 +1771,18 @@ static double calculate_ue_sat_ta(position_t *position_params, struct NR_Positio void nr_rrc_mac_config_req_sib19_r17(module_id_t module_id, NR_SIB19_r17_t *sib19_r17) { NR_UE_MAC_INST_t *mac = get_mac_inst(module_id); - struct NR_NTN_Config_r17 *ntn_Config_r17 = mac->sc_info.ntn_Config_r17; - + int ret = pthread_mutex_lock(&mac->if_mutex); + AssertFatal(!ret, "mutex failed %d\n", ret); + // update ntn_Config_r17 with received values + struct NR_NTN_Config_r17 *ntn_Config_r17 = mac->sc_info.ntn_Config_r17; UPDATE_IE(ntn_Config_r17, sib19_r17->ntn_Config_r17, NR_NTN_Config_r17_t); // populate ntn_ta structure from mac // if ephemerisInfo_r17 present in SIB19 struct NR_EphemerisInfo_r17 *ephemeris_info = ntn_Config_r17->ephemerisInfo_r17; if (ephemeris_info) { - struct NR_PositionVelocity_r17 *position_velocity = ntn_Config_r17->ephemerisInfo_r17->choice.positionVelocity_r17; + struct NR_PositionVelocity_r17 *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)) { @@ -1798,6 +1800,9 @@ void nr_rrc_mac_config_req_sib19_r17(module_id_t module_id, NR_SIB19_r17_t *sib1 if (ntn_Config_r17->ta_Info_r17->ta_CommonDrift_r17) mac->ntn_ta.ntn_ta_commondrift = *ntn_Config_r17->ta_Info_r17->ta_CommonDrift_r17 * 0.2e-3; } + mac->ntn_ta.ntn_params_changed = true; + ret = pthread_mutex_unlock(&mac->if_mutex); + AssertFatal(!ret, "mutex failed %d\n", ret); } static void handle_reconfiguration_with_sync(NR_UE_MAC_INST_t *mac, diff --git a/openair2/LAYER2/NR_MAC_UE/mac_defs.h b/openair2/LAYER2/NR_MAC_UE/mac_defs.h index 8f211e2215..55120dca96 100644 --- a/openair2/LAYER2/NR_MAC_UE/mac_defs.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_defs.h @@ -554,14 +554,16 @@ typedef struct { } si_schedInfo_t; typedef struct ntn_timing_advance_components { -// N_common_ta_adj represents common propagation delay received in SIB19 (ms) -double N_common_ta_adj; -// N_UE_TA_adj calculated propagation delay from UE and SAT (ms) -double N_UE_TA_adj; -// drift rate of common ta in µs/s -double ntn_ta_commondrift; -// cell scheduling offset expressed in terms of 15kHz SCS -long cell_specific_k_offset; + // N_common_ta_adj represents common propagation delay received in SIB19 (ms) + double N_common_ta_adj; + // N_UE_TA_adj calculated propagation delay from UE and SAT (ms) + double N_UE_TA_adj; + // drift rate of common ta in µs/s + double ntn_ta_commondrift; + // 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 */ @@ -673,9 +675,20 @@ typedef struct NR_UE_MAC_INST_s { ue_mac_stats_t stats; } NR_UE_MAC_INST_t; -#define GET_NTN_UE_K_OFFSET(mac, scs) (mac->ntn_ta.cell_specific_k_offset << scs) -#define GET_COMPLETE_TIME_ADVANCE_MS(mac) ((mac)->ntn_ta.N_common_ta_adj + (mac)->ntn_ta.N_UE_TA_adj * 2) -#define GET_DURATION_RX_TO_TX(mac) (NR_UE_CAPABILITY_SLOT_RX_TO_TX + (mac)->ntn_ta.cell_specific_k_offset) +static inline int GET_NTN_UE_K_OFFSET(const ntn_timing_advance_componets_t *ntn_ta, int scs) +{ + 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) * 2; +} + +static inline long GET_DURATION_RX_TO_TX(const ntn_timing_advance_componets_t *ntn_ta) +{ + return NR_UE_CAPABILITY_SLOT_RX_TO_TX + ntn_ta->cell_specific_k_offset; +} /*@}*/ #endif /*__LAYER2_MAC_DEFS_H__ */ diff --git a/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c b/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c index 064fcc4e78..10d982442f 100644 --- a/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c +++ b/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c @@ -70,6 +70,7 @@ void nr_ue_init_mac(NR_UE_MAC_INST_t *mac) mac->p_Max = INT_MIN; mac->p_Max_alt = INT_MIN; mac->n_ta_offset = -1; + mac->ntn_ta.ntn_params_changed = false; pthread_mutex_init(&mac->if_mutex, NULL); reset_mac_inst(mac); diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c index 45b1cf6320..70e3019701 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c @@ -616,7 +616,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); + const double ta_Common_ms = GET_COMPLETE_TIME_ADVANCE_MS(&mac->ntn_ta); const int mu = mac->current_UL_BWP->scs; const int slots_per_ms = nr_slots_per_frame[mu] / 10; @@ -917,7 +917,7 @@ void nr_get_RA_window(NR_UE_MAC_INST_t *mac) NR_RACH_ConfigCommon_t *setup = mac->current_UL_BWP->rach_ConfigCommon; AssertFatal(&setup->rach_ConfigGeneric != NULL, "In %s: FATAL! rach_ConfigGeneric is NULL...\n", __FUNCTION__); - const double ta_Common_ms = GET_COMPLETE_TIME_ADVANCE_MS(mac); + const double ta_Common_ms = GET_COMPLETE_TIME_ADVANCE_MS(&mac->ntn_ta); const int mu = mac->current_DL_BWP->scs; const int slots_per_ms = nr_slots_per_frame[mu] / 10; diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c index 3f1077bb9a..8a46ad9a25 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c @@ -499,7 +499,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, mac->current_UL_BWP->scs); + const int ntn_ue_koffset = GET_NTN_UE_K_OFFSET(&mac->ntn_ta, 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; @@ -597,7 +597,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, mac->current_UL_BWP->scs); + const int ntn_ue_koffset = GET_NTN_UE_K_OFFSET(&mac->ntn_ta, 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; @@ -914,14 +914,14 @@ 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, dlsch_pdu->SubcarrierSpacing); + const int ntn_ue_koffset = GET_NTN_UE_K_OFFSET(&mac->ntn_ta, dlsch_pdu->SubcarrierSpacing); const uint16_t feedback_ti = 1 + dci->pdsch_to_harq_feedback_timing_indicator.val + ntn_ue_koffset; if (rnti_type != TYPE_RA_RNTI_ && rnti_type != TYPE_SI_RNTI_) { - AssertFatal(feedback_ti > GET_DURATION_RX_TO_TX(mac), + AssertFatal(feedback_ti > GET_DURATION_RX_TO_TX(&mac->ntn_ta), "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)); + GET_DURATION_RX_TO_TX(&mac->ntn_ta)); // set the harq status at MAC for feedback const int tpc[] = {-1, 0, 1, 3}; set_harq_status(mac, @@ -1259,14 +1259,14 @@ 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, dlsch_pdu->SubcarrierSpacing); + const int ntn_ue_koffset = GET_NTN_UE_K_OFFSET(&mac->ntn_ta, dlsch_pdu->SubcarrierSpacing); const uint16_t 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), + AssertFatal(feedback_ti > GET_DURATION_RX_TO_TX(&mac->ntn_ta), "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)); + GET_DURATION_RX_TO_TX(&mac->ntn_ta)); // set the harq status at MAC for feedback const int tpc[] = {-1, 0, 1, 3}; @@ -3446,7 +3446,7 @@ static void set_time_alignment(NR_UE_MAC_INST_t *mac, int ta, ta_type_t type, in ul_time_alignment->ta_command = ta; ul_time_alignment->ta_apply = type; - const int ntn_ue_koffset = GET_NTN_UE_K_OFFSET(mac, mac->current_UL_BWP->scs); + const int ntn_ue_koffset = GET_NTN_UE_K_OFFSET(&mac->ntn_ta, mac->current_UL_BWP->scs); const int n_slots_frame = nr_slots_per_frame[mac->current_UL_BWP->scs]; 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; @@ -4101,7 +4101,7 @@ static void nr_ue_process_rar(NR_UE_MAC_INST_t *mac, nr_downlink_indication_t *d LOG_E(MAC, "Cannot schedule Msg3. Something wrong in TDA information\n"); return; } - const int ntn_ue_koffset = GET_NTN_UE_K_OFFSET(mac, mac->current_UL_BWP->scs); + const int ntn_ue_koffset = GET_NTN_UE_K_OFFSET(&mac->ntn_ta, mac->current_UL_BWP->scs); ret = nr_ue_pusch_scheduler(mac, is_Msg3, frame, slot, &frame_tx, &slot_tx, tda_info.k2 + ntn_ue_koffset); // TA command diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c index 44bcedc435..8e4fbf7154 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c @@ -62,6 +62,8 @@ static void nr_ue_prach_scheduler(NR_UE_MAC_INST_t *mac, frame_t frameP, sub_frame_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, float P_CMAX, @@ -1266,9 +1268,9 @@ void nr_ue_aperiodic_srs_scheduling(NR_UE_MAC_INST_t *mac, long resource_trigger return; } - AssertFatal(slot_offset > GET_DURATION_RX_TO_TX(mac), + AssertFatal(slot_offset > GET_DURATION_RX_TO_TX(&mac->ntn_ta), "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)); + slot_offset, GET_DURATION_RX_TO_TX(&mac->ntn_ta)); int n_slots_frame = nr_slots_per_frame[current_UL_BWP->scs]; int sched_slot = (slot + slot_offset) % n_slots_frame; NR_TDD_UL_DL_ConfigCommon_t *tdd_config = mac->tdd_UL_DL_ConfigurationCommon; @@ -1368,6 +1370,11 @@ 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, @@ -1772,24 +1779,24 @@ int nr_ue_pusch_scheduler(const NR_UE_MAC_INST_t *mac, AssertFatal(1 == 0, "Invalid numerology %i\n", mu); } - AssertFatal((k2 + delta) > GET_DURATION_RX_TO_TX(mac), + AssertFatal((k2 + delta) > GET_DURATION_RX_TO_TX(&mac->ntn_ta), "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), - GET_DURATION_RX_TO_TX(mac), - GET_DURATION_RX_TO_TX(mac)); + GET_DURATION_RX_TO_TX(&mac->ntn_ta), + GET_DURATION_RX_TO_TX(&mac->ntn_ta), + GET_DURATION_RX_TO_TX(&mac->ntn_ta)); *slot_tx = (current_slot + k2 + delta) % nr_slots_per_frame[mu]; *frame_tx = (current_frame + (current_slot + k2 + delta) / nr_slots_per_frame[mu]) % MAX_FRAME_NUMBER; } else { - AssertFatal(k2 > GET_DURATION_RX_TO_TX(mac), + AssertFatal(k2 > GET_DURATION_RX_TO_TX(&mac->ntn_ta), "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), - GET_DURATION_RX_TO_TX(mac), - GET_DURATION_RX_TO_TX(mac)); + GET_DURATION_RX_TO_TX(&mac->ntn_ta), + GET_DURATION_RX_TO_TX(&mac->ntn_ta), + GET_DURATION_RX_TO_TX(&mac->ntn_ta)); 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); @@ -3591,6 +3598,17 @@ 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->cell_specific_k_offset = mac->ntn_ta.cell_specific_k_offset; + 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) * 2; + 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; diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band66.fr1.25PRB.usrpx300.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band66.fr1.25PRB.usrpx300.conf index ebf9279bbd..c8f0c31489 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band66.fr1.25PRB.usrpx300.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band66.fr1.25PRB.usrpx300.conf @@ -165,7 +165,7 @@ gNBs = #ntn_Config_r17 # cellSpecificKoffset_r17 = 478; # GEO satellite # cellSpecificKoffset_r17 = 40; # LEO satellite -# ta-Common-r17 = 29319745; +# ta-Common-r17 = 29314900; # positionX-r17 = 0; # positionY-r17 = 0; # positionZ-r17 = 32433846; From 2989bb592bb78a6b65ff66cc46d43cbdf7022f61 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Fri, 29 Nov 2024 18:56:59 +0100 Subject: [PATCH 07/12] handle position from RRC --- CMakeLists.txt | 2 -- executables/position_interface.h | 4 ++-- openair2/LAYER2/NR_MAC_UE/config_ue.c | 8 ++++---- openair2/LAYER2/NR_MAC_UE/mac_proto.h | 4 ++-- openair2/RRC/NR_UE/rrc_UE.c | 4 +++- 5 files changed, 11 insertions(+), 11 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b7b245ab76..0eb1128159 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2219,7 +2219,6 @@ target_link_libraries(nr_pucchsim PRIVATE target_link_libraries(nr_pucchsim PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs) add_executable(nr_dlsim - ${OPENAIR_DIR}/executables/position_interface.c ${OPENAIR1_DIR}/SIMULATION/NR_PHY/dlsim.c ${OPENAIR1_DIR}/SIMULATION/NR_PHY/nr_dummy_functions.c ${OPENAIR_DIR}/executables/softmodem-common.c @@ -2255,7 +2254,6 @@ target_link_libraries(nr_ulschsim PRIVATE target_link_libraries(nr_ulschsim PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs) add_executable(nr_ulsim - ${OPENAIR_DIR}/executables/position_interface.c ${OPENAIR1_DIR}/SIMULATION/NR_PHY/ulsim.c ${OPENAIR1_DIR}/SIMULATION/NR_PHY/nr_dummy_functions.c ${OPENAIR_DIR}/executables/softmodem-common.c diff --git a/executables/position_interface.h b/executables/position_interface.h index 6fd80819e4..8d8ad70d91 100644 --- a/executables/position_interface.h +++ b/executables/position_interface.h @@ -47,7 +47,7 @@ } // clang-format on -typedef struct { +typedef struct position { double positionX; double positionY; double positionZ; @@ -56,4 +56,4 @@ typedef struct { void config_position_coordinates(int Mod_id); position_t *init_position_coordinates(char *sectionName); position_t *get_position_coordinates(int Mod_id); -#endif \ No newline at end of file +#endif diff --git a/openair2/LAYER2/NR_MAC_UE/config_ue.c b/openair2/LAYER2/NR_MAC_UE/config_ue.c index 95a08b113c..a4161dbd61 100644 --- a/openair2/LAYER2/NR_MAC_UE/config_ue.c +++ b/openair2/LAYER2/NR_MAC_UE/config_ue.c @@ -1749,7 +1749,7 @@ void nr_rrc_mac_config_req_sib1(module_id_t module_id, } // computes delay between ue and sat based on SIB19 ephemeris data -static double calculate_ue_sat_ta(position_t *position_params, struct NR_PositionVelocity_r17 *sat_pos) +static double calculate_ue_sat_ta(const position_t *position_params, struct NR_PositionVelocity_r17 *sat_pos) { // get UE position coordinates double posx = position_params->positionX; @@ -1768,7 +1768,7 @@ static double calculate_ue_sat_ta(position_t *position_params, struct NR_Positio return ta_ms; } -void nr_rrc_mac_config_req_sib19_r17(module_id_t module_id, NR_SIB19_r17_t *sib19_r17) +void nr_rrc_mac_config_req_sib19_r17(module_id_t module_id, const position_t *pos, NR_SIB19_r17_t *sib19_r17) { NR_UE_MAC_INST_t *mac = get_mac_inst(module_id); int ret = pthread_mutex_lock(&mac->if_mutex); @@ -1786,7 +1786,7 @@ void nr_rrc_mac_config_req_sib19_r17(module_id_t module_id, NR_SIB19_r17_t *sib1 if (position_velocity && (position_velocity->positionX_r17 != 0 || position_velocity->positionY_r17 != 0 || position_velocity->positionZ_r17 != 0)) { - mac->ntn_ta.N_UE_TA_adj = calculate_ue_sat_ta(get_position_coordinates(module_id), position_velocity); + mac->ntn_ta.N_UE_TA_adj = calculate_ue_sat_ta(pos, position_velocity); } } // if cellSpecificKoffset_r17 is present @@ -2647,4 +2647,4 @@ void nr_rrc_mac_config_req_cg(module_id_t module_id, ue_init_config_request(mac, mac->current_DL_BWP->scs); ret = pthread_mutex_unlock(&mac->if_mutex); AssertFatal(!ret, "mutex failed %d\n", ret); -} \ No newline at end of file +} diff --git a/openair2/LAYER2/NR_MAC_UE/mac_proto.h b/openair2/LAYER2/NR_MAC_UE/mac_proto.h index 094d1e5965..d4e3dbe493 100644 --- a/openair2/LAYER2/NR_MAC_UE/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_proto.h @@ -91,8 +91,8 @@ void nr_rrc_mac_config_req_sib1(module_id_t module_id, NR_SI_SchedulingInfo_v1700_t *si_SchedulingInfo_v1700, NR_ServingCellConfigCommonSIB_t *scc); -void nr_rrc_mac_config_req_sib19_r17(module_id_t module_id, - NR_SIB19_r17_t *sib19_r17); +struct position; /* forward declaration */ +void nr_rrc_mac_config_req_sib19_r17(module_id_t module_id, const struct position *pos, NR_SIB19_r17_t *sib19_r17); void nr_rrc_mac_config_req_reset(module_id_t module_id, NR_UE_MAC_reset_cause_t cause); diff --git a/openair2/RRC/NR_UE/rrc_UE.c b/openair2/RRC/NR_UE/rrc_UE.c index 70708625f7..44534a5cb0 100644 --- a/openair2/RRC/NR_UE/rrc_UE.c +++ b/openair2/RRC/NR_UE/rrc_UE.c @@ -62,6 +62,7 @@ #include "common/utils/LOG/log.h" #include "common/utils/LOG/vcd_signal_dumper.h" +#include "executables/position_interface.h" #ifndef CELLULAR #include "RRC/NR/MESSAGES/asn1_msg.h" @@ -241,7 +242,8 @@ static void nr_decode_SI(NR_UE_RRC_SI_INFO *SI_info, NR_SystemInformation_t *si, SI_info->SInfo_r17.sib19_validity = true; if (g_log->log_component[NR_RRC].level >= OAILOG_DEBUG) xer_fprint(stdout, &asn_DEF_NR_SIB19_r17, (const void *)typeandinfo->choice.sib19_v1700); - nr_rrc_mac_config_req_sib19_r17(ue_id, typeandinfo->choice.sib19_v1700); + position_t *p = get_position_coordinates(0); + nr_rrc_mac_config_req_sib19_r17(ue_id, p, typeandinfo->choice.sib19_v1700); nr_timer_start(&SI_info->SInfo_r17.sib19_timer); break; default: From 3f74749aa69bf88a6cd57635d0b005f8df15affb Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Fri, 29 Nov 2024 19:02:41 +0100 Subject: [PATCH 08/12] Simplify position reading --- executables/nr-ue.c | 1 - executables/position_interface.c | 30 ++++++++++-------------------- executables/position_interface.h | 4 +--- openair2/RRC/NR_UE/rrc_UE.c | 4 ++-- 4 files changed, 13 insertions(+), 26 deletions(-) diff --git a/executables/nr-ue.c b/executables/nr-ue.c index 2536e90060..27f9654aa4 100644 --- a/executables/nr-ue.c +++ b/executables/nr-ue.c @@ -160,7 +160,6 @@ void init_nr_ue_vars(PHY_VARS_NR_UE *ue, uint8_t UE_id) ue->ntn_config_message = CALLOC(1, sizeof(*ue->ntn_config_message)); ue->ntn_config_message->update = false; - config_position_coordinates(UE_id); // initialize all signal buffers init_nr_ue_signal(ue, nb_connected_gNB); diff --git a/executables/position_interface.c b/executables/position_interface.c index 4aecf16604..73ce2f4cd7 100644 --- a/executables/position_interface.c +++ b/executables/position_interface.c @@ -22,32 +22,22 @@ #include "position_interface.h" extern uint16_t NB_UE_INST; -static position_t **positionArray = 0; -void config_position_coordinates(int Mod_id) +static position_t read_position_coordinates(char *sectionName) { - AssertFatal(Mod_id < NB_UE_INST, "Mod_id must be less than NB_UE_INST. Mod_id:%d NB_UE_INST:%d", Mod_id, NB_UE_INST); - if (positionArray == NULL) { - positionArray = (position_t **)calloc(1, sizeof(position_t *) * NB_UE_INST); - } - if (!positionArray[Mod_id]) { - char positionName[64]; - sprintf(positionName, "position%d", Mod_id); - positionArray[Mod_id] = (void *) init_position_coordinates(positionName); - } -} - -position_t *init_position_coordinates(char *sectionName) -{ - position_t *position = (position_t *)calloc(sizeof(position_t), 1); + position_t p; + position_t *position = &p; paramdef_t position_params[] = POSITION_CONFIG_PARAMS_DEF; int ret = config_get(config_get_if(), position_params, sizeofArray(position_params), sectionName); AssertFatal(ret >= 0, "configuration couldn't be performed for position name: %s", sectionName); - return position; + return p; } -position_t *get_position_coordinates(int Mod_id) +position_t get_position_coordinates(int Mod_id) { - return positionArray[Mod_id]; -} \ No newline at end of file + AssertFatal(Mod_id < NB_UE_INST, "Mod_id must be less than NB_UE_INST. Mod_id:%d NB_UE_INST:%d", Mod_id, NB_UE_INST); + char positionName[64]; + snprintf(positionName, sizeof(positionName), "position%d", Mod_id); + return read_position_coordinates(positionName); +} diff --git a/executables/position_interface.h b/executables/position_interface.h index 8d8ad70d91..058d94173a 100644 --- a/executables/position_interface.h +++ b/executables/position_interface.h @@ -53,7 +53,5 @@ typedef struct position { double positionZ; } position_t; -void config_position_coordinates(int Mod_id); -position_t *init_position_coordinates(char *sectionName); -position_t *get_position_coordinates(int Mod_id); +position_t get_position_coordinates(int Mod_id); #endif diff --git a/openair2/RRC/NR_UE/rrc_UE.c b/openair2/RRC/NR_UE/rrc_UE.c index 44534a5cb0..8c12e47739 100644 --- a/openair2/RRC/NR_UE/rrc_UE.c +++ b/openair2/RRC/NR_UE/rrc_UE.c @@ -242,8 +242,8 @@ static void nr_decode_SI(NR_UE_RRC_SI_INFO *SI_info, NR_SystemInformation_t *si, SI_info->SInfo_r17.sib19_validity = true; if (g_log->log_component[NR_RRC].level >= OAILOG_DEBUG) xer_fprint(stdout, &asn_DEF_NR_SIB19_r17, (const void *)typeandinfo->choice.sib19_v1700); - position_t *p = get_position_coordinates(0); - nr_rrc_mac_config_req_sib19_r17(ue_id, p, typeandinfo->choice.sib19_v1700); + position_t p = get_position_coordinates(0); + nr_rrc_mac_config_req_sib19_r17(ue_id, &p, typeandinfo->choice.sib19_v1700); nr_timer_start(&SI_info->SInfo_r17.sib19_timer); break; default: From ef55aaa7c9c572b121b839a463ee64e140e3a5ff Mon Sep 17 00:00:00 2001 From: Roberto Rosca Date: Mon, 2 Dec 2024 16:03:09 +0200 Subject: [PATCH 09/12] Store position coordinates in NR_UE_RRC_INST_t position_coordinates will be allocated and populated upon receiving SIB19 Co-authored-by: Robert Schmidt --- executables/position_interface.c | 12 ++++-------- executables/position_interface.h | 3 ++- openair2/RRC/NR_UE/rrc_UE.c | 16 +++++++++++----- openair2/RRC/NR_UE/rrc_defs.h | 4 ++++ 4 files changed, 21 insertions(+), 14 deletions(-) diff --git a/executables/position_interface.c b/executables/position_interface.c index 73ce2f4cd7..84509fbb8e 100644 --- a/executables/position_interface.c +++ b/executables/position_interface.c @@ -23,21 +23,17 @@ extern uint16_t NB_UE_INST; -static position_t read_position_coordinates(char *sectionName) +static void read_position_coordinates(char *sectionName, position_t *position) { - position_t p; - position_t *position = &p; paramdef_t position_params[] = POSITION_CONFIG_PARAMS_DEF; int ret = config_get(config_get_if(), position_params, sizeofArray(position_params), sectionName); AssertFatal(ret >= 0, "configuration couldn't be performed for position name: %s", sectionName); - - return p; } -position_t get_position_coordinates(int Mod_id) +void get_position_coordinates(int Mod_id, position_t *position) { AssertFatal(Mod_id < NB_UE_INST, "Mod_id must be less than NB_UE_INST. Mod_id:%d NB_UE_INST:%d", Mod_id, NB_UE_INST); char positionName[64]; snprintf(positionName, sizeof(positionName), "position%d", Mod_id); - return read_position_coordinates(positionName); -} + read_position_coordinates(positionName, position); +} \ No newline at end of file diff --git a/executables/position_interface.h b/executables/position_interface.h index 058d94173a..0324bceb15 100644 --- a/executables/position_interface.h +++ b/executables/position_interface.h @@ -53,5 +53,6 @@ typedef struct position { double positionZ; } position_t; -position_t get_position_coordinates(int Mod_id); +void get_position_coordinates(int Mod_id, position_t *position); + #endif diff --git a/openair2/RRC/NR_UE/rrc_UE.c b/openair2/RRC/NR_UE/rrc_UE.c index 8c12e47739..b59067430d 100644 --- a/openair2/RRC/NR_UE/rrc_UE.c +++ b/openair2/RRC/NR_UE/rrc_UE.c @@ -166,7 +166,7 @@ static void set_DRB_status(NR_UE_RRC_INST_t *rrc, NR_DRB_Identity_t drb_id, NR_R rrc->status_DRBs[drb_id - 1] = status; } -static void nr_decode_SI(NR_UE_RRC_SI_INFO *SI_info, NR_SystemInformation_t *si, instance_t ue_id) +static void nr_decode_SI(NR_UE_RRC_SI_INFO *SI_info, NR_SystemInformation_t *si, instance_t ue_id, position_t *position) { VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_UE_DECODE_SI, VCD_FUNCTION_IN); @@ -242,8 +242,14 @@ static void nr_decode_SI(NR_UE_RRC_SI_INFO *SI_info, NR_SystemInformation_t *si, SI_info->SInfo_r17.sib19_validity = true; if (g_log->log_component[NR_RRC].level >= OAILOG_DEBUG) xer_fprint(stdout, &asn_DEF_NR_SIB19_r17, (const void *)typeandinfo->choice.sib19_v1700); - position_t p = get_position_coordinates(0); - nr_rrc_mac_config_req_sib19_r17(ue_id, &p, typeandinfo->choice.sib19_v1700); + + // allocate memory for position coordinates + if (!position) + position = CALLOC(1, sizeof(*position)); + // populate position with position from config file + get_position_coordinates(ue_id, position); + + nr_rrc_mac_config_req_sib19_r17(ue_id, position, typeandinfo->choice.sib19_v1700); nr_timer_start(&SI_info->SInfo_r17.sib19_timer); break; default: @@ -389,7 +395,7 @@ static void nr_rrc_process_reconfiguration_v1530(NR_UE_RRC_INST_t *rrc, NR_RRCRe SEQUENCE_free(&asn_DEF_NR_SystemInformation, si, 1); } else { LOG_I(NR_RRC, "[UE %ld] Decoding dedicatedSystemInformationDelivery\n", rrc->ue_id); - nr_decode_SI(SI_info, si, rrc->ue_id); + nr_decode_SI(SI_info, si, rrc->ue_id, rrc->position_coordinates); } } if (rec_1530->otherConfig) { @@ -898,7 +904,7 @@ static int8_t nr_rrc_ue_decode_NR_BCCH_DL_SCH_Message(NR_UE_RRC_INST_t *rrc, case NR_BCCH_DL_SCH_MessageType__c1_PR_systemInformation: LOG_I(NR_RRC, "[UE %ld] Decoding SI\n", rrc->ue_id); NR_SystemInformation_t *si = bcch_message->message.choice.c1->choice.systemInformation; - nr_decode_SI(SI_info, si, rrc->ue_id); + nr_decode_SI(SI_info, si, rrc->ue_id, rrc->position_coordinates); break; case NR_BCCH_DL_SCH_MessageType__c1_PR_NOTHING: default: diff --git a/openair2/RRC/NR_UE/rrc_defs.h b/openair2/RRC/NR_UE/rrc_defs.h index a4cd52ee23..6d22e4ad6c 100644 --- a/openair2/RRC/NR_UE/rrc_defs.h +++ b/openair2/RRC/NR_UE/rrc_defs.h @@ -196,6 +196,8 @@ typedef struct rrcPerNB { NR_RSRP_Range_t s_measure; } rrcPerNB_t; +/* forward declaration */ +struct position; typedef struct NR_UE_RRC_INST_s { instance_t ue_id; rrcPerNB_t perNB[NB_CNX_UE]; @@ -236,6 +238,8 @@ typedef struct NR_UE_RRC_INST_s { //Sidelink params NR_SL_PreconfigurationNR_r16_t *sl_preconfig; + struct position *position_coordinates; + } NR_UE_RRC_INST_t; #endif From 0b1dd3ed501ea00f09660555c70f6de6d633aa6c Mon Sep 17 00:00:00 2001 From: Roberto Rosca Date: Fri, 6 Dec 2024 12:02:40 +0200 Subject: [PATCH 10/12] Update 5g_rfsimulator_ntn_geo docker file and configs used for test to exclude unused parameters and add ntn related values. --- ci-scripts/conf_files/gnb.sa.band66.ntn.25prb.rfsim.conf | 7 +++++++ ci-scripts/conf_files/nrue.uicc.conf | 8 +++++++- .../yaml_files/5g_rfsimulator_ntn_geo/docker-compose.yaml | 2 +- 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/ci-scripts/conf_files/gnb.sa.band66.ntn.25prb.rfsim.conf b/ci-scripts/conf_files/gnb.sa.band66.ntn.25prb.rfsim.conf index 8731d00eb0..14b8650060 100644 --- a/ci-scripts/conf_files/gnb.sa.band66.ntn.25prb.rfsim.conf +++ b/ci-scripts/conf_files/gnb.sa.band66.ntn.25prb.rfsim.conf @@ -148,6 +148,13 @@ gNBs = #ext2 #ntn_Config_r17 cellSpecificKoffset_r17 = 478; + ta-Common-r17 = 29314900; + positionX-r17 = 0; + positionY-r17 = 0; + positionZ-r17 = 32433846; + velocityVX-r17 = 0; + velocityVY-r17 = 0; + velocityVZ-r17 = 0; } ); diff --git a/ci-scripts/conf_files/nrue.uicc.conf b/ci-scripts/conf_files/nrue.uicc.conf index d97a271ff6..5424abe30f 100644 --- a/ci-scripts/conf_files/nrue.uicc.conf +++ b/ci-scripts/conf_files/nrue.uicc.conf @@ -6,6 +6,12 @@ uicc0 = { nssai_sst=1; } +position0 = { + x = 0.0; + y = 0.0; + z = 6377900.0; +} + thread-pool = "-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1" #/* configuration for channel modelisation */ @@ -34,4 +40,4 @@ channelmod = { ds_tdl = 0; } ); -}; +}; \ No newline at end of file diff --git a/ci-scripts/yaml_files/5g_rfsimulator_ntn_geo/docker-compose.yaml b/ci-scripts/yaml_files/5g_rfsimulator_ntn_geo/docker-compose.yaml index 5876f5683c..6017a69ed9 100644 --- a/ci-scripts/yaml_files/5g_rfsimulator_ntn_geo/docker-compose.yaml +++ b/ci-scripts/yaml_files/5g_rfsimulator_ntn_geo/docker-compose.yaml @@ -110,7 +110,7 @@ services: - NET_ADMIN # for interface bringup - NET_RAW # for ping environment: - USE_ADDITIONAL_OPTIONS: --band 66 -C 2152680000 --CO -400000000 -r 25 --numerology 0 --ssb 48 --rfsim --rfsimulator.prop_delay 238.74 --ntn-koffset 478 --ntn-ta-common 477.48 --rfsimulator.serveraddr 192.168.71.140 --log_config.global_log_options level,nocolor,time + USE_ADDITIONAL_OPTIONS: --band 66 -C 2152680000 --CO -400000000 -r 25 --numerology 0 --ssb 48 --rfsim --rfsimulator.prop_delay 238.74 --rfsimulator.serveraddr 192.168.71.140 --log_config.global_log_options level,nocolor,time depends_on: - oai-gnb networks: From fc26b8c053a991f3a429916d15ee55775c1592dc Mon Sep 17 00:00:00 2001 From: Bartosz Podrygajlo Date: Tue, 10 Dec 2024 10:53:01 +0100 Subject: [PATCH 11/12] Fix process_slot_tx_barriers for high rx-to-tx values Set the number of barriers to 512 and implement proper slot and frame based selection. Now the dynamic barriers should not be overwritten in case the rx-to-tx offset is high. The maximum offset supported is 512. --- executables/nr-ue.c | 17 +++++++++-------- openair1/PHY/defs_nr_UE.h | 11 ++++++++++- openair1/SCHED_NR_UE/phy_procedures_nr_ue.c | 15 +++++++++------ 3 files changed, 28 insertions(+), 15 deletions(-) diff --git a/executables/nr-ue.c b/executables/nr-ue.c index 27f9654aa4..d892bff9e5 100644 --- a/executables/nr-ue.c +++ b/executables/nr-ue.c @@ -553,8 +553,8 @@ void processSlotTX(void *arg) int slots_per_frame = (UE->sl_mode == 2) ? UE->SL_UE_PHY_PARAMS.sl_frame_params.slots_per_frame : UE->frame_parms.slots_per_frame; - int next_slot = (proc->nr_slot_tx + 1 + proc->nr_slot_tx_offset) % slots_per_frame; - dynamic_barrier_join(&UE->process_slot_tx_barriers[next_slot]); + int next_slot_and_frame = proc->nr_slot_tx + 1 + proc->nr_slot_tx_offset + proc->frame_tx * slots_per_frame; + dynamic_barrier_join(&UE->process_slot_tx_barriers[next_slot_and_frame % NUM_PROCESS_SLOT_TX_BARRIERS]); RU_write(rxtxD, sl_tx_action); free(rxtxD); TracyCZoneEnd(ctx); @@ -810,8 +810,7 @@ void *UE_thread(void *arg) int absolute_slot = 0, decoded_frame_rx = MAX_FRAME_NUMBER - 1, trashed_frames = 0; int tx_wait_for_dlsch[NR_MAX_SLOTS_PER_FRAME]; - int num_ind_fifo = nb_slot_frame; - for(int i = 0; i < num_ind_fifo; i++) { + for(int i = 0; i < NUM_PROCESS_SLOT_TX_BARRIERS; i++) { dynamic_barrier_init(&UE->process_slot_tx_barriers[i]); } int shiftForNextFrame = 0; @@ -822,7 +821,7 @@ void *UE_thread(void *arg) if (get_softmodem_params()->sync_ref && UE->sl_mode == 2) { UE->is_synchronized = 1; } else { - //warm up the RF board + //warm up the RF board int64_t tmp; for (int i = 0; i < 50; i++) readFrame(UE, &tmp, true); @@ -934,7 +933,7 @@ void *UE_thread(void *arg) } // 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)); - for (int i = 0; i < num_ind_fifo; i++) { + for (int i = 0; i < NUM_PROCESS_SLOT_TX_BARRIERS; i++) { dynamic_barrier_reset(&UE->process_slot_tx_barriers[i]); } continue; @@ -957,7 +956,7 @@ void *UE_thread(void *arg) if (UE->ntn_config_message->update) { UE->ntn_config_message->update = false; update_ntn_system_information = true; - nr_slot_tx_offset = UE->ntn_config_message->ntn_config_params.cell_specific_k_offset % nb_slot_frame; + nr_slot_tx_offset = UE->ntn_config_message->ntn_config_params.cell_specific_k_offset; } int slot_nr = absolute_slot % nb_slot_frame; @@ -1054,7 +1053,9 @@ void *UE_thread(void *arg) int sync_to_previous_thread = stream_status == STREAM_STATUS_SYNCED ? 1 : 0; int slot = curMsgTx->proc.nr_slot_tx; - dynamic_barrier_update(&UE->process_slot_tx_barriers[slot], + int slot_and_frame = slot + curMsgTx->proc.frame_tx * UE->frame_parms.slots_per_frame; + + dynamic_barrier_update(&UE->process_slot_tx_barriers[slot_and_frame % NUM_PROCESS_SLOT_TX_BARRIERS], tx_wait_for_dlsch[slot] + sync_to_previous_thread, start_process_slot_tx, curMsgTx); diff --git a/openair1/PHY/defs_nr_UE.h b/openair1/PHY/defs_nr_UE.h index 2db8530a99..729acc84ca 100644 --- a/openair1/PHY/defs_nr_UE.h +++ b/openair1/PHY/defs_nr_UE.h @@ -85,6 +85,15 @@ #define UNUSED(x) (void)x; #define NUM_DL_ACTORS 4 +// Set the number of barriers for processSlotTX to 512. This value has to be at least 483 for NTN where +// DL-to-UL offset is up to 483. The selected value is also half of the frame range so that +// (slot + frame * slots_per_frame) % NUM_PROCESS_SLOT_TX_BARRIERS is contiguous between the last slot of +// frame 1023 and first slot of frame 0 +// e.g. in numerology 1: +// (19 + 1023 * 20) % 512 = 511 +// (0 + 0 * 20) % 512 = 0 +#define NUM_PROCESS_SLOT_TX_BARRIERS 512 + #include "impl_defs_top.h" #include "impl_defs_nr.h" #include "time_meas.h" @@ -527,7 +536,7 @@ typedef struct PHY_VARS_NR_UE_s { void *phy_sim_pdsch_dl_ch_estimates_ext; uint8_t *phy_sim_dlsch_b; - dynamic_barrier_t process_slot_tx_barriers[NR_MAX_SLOTS_PER_FRAME]; + dynamic_barrier_t process_slot_tx_barriers[NUM_PROCESS_SLOT_TX_BARRIERS]; // Gain change required for automation RX gain change int adjust_rxgain; diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c index 664a293a96..ab92b17711 100644 --- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c +++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c @@ -729,8 +729,9 @@ static bool nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, if (is_cw0_active != ACTIVE && is_cw1_active != ACTIVE) { // don't wait anymore LOG_E(NR_PHY, "Internal error nr_ue_dlsch_procedure() called but no active cw on slot %d, harq %d\n", nr_slot_rx, harq_pid); - const int ack_nack_slot = (proc->nr_slot_rx + dlsch[0].dlsch_config.k1_feedback) % ue->frame_parms.slots_per_frame; - dynamic_barrier_join(&ue->process_slot_tx_barriers[ack_nack_slot]); + const int ack_nack_slot_and_frame = + (proc->nr_slot_rx + dlsch[0].dlsch_config.k1_feedback) + proc->frame_rx * ue->frame_parms.slots_per_frame; + dynamic_barrier_join(&ue->process_slot_tx_barriers[ack_nack_slot_and_frame % NUM_PROCESS_SLOT_TX_BARRIERS]); return false; } @@ -865,8 +866,9 @@ static bool nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, // DLSCH decoding finished! don't wait anymore in Tx process, we know if we should answer ACK/NACK PUCCH if (dlsch[0].rnti_type == TYPE_C_RNTI_) { - const int ack_nack_slot = (proc->nr_slot_rx + dlsch[0].dlsch_config.k1_feedback) % ue->frame_parms.slots_per_frame; - dynamic_barrier_join(&ue->process_slot_tx_barriers[ack_nack_slot]); + const int ack_nack_slot_and_frame = + (proc->nr_slot_rx + dlsch[0].dlsch_config.k1_feedback) + proc->frame_rx * ue->frame_parms.slots_per_frame; + dynamic_barrier_join(&ue->process_slot_tx_barriers[ack_nack_slot_and_frame % NUM_PROCESS_SLOT_TX_BARRIERS]); } if (ue->phy_sim_dlsch_b) @@ -1148,8 +1150,9 @@ void pdsch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_phy_ nr_ue_dlsch_procedures(ue, proc, dlsch, llr, G); else { LOG_E(NR_PHY, "Demodulation impossible, internal error\n"); - int ack_nack_slot = (proc->nr_slot_rx + dlsch_config->k1_feedback) % ue->frame_parms.slots_per_frame; - dynamic_barrier_join(&ue->process_slot_tx_barriers[ack_nack_slot]); + const int ack_nack_slot_and_frame = + proc->nr_slot_rx + dlsch_config->k1_feedback + proc->frame_rx * ue->frame_parms.slots_per_frame; + dynamic_barrier_join(&ue->process_slot_tx_barriers[ack_nack_slot_and_frame % NUM_PROCESS_SLOT_TX_BARRIERS]); LOG_W(NR_PHY, "nr_ue_pdsch_procedures failed in slot %d\n", proc->nr_slot_rx); } From a049c53e99df1bd4714423f2b693937dcca012b2 Mon Sep 17 00:00:00 2001 From: "Badescu, Ciprian" Date: Wed, 11 Dec 2024 03:56:16 +0200 Subject: [PATCH 12/12] better handling of writeBlockSize greater than samples/slot fix the case when writeBlockSize is greater than samples/slot by sending samples from the same buffer instead of out-of-bounds memory read --- executables/nr-ue.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/executables/nr-ue.c b/executables/nr-ue.c index d892bff9e5..9e5347e957 100644 --- a/executables/nr-ue.c +++ b/executables/nr-ue.c @@ -483,11 +483,23 @@ static void RU_write(nr_rxtx_thread_data_t *rxtxD, bool sl_tx_action) } } - int tmp = openair0_write_reorder(&UE->rfdevice, proc->timestamp_tx, txp, rxtxD->writeBlockSize, fp->nb_antennas_tx, flags); - AssertFatal(tmp == rxtxD->writeBlockSize, ""); + openair0_timestamp writeTimestamp = proc->timestamp_tx; + int writeBlockSize = rxtxD->writeBlockSize; + if ( writeBlockSize > fp->get_samples_per_slot(proc->nr_slot_tx, fp)) { + // if writeBlockSize gets longer that slot size, fill with dummy + const int dummyBlockSize = writeBlockSize - fp->get_samples_per_slot(proc->nr_slot_tx, fp); + int tmp = openair0_write_reorder(&UE->rfdevice, writeTimestamp, txp, dummyBlockSize, fp->nb_antennas_tx, flags); + AssertFatal(tmp == dummyBlockSize, ""); + + writeTimestamp += dummyBlockSize; + writeBlockSize -= dummyBlockSize; + } + + int tmp = openair0_write_reorder(&UE->rfdevice, writeTimestamp, txp, writeBlockSize, fp->nb_antennas_tx, flags); + AssertFatal(tmp == writeBlockSize, ""); for (int i = 0; i < fp->nb_antennas_tx; i++) - memset(txp[i], 0, rxtxD->writeBlockSize); + memset(txp[i], 0, writeBlockSize); } void processSlotTX(void *arg)