diff --git a/lib/include/srsran/interfaces/ue_mac_interfaces.h b/lib/include/srsran/interfaces/ue_mac_interfaces.h index 540e5f130..d34a2fd8f 100644 --- a/lib/include/srsran/interfaces/ue_mac_interfaces.h +++ b/lib/include/srsran/interfaces/ue_mac_interfaces.h @@ -100,21 +100,7 @@ public: virtual void set_mbsfn_config(uint32_t nof_mbsfn_services) = 0; }; -class mac_interface_rrc_common -{ -public: - // Class to handle UE specific RNTIs between RRC and MAC - typedef struct { - uint16_t crnti; - uint16_t rar_rnti; - uint16_t temp_rnti; - uint16_t tpc_rnti; - uint16_t sps_rnti; - uint64_t contention_id; - } ue_rnti_t; -}; - -class mac_interface_rrc : public mac_interface_rrc_common +class mac_interface_rrc { public: /* Instructs the MAC to start receiving BCCH */ @@ -138,9 +124,9 @@ public: virtual void set_rach_ded_cfg(uint32_t preamble_index, uint32_t prach_mask) = 0; - virtual void get_rntis(ue_rnti_t* rntis) = 0; - virtual void set_contention_id(uint64_t uecri) = 0; - virtual void set_ho_rnti(uint16_t crnti, uint16_t target_pci) = 0; + virtual uint16_t get_crnti() = 0; + virtual void set_contention_id(uint64_t uecri) = 0; + virtual void set_ho_rnti(uint16_t crnti, uint16_t target_pci) = 0; virtual void reconfiguration(const uint32_t& cc_idx, const bool& enable) = 0; virtual void reset() = 0; diff --git a/lib/src/phy/rf/rf_imp.c b/lib/src/phy/rf/rf_imp.c index eb0cac1ad..6da4fa88d 100644 --- a/lib/src/phy/rf/rf_imp.c +++ b/lib/src/phy/rf/rf_imp.c @@ -28,12 +28,12 @@ int rf_get_available_devices(char** devnames, int max_strlen) int srsran_rf_set_rx_gain_th(srsran_rf_t* rf, double gain) { + pthread_mutex_lock(&rf->mutex); if (gain > rf->cur_rx_gain + 2 || gain < rf->cur_rx_gain - 2) { - pthread_mutex_lock(&rf->mutex); rf->new_rx_gain = gain; pthread_cond_signal(&rf->cond); - pthread_mutex_unlock(&rf->mutex); } + pthread_mutex_unlock(&rf->mutex); return SRSRAN_SUCCESS; } diff --git a/lib/src/phy/rf/rf_zmq_imp.c b/lib/src/phy/rf/rf_zmq_imp.c index 793c0862b..e4f05a52c 100644 --- a/lib/src/phy/rf/rf_zmq_imp.c +++ b/lib/src/phy/rf/rf_zmq_imp.c @@ -53,6 +53,7 @@ typedef struct { pthread_mutex_t tx_config_mutex; pthread_mutex_t rx_config_mutex; pthread_mutex_t decim_mutex; + pthread_mutex_t rx_gain_mutex; } rf_zmq_handler_t; void update_rates(rf_zmq_handler_t* handler, double srate); @@ -196,7 +197,9 @@ int rf_zmq_open_multi(char* args, void** h, uint32_t nof_channels) bzero(handler, sizeof(rf_zmq_handler_t)); *h = handler; handler->base_srate = ZMQ_BASERATE_DEFAULT_HZ; // Sample rate for 100 PRB cell + pthread_mutex_lock(&handler->rx_gain_mutex); handler->rx_gain = 0.0; + pthread_mutex_unlock(&handler->rx_gain_mutex); handler->info.max_rx_gain = ZMQ_MAX_GAIN_DB; handler->info.min_rx_gain = ZMQ_MIN_GAIN_DB; handler->info.max_tx_gain = ZMQ_MAX_GAIN_DB; @@ -220,6 +223,9 @@ int rf_zmq_open_multi(char* args, void** h, uint32_t nof_channels) if (pthread_mutex_init(&handler->decim_mutex, NULL)) { perror("Mutex init"); } + if (pthread_mutex_init(&handler->rx_gain_mutex, NULL)) { + perror("Mutex init"); + } // parse args if (args && strlen(args)) { @@ -408,6 +414,7 @@ int rf_zmq_close(void* h) pthread_mutex_destroy(&handler->tx_config_mutex); pthread_mutex_destroy(&handler->rx_config_mutex); pthread_mutex_destroy(&handler->decim_mutex); + pthread_mutex_destroy(&handler->rx_gain_mutex); // Free all free(handler); @@ -463,7 +470,9 @@ int rf_zmq_set_rx_gain(void* h, double gain) { if (h) { rf_zmq_handler_t* handler = (rf_zmq_handler_t*)h; + pthread_mutex_lock(&handler->rx_gain_mutex); handler->rx_gain = gain; + pthread_mutex_unlock(&handler->rx_gain_mutex); } return SRSRAN_SUCCESS; } @@ -488,7 +497,9 @@ double rf_zmq_get_rx_gain(void* h) double ret = 0.0; if (h) { rf_zmq_handler_t* handler = (rf_zmq_handler_t*)h; + pthread_mutex_lock(&handler->rx_gain_mutex); ret = handler->rx_gain; + pthread_mutex_unlock(&handler->rx_gain_mutex); } return ret; } @@ -663,7 +674,7 @@ int rf_zmq_recv_with_time_multi(void* h, void** data, uint32_t nsamples, bool bl // receive samples srsran_timestamp_t ts_tx = {}, ts_rx = {}; - srsran_timestamp_init_uint64(&ts_tx, handler->transmitter[0].nsamples, handler->base_srate); + srsran_timestamp_init_uint64(&ts_tx, rf_zmq_tx_get_nsamples(&handler->transmitter[0]), handler->base_srate); srsran_timestamp_init_uint64(&ts_rx, handler->next_rx_ts, handler->base_srate); rf_zmq_info(handler->id, " - next rx time: %d + %.3f\n", ts_rx.full_secs, ts_rx.frac_secs); rf_zmq_info(handler->id, " - next tx time: %d + %.3f\n", ts_tx.full_secs, ts_tx.frac_secs); @@ -766,7 +777,9 @@ int rf_zmq_recv_with_time_multi(void* h, void** data, uint32_t nsamples, bool bl } // Set gain + pthread_mutex_lock(&handler->rx_gain_mutex); float scale = srsran_convert_dB_to_amplitude(handler->rx_gain); + pthread_mutex_unlock(&handler->rx_gain_mutex); for (uint32_t c = 0; c < handler->nof_channels; c++) { if (buffers[c]) { srsran_vec_sc_prod_cfc(buffers[c], scale, buffers[c], nsamples); diff --git a/lib/src/phy/rf/rf_zmq_imp_trx.h b/lib/src/phy/rf/rf_zmq_imp_trx.h index 1da44cac0..c574581a9 100644 --- a/lib/src/phy/rf/rf_zmq_imp_trx.h +++ b/lib/src/phy/rf/rf_zmq_imp_trx.h @@ -97,6 +97,8 @@ SRSRAN_API int rf_zmq_tx_align(rf_zmq_tx_t* q, uint64_t ts); SRSRAN_API int rf_zmq_tx_baseband(rf_zmq_tx_t* q, cf_t* buffer, uint32_t nsamples); +SRSRAN_API int rf_zmq_tx_get_nsamples(rf_zmq_tx_t* q); + SRSRAN_API int rf_zmq_tx_zeros(rf_zmq_tx_t* q, uint32_t nsamples); SRSRAN_API bool rf_zmq_tx_match_freq(rf_zmq_tx_t* q, uint32_t freq_hz); diff --git a/lib/src/phy/rf/rf_zmq_imp_tx.c b/lib/src/phy/rf/rf_zmq_imp_tx.c index 078a5b92f..3a53f1f49 100644 --- a/lib/src/phy/rf/rf_zmq_imp_tx.c +++ b/lib/src/phy/rf/rf_zmq_imp_tx.c @@ -200,6 +200,14 @@ int rf_zmq_tx_baseband(rf_zmq_tx_t* q, cf_t* buffer, uint32_t nsamples) return n; } +int rf_zmq_tx_get_nsamples(rf_zmq_tx_t* q) +{ + pthread_mutex_lock(&q->mutex); + int ret = q->nsamples; + pthread_mutex_unlock(&q->mutex); + return ret; +} + int rf_zmq_tx_zeros(rf_zmq_tx_t* q, uint32_t nsamples) { pthread_mutex_lock(&q->mutex); diff --git a/srsenb/src/main.cc b/srsenb/src/main.cc index 6a94d7379..ba9c58477 100644 --- a/srsenb/src/main.cc +++ b/srsenb/src/main.cc @@ -21,6 +21,7 @@ #include "srsran/common/config_file.h" #include "srsran/common/crash_handler.h" #include "srsran/common/signal_handler.h" +#include "srsran/common/tsan_options.h" #include "srsran/srslog/event_trace.h" #include "srsran/srslog/srslog.h" diff --git a/srsue/hdr/metrics_json.h b/srsue/hdr/metrics_json.h index fcd863b6a..e35124223 100644 --- a/srsue/hdr/metrics_json.h +++ b/srsue/hdr/metrics_json.h @@ -35,6 +35,8 @@ public: private: srslog::log_channel& log_c; ue_metrics_interface* ue = nullptr; + + std::mutex mutex = {}; }; } // namespace srsue diff --git a/srsue/hdr/metrics_stdout.h b/srsue/hdr/metrics_stdout.h index 626a5f74a..c571dd7e6 100644 --- a/srsue/hdr/metrics_stdout.h +++ b/srsue/hdr/metrics_stdout.h @@ -54,6 +54,7 @@ private: bool table_has_neighbours = false; ///< state of last table head uint8_t n_reports = 10; ue_metrics_interface* ue = nullptr; + std::mutex mutex; }; } // namespace srsue diff --git a/srsue/hdr/phy/phy.h b/srsue/hdr/phy/phy.h index 7c887c585..96a98611d 100644 --- a/srsue/hdr/phy/phy.h +++ b/srsue/hdr/phy/phy.h @@ -184,7 +184,7 @@ private: std::mutex config_mutex; std::condition_variable config_cond; - bool is_configured = false; + std::atomic is_configured = {false}; const static int SF_RECV_THREAD_PRIO = 0; const static int WORKERS_THREAD_PRIO = 2; diff --git a/srsue/hdr/phy/phy_common.h b/srsue/hdr/phy/phy_common.h index e850caac2..6a61f601b 100644 --- a/srsue/hdr/phy/phy_common.h +++ b/srsue/hdr/phy/phy_common.h @@ -138,8 +138,48 @@ public: void set_cell(const srsran_cell_t& c); - bool sr_enabled = false; - int sr_last_tx_tti = -1; + class sr_signal + { + public: + void reset() + { + std::lock_guard lock(mutex); + enabled = false; + last_tx_tti = -1; + } + bool is_triggered() + { + std::lock_guard lock(mutex); + return enabled; + } + void trigger() + { + std::lock_guard lock(mutex); + enabled = true; + last_tx_tti = -1; + } + int get_last_tx_tti() + { + std::lock_guard lock(mutex); + return last_tx_tti; + } + bool set_last_tx_tti(int last_tx_tti_) + { + std::lock_guard lock(mutex); + if (enabled) { + enabled = false; + last_tx_tti = last_tx_tti_; + return true; + } + return false; + } + + private: + std::mutex mutex; + bool enabled = false; + int last_tx_tti = -1; + }; + sr_signal sr; srsran::radio_interface_phy* get_radio(); @@ -212,7 +252,11 @@ public: return rx_gain_offset; } - void neighbour_cells_reset(uint32_t cc_idx) { avg_rsrp_neigh[cc_idx] = NAN; } + void neighbour_cells_reset(uint32_t cc_idx) + { + std::unique_lock lock(meas_mutex); + avg_rsrp_neigh[cc_idx] = NAN; + } void set_neighbour_cells(uint32_t cc_idx, const std::vector& meas) { diff --git a/srsue/hdr/phy/scell/intra_measure_base.h b/srsue/hdr/phy/scell/intra_measure_base.h index e4836d71b..b5b46fc9f 100644 --- a/srsue/hdr/phy/scell/intra_measure_base.h +++ b/srsue/hdr/phy/scell/intra_measure_base.h @@ -126,7 +126,6 @@ public: protected: struct measure_context_t { uint32_t cc_idx = 0; ///< Component carrier index - float rx_gain_offset_db = 0.0f; ///< Current gain offset std::set active_pci = {}; ///< Set with the active PCIs uint32_t sf_len = 0; ///< Subframe length in samples uint32_t meas_len_ms = 20; ///< Measure length in milliseconds/sub-frames @@ -138,6 +137,8 @@ protected: explicit measure_context_t(meas_itf& new_cell_itf_) : new_cell_itf(new_cell_itf_) {} }; + std::atomic rx_gain_offset_db = {0.0f}; ///< Current gain offset + /** * @brief Generic initialization method, necessary to configure main parameters * @param cc_idx_ Indicates the component carrier index linked to the intra frequency measurement instance @@ -261,9 +262,10 @@ private: * as it is protected by the state. * @param context Provides current measurement context * @param buffer Provides current measurement context + * @param rx_gain_offset Provides last received rx_gain_offset * @return True if the measurement functions are executed without errors, otherwise false */ - virtual bool measure_rat(measure_context_t context, std::vector& buffer) = 0; + virtual bool measure_rat(measure_context_t context, std::vector& buffer, float rx_gain_offset) = 0; /** * @brief Measurement process helper method. Encapsulates the neighbour cell measurement functionality diff --git a/srsue/hdr/phy/scell/intra_measure_lte.h b/srsue/hdr/phy/scell/intra_measure_lte.h index fab9df810..7a1b7a931 100644 --- a/srsue/hdr/phy/scell/intra_measure_lte.h +++ b/srsue/hdr/phy/scell/intra_measure_lte.h @@ -67,9 +67,10 @@ private: * @brief LTE specific measurement process * @param context Measurement context * @param buffer Provides the baseband buffer to perform the measurements + * @param rx_gain_offset Provides last received rx_gain_offset * @return True if no error happens, otherwise false */ - bool measure_rat(measure_context_t context, std::vector& buffer) override; + bool measure_rat(measure_context_t context, std::vector& buffer, float rx_gain_offset) override; srslog::basic_logger& logger; srsran_cell_t serving_cell = {}; ///< Current serving cell in the EARFCN, to avoid reporting it diff --git a/srsue/hdr/phy/scell/intra_measure_nr.h b/srsue/hdr/phy/scell/intra_measure_nr.h index 6477af0cd..391483248 100644 --- a/srsue/hdr/phy/scell/intra_measure_nr.h +++ b/srsue/hdr/phy/scell/intra_measure_nr.h @@ -106,9 +106,10 @@ private: * @attention It searches and measures the SSB with best SNR * @param context Measurement context * @param buffer Provides the baseband buffer to perform the measurements + * @param rx_gain_offset Provides last received rx_gain_offset * @return True if no error happen, otherwise false */ - bool measure_rat(measure_context_t context, std::vector& buffer) override; + bool measure_rat(measure_context_t context, std::vector& buffer, float rx_gain_offset) override; srslog::basic_logger& logger; uint32_t cc_idx = 0; diff --git a/srsue/hdr/phy/sync.h b/srsue/hdr/phy/sync.h index 9d8fe476b..97b3c91d7 100644 --- a/srsue/hdr/phy/sync.h +++ b/srsue/hdr/phy/sync.h @@ -206,6 +206,7 @@ private: search search_p; sfn_sync sfn_p; std::vector > intra_freq_meas; + std::mutex intra_freq_cfg_mutex; // Pointers to other classes stack_interface_phy_lte* stack = nullptr; @@ -259,11 +260,97 @@ private: search::ret_code cell_search_ret = search::CELL_NOT_FOUND; // Sampling rate mode (find is 1.96 MHz, camp is the full cell BW) - enum { SRATE_NONE = 0, SRATE_FIND, SRATE_CAMP } srate_mode = SRATE_NONE; - float current_srate = 0; + class srate_safe + { + public: + void reset() + { + std::lock_guard lock(mutex); + srate_mode = SRATE_NONE; + current_srate = 0; + } + float get_srate() + { + std::lock_guard lock(mutex); + return current_srate; + } + bool is_normal() + { + std::lock_guard lock(mutex); + return std::isnormal(current_srate) and current_srate > 0.0f; + } + bool set_camp(float new_srate) + { + std::lock_guard lock(mutex); + if (current_srate != new_srate || srate_mode != SRATE_CAMP) { + current_srate = new_srate; + srate_mode = SRATE_CAMP; + return true; + } + return false; + } + bool set_find() + { + std::lock_guard lock(mutex); + if (srate_mode != SRATE_FIND) { + srate_mode = SRATE_FIND; + current_srate = 1.92e6; + return true; + } + return false; + } + + private: + enum { SRATE_NONE = 0, SRATE_FIND, SRATE_CAMP } srate_mode = SRATE_NONE; + float current_srate = 0; + std::mutex mutex; + }; + // Protect sampling rate changes since accessed by multiple threads + srate_safe srate; // This is the primary cell - srsran_cell_t cell = {}; + class cell_safe + { + public: + void set_pci(uint32_t id) + { + std::lock_guard lock(mutex); + cell.id = id; + } + void reset() + { + std::lock_guard lock(mutex); + cell = {}; + } + bool is_valid() + { + std::lock_guard lock(mutex); + return srsran_cell_isvalid(&cell); + } + void set(srsran_cell_t& x) + { + std::lock_guard lock(mutex); + cell = x; + } + srsran_cell_t get() + { + std::lock_guard lock(mutex); + return cell; + } + bool equals(srsran_cell_t& x) + { + std::lock_guard lock(mutex); + return memcmp(&cell, &x, sizeof(srsran_cell_t)) == 0; + } + + private: + srsran_cell_t cell = {}; + std::mutex mutex; + }; + + // Protect access to cell configuration since it's accessed by multiple threads + cell_safe cell; + bool force_camping_sfn_sync = false; uint32_t tti = 0; srsran_timestamp_t stack_tti_ts_new = {}; diff --git a/srsue/hdr/phy/sync_state.h b/srsue/hdr/phy/sync_state.h index aa3338bf1..a014cc38f 100644 --- a/srsue/hdr/phy/sync_state.h +++ b/srsue/hdr/phy/sync_state.h @@ -82,8 +82,16 @@ public: } /* Helpers below this */ - bool is_idle() { return cur_state == IDLE; } - bool is_camping() { return cur_state == CAMPING; } + bool is_idle() + { + std::lock_guard lock(mutex); + return cur_state == IDLE; + } + bool is_camping() + { + std::lock_guard lock(mutex); + return cur_state == CAMPING; + } bool wait_idle(uint32_t timeout_ms) { std::unique_lock lock(mutex); diff --git a/srsue/hdr/stack/mac/dl_harq.h b/srsue/hdr/stack/mac/dl_harq.h index 035311fc1..0ca4cc60c 100644 --- a/srsue/hdr/stack/mac/dl_harq.h +++ b/srsue/hdr/stack/mac/dl_harq.h @@ -17,6 +17,7 @@ #include "dl_sps.h" #include "srsran/common/mac_pcap.h" #include "srsran/common/timers.h" +#include "srsue/hdr/stack/mac_common/mac_common.h" /* Downlink HARQ entity as defined in 5.3.2 of 36.321 */ @@ -27,7 +28,7 @@ class dl_harq_entity public: dl_harq_entity(uint8_t cc_idx_); - bool init(mac_interface_rrc::ue_rnti_t* rntis, demux* demux_unit); + bool init(ue_rnti* rntis, demux* demux_unit); void reset(); void start_pcap(srsran::mac_pcap* pcap_); @@ -38,6 +39,7 @@ public: void set_si_window_start(int si_window_start); float get_average_retx(); + void set_average_retx(uint32_t n_retx); private: class dl_harq_process @@ -112,10 +114,12 @@ private: demux* demux_unit = nullptr; srslog::basic_logger& logger; srsran::mac_pcap* pcap = nullptr; - mac_interface_rrc::ue_rnti_t* rntis = nullptr; + ue_rnti* rntis = nullptr; uint16_t last_temporal_crnti = 0; int si_window_start = 0; + std::mutex retx_cnt_mutex = {}; + float average_retx = 0.0; uint64_t nof_pkts = 0; uint8_t cc_idx = 0; diff --git a/srsue/hdr/stack/mac/mac.h b/srsue/hdr/stack/mac/mac.h index 66bd0c0ca..c71c131c7 100644 --- a/srsue/hdr/stack/mac/mac.h +++ b/srsue/hdr/stack/mac/mac.h @@ -84,8 +84,8 @@ public: void set_rach_ded_cfg(uint32_t preamble_index, uint32_t prach_mask); - void get_rntis(ue_rnti_t* rntis); - void set_ho_rnti(uint16_t crnti, uint16_t target_pci); + uint16_t get_crnti(); + void set_ho_rnti(uint16_t crnti, uint16_t target_pci); /*********** interface for stack ******************/ void process_pdus(); @@ -100,8 +100,6 @@ public: private: void clear_rntis(); - bool is_in_window(uint32_t tti, int* start, int* len); - // Interaction with PHY phy_interface_mac_lte* phy_h = nullptr; rlc_interface_mac* rlc_h = nullptr; @@ -110,13 +108,11 @@ private: srslog::basic_logger& logger; mac_interface_phy_lte::mac_phy_cfg_mbsfn_t phy_mbsfn_cfg = {}; - // RNTI search window scheduling - int si_window_length = -1, si_window_start = -1; - int ra_window_length = -1, ra_window_start = -1; - int p_window_start = -1; + // Control scheduling for SI/RA/P RNTIs + rnti_window_safe si_window, ra_window, p_window; // UE-specific RNTIs - ue_rnti_t uernti; + ue_rnti uernti; /* Multiplexing/Demultiplexing Units */ mux mux_unit; @@ -156,6 +152,7 @@ private: srsran::mac_pcap* pcap = nullptr; bool is_first_ul_grant = false; + std::mutex metrics_mutex = {}; mac_metrics_t metrics[SRSRAN_MAX_CARRIERS] = {}; std::atomic initialized = {false}; diff --git a/srsue/hdr/stack/mac/mux.h b/srsue/hdr/stack/mac/mux.h index dc7082f7a..46f8a322c 100644 --- a/srsue/hdr/stack/mac/mux.h +++ b/srsue/hdr/stack/mac/mux.h @@ -57,6 +57,7 @@ public: void print_logical_channel_state(const std::string& info); private: + uint8_t* pdu_get_unsafe(srsran::byte_buffer_t* payload, uint32_t pdu_sz); bool pdu_move_to_msg3(uint32_t pdu_sz); uint32_t allocate_sdu(uint32_t lcid, srsran::sch_pdu* pdu, int max_sdu_sz); bool sched_sdu(srsran::logical_channel_config_t* ch, int* sdu_space, int max_sdu_sz); diff --git a/srsue/hdr/stack/mac/proc_ra.h b/srsue/hdr/stack/mac/proc_ra.h index fdfc38fcb..5d62b55bc 100644 --- a/srsue/hdr/stack/mac/proc_ra.h +++ b/srsue/hdr/stack/mac/proc_ra.h @@ -22,6 +22,7 @@ #include "srsran/common/mac_pcap.h" #include "srsran/common/timers.h" #include "srsran/mac/pdu.h" +#include "srsue/hdr/stack/mac_common/mac_common.h" /* Random access procedure as specified in Section 5.1 of 36.321 */ @@ -36,7 +37,7 @@ public: void init(phy_interface_mac_lte* phy_h, rrc_interface_mac* rrc_, - mac_interface_rrc::ue_rnti_t* rntis, + ue_rnti* rntis, srsran::timer_handler::unique_timer* time_alignment_timer_, mux* mux_unit, srsran::ext_task_sched_handle* task_sched_); @@ -50,7 +51,7 @@ public: void start_mac_order(uint32_t msg_len_bits = 56); void step(uint32_t tti); - void update_rar_window(int& rar_window_start, int& rar_window_length); + void update_rar_window(rnti_window_safe& ra_window); bool is_contention_resolution(); void harq_retx(); void harq_max_retx(); @@ -140,7 +141,7 @@ private: srsran::timer_handler::unique_timer* time_alignment_timer = nullptr; srsran::timer_handler::unique_timer contention_resolution_timer; - mac_interface_rrc::ue_rnti_t* rntis = nullptr; + ue_rnti* rntis = nullptr; std::atomic transmitted_contention_id = {0}; std::atomic transmitted_crnti = {0}; diff --git a/srsue/hdr/stack/mac/proc_sr.h b/srsue/hdr/stack/mac/proc_sr.h index 1896cdc2e..1bd517cf6 100644 --- a/srsue/hdr/stack/mac/proc_sr.h +++ b/srsue/hdr/stack/mac/proc_sr.h @@ -15,6 +15,7 @@ #include "srsran/interfaces/ue_mac_interfaces.h" #include "srsran/srslog/srslog.h" +#include #include /* Scheduling Request procedure as defined in 5.4.4 of 36.321 */ @@ -48,6 +49,9 @@ private: phy_interface_mac_lte* phy_h; srslog::basic_logger& logger; + // Protects access to is_pending_sr, which can be accessed by PHY worker + std::mutex mutex = {}; + bool initiated; }; diff --git a/srsue/hdr/stack/mac/ul_harq.h b/srsue/hdr/stack/mac/ul_harq.h index 812fd9084..7507a69d8 100644 --- a/srsue/hdr/stack/mac/ul_harq.h +++ b/srsue/hdr/stack/mac/ul_harq.h @@ -29,7 +29,7 @@ class ul_harq_entity public: ul_harq_entity(const uint8_t cc_idx_); - bool init(mac_interface_rrc_common::ue_rnti_t* rntis_, ra_proc* ra_proc_h_, mux* mux_unit_); + bool init(ue_rnti* rntis_, ra_proc* ra_proc_h_, mux* mux_unit_); void reset(); void reset_ndi(); @@ -96,8 +96,9 @@ private: srsran::mac_pcap* pcap = nullptr; srslog::basic_logger& logger; - mac_interface_rrc_common::ue_rnti_t* rntis = nullptr; - srsran::ul_harq_cfg_t harq_cfg = {}; + ue_rnti* rntis = nullptr; + + srsran::ul_harq_cfg_t harq_cfg = {}; float average_retx = 0.0; uint64_t nof_pkts = 0; diff --git a/srsue/hdr/stack/mac_common/mac_common.h b/srsue/hdr/stack/mac_common/mac_common.h index 17aaf411b..7cb3eccbf 100644 --- a/srsue/hdr/stack/mac_common/mac_common.h +++ b/srsue/hdr/stack/mac_common/mac_common.h @@ -14,8 +14,10 @@ #define SRSUE_MAC_COMMON_H #include "srsran/common/string_helpers.h" +#include "srsran/phy/common/phy_common.h" #include "srsran/srslog/srslog.h" #include +#include /** * @brief Common definitions/interfaces between LTE/NR MAC components @@ -25,6 +27,161 @@ */ namespace srsue { +// Helper class to protect access to RNTIs +class ue_rnti +{ +public: + void reset() + { + std::lock_guard lock(mutex); + crnti = 0; + rar_rnti = 0; + temp_rnti = 0; + tpc_rnti = 0; + sps_rnti = 0; + contention_id = 0; + } + uint16_t get_crnti() + { + std::lock_guard lock(mutex); + return crnti; + } + uint16_t get_rar_rnti() + { + std::lock_guard lock(mutex); + return rar_rnti; + } + uint16_t get_temp_rnti() + { + std::lock_guard lock(mutex); + return temp_rnti; + } + uint16_t get_sps_rnti() + { + std::lock_guard lock(mutex); + return sps_rnti; + } + uint64_t get_contention_id() + { + std::lock_guard lock(mutex); + return contention_id; + } + void set_crnti(uint16_t rnti) + { + std::lock_guard lock(mutex); + crnti = rnti; + } + void set_rar_rnti(uint16_t rnti) + { + std::lock_guard lock(mutex); + rar_rnti = rnti; + } + void set_temp_rnti(uint16_t rnti) + { + std::lock_guard lock(mutex); + temp_rnti = rnti; + } + void set_contention_id(uint64_t id) + { + std::lock_guard lock(mutex); + contention_id = id; + } + void set_crnti_to_temp() + { + std::lock_guard lock(mutex); + crnti = temp_rnti; + } + void clear_temp_rnti() + { + std::lock_guard lock(mutex); + temp_rnti = SRSRAN_INVALID_RNTI; + } + void clear_rar_rnti() + { + std::lock_guard lock(mutex); + rar_rnti = SRSRAN_INVALID_RNTI; + } + void clear_crnti() + { + std::lock_guard lock(mutex); + crnti = SRSRAN_INVALID_RNTI; + } + +private: + std::mutex mutex; + uint16_t crnti = 0; + uint16_t rar_rnti = 0; + uint16_t temp_rnti = 0; + uint16_t tpc_rnti = 0; + uint16_t sps_rnti = 0; + uint64_t contention_id = 0; +}; + +// Helper class to control RNTI search windows in a protected manner +class rnti_window_safe +{ +public: + void reset() + { + std::lock_guard lock(mutex); + length = -1; + start = -1; + } + void set(int length_, int start_) + { + std::lock_guard lock(mutex); + length = length_; + start = start_; + } + int get_length() + { + std::lock_guard lock(mutex); + return length; + } + int get_start() + { + std::lock_guard lock(mutex); + return start; + } + bool is_set() + { + std::lock_guard lock(mutex); + return start > 0; + } + bool is_in_window(int tti) + { + std::lock_guard lock(mutex); + if (start == 0 || length == 0) { + return false; + } + if ((int)srsran_tti_interval(tti, start) < length + 5) { + if (tti > start) { + if (tti <= start + length) { + return true; + } else { + start = 0; + length = 0; + return false; + } + } else { + if (tti <= (start + length) % 10240) { + return true; + } else { + start = 0; + length = 0; + return false; + } + } + } + return false; + } + +private: + int length = -1; + int start = -1; + std::mutex mutex; +}; + // BSR trigger are common between LTE and NR typedef enum { NONE, REGULAR, PADDING, PERIODIC } bsr_trigger_type_t; char* bsr_trigger_type_tostring(bsr_trigger_type_t type); diff --git a/srsue/src/main.cc b/srsue/src/main.cc index 4d61b1c8e..f7c700bc2 100644 --- a/srsue/src/main.cc +++ b/srsue/src/main.cc @@ -15,6 +15,7 @@ #include "srsran/common/crash_handler.h" #include "srsran/common/metrics_hub.h" #include "srsran/common/signal_handler.h" +#include "srsran/common/tsan_options.h" #include "srsran/srslog/event_trace.h" #include "srsran/srslog/srslog.h" #include "srsran/srsran.h" diff --git a/srsue/src/metrics_csv.cc b/srsue/src/metrics_csv.cc index 50f5643c0..bd8490f83 100644 --- a/srsue/src/metrics_csv.cc +++ b/srsue/src/metrics_csv.cc @@ -47,11 +47,13 @@ metrics_csv::~metrics_csv() void metrics_csv::set_ue_handle(ue_metrics_interface* ue_) { + std::lock_guard lock(mutex); ue = ue_; } void metrics_csv::set_flush_period(const uint32_t flush_period_sec_) { + std::lock_guard lock(mutex); flush_period_sec = flush_period_sec_; } diff --git a/srsue/src/metrics_json.cc b/srsue/src/metrics_json.cc index a012a8a74..e51ba7a38 100644 --- a/srsue/src/metrics_json.cc +++ b/srsue/src/metrics_json.cc @@ -17,6 +17,7 @@ using namespace srsue; void metrics_json::set_ue_handle(ue_metrics_interface* ue_) { + std::lock_guard lock(mutex); ue = ue_; } @@ -138,6 +139,7 @@ static double get_time_stamp() void metrics_json::set_metrics(const ue_metrics_t& metrics, const uint32_t period_usec) { + std::lock_guard lock(mutex); if (!ue) { return; } diff --git a/srsue/src/metrics_stdout.cc b/srsue/src/metrics_stdout.cc index 6818a019e..74efc9cd7 100644 --- a/srsue/src/metrics_stdout.cc +++ b/srsue/src/metrics_stdout.cc @@ -53,11 +53,13 @@ char const* const prefixes[2][9] = { void metrics_stdout::set_ue_handle(ue_metrics_interface* ue_) { + std::lock_guard lock(mutex); ue = ue_; } void metrics_stdout::toggle_print(bool b) { + std::lock_guard lock(mutex); do_print = b; } @@ -161,6 +163,7 @@ void metrics_stdout::set_metrics_helper(const phy_metrics_t& phy, void metrics_stdout::set_metrics(const ue_metrics_t& metrics, const uint32_t period_usec) { + std::lock_guard lock(mutex); if (ue == nullptr) { return; } diff --git a/srsue/src/phy/lte/cc_worker.cc b/srsue/src/phy/lte/cc_worker.cc index ddafb7efe..9fa2e921e 100644 --- a/srsue/src/phy/lte/cc_worker.cc +++ b/srsue/src/phy/lte/cc_worker.cc @@ -784,12 +784,10 @@ bool cc_worker::encode_uplink(mac_interface_phy_lte::tb_action_ul_t* action, srs void cc_worker::set_uci_sr(srsran_uci_data_t* uci_data) { - Debug("set_uci_sr() query: sr_enabled=%d, last_tx_tti=%d", phy->sr_enabled, phy->sr_last_tx_tti); - if (srsran_ue_ul_gen_sr(&ue_ul_cfg, &sf_cfg_ul, uci_data, phy->sr_enabled)) { - if (phy->sr_enabled) { - phy->sr_last_tx_tti = CURRENT_TTI_TX; - phy->sr_enabled = false; - Debug("set_uci_sr() sending SR: sr_enabled=%d, last_tx_tti=%d", phy->sr_enabled, phy->sr_last_tx_tti); + Debug("set_uci_sr() query: sr_enabled=%d, last_tx_tti=%d", phy->sr.is_triggered(), phy->sr.get_last_tx_tti()); + if (srsran_ue_ul_gen_sr(&ue_ul_cfg, &sf_cfg_ul, uci_data, phy->sr.is_triggered())) { + if (phy->sr.set_last_tx_tti(CURRENT_TTI_TX)) { + Debug("set_uci_sr() sending SR: sr_enabled=true, last_tx_tti=%d", CURRENT_TTI_TX); } } } diff --git a/srsue/src/phy/phy.cc b/srsue/src/phy/phy.cc index e9d84e7c6..da093bd7c 100644 --- a/srsue/src/phy/phy.cc +++ b/srsue/src/phy/phy.cc @@ -240,8 +240,6 @@ void phy::configure_prach_params() { Debug("Configuring PRACH parameters"); - prach_cfg.tdd_config = tdd_config; - if (!prach_buffer.set_cell(selected_cell, prach_cfg)) { Error("Configuring PRACH parameters"); } @@ -294,7 +292,9 @@ void phy::set_cells_to_meas(uint32_t earfcn, const std::set& pci) void phy::meas_stop() { - sfsync.meas_stop(); + if (is_configured) { + sfsync.meas_stop(); + } } // This function executes one part of the procedure immediatly and returns to continue in the background. @@ -415,14 +415,13 @@ uint32_t phy::get_current_tti() void phy::sr_send() { - common.sr_enabled = true; - common.sr_last_tx_tti = -1; - Debug("sr_send(): sr_enabled=%d, last_tx_tti=%d", common.sr_enabled, common.sr_last_tx_tti); + common.sr.trigger(); + Debug("SR is triggered"); } int phy::sr_last_tx_tti() { - return common.sr_last_tx_tti; + return common.sr.get_last_tx_tti(); } void phy::set_rar_grant(uint8_t grant_payload[SRSRAN_RAR_GRANT_LEN], uint16_t rnti) @@ -460,6 +459,7 @@ bool phy::set_config(const srsran::phy_cfg_t& config_, uint32_t cc_idx) // - The PRACH configuration is present if (!cc_idx && config_.prach_cfg_present) { prach_cfg = config_.prach_cfg; + prach_cfg.tdd_config = tdd_config; } // Apply configurations asynchronously to avoid race conditions diff --git a/srsue/src/phy/phy_common.cc b/srsue/src/phy/phy_common.cc index 4803d5fce..91a0e4e45 100644 --- a/srsue/src/phy/phy_common.cc +++ b/srsue/src/phy/phy_common.cc @@ -49,7 +49,7 @@ void phy_common::init(phy_args_t* _args, stack = _stack; args = _args; insync_itf = _chest_loop; - sr_last_tx_tti = -1; + sr.reset(); // Instantiate UL channel emulator if (args->ul_channel_args.enable) { @@ -873,10 +873,9 @@ void phy_common::reset() { reset_radio(); - sr_enabled = false; + sr.reset(); cur_pathloss = 0; cur_pusch_power = 0; - sr_last_tx_tti = -1; last_ri = 0; // Reset all measurements diff --git a/srsue/src/phy/prach.cc b/srsue/src/phy/prach.cc index 86021bd95..9f679e5b5 100644 --- a/srsue/src/phy/prach.cc +++ b/srsue/src/phy/prach.cc @@ -32,6 +32,7 @@ using namespace srsue; void prach::init(uint32_t max_prb) { + std::lock_guard lock(mutex); for (auto& i : buffer) { for (auto& j : i) { j = srsran_vec_cf_malloc(SRSRAN_PRACH_MAX_LEN); @@ -65,6 +66,7 @@ void prach::init(uint32_t max_prb) void prach::stop() { + std::lock_guard lock(mutex); if (!mem_initiated) { return; } @@ -176,6 +178,7 @@ bool prach::is_ready_to_send(uint32_t current_tti_, uint32_t current_pci) { // Make sure the curernt PCI is the one we configured the PRACH for if (is_pending() && current_pci == cell.id) { + std::lock_guard lock(mutex); // consider the number of subframes the transmission must be anticipated uint32_t tti_tx = TTI_TX(current_tti_); if (srsran_prach_tti_opportunity(&prach_obj, tti_tx, allowed_subframe)) { @@ -189,6 +192,7 @@ bool prach::is_ready_to_send(uint32_t current_tti_, uint32_t current_pci) phy_interface_mac_lte::prach_info_t prach::get_info() const { + std::lock_guard lock(mutex); phy_interface_mac_lte::prach_info_t info = {}; info.preamble_format = prach_obj.config_idx / 16; @@ -207,6 +211,7 @@ phy_interface_mac_lte::prach_info_t prach::get_info() const cf_t* prach::generate(float cfo, uint32_t* nof_sf, float* target_power) { + std::lock_guard lock(mutex); if (!cell_initiated || preamble_idx < 0 || !nof_sf || unsigned(preamble_idx) >= max_preambles || !srsran_cell_isvalid(&cell) || len >= MAX_LEN_SF * 30720 || len == 0) { Error("PRACH: Invalid parameters: cell_initiated=%d, preamble_idx=%d, cell.nof_prb=%d, len=%d", diff --git a/srsue/src/phy/scell/intra_measure_base.cc b/srsue/src/phy/scell/intra_measure_base.cc index 986f850f2..11da6584d 100644 --- a/srsue/src/phy/scell/intra_measure_base.cc +++ b/srsue/src/phy/scell/intra_measure_base.cc @@ -36,7 +36,7 @@ void intra_measure_base::init_generic(uint32_t cc_idx_, const args_t& args) context.meas_period_ms = args.period_ms; context.trigger_tti_period = args.tti_period; context.trigger_tti_offset = args.tti_offset; - context.rx_gain_offset_db = args.rx_gain_offset_db; + rx_gain_offset_db = args.rx_gain_offset_db; // Compute subframe length from the sampling rate if available if (std::isnormal(args.srate_hz)) { @@ -86,7 +86,7 @@ void intra_measure_base::stop() void intra_measure_base::set_rx_gain_offset(float rx_gain_offset_db_) { - context.rx_gain_offset_db = rx_gain_offset_db_; + rx_gain_offset_db = rx_gain_offset_db_; } void intra_measure_base::meas_stop() @@ -179,7 +179,7 @@ void intra_measure_base::measure_proc() } // Perform measurements for the actual RAT - if (not measure_rat(context, search_buffer)) { + if (not measure_rat(context, search_buffer, rx_gain_offset_db)) { Log(error, "Error measuring RAT"); } } diff --git a/srsue/src/phy/scell/intra_measure_lte.cc b/srsue/src/phy/scell/intra_measure_lte.cc index a68af2991..7719a42c1 100644 --- a/srsue/src/phy/scell/intra_measure_lte.cc +++ b/srsue/src/phy/scell/intra_measure_lte.cc @@ -47,7 +47,7 @@ void intra_measure_lte::set_primary_cell(uint32_t earfcn, srsran_cell_t cell) set_current_sf_len((uint32_t)SRSRAN_SF_LEN_PRB(cell.nof_prb)); } -bool intra_measure_lte::measure_rat(measure_context_t context, std::vector& buffer) +bool intra_measure_lte::measure_rat(measure_context_t context, std::vector& buffer, float rx_gain_offset) { std::set cells_to_measure = context.active_pci; @@ -84,7 +84,7 @@ bool intra_measure_lte::measure_rat(measure_context_t context, std::vector m.rat = srsran::srsran_rat_t::lte; m.pci = cell.id; m.earfcn = current_earfcn; - m.rsrp = refsignal_dl_sync.rsrp_dBfs - context.rx_gain_offset_db; + m.rsrp = refsignal_dl_sync.rsrp_dBfs - rx_gain_offset_db; m.rsrq = refsignal_dl_sync.rsrq_dB; m.cfo_hz = refsignal_dl_sync.cfo_Hz; neighbour_cells.push_back(m); diff --git a/srsue/src/phy/scell/intra_measure_nr.cc b/srsue/src/phy/scell/intra_measure_nr.cc index 6fd63a43d..bef371190 100644 --- a/srsue/src/phy/scell/intra_measure_nr.cc +++ b/srsue/src/phy/scell/intra_measure_nr.cc @@ -81,7 +81,7 @@ bool intra_measure_nr::set_config(const config_t& cfg) return true; } -bool intra_measure_nr::measure_rat(const measure_context_t context, std::vector& buffer) +bool intra_measure_nr::measure_rat(const measure_context_t context, std::vector& buffer, float rx_gain_offset) { std::chrono::steady_clock::time_point begin = std::chrono::steady_clock::now(); @@ -117,7 +117,7 @@ bool intra_measure_nr::measure_rat(const measure_context_t context, std::vector< // Prepare found measurements std::vector meas_list(1); meas_list[0].rat = get_rat(); - meas_list[0].rsrp = meas.rsrp_dB + context.rx_gain_offset_db; + meas_list[0].rsrp = meas.rsrp_dB + rx_gain_offset_db; meas_list[0].cfo_hz = meas.cfo_hz; meas_list[0].earfcn = get_earfcn(); meas_list[0].pci = N_id; diff --git a/srsue/src/phy/sync.cc b/srsue/src/phy/sync.cc index 040320e45..046f653f0 100644 --- a/srsue/src/phy/sync.cc +++ b/srsue/src/phy/sync.cc @@ -88,14 +88,17 @@ void sync::init(srsran::radio_interface_phy* _radio, sfn_p.init(&ue_sync, worker_com->args, sf_buffer, sf_buffer.size()); // Start intra-frequency measurement - for (uint32_t i = 0; i < worker_com->args->nof_lte_carriers; i++) { - scell::intra_measure_lte* q = new scell::intra_measure_lte(phy_logger, *this); - scell::intra_measure_base::args_t args = {}; - args.len_ms = worker_com->args->intra_freq_meas_len_ms; - args.period_ms = worker_com->args->intra_freq_meas_period_ms; - args.rx_gain_offset_db = worker_com->args->rx_gain_offset; - q->init(i, args); - intra_freq_meas.push_back(std::unique_ptr(q)); + { + std::lock_guard lock(intra_freq_cfg_mutex); + for (uint32_t i = 0; i < worker_com->args->nof_lte_carriers; i++) { + scell::intra_measure_lte* q = new scell::intra_measure_lte(phy_logger, *this); + scell::intra_measure_base::args_t args = {}; + args.len_ms = worker_com->args->intra_freq_meas_len_ms; + args.period_ms = worker_com->args->intra_freq_meas_period_ms; + args.rx_gain_offset_db = worker_com->args->rx_gain_offset; + q->init(i, args); + intra_freq_meas.push_back(std::unique_ptr(q)); + } } // Allocate Secondary serving cell synchronization @@ -125,6 +128,7 @@ sync::~sync() void sync::stop() { + std::lock_guard lock(intra_freq_cfg_mutex); worker_com->semaphore.wait_all(); for (auto& q : intra_freq_meas) { q->stop(); @@ -142,7 +146,7 @@ void sync::reset() in_sync_cnt = 0; out_of_sync_cnt = 0; current_earfcn = -1; - srate_mode = SRATE_NONE; + srate.reset(); sfn_p.reset(); search_p.reset(); } @@ -219,8 +223,7 @@ rrc_interface_phy_lte::cell_search_ret_t sync::cell_search_start(phy_cell_t* fou rrc_proc_state = PROC_SEARCH_RUNNING; - if (srate_mode != SRATE_FIND) { - srate_mode = SRATE_FIND; + if (srate.set_find()) { radio_h->set_rx_srate(1.92e6); radio_h->set_tx_srate(1.92e6); Info("SYNC: Setting Cell Search sampling rate"); @@ -244,10 +247,10 @@ rrc_interface_phy_lte::cell_search_ret_t sync::cell_search_start(phy_cell_t* fou // Check return state switch (cell_search_ret) { case search::CELL_FOUND: - phy_logger.info("Cell Search: Found cell with PCI=%d with %d PRB", cell.id, cell.nof_prb); + phy_logger.info("Cell Search: Found cell with PCI=%d with %d PRB", cell.get().id, cell.get().nof_prb); if (found_cell) { found_cell->earfcn = current_earfcn; - found_cell->pci = cell.id; + found_cell->pci = cell.get().id; found_cell->cfo_hz = search_p.get_last_cfo(); } ret.found = rrc_interface_phy_lte::cell_search_ret_t::CELL_FOUND; @@ -328,7 +331,7 @@ bool sync::cell_select_start(phy_cell_t new_cell) search_p.reset(); // Reconfigure cell if necessary - cell.id = new_cell.pci; + cell.set_pci(new_cell.pci); if (not set_cell(new_cell.cfo_hz)) { Error("Cell Select: Reconfiguring cell"); goto clean_exit; @@ -346,19 +349,16 @@ bool sync::cell_select_start(phy_cell_t new_cell) } // Reconfigure first intra-frequency measurement - intra_freq_meas[0]->set_primary_cell(current_earfcn, cell); + intra_freq_meas[0]->set_primary_cell(current_earfcn, cell.get()); // Reconfigure secondary serving cell synchronization assuming the same BW than the primary // The secondary serving cell synchronization will not resize again when the SCell gets configured for (auto& e : scell_sync) { - e.second->set_bw(cell.nof_prb); + e.second->set_bw(cell.get().nof_prb); } // Change sampling rate if necessary - if (srate_mode != SRATE_CAMP) { - phy_logger.info("Cell Select: Setting CAMPING sampling rate"); - set_sampling_rate(); - } + set_sampling_rate(); // SFN synchronization phy_state.run_sfn_sync(); @@ -402,8 +402,10 @@ bool sync::wait_idle() void sync::run_cell_search_state() { - cell_search_ret = search_p.run(&cell, mib); + srsran_cell_t tmp_cell = cell.get(); + cell_search_ret = search_p.run(&tmp_cell, mib); if (cell_search_ret == search::CELL_FOUND) { + cell.set(tmp_cell); stack->bch_decoded_ok(SYNC_CC_IDX, mib.data(), mib.size() / 8); } phy_state.state_exit(); @@ -411,12 +413,11 @@ void sync::run_cell_search_state() void sync::run_sfn_sync_state() { - srsran_cell_t temp_cell = cell; - switch (sfn_p.run_subframe(&temp_cell, &tti, mib)) { + srsran_cell_t old_cell = cell.get(); + switch (sfn_p.run_subframe(&old_cell, &tti, mib)) { case sfn_sync::SFN_FOUND: - if (memcmp(&cell, &temp_cell, sizeof(srsran_cell_t)) != 0) { - srsran_cell_fprint(stdout, &cell, 0); - srsran_cell_fprint(stdout, &temp_cell, 0); + if (!cell.equals(old_cell)) { + srsran_cell_fprint(stdout, &old_cell, 0); phy_logger.error("Detected cell during SFN synchronization differs from configured cell. Cell reselection to " "cells with different MIB is not supported"); srsran::console("Detected cell during SFN synchronization differs from configured cell. Cell reselection " @@ -465,7 +466,7 @@ void sync::run_camping_in_sync_state(lte::sf_worker* lte_worker, // Force decode MIB if required if (force_camping_sfn_sync) { uint32_t _tti = 0; - srsran_cell_t temp_cell = cell; + srsran_cell_t temp_cell = cell.get(); sfn_sync::ret_code ret = sfn_p.decode_mib(&temp_cell, &_tti, &sync_buffer, mib); if (ret == sfn_sync::SFN_FOUND) { @@ -475,7 +476,7 @@ void sync::run_camping_in_sync_state(lte::sf_worker* lte_worker, // Disable force_camping_sfn_sync = false; - if (memcmp(&cell, &temp_cell, sizeof(srsran_cell_t)) != 0) { + if (!cell.equals(temp_cell)) { phy_logger.error("Detected cell during SFN synchronization differs from configured cell. Cell " "reselection to cells with different MIB is not supported"); srsran::console("Detected cell during SFN synchronization differs from configured cell. Cell " @@ -499,14 +500,15 @@ void sync::run_camping_in_sync_state(lte::sf_worker* lte_worker, } // Check if we need to TX a PRACH - if (prach_buffer->is_ready_to_send(tti, cell.id)) { + if (prach_buffer->is_ready_to_send(tti, cell.get().id)) { prach_ptr = prach_buffer->generate(get_tx_cfo(), &prach_nof_sf, &prach_power); if (prach_ptr == nullptr) { Error("Generating PRACH"); } } - lte_worker->set_prach(prach_ptr ? &prach_ptr[prach_sf_cnt * SRSRAN_SF_LEN_PRB(cell.nof_prb)] : nullptr, prach_power); + lte_worker->set_prach(prach_ptr ? &prach_ptr[prach_sf_cnt * SRSRAN_SF_LEN_PRB(cell.get().nof_prb)] : nullptr, + prach_power); // Execute Serving Cell state FSM worker_com->cell_state.run_tti(tti); @@ -618,8 +620,8 @@ void sync::run_idle_state() { if (radio_h->is_init()) { uint32_t nsamples = 1920; - if (std::isnormal(current_srate) and current_srate > 0.0f) { - nsamples = current_srate / 1000; + if (srate.is_normal()) { + nsamples = srate.get_srate() / 1000; } Debug("Discarding %d samples", nsamples); srsran_timestamp_t rx_time = {}; @@ -812,18 +814,21 @@ void sync::set_ue_sync_opts(srsran_ue_sync_t* q, float cfo_) bool sync::set_cell(float cfo_in) { - if (!srsran_cell_isvalid(&cell)) { - Error("SYNC: Setting cell: invalid cell (nof_prb=%d, pci=%d, ports=%d)", cell.nof_prb, cell.id, cell.nof_ports); + if (!cell.is_valid()) { + Error("SYNC: Setting cell: invalid cell (nof_prb=%d, pci=%d, ports=%d)", + cell.get().nof_prb, + cell.get().id, + cell.get().nof_ports); return false; } // Set cell in all objects - if (srsran_ue_sync_set_cell(&ue_sync, cell)) { + if (srsran_ue_sync_set_cell(&ue_sync, cell.get())) { Error("SYNC: Setting cell: initiating ue_sync"); return false; } - sfn_p.set_cell(cell); - worker_com->set_cell(cell); + sfn_p.set_cell(cell.get()); + worker_com->set_cell(cell.get()); // Reset cell configuration for (uint32_t i = 0; i < worker_com->args->nof_phy_threads; i++) { @@ -834,7 +839,7 @@ bool sync::set_cell(float cfo_in) for (uint32_t i = 0; i < worker_com->args->nof_phy_threads; i++) { lte::sf_worker* w = lte_worker_pool->wait_worker_id(i); if (w) { - success &= w->set_cell_unlocked(0, cell); + success &= w->set_cell_unlocked(0, cell.get()); w->release(); } } @@ -895,21 +900,18 @@ bool sync::set_frequency() void sync::set_sampling_rate() { - float new_srate = (float)srsran_sampling_freq_hz(cell.nof_prb); + float new_srate = (float)srsran_sampling_freq_hz(cell.get().nof_prb); if (new_srate < 0.0) { - Error("Invalid sampling rate for %d PRBs. keeping same.", cell.nof_prb); + Error("Invalid sampling rate for %d PRBs. keeping same.", cell.get().nof_prb); return; } - if (current_srate != new_srate || srate_mode != SRATE_CAMP) { - current_srate = new_srate; - Info("SYNC: Setting sampling rate %.2f MHz", current_srate / 1000000); - - srate_mode = SRATE_CAMP; - radio_h->set_rx_srate(current_srate); - radio_h->set_tx_srate(current_srate); + if (srate.set_camp(new_srate)) { + Info("SYNC: Setting sampling rate %.2f MHz", new_srate / 1000000); + radio_h->set_rx_srate(new_srate); + radio_h->set_tx_srate(new_srate); } else { - Error("Error setting sampling rate for cell with %d PRBs", cell.nof_prb); + Error("Error setting sampling rate for cell with %d PRBs", cell.get().nof_prb); } } @@ -921,7 +923,7 @@ uint32_t sync::get_current_tti() void sync::get_current_cell(srsran_cell_t* cell_, uint32_t* earfcn_) { if (cell_) { - *cell_ = cell; + *cell_ = cell.get(); } if (earfcn_) { *earfcn_ = current_earfcn; @@ -959,12 +961,13 @@ int sync::radio_recv_fnc(srsran::rf_buffer_t& data, srsran_timestamp_t* rx_time) // Execute channel DL emulator if (channel_emulator and rx_time) { - channel_emulator->set_srate((uint32_t)current_srate); + channel_emulator->set_srate((uint32_t)srate.get_srate()); channel_emulator->run(data.to_cf_t(), data.to_cf_t(), data.get_nof_samples(), *rx_time); } // Save signal for Intra-frequency measurement - if (srsran_cell_isvalid(&cell)) { + if (cell.is_valid()) { + std::lock_guard lock(intra_freq_cfg_mutex); for (uint32_t i = 0; (uint32_t)i < intra_freq_meas.size(); i++) { // Feed the exact number of base-band samples for avoiding an invalid buffer read intra_freq_meas[i]->run_tti(tti, data.get(i, 0, worker_com->args->nof_rx_ant), data.get_nof_samples()); @@ -1031,12 +1034,14 @@ void sync::set_rx_gain(float gain) void sync::set_inter_frequency_measurement(uint32_t cc_idx, uint32_t earfcn_, srsran_cell_t cell_) { + std::lock_guard lock(intra_freq_cfg_mutex); if (cc_idx < intra_freq_meas.size()) { intra_freq_meas[cc_idx]->set_primary_cell(earfcn_, cell_); } } void sync::set_cells_to_meas(uint32_t earfcn_, const std::set& pci) { + std::lock_guard lock(intra_freq_cfg_mutex); bool found = false; for (size_t i = 0; i < intra_freq_meas.size() and not found; i++) { if (earfcn_ == intra_freq_meas[i]->get_earfcn()) { @@ -1051,6 +1056,7 @@ void sync::set_cells_to_meas(uint32_t earfcn_, const std::set& pci) void sync::meas_stop() { + std::lock_guard lock(intra_freq_cfg_mutex); for (auto& q : intra_freq_meas) { q->meas_stop(); } diff --git a/srsue/src/stack/mac/dl_harq.cc b/srsue/src/stack/mac/dl_harq.cc index f72533780..900cfe4b8 100644 --- a/srsue/src/stack/mac/dl_harq.cc +++ b/srsue/src/stack/mac/dl_harq.cc @@ -25,7 +25,7 @@ dl_harq_entity::dl_harq_entity(uint8_t cc_idx_) : proc(SRSRAN_MAX_HARQ_PROC), logger(srslog::fetch_basic_logger("MAC")), cc_idx(cc_idx_) {} -bool dl_harq_entity::init(mac_interface_rrc::ue_rnti_t* rntis_, demux* demux_unit_) +bool dl_harq_entity::init(ue_rnti* rntis_, demux* demux_unit_) { demux_unit = demux_unit_; rntis = rntis_; @@ -45,7 +45,7 @@ void dl_harq_entity::new_grant_dl(mac_interface_phy_lte::mac_grant_dl_t grant, { bzero(action, sizeof(mac_interface_phy_lte::tb_action_dl_t)); - if (grant.rnti != rntis->sps_rnti) { + if (grant.rnti != rntis->get_sps_rnti()) { // Set BCCH PID for SI RNTI dl_harq_process* proc_ptr = NULL; if (grant.rnti == SRSRAN_SIRNTI) { @@ -58,8 +58,8 @@ void dl_harq_entity::new_grant_dl(mac_interface_phy_lte::mac_grant_dl_t grant, proc_ptr = &proc[grant.pid]; } // Consider the NDI to have been toggled - if (grant.rnti == rntis->temp_rnti && last_temporal_crnti != rntis->temp_rnti) { - last_temporal_crnti = rntis->temp_rnti; + if (grant.rnti == rntis->get_temp_rnti() && last_temporal_crnti != rntis->get_temp_rnti()) { + last_temporal_crnti = rntis->get_temp_rnti(); proc_ptr->reset_ndi(); Info("Considering NDI in pid=%d to be toggled for first Temporal C-RNTI", grant.pid); } @@ -103,8 +103,14 @@ void dl_harq_entity::set_si_window_start(int si_window_start_) float dl_harq_entity::get_average_retx() { + std::unique_lock lock(retx_cnt_mutex); return average_retx; } +void dl_harq_entity::set_average_retx(uint32_t n_retx) +{ + std::unique_lock lock(retx_cnt_mutex); + average_retx = SRSRAN_VEC_CMA((float)n_retx, average_retx, nof_pkts++); +} dl_harq_entity::dl_harq_process::dl_harq_process() : subproc(SRSRAN_MAX_TB) {} @@ -320,7 +326,7 @@ void dl_harq_entity::dl_harq_process::dl_tb_process::tb_decoded(mac_interface_ph harq_entity->pcap->write_dl_crnti( payload_buffer_ptr, cur_grant.tb[tid].tbs, cur_grant.rnti, ack, cur_grant.tti, harq_entity->cc_idx); } - if (cur_grant.rnti == harq_entity->rntis->temp_rnti) { + if (cur_grant.rnti == harq_entity->rntis->get_temp_rnti()) { Debug("Delivering PDU=%d bytes to Dissassemble and Demux unit (Temporal C-RNTI)", cur_grant.tb[tid].tbs); harq_entity->demux_unit->push_pdu_temp_crnti(payload_buffer_ptr, cur_grant.tb[tid].tbs); @@ -332,7 +338,7 @@ void dl_harq_entity::dl_harq_process::dl_tb_process::tb_decoded(mac_interface_ph harq_entity->demux_unit->push_pdu(payload_buffer_ptr, cur_grant.tb[tid].tbs, grant.tti); // Compute average number of retransmissions per packet - harq_entity->average_retx = SRSRAN_VEC_CMA((float)n_retx, harq_entity->average_retx, harq_entity->nof_pkts++); + harq_entity->set_average_retx(n_retx); } } diff --git a/srsue/src/stack/mac/mac.cc b/srsue/src/stack/mac/mac.cc index ecd283490..4ee3d5e55 100644 --- a/srsue/src/stack/mac/mac.cc +++ b/srsue/src/stack/mac/mac.cc @@ -198,7 +198,7 @@ void mac::run_tti(const uint32_t tti) sr_procedure.step(tti); phr_procedure.step(); ra_procedure.step(tti); - ra_procedure.update_rar_window(ra_window_start, ra_window_length); + ra_procedure.update_rar_window(ra_window); // Count TTI for metrics for (uint32_t i = 0; i < SRSRAN_MAX_CARRIERS; i++) { @@ -210,13 +210,13 @@ void mac::bcch_start_rx(int si_window_start_, int si_window_length_) { if (si_window_length_ >= 0 && si_window_start_ >= 0) { dl_harq.at(0)->set_si_window_start(si_window_start_); - si_window_length = si_window_length_; - si_window_start = si_window_start_; + si_window.set(si_window_length_, si_window_start_); } else { - si_window_length = 0; - si_window_start = 0; + si_window.reset(); } - Info("SCHED: Searching for DL dci for SI-RNTI window_st=%d, window_len=%d", si_window_start, si_window_length); + Info("SCHED: Searching for DL dci for SI-RNTI window_st=%d, window_len=%d", + si_window.get_start(), + si_window.get_length()); } void mac::bcch_stop_rx() @@ -226,28 +226,25 @@ void mac::bcch_stop_rx() void mac::pcch_start_rx() { - this->p_window_start = 1; + this->p_window.set(0, 1); } void mac::clear_rntis() { - p_window_start = 0; - si_window_start = 0; - ra_window_start = -1; - ra_window_length = -1; - bzero(&uernti, sizeof(ue_rnti_t)); + p_window.reset(); + si_window.reset(); + ra_window.reset(); + uernti.reset(); } -void mac::get_rntis(ue_rnti_t* rntis) +uint16_t mac::get_crnti() { - if (rntis) { - *rntis = uernti; - } + return uernti.get_crnti(); } void mac::set_ho_rnti(uint16_t crnti, uint16_t target_pci) { - uernti.crnti = crnti; + uernti.set_crnti(crnti); if (pcap) { pcap->set_ue_id(target_pci); } @@ -255,71 +252,44 @@ void mac::set_ho_rnti(uint16_t crnti, uint16_t target_pci) uint16_t mac::get_ul_sched_rnti(uint32_t tti) { - if (uernti.temp_rnti && !uernti.crnti) { - return uernti.temp_rnti; + if (uernti.get_temp_rnti() && !uernti.get_crnti()) { + return uernti.get_temp_rnti(); } - if (uernti.crnti) { - return uernti.crnti; + if (uernti.get_crnti()) { + return uernti.get_crnti(); } return SRSRAN_INVALID_RNTI; } -bool mac::is_in_window(uint32_t tti, int* start, int* len) -{ - uint32_t st = (uint32_t)*start; - uint32_t l = (uint32_t)*len; - - if (srsran_tti_interval(tti, st) < l + 5) { - if (tti > st) { - if (tti <= st + l) { - return true; - } else { - *start = 0; - *len = 0; - return false; - } - } else { - if (tti <= (st + l) % 10240) { - return true; - } else { - *start = 0; - *len = 0; - return false; - } - } - } - return false; -} - uint16_t mac::get_dl_sched_rnti(uint32_t tti) { // Priority: SI-RNTI, P-RNTI, RA-RNTI, Temp-RNTI, CRNTI - if (si_window_start > 0) { - if (is_in_window(tti, &si_window_start, &si_window_length)) { - // TODO: This scheduling decision belongs to RRC - if (si_window_length > 1) { // This is not a SIB1 - if ((tti / 10) % 2 == 0 && (tti % 10) == 5) { // Skip subframe #5 for which SFN mod 2 = 0 - return SRSRAN_INVALID_RNTI; - } + if (si_window.is_in_window(tti)) { + // TODO: This scheduling decision belongs to RRC + if (si_window.get_length() > 1) { // This is not a SIB1 + if ((tti / 10) % 2 == 0 && (tti % 10) == 5) { // Skip subframe #5 for which SFN mod 2 = 0 + return SRSRAN_INVALID_RNTI; } - Debug("SCHED: Searching SI-RNTI, tti=%d, window start=%d, length=%d", tti, si_window_start, si_window_length); - return SRSRAN_SIRNTI; } + Debug("SCHED: Searching SI-RNTI, tti=%d, window start=%d, length=%d", + tti, + si_window.get_start(), + si_window.get_length()); + return SRSRAN_SIRNTI; } - if (uernti.rar_rnti && ra_window_start > 0 && ra_window_length > 0 && - is_in_window(tti, &ra_window_start, &ra_window_length)) { - Debug("SCHED: Searching RAR-RNTI=0x%x, tti=%d", uernti.rar_rnti, tti); - return uernti.rar_rnti; + if (uernti.get_rar_rnti() && ra_window.is_in_window(tti)) { + Debug("SCHED: Searching RAR-RNTI=0x%x, tti=%d", uernti.get_rar_rnti(), tti); + return uernti.get_rar_rnti(); } - if (uernti.temp_rnti && !uernti.crnti) { - Debug("SCHED: Searching Temp-RNTI=0x%x", uernti.temp_rnti); - return uernti.temp_rnti; + if (uernti.get_temp_rnti() && !uernti.get_crnti()) { + Debug("SCHED: Searching Temp-RNTI=0x%x", uernti.get_temp_rnti()); + return uernti.get_temp_rnti(); } - if (uernti.crnti) { - Debug("SCHED: Searching C-RNTI=0x%x", uernti.crnti); - return uernti.crnti; + if (uernti.get_crnti()) { + Debug("SCHED: Searching C-RNTI=0x%x", uernti.get_crnti()); + return uernti.get_crnti(); } - if (p_window_start > 0) { + if (p_window.is_set()) { Debug("SCHED: Searching P-RNTI"); return SRSRAN_PRNTI; } @@ -419,14 +389,17 @@ void mac::tb_decoded(uint32_t cc_idx, mac_grant_dl_t grant, bool ack[SRSRAN_MAX_ dl_harq.at(cc_idx)->tb_decoded(grant, ack); process_pdus(); - for (uint32_t tb = 0; tb < SRSRAN_MAX_CODEWORDS; tb++) { - if (grant.tb[tb].tbs) { - if (ack[tb]) { - metrics[cc_idx].rx_brate += grant.tb[tb].tbs * 8; - } else { - metrics[cc_idx].rx_errors++; + { + std::lock_guard lock(metrics_mutex); + for (uint32_t tb = 0; tb < SRSRAN_MAX_CODEWORDS; tb++) { + if (grant.tb[tb].tbs) { + if (ack[tb]) { + metrics[cc_idx].rx_brate += grant.tb[tb].tbs * 8; + } else { + metrics[cc_idx].rx_errors++; + } + metrics[cc_idx].rx_pkts++; } - metrics[cc_idx].rx_pkts++; } } } @@ -452,7 +425,7 @@ void mac::new_grant_dl(uint32_t cc_idx, } } else if (!(grant.rnti == SRSRAN_SIRNTI && cc_idx != 0)) { // If PDCCH for C-RNTI and RA procedure in Contention Resolution, notify it - if (grant.rnti == uernti.crnti && ra_procedure.is_contention_resolution()) { + if (grant.rnti == uernti.get_crnti() && ra_procedure.is_contention_resolution()) { ra_procedure.pdcch_to_crnti(false); } // Assert DL HARQ entity @@ -580,7 +553,7 @@ void mac::timer_alignment_expire() void mac::set_contention_id(uint64_t uecri) { - uernti.contention_id = uecri; + uernti.set_contention_id(uecri); } void mac::set_rach_ded_cfg(uint32_t preamble_index, uint32_t prach_mask) diff --git a/srsue/src/stack/mac/mux.cc b/srsue/src/stack/mac/mux.cc index bc3986f04..654f329e5 100644 --- a/srsue/src/stack/mac/mux.cc +++ b/srsue/src/stack/mac/mux.cc @@ -96,11 +96,15 @@ srsran::ul_sch_lcid bsr_format_convert(bsr_proc::bsr_format_t format) } } -// Multiplexing and logical channel priorization as defined in Section 5.4.3 uint8_t* mux::pdu_get(srsran::byte_buffer_t* payload, uint32_t pdu_sz) { std::lock_guard lock(mutex); + return pdu_get_unsafe(payload, pdu_sz); +} +// Multiplexing and logical channel priorization as defined in Section 5.4.3 +uint8_t* mux::pdu_get_unsafe(srsran::byte_buffer_t* payload, uint32_t pdu_sz) +{ // Logical Channel Procedure payload->clear(); pdu_msg.init_tx(payload, pdu_sz, true); @@ -240,6 +244,7 @@ uint8_t* mux::pdu_get(srsran::byte_buffer_t* payload, uint32_t pdu_sz) void mux::append_crnti_ce_next_tx(uint16_t crnti) { + std::lock_guard lock(mutex); pending_crnti_ce = crnti; } @@ -321,6 +326,7 @@ uint32_t mux::allocate_sdu(uint32_t lcid, srsran::sch_pdu* pdu_msg, int max_sdu_ void mux::msg3_flush() { + std::lock_guard lock(mutex); Debug("Msg3 buffer flushed"); msg3_buff.clear(); msg3_has_been_transmitted = false; @@ -329,17 +335,20 @@ void mux::msg3_flush() bool mux::msg3_is_transmitted() { + std::lock_guard lock(mutex); return msg3_has_been_transmitted; } void mux::msg3_prepare() { + std::lock_guard lock(mutex); msg3_has_been_transmitted = false; msg3_pending = true; } bool mux::msg3_is_pending() { + std::lock_guard lock(mutex); return msg3_pending; } @@ -351,9 +360,10 @@ bool mux::msg3_is_empty() /* Returns a pointer to the Msg3 buffer */ uint8_t* mux::msg3_get(srsran::byte_buffer_t* payload, uint32_t pdu_sz) { + std::lock_guard lock(mutex); if (pdu_sz < msg3_buff.get_tailroom()) { if (msg3_is_empty()) { - if (!pdu_get(&msg3_buff, pdu_sz)) { + if (!pdu_get_unsafe(&msg3_buff, pdu_sz)) { Error("Moving PDU from Mux unit to Msg3 buffer"); return NULL; } diff --git a/srsue/src/stack/mac/proc_ra.cc b/srsue/src/stack/mac/proc_ra.cc index c38f8ac39..902b09b58 100644 --- a/srsue/src/stack/mac/proc_ra.cc +++ b/srsue/src/stack/mac/proc_ra.cc @@ -45,7 +45,7 @@ int delta_preamble_db_table[5] = {0, 0, -3, -3, 8}; // Initializes memory and pointers to other objects void ra_proc::init(phy_interface_mac_lte* phy_h_, rrc_interface_mac* rrc_, - mac_interface_rrc::ue_rnti_t* rntis_, + ue_rnti* rntis_, srsran::timer_handler::unique_timer* time_alignment_timer_, mux* mux_unit_, srsran::ext_task_sched_handle* task_sched_) @@ -153,7 +153,7 @@ void ra_proc::state_pdcch_setup() srsran::console( "Random Access Transmission: seq=%d, tti=%d, ra-rnti=0x%x\n", sel_preamble.load(), info.tti_ra, ra_rnti); rar_window_st = ra_tti + 3; - rntis->rar_rnti = ra_rnti; + rntis->set_rar_rnti(ra_rnti); state = RESPONSE_RECEPTION; } else { rDebug("preamble not yet transmitted"); @@ -304,7 +304,7 @@ void ra_proc::preamble_transmission() (preambleTransmissionCounter - 1) * rach_cfg.powerRampingStep; phy_h->prach_send(sel_preamble, sel_maskIndex - 1, received_target_power_dbm); - rntis->rar_rnti = SRSRAN_INVALID_RNTI; + rntis->clear_rar_rnti(); ra_tti = 0; rar_received = false; backoff_interval_start = -1; @@ -396,7 +396,7 @@ void ra_proc::tb_decoded_ok(const uint8_t cc_idx, const uint32_t tti) uint8_t grant[srsran::rar_subh::RAR_GRANT_LEN] = {}; rar_pdu_msg.get()->get_sched_grant(grant); - rntis->rar_rnti = SRSRAN_INVALID_RNTI; + rntis->clear_rar_rnti(); phy_h->set_rar_grant(grant, rar_pdu_msg.get()->get_temp_crnti()); current_ta = rar_pdu_msg.get()->get_ta_cmd(); @@ -407,7 +407,7 @@ void ra_proc::tb_decoded_ok(const uint8_t cc_idx, const uint32_t tti) rar_pdu_msg.get()->get_temp_crnti()); // Save Temp-CRNTI before generating the reply - rntis->temp_rnti = rar_pdu_msg.get()->get_temp_crnti(); + rntis->set_temp_rnti(rar_pdu_msg.get()->get_temp_crnti()); // Perform actions when preamble was selected by UE MAC if (preambleIndex <= 0) { @@ -416,7 +416,7 @@ void ra_proc::tb_decoded_ok(const uint8_t cc_idx, const uint32_t tti) // If this is the first successfully received RAR within this procedure, Msg3 is empty if (mux_unit->msg3_is_empty()) { // Save transmitted C-RNTI (if any) - transmitted_crnti = rntis->crnti; + transmitted_crnti = rntis->get_crnti(); // If we have a C-RNTI, tell Mux unit to append C-RNTI CE if no CCCH SDU transmission if (transmitted_crnti) { @@ -426,7 +426,7 @@ void ra_proc::tb_decoded_ok(const uint8_t cc_idx, const uint32_t tti) } // Save transmitted UE contention id, as defined by higher layers - transmitted_contention_id = rntis->contention_id; + transmitted_contention_id = rntis->get_contention_id(); task_queue.push([this]() { rDebug("Waiting for Contention Resolution"); @@ -449,7 +449,7 @@ void ra_proc::tb_decoded_ok(const uint8_t cc_idx, const uint32_t tti) */ void ra_proc::response_error() { - rntis->temp_rnti = 0; + rntis->clear_temp_rnti(); preambleTransmissionCounter++; contention_resolution_timer.stop(); if (preambleTransmissionCounter >= rach_cfg.preambleTransMax + 1) { @@ -483,16 +483,16 @@ void ra_proc::complete() { // Start looking for PDCCH CRNTI if (!transmitted_crnti) { - rntis->crnti = rntis->temp_rnti; + rntis->set_crnti_to_temp(); } - rntis->temp_rnti = 0; + rntis->clear_temp_rnti(); mux_unit->msg3_flush(); rrc->ra_completed(); - srsran::console("Random Access Complete. c-rnti=0x%x, ta=%d\n", rntis->crnti, current_ta); - rInfo("Random Access Complete. c-rnti=0x%x, ta=%d", rntis->crnti, current_ta); + srsran::console("Random Access Complete. c-rnti=0x%x, ta=%d\n", rntis->get_crnti(), current_ta); + rInfo("Random Access Complete. c-rnti=0x%x, ta=%d", rntis->get_crnti(), current_ta); state = IDLE; } @@ -591,17 +591,15 @@ void ra_proc::pdcch_to_crnti(bool is_new_uplink_transmission) } // Called from the Stack thread -void ra_proc::update_rar_window(int& rar_window_start, int& rar_window_length) +void ra_proc::update_rar_window(rnti_window_safe& ra_window) { if (state != RESPONSE_RECEPTION) { // reset RAR window params to default values to disable RAR search - rar_window_start = -1; - rar_window_length = -1; + ra_window.reset(); } else { - rar_window_length = rach_cfg.responseWindowSize; - rar_window_start = rar_window_st; + ra_window.set(rach_cfg.responseWindowSize, rar_window_st); } - rDebug("rar_window_start=%d, rar_window_length=%d", rar_window_start, rar_window_length); + rDebug("rar_window_start=%d, rar_window_length=%d", ra_window.get_start(), ra_window.get_length()); } // Restart timer at each Msg3 HARQ retransmission (5.1.5) diff --git a/srsue/src/stack/mac/proc_sr.cc b/srsue/src/stack/mac/proc_sr.cc index fe6e1b5ce..e08968b6e 100644 --- a/srsue/src/stack/mac/proc_sr.cc +++ b/srsue/src/stack/mac/proc_sr.cc @@ -39,6 +39,7 @@ void sr_proc::init(ra_proc* ra_, phy_interface_mac_lte* phy_h_, rrc_interface_ma void sr_proc::reset() { + std::lock_guard lock(mutex); is_pending_sr = false; } @@ -75,37 +76,56 @@ void sr_proc::set_config(srsran::sr_cfg_t& cfg) void sr_proc::step(uint32_t tti) { - if (initiated) { - if (is_pending_sr) { - if (sr_cfg.enabled) { - if (sr_counter < sr_cfg.dsr_transmax) { - if (sr_counter == 0 || need_tx(tti)) { - sr_counter++; - Info("SR: Signalling PHY sr_counter=%d", sr_counter); - phy_h->sr_send(); - } - } else { - if (need_tx(tti)) { - Info("SR: Releasing PUCCH/SRS resources, sr_counter=%d, dsr_transmax=%d", - sr_counter, - sr_cfg.dsr_transmax); - srsran::console("Scheduling request failed: releasing RRC connection...\n"); - rrc->release_pucch_srs(); - ra->start_mac_order(); - reset(); + bool do_mac_order = false; + bool do_release_pucch = false; + bool do_sr = false; + + { + std::lock_guard lock(mutex); + if (initiated) { + if (is_pending_sr) { + if (sr_cfg.enabled) { + if (sr_counter < sr_cfg.dsr_transmax) { + if (sr_counter == 0 || need_tx(tti)) { + sr_counter++; + Info("SR: Signalling PHY sr_counter=%d", sr_counter); + do_sr = true; + } + } else { + if (need_tx(tti)) { + Info("SR: Releasing PUCCH/SRS resources, sr_counter=%d, dsr_transmax=%d", + sr_counter, + sr_cfg.dsr_transmax); + srsran::console("Scheduling request failed: releasing RRC connection...\n"); + do_mac_order = true; + do_release_pucch = true; + is_pending_sr = false; + } } + } else if (ra->is_idle()) { + Info("SR: PUCCH not configured. Starting RA procedure"); + do_mac_order = true; + is_pending_sr = false; } - } else if (ra->is_idle()) { - Info("SR: PUCCH not configured. Starting RA procedure"); - ra->start_mac_order(); - reset(); } } } + + // These calls go out of this component, so call them with mutex unlocked + if (do_sr) { + phy_h->sr_send(); + } + if (do_release_pucch) { + rrc->release_pucch_srs(); + } + if (do_mac_order) { + ra->start_mac_order(); + } } void sr_proc::start() { + std::lock_guard lock(mutex); if (initiated) { if (!is_pending_sr) { sr_counter = 0; diff --git a/srsue/src/stack/mac/ul_harq.cc b/srsue/src/stack/mac/ul_harq.cc index ada9f2db8..f7456a9ce 100644 --- a/srsue/src/stack/mac/ul_harq.cc +++ b/srsue/src/stack/mac/ul_harq.cc @@ -26,7 +26,7 @@ ul_harq_entity::ul_harq_entity(const uint8_t cc_idx_) : proc(SRSRAN_MAX_HARQ_PROC), logger(srslog::fetch_basic_logger("MAC")), cc_idx(cc_idx_) {} -bool ul_harq_entity::init(mac_interface_rrc_common::ue_rnti_t* rntis_, ra_proc* ra_procedure_, mux* mux_unit_) +bool ul_harq_entity::init(ue_rnti* rntis_, ra_proc* ra_procedure_, mux* mux_unit_) { mux_unit = mux_unit_; ra_procedure = ra_procedure_; @@ -75,12 +75,12 @@ void ul_harq_entity::new_grant_ul(mac_interface_phy_lte::mac_grant_ul_t grant, Error("Invalid PID: %d", grant.pid); return; } - if (grant.rnti == rntis->crnti || grant.rnti == rntis->temp_rnti || SRSRAN_RNTI_ISRAR(grant.rnti)) { - if (grant.rnti == rntis->crnti && proc[grant.pid].is_sps()) { + if (grant.rnti == rntis->get_crnti() || grant.rnti == rntis->get_temp_rnti() || SRSRAN_RNTI_ISRAR(grant.rnti)) { + if (grant.rnti == rntis->get_crnti() && proc[grant.pid].is_sps()) { grant.tb.ndi = true; } proc[grant.pid].new_grant_ul(grant, action); - } else if (grant.rnti == rntis->sps_rnti) { + } else if (grant.rnti == rntis->get_sps_rnti()) { if (grant.tb.ndi) { grant.tb.ndi = proc[grant.pid].get_ndi(); proc[grant.pid].new_grant_ul(grant, action); @@ -174,7 +174,7 @@ void ul_harq_entity::ul_harq_process::new_grant_ul(mac_interface_phy_lte::mac_gr // Get maximum retransmissions uint32_t max_retx; - if (grant.rnti == harq_entity->rntis->temp_rnti) { + if (grant.rnti == harq_entity->rntis->get_temp_rnti()) { max_retx = harq_entity->harq_cfg.max_harq_msg3_tx; } else { max_retx = harq_entity->harq_cfg.max_harq_tx; @@ -183,11 +183,11 @@ void ul_harq_entity::ul_harq_process::new_grant_ul(mac_interface_phy_lte::mac_gr // Check maximum retransmissions, do not consider last retx ACK if (current_tx_nb >= max_retx && !grant.hi_value) { Info("UL %d: Maximum number of ReTX reached (%d). Discarding TB.", pid, max_retx); - if (grant.rnti == harq_entity->rntis->temp_rnti) { + if (grant.rnti == harq_entity->rntis->get_temp_rnti()) { harq_entity->ra_procedure->harq_max_retx(); } reset(); - } else if (grant.rnti == harq_entity->rntis->temp_rnti && current_tx_nb && !grant.hi_value) { + } else if (grant.rnti == harq_entity->rntis->get_temp_rnti() && current_tx_nb && !grant.hi_value) { harq_entity->ra_procedure->harq_retx(); } } @@ -206,9 +206,9 @@ void ul_harq_entity::ul_harq_process::new_grant_ul(mac_interface_phy_lte::mac_gr action->tb.enabled = true; // Decide if adaptive retx or new tx. 3 checks in 5.4.2.1 - } else if ((grant.rnti != harq_entity->rntis->temp_rnti && + } else if ((grant.rnti != harq_entity->rntis->get_temp_rnti() && grant.tb.ndi != get_ndi()) || // If not addressed to T-CRNTI and NDI toggled - (grant.rnti == harq_entity->rntis->crnti && + (grant.rnti == harq_entity->rntis->get_crnti() && !has_grant()) || // If addressed to C-RNTI and buffer is empty (grant.is_rar)) // Grant received in a RAR { @@ -245,7 +245,7 @@ void ul_harq_entity::ul_harq_process::new_grant_ul(mac_interface_phy_lte::mac_gr } } - if (grant.rnti == harq_entity->rntis->crnti && harq_entity->ra_procedure->is_contention_resolution()) { + if (grant.rnti == harq_entity->rntis->get_crnti() && harq_entity->ra_procedure->is_contention_resolution()) { harq_entity->ra_procedure->pdcch_to_crnti(true); } } else if (has_grant()) { @@ -256,10 +256,10 @@ void ul_harq_entity::ul_harq_process::new_grant_ul(mac_interface_phy_lte::mac_gr } if (harq_entity->pcap) { uint16_t rnti; - if (grant.rnti == harq_entity->rntis->temp_rnti && harq_entity->rntis->temp_rnti) { - rnti = harq_entity->rntis->temp_rnti; + if (grant.rnti == harq_entity->rntis->get_temp_rnti() && harq_entity->rntis->get_temp_rnti()) { + rnti = harq_entity->rntis->get_temp_rnti(); } else { - rnti = harq_entity->rntis->crnti; + rnti = harq_entity->rntis->get_crnti(); } harq_entity->pcap->write_ul_crnti(pdu_ptr, grant.tb.tbs, rnti, get_nof_retx(), grant.tti_tx, harq_entity->cc_idx); } @@ -355,11 +355,11 @@ void ul_harq_entity::ul_harq_process::generate_new_tx(mac_interface_phy_lte::mac current_tx_nb = 0; current_irv = 0; - action->is_rar = grant.is_rar || (grant.rnti == harq_entity->rntis->temp_rnti); + action->is_rar = grant.is_rar || (grant.rnti == harq_entity->rntis->get_temp_rnti()); Info("UL %d: New TX%s, RV=%d, TBS=%d", pid, - grant.rnti == harq_entity->rntis->temp_rnti ? " for Msg3" : "", + grant.rnti == harq_entity->rntis->get_temp_rnti() ? " for Msg3" : "", get_rv(), cur_grant.tb.tbs); generate_tx(action); diff --git a/srsue/src/stack/rrc/rrc_procedures.cc b/srsue/src/stack/rrc/rrc_procedures.cc index d391c2d4f..1dc96cf76 100644 --- a/srsue/src/stack/rrc/rrc_procedures.cc +++ b/srsue/src/stack/rrc/rrc_procedures.cc @@ -1361,13 +1361,11 @@ rrc::connection_reest_proc::connection_reest_proc(srsue::rrc* rrc_) : rrc_ptr(rr proc_outcome_t rrc::connection_reest_proc::init(asn1::rrc::reest_cause_e cause) { // Save Current RNTI before MAC Reset - mac_interface_rrc::ue_rnti_t uernti; - rrc_ptr->mac->get_rntis(&uernti); + uint16_t crnti = rrc_ptr->mac->get_crnti(); size_t nof_scells_active = rrc_ptr->phy_ctrl->current_config_scells().count(); // 5.3.7.1 - Conditions for Reestablishment procedure - if (not rrc_ptr->security_is_activated or rrc_ptr->state != RRC_STATE_CONNECTED or - uernti.crnti == SRSRAN_INVALID_RNTI) { + if (not rrc_ptr->security_is_activated or rrc_ptr->state != RRC_STATE_CONNECTED or crnti == SRSRAN_INVALID_RNTI) { Warning("Conditions are NOT met to start procedure."); return proc_outcome_t::error; } @@ -1379,7 +1377,7 @@ proc_outcome_t rrc::connection_reest_proc::init(asn1::rrc::reest_cause_e cause) reest_source_pci = rrc_ptr->ho_handler.get()->ho_src_cell.pci; reest_source_freq = rrc_ptr->ho_handler.get()->ho_src_cell.earfcn; } else { - reest_rnti = uernti.crnti; + reest_rnti = crnti; reest_source_pci = rrc_ptr->meas_cells.serving_cell().get_pci(); // needed for reestablishment with another cell reest_source_freq = rrc_ptr->meas_cells.serving_cell().get_earfcn(); } @@ -1651,9 +1649,7 @@ srsran::proc_outcome_t rrc::ho_proc::init(const asn1::rrc::rrc_conn_recfg_s& rrc // Save serving cell and current configuration ho_src_cell = rrc_ptr->meas_cells.serving_cell().phy_cell; - mac_interface_rrc::ue_rnti_t uernti; - rrc_ptr->mac->get_rntis(&uernti); - ho_src_rnti = uernti.crnti; + ho_src_rnti = rrc_ptr->mac->get_crnti(); // Section 5.3.5.4 rrc_ptr->t310.stop(); diff --git a/srsue/src/stack/rrc/test/rrc_meas_test.cc b/srsue/src/stack/rrc/test/rrc_meas_test.cc index 7c3756d58..1c438ebf0 100644 --- a/srsue/src/stack/rrc/test/rrc_meas_test.cc +++ b/srsue/src/stack/rrc/test/rrc_meas_test.cc @@ -155,9 +155,9 @@ public: void set_config(srsran::sr_cfg_t& sr_cfg) override {} void set_rach_ded_cfg(uint32_t preamble_index, uint32_t prach_mask) override {} - void get_rntis(ue_rnti_t* rntis) override {} - void set_contention_id(uint64_t uecri) override {} - void set_ho_rnti(uint16_t crnti, uint16_t target_pci) override {} + uint16_t get_crnti() override { return 0; } + void set_contention_id(uint64_t uecri) override {} + void set_ho_rnti(uint16_t crnti, uint16_t target_pci) override {} void reconfiguration(const uint32_t& cc_idx, const bool& enable) override {} void reset() override {}