Fix TSAN warnings in UE (#3021)

* Protect PHY SR signal management in a class

* Protect intra_freq_meas vector

* Protect cell and srate shared variables in thread-safe classes

* srsue,srsenb: include TSAN options header

* Protect ue_rnti_t and rnti scheduling windows behind thread-safe classes

* Protect access to state variable in sync_state

* Protect access to metrics configuration

* Protect access to is_pending_sr

* Protect access to UE prach worker

* Protect UE mux

* Avoid unlocking mutex twice

* Fix data races in RF/ZMQ

* Fix data races in intra_measure and PHY

* Fix minor data races in MAC

* Make TSAN default behaviour to not halt on error

* Fix blocking in intra cell measurement

* Address comments

Co-authored-by: Andre Puschmann <andre@softwareradiosystems.com>
master
Ismael Gomez 3 years ago committed by GitHub
parent c0fd64c4e6
commit 4e39982a19
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -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;

@ -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;
}

@ -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);

@ -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);

@ -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);

@ -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"

@ -35,6 +35,8 @@ public:
private:
srslog::log_channel& log_c;
ue_metrics_interface* ue = nullptr;
std::mutex mutex = {};
};
} // namespace srsue

@ -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

@ -184,7 +184,7 @@ private:
std::mutex config_mutex;
std::condition_variable config_cond;
bool is_configured = false;
std::atomic<bool> is_configured = {false};
const static int SF_RECV_THREAD_PRIO = 0;
const static int WORKERS_THREAD_PRIO = 2;

