diff --git a/lib/include/srsran/interfaces/ue_nr_interfaces.h b/lib/include/srsran/interfaces/ue_nr_interfaces.h index c6dc69902..edcd93140 100644 --- a/lib/include/srsran/interfaces/ue_nr_interfaces.h +++ b/lib/include/srsran/interfaces/ue_nr_interfaces.h @@ -258,6 +258,12 @@ public: const float preamble_received_target_power, const float ta_base_sec = 0.0f) = 0; + /// Apply TA command after RAR + virtual void set_timeadv_rar(uint32_t tti, uint32_t ta_cmd) = 0; + + /// Apply TA command after MAC CE + virtual void set_timeadv(uint32_t tti, uint32_t ta_cmd) = 0; + /** * @brief Query PHY if there is a valid PUCCH SR resource configured for a given SR identifier * @param sr_id SR identifier diff --git a/srsue/hdr/phy/nr/sync_sa.h b/srsue/hdr/phy/nr/sync_sa.h index 7a27b43bd..1ff410570 100644 --- a/srsue/hdr/phy/nr/sync_sa.h +++ b/srsue/hdr/phy/nr/sync_sa.h @@ -79,6 +79,9 @@ public: void worker_end(const worker_context_t& w_ctx, const bool& tx_enable, srsran::rf_buffer_t& buffer) override; + void add_ta_cmd_rar(uint32_t tti, uint32_t ta_cmd); + void add_ta_cmd_new(uint32_t tti, uint32_t ta_cmd); + private: stack_interface_phy_nr* stack = nullptr; ///< Stand-Alone RRC interface srsran::radio_interface_phy* radio = nullptr; ///< Radio object @@ -107,6 +110,9 @@ private: cell_search searcher; slot_sync slot_synchronizer; + // Time Aligment Controller, internal thread safe + ta_control ta; + // FSM States bool wait_idle(); void run_state_idle(); diff --git a/srsue/hdr/phy/phy_nr_sa.h b/srsue/hdr/phy/phy_nr_sa.h index 3e6dbbc0f..cfc19bd53 100644 --- a/srsue/hdr/phy/phy_nr_sa.h +++ b/srsue/hdr/phy/phy_nr_sa.h @@ -50,6 +50,9 @@ public: const int preamble_index, const float preamble_received_target_power, const float ta_base_sec) final; + void set_timeadv_rar(uint32_t tti, uint32_t ta_cmd) final; + void set_timeadv(uint32_t tti, uint32_t ta_cmd) final; + void set_earfcn(std::vector earfcns); bool has_valid_sr_resource(uint32_t sr_id) final; void clear_pending_grants() final; diff --git a/srsue/hdr/stack/mac_nr/demux_nr.h b/srsue/hdr/stack/mac_nr/demux_nr.h index fffb26181..38e8faa1c 100644 --- a/srsue/hdr/stack/mac_nr/demux_nr.h +++ b/srsue/hdr/stack/mac_nr/demux_nr.h @@ -15,6 +15,7 @@ #include "mac_nr_interfaces.h" #include "srsran/common/block_queue.h" +#include "srsran/interfaces/ue_nr_interfaces.h" #include "srsran/interfaces/ue_rlc_interfaces.h" namespace srsue { @@ -35,7 +36,7 @@ public: demux_nr(srslog::basic_logger& logger_); ~demux_nr(); - int32_t init(rlc_interface_mac* rlc_); + int32_t init(rlc_interface_mac* rlc_, phy_interface_mac_nr* phy_); void process_pdus(); /// Called by MAC to process received PDUs @@ -51,6 +52,7 @@ private: srslog::basic_logger& logger; rlc_interface_mac* rlc = nullptr; + phy_interface_mac_nr* phy = nullptr; uint64_t received_crueid = 0; diff --git a/srsue/src/phy/phy_nr_sa.cc b/srsue/src/phy/phy_nr_sa.cc index 435bbad28..83cc1c319 100644 --- a/srsue/src/phy/phy_nr_sa.cc +++ b/srsue/src/phy/phy_nr_sa.cc @@ -230,6 +230,16 @@ void phy_nr_sa::send_prach(const uint32_t prach_occasion, workers.send_prach(prach_occasion, preamble_index, preamble_received_target_power); } +void phy_nr_sa::set_timeadv_rar(uint32_t tti, uint32_t ta_cmd) +{ + sync.add_ta_cmd_rar(tti, ta_cmd); +} + +void phy_nr_sa::set_timeadv(uint32_t tti, uint32_t ta_cmd) +{ + sync.add_ta_cmd_new(tti, ta_cmd); +} + int phy_nr_sa::set_rar_grant(uint32_t rar_slot_idx, std::array packed_ul_grant, uint16_t rnti, diff --git a/srsue/src/phy/sync_sa.cc b/srsue/src/phy/sync_sa.cc index 23460d3d0..464ceded1 100644 --- a/srsue/src/phy/sync_sa.cc +++ b/srsue/src/phy/sync_sa.cc @@ -16,7 +16,7 @@ namespace srsue { namespace nr { sync_sa::sync_sa(srslog::basic_logger& logger_, worker_pool& workers_) : - logger(logger_), workers(workers_), slot_synchronizer(logger_), searcher(logger_), srsran::thread("SYNC") + logger(logger_), workers(workers_), slot_synchronizer(logger_), searcher(logger_), ta(logger_), srsran::thread("SYNC") {} sync_sa::~sync_sa() @@ -78,10 +78,21 @@ bool sync_sa::reset() { // Wait worker pool to finish any processing tti_semaphore.wait_all(); + ta.set_base_sec(0); return true; } +void sync_sa::add_ta_cmd_rar(uint32_t tti_, uint32_t ta_cmd) +{ + ta.add_ta_cmd_rar(tti_, ta_cmd); +} + +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::cell_go_idle() { std::unique_lock ul(rrc_mutex); @@ -293,6 +304,8 @@ void sync_sa::run_state_cell_camping() context.last = true; // Set last if standalone last_rx_time.add(FDD_HARQ_DELAY_DL_MS * 1e-3); context.tx_time.copy(last_rx_time); + // Apply current TA + context.tx_time.sub((double)ta.get_sec()); nr_worker->set_context(context); diff --git a/srsue/src/stack/mac_nr/demux_nr.cc b/srsue/src/stack/mac_nr/demux_nr.cc index 394854f16..f7adcfcf8 100644 --- a/srsue/src/stack/mac_nr/demux_nr.cc +++ b/srsue/src/stack/mac_nr/demux_nr.cc @@ -21,9 +21,10 @@ demux_nr::demux_nr(srslog::basic_logger& logger_) : logger(logger_) {} demux_nr::~demux_nr() {} -int32_t demux_nr::init(rlc_interface_mac* rlc_) +int32_t demux_nr::init(rlc_interface_mac* rlc_, phy_interface_mac_nr* phy_) { rlc = rlc_; + phy = phy_; return SRSRAN_SUCCESS; } @@ -104,7 +105,8 @@ void demux_nr::handle_pdu(srsran::mac_sch_pdu_nr& pdu_buffer, srsran::unique_byt logger.info("DRX CE not implemented."); break; case srsran::mac_sch_subpdu_nr::nr_lcid_sch_t::TA_CMD: - logger.info("Timing Advance CE not implemented."); + logger.info("Received TA=%d.", subpdu.get_ta().ta_command); + phy->set_timeadv(0, subpdu.get_ta().ta_command); break; case srsran::mac_sch_subpdu_nr::nr_lcid_sch_t::CON_RES_ID: received_crueid = subpdu.get_ue_con_res_id_ce_packed(); diff --git a/srsue/src/stack/mac_nr/mac_nr.cc b/srsue/src/stack/mac_nr/mac_nr.cc index d050649b4..99bdccdc3 100644 --- a/srsue/src/stack/mac_nr/mac_nr.cc +++ b/srsue/src/stack/mac_nr/mac_nr.cc @@ -65,7 +65,7 @@ int mac_nr::init(const mac_nr_args_t& args_, return SRSRAN_ERROR; } - if (demux.init(rlc) != SRSRAN_SUCCESS) { + if (demux.init(rlc, phy) != SRSRAN_SUCCESS) { logger.error("Couldn't initialize demux unit."); return SRSRAN_ERROR; } diff --git a/srsue/src/stack/mac_nr/proc_ra_nr.cc b/srsue/src/stack/mac_nr/proc_ra_nr.cc index e52890351..200cc96cd 100644 --- a/srsue/src/stack/mac_nr/proc_ra_nr.cc +++ b/srsue/src/stack/mac_nr/proc_ra_nr.cc @@ -224,10 +224,13 @@ void proc_ra_nr::ra_response_reception(const mac_interface_phy_nr::tb_action_dl_ // Set Temporary-C-RNTI if provided, otherwise C-RNTI is ok phy->set_rar_grant(tb.rx_slot_idx, subpdu.get_ul_grant(), temp_crnti, srsran_rnti_type_ra); + // Apply TA CMD + current_ta = subpdu.get_ta(); + phy->set_timeadv_rar(tb.rx_slot_idx, current_ta); + // reset all parameters that are used before rar rar_rnti = SRSRAN_INVALID_RNTI; mac.msg3_prepare(); - current_ta = subpdu.get_ta(); // Set Backoff parameter if (subpdu.has_backoff()) { diff --git a/srsue/src/stack/mac_nr/test/mac_nr_test.cc b/srsue/src/stack/mac_nr/test/mac_nr_test.cc index fa4a178a3..22d652bf6 100644 --- a/srsue/src/stack/mac_nr/test/mac_nr_test.cc +++ b/srsue/src/stack/mac_nr/test/mac_nr_test.cc @@ -52,6 +52,9 @@ public: bool has_valid_sr_resource(uint32_t sr_id) override { return false; } void clear_pending_grants() override {} + void set_timeadv_rar(uint32_t tti, uint32_t ta_cmd) final{}; + void set_timeadv(uint32_t tti, uint32_t ta_cmd) final{}; + private: uint32_t prach_occasion = 0; uint32_t preamble_index = 0; diff --git a/srsue/src/stack/mac_nr/test/proc_ra_nr_test.cc b/srsue/src/stack/mac_nr/test/proc_ra_nr_test.cc index 420ae38b1..0663bedb3 100644 --- a/srsue/src/stack/mac_nr/test/proc_ra_nr_test.cc +++ b/srsue/src/stack/mac_nr/test/proc_ra_nr_test.cc @@ -46,6 +46,8 @@ public: { return -1; } + void set_timeadv_rar(uint32_t tti, uint32_t ta_cmd) final {} + void set_timeadv(uint32_t tti, uint32_t ta_cmd) final {} private: uint32_t prach_occasion = 0; diff --git a/srsue/src/stack/mac_nr/test/proc_sr_nr_test.cc b/srsue/src/stack/mac_nr/test/proc_sr_nr_test.cc index 4984b0e73..97cbb010d 100644 --- a/srsue/src/stack/mac_nr/test/proc_sr_nr_test.cc +++ b/srsue/src/stack/mac_nr/test/proc_sr_nr_test.cc @@ -47,6 +47,9 @@ public: bool has_valid_sr_resource(uint32_t sr_id) override { return false; } void clear_pending_grants() override {} + void set_timeadv_rar(uint32_t tti, uint32_t ta_cmd) final{}; + void set_timeadv(uint32_t tti, uint32_t ta_cmd) final{}; + private: uint32_t prach_occasion = 0; uint32_t preamble_index = 0;