diff --git a/lib/include/srsran/common/phy_cfg_nr.h b/lib/include/srsran/common/phy_cfg_nr.h index 37c1ca499..637b0b114 100644 --- a/lib/include/srsran/common/phy_cfg_nr.h +++ b/lib/include/srsran/common/phy_cfg_nr.h @@ -45,7 +45,8 @@ struct phy_cfg_nr_t { srsran_harq_ack_cfg_hl_t harq_ack = {}; srsran_csi_hl_cfg_t csi = {}; srsran_carrier_nr_t carrier = {}; - ssb_cfg_t ssb; + ssb_cfg_t ssb = {}; + uint32_t t_offset = 0; ///< n-TimingAdvanceOffset phy_cfg_nr_t() {} diff --git a/srsue/hdr/phy/nr/sync_sa.h b/srsue/hdr/phy/nr/sync_sa.h index 1ff410570..59f015a99 100644 --- a/srsue/hdr/phy/nr/sync_sa.h +++ b/srsue/hdr/phy/nr/sync_sa.h @@ -81,6 +81,7 @@ public: void add_ta_cmd_rar(uint32_t tti, uint32_t ta_cmd); void add_ta_cmd_new(uint32_t tti, uint32_t ta_cmd); + void add_ta_offset(uint32_t ta_offset); private: stack_interface_phy_nr* stack = nullptr; ///< Stand-Alone RRC interface diff --git a/srsue/hdr/phy/ta_control.h b/srsue/hdr/phy/ta_control.h index a1891bbcf..6246acd35 100644 --- a/srsue/hdr/phy/ta_control.h +++ b/srsue/hdr/phy/ta_control.h @@ -95,6 +95,19 @@ public: next_base_sec * 1e6f); } + void add_ta_offset(uint32_t ta_offset) + { + std::lock_guard lock(mutex); + + // Assuming numerology 0 + next_base_nta = ta_offset / 64; + + // Update base in seconds + next_base_sec = static_cast(next_base_nta) * SRSRAN_LTE_TS; + + logger.info("PHY: Set TA offset: n_ta_offset: %d, ta_usec: %.1f", next_base_nta, next_base_sec * 1e6f); + } + /** * Increments (delta) the next base time according to time alignment command from a Random Access Response (RAR). * diff --git a/srsue/src/phy/phy_nr_sa.cc b/srsue/src/phy/phy_nr_sa.cc index 83cc1c319..df7334339 100644 --- a/srsue/src/phy/phy_nr_sa.cc +++ b/srsue/src/phy/phy_nr_sa.cc @@ -258,6 +258,9 @@ bool phy_nr_sa::set_config(const srsran::phy_cfg_nr_t& cfg) // Set UE configuration bool ret = workers.set_config(config_nr); + // Pass n_ta_offset to sync + sync.add_ta_offset(config_nr.t_offset); + // Notify PHY config completion if (stack != nullptr) { stack->set_phy_config_complete(ret); diff --git a/srsue/src/phy/sync_sa.cc b/srsue/src/phy/sync_sa.cc index 464ceded1..68d8ade90 100644 --- a/srsue/src/phy/sync_sa.cc +++ b/srsue/src/phy/sync_sa.cc @@ -93,6 +93,11 @@ void sync_sa::add_ta_cmd_new(uint32_t tti_, uint32_t ta_cmd) ta.add_ta_cmd_new(tti_, ta_cmd); } +void sync_sa::add_ta_offset(uint32_t ta_offset) +{ + ta.add_ta_offset(ta_offset); +} + void sync_sa::cell_go_idle() { std::unique_lock ul(rrc_mutex); diff --git a/srsue/src/stack/rrc_nr/rrc_nr.cc b/srsue/src/stack/rrc_nr/rrc_nr.cc index e8b762e36..3119532c7 100644 --- a/srsue/src/stack/rrc_nr/rrc_nr.cc +++ b/srsue/src/stack/rrc_nr/rrc_nr.cc @@ -486,6 +486,26 @@ void rrc_nr::handle_sib1(const sib1_s& sib1) // Apply SSB Config fill_phy_ssb_cfg(sib1.serving_cell_cfg_common, &phy_cfg.ssb); + // Apply n-TimingAdvanceOffset + if (sib1.serving_cell_cfg_common.n_timing_advance_offset_present) { + switch (sib1.serving_cell_cfg_common.n_timing_advance_offset.value) { + case serving_cell_cfg_common_sib_s::n_timing_advance_offset_opts::n0: + phy_cfg.t_offset = 0; + break; + case serving_cell_cfg_common_sib_s::n_timing_advance_offset_opts::n25600: + phy_cfg.t_offset = 25600; + break; + case serving_cell_cfg_common_sib_s::n_timing_advance_offset_opts::n39936: + phy_cfg.t_offset = 39936; + break; + default: + logger.error("Invalid n_ta_offset option"); + break; + } + } else { + phy_cfg.t_offset = 25600; + } + phy_cfg_state = PHY_CFG_STATE_SA_SIB_CFG; if (not phy->set_config(phy_cfg)) { logger.warning("Could not set phy config.");