@ -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<std::mutex> lock(mutex);
enabled = false;
last_tx_tti = -1;
}
bool is_triggered()
{
std::lock_guard<std::mutex> lock(mutex);
return enabled;
}
void trigger()
{
std::lock_guard<std::mutex> lock(mutex);
enabled = true;
last_tx_tti = -1;
}
int get_last_tx_tti()
{
std::lock_guard<std::mutex> lock(mutex);
return last_tx_tti;
}
bool set_last_tx_tti(int last_tx_tti_)
{
std::lock_guard<std::mutex> 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<std::mutex> lock(meas_mutex);
avg_rsrp_neigh[cc_idx] = NAN;
}
void set_neighbour_cells(uint32_t cc_idx, const std::vector<phy_meas_t>& meas)
{

@ -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<uint32_t> 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<float> 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<cf_t>& buffer) = 0;
virtual bool measure_rat(measure_context_t context, std::vector<cf_t>& buffer, float rx_gain_offset) = 0;
/**
* @brief Measurement process helper method. Encapsulates the neighbour cell measurement functionality

@ -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<cf_t>& buffer) override;
bool measure_rat(measure_context_t context, std::vector<cf_t>& 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

@ -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<cf_t>& buffer) override;
bool measure_rat(measure_context_t context, std::vector<cf_t>& buffer, float rx_gain_offset) override;
srslog::basic_logger& logger;
uint32_t cc_idx = 0;

@ -206,6 +206,7 @@ private:
search search_p;
sfn_sync sfn_p;
std::vector<std::unique_ptr<scell::intra_measure_lte> > 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<std::mutex> lock(mutex);
srate_mode = SRATE_NONE;
current_srate = 0;
}
float get_srate()
{
std::lock_guard<std::mutex> lock(mutex);
return current_srate;
}
bool is_normal()
{
std::lock_guard<std::mutex> lock(mutex);
return std::isnormal(current_srate) and current_srate > 0.0f;
}
bool set_camp(float new_srate)
{
std::lock_guard<std::mutex> 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<std::mutex> 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<std::mutex> lock(mutex);
cell.id = id;
}
void reset()
{
std::lock_guard<std::mutex> lock(mutex);
cell = {};
}
bool is_valid()
{
std::lock_guard<std::mutex> lock(mutex);
return srsran_cell_isvalid(&cell);
}
void set(srsran_cell_t& x)
{
std::lock_guard<std::mutex> lock(mutex);
cell = x;
}
srsran_cell_t get()
{
std::lock_guard<std::mutex> lock(mutex);
return cell;
}
bool equals(srsran_cell_t& x)
{
std::lock_guard<std::mutex> 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 = {};

@ -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<std::mutex> lock(mutex);
return cur_state == IDLE;
}
bool is_camping()
{
std::lock_guard<std::mutex> lock(mutex);
return cur_state == CAMPING;
}
bool wait_idle(uint32_t timeout_ms)
{
std::unique_lock<std::mutex> lock(mutex);

@ -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;

@ -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<bool> initialized = {false};

@ -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);

@ -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<uint64_t> transmitted_contention_id = {0};
std::atomic<uint16_t> transmitted_crnti = {0};

@ -15,6 +15,7 @@
#include "srsran/interfaces/ue_mac_interfaces.h"
#include "srsran/srslog/srslog.h"
#include <mutex>
#include <stdint.h>
/* 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;
};

@ -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;

@ -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 <map>
#include <mutex>
/**
* @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<std::mutex> 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<std::mutex> lock(mutex);
return crnti;
}
uint16_t get_rar_rnti()
{
std::lock_guard<std::mutex> lock(mutex);
return rar_rnti;
}
uint16_t get_temp_rnti()
{
std::lock_guard<std::mutex> lock(mutex);
return temp_rnti;
}
uint16_t get_sps_rnti()
{
std::lock_guard<std::mutex> lock(mutex);
return sps_rnti;
}
uint64_t get_contention_id()
{
std::lock_guard<std::mutex> lock(mutex);
return contention_id;
}
void set_crnti(uint16_t rnti)
{
std::lock_guard<std::mutex> lock(mutex);
crnti = rnti;
}
void set_rar_rnti(uint16_t rnti)
{
std::lock_guard<std::mutex> lock(mutex);
rar_rnti = rnti;
}
void set_temp_rnti(uint16_t rnti)
{
std::lock_guard<std::mutex> lock(mutex);
temp_rnti = rnti;
}
void set_contention_id(uint64_t id)
{
std::lock_guard<std::mutex> lock(mutex);
contention_id = id;
}
void set_crnti_to_temp()
{
std::lock_guard<std::mutex> lock(mutex);
crnti = temp_rnti;
}
void clear_temp_rnti()
{
std::lock_guard<std::mutex> lock(mutex);
temp_rnti = SRSRAN_INVALID_RNTI;
}
void clear_rar_rnti()
{
std::lock_guard<std::mutex> lock(mutex);
rar_rnti = SRSRAN_INVALID_RNTI;
}
void clear_crnti()
{
std::lock_guard<std::mutex> 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<std::mutex> lock(mutex);
length = -1;
start = -1;
}
void set(int length_, int start_)
{
std::lock_guard<std::mutex> lock(mutex);
length = length_;
start = start_;
}
int get_length()
{
std::lock_guard<std::mutex> lock(mutex);
return length;
}
int get_start()
{
std::lock_guard<std::mutex> lock(mutex);
return start;
}
bool is_set()
{
std::lock_guard<std::mutex> lock(mutex);
return start > 0;
}
bool is_in_window(int tti)
{
std::lock_guard<std::mutex> 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);

@ -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"

@ -47,11 +47,13 @@ metrics_csv::~metrics_csv()
void metrics_csv::set_ue_handle(ue_metrics_interface* ue_)
{
std::lock_guard<std::mutex> lock(mutex);
ue = ue_;
}
void metrics_csv::set_flush_period(const uint32_t flush_period_sec_)
{
std::lock_guard<std::mutex> lock(mutex);
flush_period_sec = flush_period_sec_;
}

@ -17,6 +17,7 @@ using namespace srsue;
void metrics_json::set_ue_handle(ue_metrics_interface* ue_)
{
std::lock_guard<std::mutex> 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<std::mutex> lock(mutex);
if (!ue) {
return;
}

@ -53,11 +53,13 @@ char const* const prefixes[2][9] = {
void metrics_stdout::set_ue_handle(ue_metrics_interface* ue_)
{
std::lock_guard<std::mutex> lock(mutex);
ue = ue_;
}
void metrics_stdout::toggle_print(bool b)
{
std::lock_guard<std::mutex> 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<std::mutex> lock(mutex);
if (ue == nullptr) {
return;
}

@ -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);
}
}
}

@ -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<uint32_t>& 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

@ -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

@ -32,6 +32,7 @@ using namespace srsue;
void prach::init(uint32_t max_prb)
{
std::lock_guard<std::mutex> 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<std::mutex> 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<std::mutex> 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<std::mutex> 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<std::mutex> 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",

@ -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");
}
}

@ -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<cf_t>& buffer)
bool intra_measure_lte::measure_rat(measure_context_t context, std::vector<cf_t>& buffer, float rx_gain_offset)
{
std::set<uint32_t> cells_to_measure = context.active_pci;
@ -84,7 +84,7 @@ bool intra_measure_lte::measure_rat(measure_context_t context, std::vector<cf_t>
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);

@ -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<cf_t>& buffer)
bool intra_measure_nr::measure_rat(const measure_context_t context, std::vector<cf_t>& 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<phy_meas_t> 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;

@ -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<scell::intra_measure_lte>(q));
{
std::lock_guard<std::mutex> 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<scell::intra_measure_lte>(q));
}
}
// Allocate Secondary serving cell synchronization
@ -125,6 +128,7 @@ sync::~sync()
void sync::stop()
{
std::lock_guard<std::mutex> 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<std::mutex> 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<std::mutex> 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<uint32_t>& pci)
{
std::lock_guard<std::mutex> 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<uint32_t>& pci)
void sync::meas_stop()
{
std::lock_guard<std::mutex> lock(intra_freq_cfg_mutex);
for (auto& q : intra_freq_meas) {
q->meas_stop();
}

@ -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<std::mutex> lock(retx_cnt_mutex);
return average_retx;
}
void dl_harq_entity::set_average_retx(uint32_t n_retx)
{
std::unique_lock<std::mutex> 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);
}
}

@ -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<std::mutex> 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)

@ -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<std::mutex> 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<std::mutex> 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<std::mutex> 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<std::mutex> lock(mutex);
return msg3_has_been_transmitted;
}
void mux::msg3_prepare()
{
std::lock_guard<std::mutex> lock(mutex);
msg3_has_been_transmitted = false;
msg3_pending = true;
}
bool mux::msg3_is_pending()
{
std::lock_guard<std::mutex> 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<std::mutex> 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;
}

@ -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)

@ -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<std::mutex> 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<std::mutex> 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<std::mutex> lock(mutex);
if (initiated) {
if (!is_pending_sr) {
sr_counter = 0;

@ -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);

@ -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();

@ -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 {}

Loading…
Cancel
Save