From 080b4a327cbb9aecf2cd1c66c9e0d8e6894e83df Mon Sep 17 00:00:00 2001 From: Xavier Arteaga Date: Thu, 16 May 2019 14:57:13 +0200 Subject: [PATCH] SRSUE: Refactored asynchronous cell and ue_radio. CA Fixed. --- lib/include/srslte/interfaces/ue_interfaces.h | 49 +++++---- lib/include/srslte/radio/radio.h | 1 + lib/src/radio/radio.cc | 33 +++--- lib/src/radio/test/benchmark_radio.cc | 7 -- srsenb/src/phy/txrx.cc | 14 --- srsue/hdr/phy/async_scell_recv.h | 28 ++++- srsue/hdr/phy/cc_worker.h | 1 - srsue/hdr/phy/phy.h | 2 +- srsue/hdr/phy/sync.h | 14 +-- srsue/hdr/radio/ue_radio.h | 75 ++++++++----- srsue/hdr/radio/ue_radio_base.h | 2 - srsue/hdr/stack/mac/dl_harq.h | 3 + srsue/hdr/stack/mac/mac.h | 13 +-- srsue/hdr/stack/mac/ul_harq.h | 3 + srsue/src/phy/async_scell_recv.cc | 51 ++++----- srsue/src/phy/cc_worker.cc | 16 +-- srsue/src/phy/phy.cc | 19 ++-- srsue/src/phy/phy_common.cc | 8 +- srsue/src/phy/sf_worker.cc | 2 +- srsue/src/phy/sync.cc | 51 +++------ srsue/src/radio/ue_radio.cc | 21 ++-- srsue/src/stack/mac/mac.cc | 103 ++++++++++-------- srsue/src/stack/rrc/rrc.cc | 18 ++- 23 files changed, 273 insertions(+), 261 deletions(-) diff --git a/lib/include/srslte/interfaces/ue_interfaces.h b/lib/include/srslte/interfaces/ue_interfaces.h index 00221bdcf..0dd0cb5be 100644 --- a/lib/include/srslte/interfaces/ue_interfaces.h +++ b/lib/include/srslte/interfaces/ue_interfaces.h @@ -656,7 +656,7 @@ public: virtual void start_noncont_ho(uint32_t preamble_index, uint32_t prach_mask) = 0; virtual void start_cont_ho() = 0; - virtual void reconfiguration() = 0; + virtual void reconfiguration(const uint32_t& cc_idx, const bool& enable) = 0; virtual void reset() = 0; virtual void wait_uplink() = 0; }; @@ -669,6 +669,9 @@ typedef struct { float freq_offset; float rx_gain; float tx_gain; + float tx_max_power; + float tx_gain_offset; + float rx_gain_offset; uint32_t nof_radios; uint32_t nof_rf_channels; // Number of RF channels per radio uint32_t nof_rx_ant; // Number of RF channels for MIMO @@ -868,31 +871,37 @@ class radio_interface_phy { public: // trx functions - virtual bool tx(cf_t* buffer[SRSLTE_MAX_PORTS], const uint32_t& nof_samples, const srslte_timestamp_t& tx_time) = 0; + virtual bool tx(const uint32_t& radio_idx, + cf_t* buffer[SRSLTE_MAX_PORTS], + const uint32_t& nof_samples, + const srslte_timestamp_t& tx_time) = 0; virtual void tx_end() = 0; - virtual bool rx_now(cf_t* buffer[SRSLTE_MAX_PORTS], const uint32_t& nof_samples, srslte_timestamp_t* rxd_time) = 0; + virtual bool rx_now(const uint32_t& radio_idx, + cf_t* buffer[SRSLTE_MAX_PORTS], + const uint32_t& nof_samples, + srslte_timestamp_t* rxd_time) = 0; // setter - virtual void set_tx_freq(const uint32_t& radio_idx, const double& freq) = 0; - virtual void set_rx_freq(const uint32_t& radio_idx, const double& freq) = 0; + virtual void set_tx_freq(const uint32_t& radio_idx, const uint32_t& channel_idx, const double& freq) = 0; + virtual void set_rx_freq(const uint32_t& radio_idx, const uint32_t& channel_idx, const double& freq) = 0; - virtual double set_rx_gain_th(const float& gain) = 0; - virtual void set_rx_gain(const uint32_t& radio_idx, const float& gain) = 0; - virtual void set_master_clock_rate(const double& rate) = 0; - virtual void set_tx_srate(const double& srate) = 0; - virtual void set_rx_srate(const double& srate) = 0; - virtual float set_tx_power(const float& power) = 0; + virtual double set_rx_gain_th(const float& gain) = 0; + virtual void set_rx_gain(const uint32_t& radio_idx, const float& gain) = 0; + virtual void set_tx_srate(const uint32_t& radio_idx, const double& srate) = 0; + virtual void set_rx_srate(const uint32_t& radio_idx, const double& srate) = 0; // getter - virtual float get_rx_gain(const uint32_t& radio_idx = 0) = 0; - virtual double get_freq_offset() = 0; - virtual double get_tx_freq(const uint32_t& radio_idx = 0) = 0; - virtual double get_rx_freq(const uint32_t& radio_idx = 0) = 0; - virtual float get_max_tx_power() = 0; - virtual bool is_continuous_tx() = 0; - virtual bool is_init() = 0; - virtual void reset() = 0; - virtual srslte_rf_info_t* get_info(const uint32_t& radio_idx = 0) = 0; + virtual float get_rx_gain(const uint32_t& radio_idx) = 0; + virtual double get_freq_offset() = 0; + virtual double get_tx_freq(const uint32_t& radio_idx) = 0; + virtual double get_rx_freq(const uint32_t& radio_idx) = 0; + virtual float get_max_tx_power() = 0; + virtual float get_tx_gain_offset() = 0; + virtual float get_rx_gain_offset() = 0; + virtual bool is_continuous_tx() = 0; + virtual bool is_init() = 0; + virtual void reset() = 0; + virtual srslte_rf_info_t* get_info(const uint32_t& radio_idx) = 0; }; class phy_interface_radio diff --git a/lib/include/srslte/radio/radio.h b/lib/include/srslte/radio/radio.h index 512a3ca87..e64d9c414 100644 --- a/lib/include/srslte/radio/radio.h +++ b/lib/include/srslte/radio/radio.h @@ -49,6 +49,7 @@ class radio { burst_preamble_samples = 0; burst_preamble_time_rounded = 0; + master_clock_rate = 0; cur_tx_srate = 0; tx_adv_sec = 0; tx_adv_nsamples = 0; diff --git a/lib/src/radio/radio.cc b/lib/src/radio/radio.cc index 587b2b46f..11e5690f8 100644 --- a/lib/src/radio/radio.cc +++ b/lib/src/radio/radio.cc @@ -179,20 +179,6 @@ void radio::get_time(srslte_timestamp_t* now) srslte_rf_get_time(&rf_device, &now->full_secs, &now->frac_secs); } -// TODO: Use Calibrated values for this -float radio::set_tx_power(float power) -{ - if (power > 10) { - power = 10; - } - if (power < -50) { - power = -50; - } - float gain = power + 74; - srslte_rf_set_tx_gain(&rf_device, gain); - return gain; -} - float radio::get_max_tx_power() { return 40; @@ -304,13 +290,21 @@ double radio::set_rx_gain_th(float gain) void radio::set_master_clock_rate(double rate) { - srslte_rf_stop_rx_stream(&rf_device); - srslte_rf_set_master_clock_rate(&rf_device, rate); - srslte_rf_start_rx_stream(&rf_device, false); + if (rate != master_clock_rate) { + srslte_rf_stop_rx_stream(&rf_device); + srslte_rf_set_master_clock_rate(&rf_device, rate); + srslte_rf_start_rx_stream(&rf_device, false); + master_clock_rate = rate; + } } void radio::set_rx_srate(double srate) { + if (srate < 10e6) { + set_master_clock_rate(4 * srate); + } else { + set_master_clock_rate(srate); + } srslte_rf_set_rx_srate(&rf_device, srate); } @@ -351,6 +345,11 @@ float radio::get_rx_gain() void radio::set_tx_srate(double srate) { + if (srate < 10e6) { + set_master_clock_rate(4 * srate); + } else { + set_master_clock_rate(srate); + } cur_tx_srate = srslte_rf_set_tx_srate(&rf_device, srate); burst_preamble_samples = (uint32_t) (cur_tx_srate * burst_preamble_sec); if (burst_preamble_samples > burst_preamble_max_samples) { diff --git a/lib/src/radio/test/benchmark_radio.cc b/lib/src/radio/test/benchmark_radio.cc index 083a0477d..a9f9c75e7 100644 --- a/lib/src/radio/test/benchmark_radio.cc +++ b/lib/src/radio/test/benchmark_radio.cc @@ -315,13 +315,6 @@ int main(int argc, char** argv) radio_h[r]->set_rx_gain(rf_gain); } - // Set radio - if (srate < 10e6) { - radio_h[r]->set_master_clock_rate(4 * srate); - } else { - radio_h[r]->set_master_clock_rate(srate); - } - // Set Rx/Tx sampling rate radio_h[r]->set_rx_srate(srate); if (tx_enable) { diff --git a/srsenb/src/phy/txrx.cc b/srsenb/src/phy/txrx.cc index bbf8e5e6f..afbe67392 100644 --- a/srsenb/src/phy/txrx.cc +++ b/srsenb/src/phy/txrx.cc @@ -82,20 +82,6 @@ void txrx::run_thread() uint32_t sf_len = SRSLTE_SF_LEN_PRB(worker_com->cell.nof_prb); float samp_rate = srslte_sampling_freq_hz(worker_com->cell.nof_prb); -#if 0 - if (30720%((int) samp_rate/1000) == 0) { - radio_h->set_master_clock_rate(30.72e6); - } else { - radio_h->set_master_clock_rate(23.04e6); - } -#else - if (samp_rate < 10e6) { - radio_h->set_master_clock_rate(4 * samp_rate); - } else { - radio_h->set_master_clock_rate(samp_rate); - } -#endif - log_h->console("Setting Sampling frequency %.2f MHz\n", (float) samp_rate/1000000); // Configure radio diff --git a/srsue/hdr/phy/async_scell_recv.h b/srsue/hdr/phy/async_scell_recv.h index 6b6986dd9..d2703621a 100644 --- a/srsue/hdr/phy/async_scell_recv.h +++ b/srsue/hdr/phy/async_scell_recv.h @@ -34,9 +34,17 @@ #include "srslte/radio/radio.h" #include "srslte/srslte.h" +#include +#include +#include +#include +#include +#include +#include + namespace srsue { -class async_scell_recv : public thread +class async_scell_recv : private thread { public: async_scell_recv(); @@ -75,14 +83,16 @@ private: { tti = 0; bzero(×tamp, sizeof(timestamp)); - bzero(buffer, sizeof(buffer)); + for (cf_t*& b : buffer) { + b = nullptr; + } } ~phch_scell_recv_buffer() { - for (int i = 0; i < SRSLTE_MAX_PORTS; i++) { - if (buffer[i]) { - free(buffer[i]); + for (cf_t*& b : buffer) { + if (b) { + free(b); } } } @@ -115,7 +125,6 @@ private: void reset(); void radio_error(); void set_ue_sync_opts(srslte_ue_sync_t* q, float cfo); - void run_thread(); void state_decode_mib(); void state_write_buffer(); @@ -130,6 +139,7 @@ private: bool running; uint32_t tti; + uint32_t radio_idx; // Pointers to other classes srslte::log* log_h; @@ -168,8 +178,14 @@ private: float dl_freq; float ul_freq; + +protected: + void run_thread() override; }; +typedef std::unique_ptr async_scell_recv_ptr; +typedef std::vector async_scell_recv_vector; + } // namespace srsue #endif // SRSUE_ASYNCH_SCELL_RECV_H diff --git a/srsue/hdr/phy/cc_worker.h b/srsue/hdr/phy/cc_worker.h index d1df57950..9ca206611 100644 --- a/srsue/hdr/phy/cc_worker.h +++ b/srsue/hdr/phy/cc_worker.h @@ -95,7 +95,6 @@ private: void set_uci_periodic_cqi(srslte_uci_data_t* uci_data); void set_uci_aperiodic_cqi(srslte_uci_data_t* uci_data); void set_uci_ack(srslte_uci_data_t* uci_data, bool is_grant_available, uint32_t dai_ul, bool is_pusch_available); - float set_power(float tx_power); uint32_t get_wideband_cqi(); srslte_cqi_report_mode_t aperiodic_mode(asn1::rrc::cqi_report_mode_aperiodic_e mode); void parse_antenna_info(asn1::rrc::phys_cfg_ded_s* dedicated); diff --git a/srsue/hdr/phy/phy.h b/srsue/hdr/phy/phy.h index 5937fc35d..f81a78e88 100644 --- a/srsue/hdr/phy/phy.h +++ b/srsue/hdr/phy/phy.h @@ -157,7 +157,7 @@ private: std::vector workers; phy_common common; sync sfsync; - async_scell_recv scell_sync[SRSLTE_MAX_RADIOS - 1]; + async_scell_recv_vector scell_sync; uint32_t scell_earfcn[SRSLTE_MAX_CARRIERS - 1]; prach prach_buffer; diff --git a/srsue/hdr/phy/sync.h b/srsue/hdr/phy/sync.h index a45344d65..ffc9f4fed 100644 --- a/srsue/hdr/phy/sync.h +++ b/srsue/hdr/phy/sync.h @@ -53,7 +53,7 @@ public: phy_common* _worker_com, srslte::log* _log_h, srslte::log* _log_phy_lib_h, - async_scell_recv* scell_sync_, + async_scell_recv_vector* scell_sync_, uint32_t prio, int sync_cpu_affinity = -1); void stop(); @@ -273,13 +273,13 @@ private: // Pointers to other classes stack_interface_phy_lte* stack; - srslte::log *log_h; - srslte::log* log_phy_lib_h; - srslte::thread_pool* workers_pool; + srslte::log* log_h; + srslte::log* log_phy_lib_h; + srslte::thread_pool* workers_pool; radio_interface_phy* radio_h; - phy_common* worker_com; - prach *prach_buffer; - async_scell_recv* scell_sync; + phy_common* worker_com; + prach* prach_buffer; + async_scell_recv_vector* scell_sync; // Object for synchronization of the primary cell srslte_ue_sync_t ue_sync; diff --git a/srsue/hdr/radio/ue_radio.h b/srsue/hdr/radio/ue_radio.h index 01bb05a26..3ad0b7969 100644 --- a/srsue/hdr/radio/ue_radio.h +++ b/srsue/hdr/radio/ue_radio.h @@ -42,51 +42,66 @@ class ue_radio : public ue_radio_base, public radio_interface_phy { public: ue_radio(); - ~ue_radio(); + ~ue_radio() override; - std::string get_type(); + std::string get_type() override; - int init(const rf_args_t& args_, srslte::logger* logger_); + int init(const rf_args_t& args_, srslte::logger* logger_) override; int init(const rf_args_t& args_, srslte::logger* logger_, phy_interface_radio* phy_); - void stop(); + void stop() override; static void rf_msg(srslte_rf_error_t error); void handle_rf_msg(srslte_rf_error_t error); - bool get_metrics(rf_metrics_t* metrics); + bool get_metrics(rf_metrics_t* metrics) override; // radio_interface_phy - bool is_init() { return radios.at(0)->is_init(); } - void reset() { return radios.at(0)->reset(); } - bool is_continuous_tx() { return radios.at(0)->is_continuous_tx(); } - bool tx(cf_t* buffer[SRSLTE_MAX_PORTS], const uint32_t& nof_samples, const srslte_timestamp_t& tx_time) + bool is_init() override { return radios.at(0)->is_init(); } + void reset() override { return radios.at(0)->reset(); } + bool is_continuous_tx() override { return radios.at(0)->is_continuous_tx(); } + bool tx(const uint32_t& radio_idx, + cf_t* buffer[SRSLTE_MAX_PORTS], + const uint32_t& nof_samples, + const srslte_timestamp_t& tx_time) override { - for (auto& radio : radios) { - radio->tx(buffer, nof_samples, tx_time); - } - return true; + return radios.at(radio_idx)->tx(buffer, nof_samples, tx_time); } - void tx_end() { return radios.at(0)->tx_end(); } + void tx_end() override { return radios.at(0)->tx_end(); } - bool rx_now(cf_t* buffer[SRSLTE_MAX_PORTS], const uint32_t& nof_samples, srslte_timestamp_t* rxd_time) + bool rx_now(const uint32_t& radio_idx, + cf_t* buffer[SRSLTE_MAX_PORTS], + const uint32_t& nof_samples, + srslte_timestamp_t* rxd_time) override { - return radios.at(0)->rx_now(buffer, nof_samples, rxd_time); + return radios.at(radio_idx)->rx_now(buffer, nof_samples, rxd_time); } - void set_rx_gain(const uint32_t& radio_idx, const float& gain) { radios.at(radio_idx)->set_rx_gain(gain); } - double set_rx_gain_th(const float& gain) { return radios.at(0)->set_rx_gain_th(gain); } - float get_rx_gain(const uint32_t& radio_idx) { return radios.at(radio_idx)->get_rx_gain(); } - void set_tx_freq(const uint32_t& radio_idx, const double& freq) { radios.at(radio_idx)->set_tx_freq(0, freq); } - void set_rx_freq(const uint32_t& radio_idx, const double& freq) { radios.at(radio_idx)->set_rx_freq(0, freq); } - double get_freq_offset() { return radios.at(0)->get_freq_offset(); } - double get_tx_freq(const uint32_t& radio_idx) { return radios.at(radio_idx)->get_tx_freq(); } - double get_rx_freq(const uint32_t& radio_idx) { return radios.at(radio_idx)->get_rx_freq(); } - float get_max_tx_power() { return radios.at(0)->get_max_tx_power(); } - void set_master_clock_rate(const double& rate) { radios.at(0)->set_master_clock_rate(rate); } - void set_tx_srate(const double& srate) { radios.at(0)->set_tx_srate(srate); } - void set_rx_srate(const double& srate) { radios.at(0)->set_rx_srate(srate); } - float set_tx_power(const float& power) { return radios.at(0)->set_tx_power(power); } - srslte_rf_info_t* get_info(const uint32_t& radio_idx) { return radios.at(radio_idx)->get_info(); } + void set_rx_gain(const uint32_t& radio_idx, const float& gain) override { radios.at(radio_idx)->set_rx_gain(gain); } + double set_rx_gain_th(const float& gain) override { return radios.at(0)->set_rx_gain_th(gain); } + float get_rx_gain(const uint32_t& radio_idx) override { return radios.at(radio_idx)->get_rx_gain(); } + void set_tx_freq(const uint32_t& radio_idx, const uint32_t& channel_idx, const double& freq) override + { + radios.at(radio_idx)->set_tx_freq(channel_idx, freq); + } + void set_rx_freq(const uint32_t& radio_idx, const uint32_t& channel_idx, const double& freq) override + { + radios.at(radio_idx)->set_rx_freq(channel_idx, freq); + } + double get_freq_offset() override { return radios.at(0)->get_freq_offset(); } + double get_tx_freq(const uint32_t& radio_idx) override { return radios.at(radio_idx)->get_tx_freq(); } + double get_rx_freq(const uint32_t& radio_idx) override { return radios.at(radio_idx)->get_rx_freq(); } + float get_max_tx_power() override { return args.tx_max_power; } + float get_tx_gain_offset() override { return args.tx_gain_offset; } + float get_rx_gain_offset() override { return args.rx_gain_offset; } + void set_tx_srate(const uint32_t& radio_idx, const double& srate) override + { + radios.at(radio_idx)->set_tx_srate(srate); + } + void set_rx_srate(const uint32_t& radio_idx, const double& srate) override + { + radios.at(radio_idx)->set_rx_srate(srate); + } + srslte_rf_info_t* get_info(const uint32_t& radio_idx) override { return radios.at(radio_idx)->get_info(); } private: srsue::rf_args_t args; diff --git a/srsue/hdr/radio/ue_radio_base.h b/srsue/hdr/radio/ue_radio_base.h index 04885af31..bd6bddc10 100644 --- a/srsue/hdr/radio/ue_radio_base.h +++ b/srsue/hdr/radio/ue_radio_base.h @@ -41,8 +41,6 @@ public: ue_radio_base(){}; virtual ~ue_radio_base(){}; - static std::shared_ptr get_instance(const std::string& type); - virtual std::string get_type() = 0; virtual int init(const srsue::rf_args_t& args_, srslte::logger* logger_) = 0; diff --git a/srsue/hdr/stack/mac/dl_harq.h b/srsue/hdr/stack/mac/dl_harq.h index d1b882c9e..6711f08cb 100644 --- a/srsue/hdr/stack/mac/dl_harq.h +++ b/srsue/hdr/stack/mac/dl_harq.h @@ -131,6 +131,9 @@ private: uint64_t nof_pkts; }; +typedef std::unique_ptr dl_harq_entity_ptr; +typedef std::vector dl_harq_entity_vector; + } // namespace srsue #endif // SRSUE_DL_HARQ_H diff --git a/srsue/hdr/stack/mac/mac.h b/srsue/hdr/stack/mac/mac.h index cc7242f01..925120416 100644 --- a/srsue/hdr/stack/mac/mac.h +++ b/srsue/hdr/stack/mac/mac.h @@ -49,11 +49,7 @@ class mac : public mac_interface_phy_lte, { public: mac(); - bool init(phy_interface_mac_lte* phy, - rlc_interface_mac* rlc, - rrc_interface_mac* rrc, - srslte::log* log_h, - uint32_t nof_carriers = 1); + bool init(phy_interface_mac_lte* phy, rlc_interface_mac* rlc, rrc_interface_mac* rrc, srslte::log* log_h); void stop(); void get_metrics(mac_metrics_t m[SRSLTE_MAX_CARRIERS]); @@ -81,7 +77,7 @@ public: void pcch_start_rx(); void setup_lcid(uint32_t lcid, uint32_t lcg, uint32_t priority, int PBR_x_tti, uint32_t BSD); void mch_start_rx(uint32_t lcid); - void reconfiguration(); + void reconfiguration(const uint32_t& cc_idx, const bool& enable); void reset(); void wait_uplink(); @@ -140,8 +136,9 @@ private: demux demux_unit; /* DL/UL HARQ */ - std::vector dl_harq; - std::vector ul_harq; + dl_harq_entity_vector dl_harq; + ul_harq_entity_vector ul_harq; + ul_harq_cfg_t ul_harq_cfg; /* MAC Uplink-related Procedures */ ra_proc ra_procedure; diff --git a/srsue/hdr/stack/mac/ul_harq.h b/srsue/hdr/stack/mac/ul_harq.h index 41bb14c0d..a81d7f66f 100644 --- a/srsue/hdr/stack/mac/ul_harq.h +++ b/srsue/hdr/stack/mac/ul_harq.h @@ -117,6 +117,9 @@ private: ra_proc* ra_procedure; }; +typedef std::unique_ptr ul_harq_entity_ptr; +typedef std::vector ul_harq_entity_vector; + } // namespace srsue #endif // SRSUE_UL_HARQ_H diff --git a/srsue/src/phy/async_scell_recv.cc b/srsue/src/phy/async_scell_recv.cc index 2758c734e..3dc17081f 100644 --- a/srsue/src/phy/async_scell_recv.cc +++ b/srsue/src/phy/async_scell_recv.cc @@ -45,7 +45,7 @@ namespace srsue { -async_scell_recv::async_scell_recv() +async_scell_recv::async_scell_recv() : thread() { initiated = false; buffer_write_idx = 0; @@ -55,6 +55,7 @@ async_scell_recv::async_scell_recv() bzero(&cell, sizeof(srslte_cell_t)); bzero(sf_buffer, sizeof(sf_buffer)); running = false; + radio_idx = 1; } async_scell_recv::~async_scell_recv() @@ -63,9 +64,9 @@ async_scell_recv::~async_scell_recv() srslte_ue_sync_free(&ue_sync); } - for (int i = 0; i < SRSLTE_MAX_PORTS; i++) { - if (sf_buffer[i]) { - free(sf_buffer[i]); + for (auto& b : sf_buffer) { + if (b) { + free(b); } } } @@ -113,7 +114,7 @@ void async_scell_recv::init(radio_interface_phy* _radio_handler, phy_common* _wo return; } - if (pthread_cond_init(&cvar_buffer, NULL)) { + if (pthread_cond_init(&cvar_buffer, nullptr)) { fprintf(stderr, "Initiating condition var\n"); return; } @@ -164,9 +165,9 @@ void async_scell_recv::set_agc_enable(bool enable) do_agc = enable; if (do_agc) { if (radio_h) { - srslte_rf_info_t* rf_info = radio_h->get_info(); + srslte_rf_info_t* rf_info = radio_h->get_info(radio_idx); srslte_ue_sync_start_agc( - &ue_sync, callback_set_rx_gain, rf_info->min_rx_gain, rf_info->max_rx_gain, radio_h->get_rx_gain()); + &ue_sync, callback_set_rx_gain, rf_info->min_rx_gain, rf_info->max_rx_gain, radio_h->get_rx_gain(radio_idx)); } else { fprintf(stderr, "Error setting Secondary cell AGC: PHY not initiated\n"); } @@ -185,7 +186,7 @@ int async_scell_recv::radio_recv_fnc(cf_t* data[SRSLTE_MAX_PORTS], uint32_t nsam int ret = 0; if (running) { - if (radio_h->rx_now(data, nsamples, rx_time)) { + if (radio_h->rx_now(radio_idx, data, nsamples, rx_time)) { log_h->debug("SYNC: received %d samples from radio\n", nsamples); ret = nsamples; } else { @@ -264,18 +265,17 @@ bool async_scell_recv::set_scell_cell(uint32_t carrier_idx, srslte_cell_t* _cell // Get transceiver mapping carrier_map_t* m = &worker_com->args->carrier_map[carrier_idx]; uint32_t channel_idx = m->channel_idx; + radio_idx = m->radio_idx; // Set radio frequency if frequency changed - if (current_earfcn[channel_idx] != dl_earfcn && ret) { + if (current_earfcn[channel_idx] != dl_earfcn) { dl_freq = srslte_band_fd(dl_earfcn) * 1e6f; ul_freq = srslte_band_fu(srslte_band_ul_earfcn(dl_earfcn)) * 1e6f; - radio_h->set_rx_freq(channel_idx, dl_freq); - radio_h->set_tx_freq(channel_idx, ul_freq); - Info("Setting DL: %.1f MHz; UL %.1fMHz; Radio/Chan: %d/%d\n", - dl_freq / 1e6, - ul_freq / 1e6, - m->radio_idx, - m->channel_idx); + for (uint32_t p = 0; p < worker_com->args->nof_rx_ant; p++) { + radio_h->set_rx_freq(m->radio_idx, m->channel_idx + p, dl_freq); + radio_h->set_tx_freq(m->radio_idx, m->channel_idx + p, ul_freq); + } + Info("Setting DL: %.1f MHz; UL %.1fMHz; Radio/Chan: %d/%d\n", dl_freq / 1e6, ul_freq / 1e6, radio_idx, channel_idx); ul_dl_factor = ul_freq / dl_freq; current_earfcn[channel_idx] = dl_earfcn; reset_ue_sync = true; @@ -284,15 +284,10 @@ bool async_scell_recv::set_scell_cell(uint32_t carrier_idx, srslte_cell_t* _cell // Detect change in cell configuration if (memcmp(&cell, _cell, sizeof(srslte_cell_t)) != 0) { // Set sampling rate, if number of PRB changed - if (cell.nof_prb != _cell->nof_prb && ret) { + if (cell.nof_prb != _cell->nof_prb) { double srate = srslte_sampling_freq_hz(_cell->nof_prb); - if (srate < 10e6) { - radio_h->set_master_clock_rate(4 * srate); - } else { - radio_h->set_master_clock_rate(srate); - } - radio_h->set_rx_srate(srate); - radio_h->set_tx_srate(srate); + radio_h->set_rx_srate(radio_idx, srate); + radio_h->set_tx_srate(radio_idx, srate); Info("Setting SRate to %.2f MHz\n", srate / 1e6); } @@ -344,7 +339,7 @@ void async_scell_recv::state_decode_mib() if (sfidx == 0) { // Run only for sub-frame index 0 - int n = srslte_ue_mib_decode(&ue_mib, bch_payload, NULL, &sfn_offset); + int n = srslte_ue_mib_decode(&ue_mib, bch_payload, nullptr, &sfn_offset); if (n < SRSLTE_SUCCESS) { // Error decoding MIB, log error @@ -502,10 +497,10 @@ bool async_scell_recv::tti_align(uint32_t tti) bool timedout = false; while (!ret && !timedout && buffer_write_idx == buffer_read_idx && running) { - struct timespec timeToWait; - struct timeval now; + struct timespec timeToWait = {}; + struct timeval now = {}; - gettimeofday(&now, NULL); + gettimeofday(&now, nullptr); timeToWait.tv_sec = now.tv_sec; timeToWait.tv_nsec = (now.tv_usec + 1000UL) * 1000UL; diff --git a/srsue/src/phy/cc_worker.cc b/srsue/src/phy/cc_worker.cc index 6b184635d..d4a495978 100644 --- a/srsue/src/phy/cc_worker.cc +++ b/srsue/src/phy/cc_worker.cc @@ -115,6 +115,7 @@ cc_worker::cc_worker(uint32_t cc_idx, uint32_t max_prb, srsue::phy_common* phy, ue_dl.pdsch.llr_is_8bit = true; ue_dl.pdsch.dl_sch.llr_is_8bit = true; } + pregen_enabled = false; } cc_worker::~cc_worker() @@ -942,21 +943,6 @@ void cc_worker::set_uci_ack(srslte_uci_data_t* uci_data, srslte_ue_dl_gen_ack(&ue_dl, &sf_cfg_dl, &ack_info, uci_data); } -float cc_worker::set_power(float tx_power) -{ - float gain = 0; - /* Check if UL power control is enabled */ - if (phy->args->ul_pwr_ctrl_en) { - /* Adjust maximum power if it changes significantly */ - if (tx_power < phy->cur_radio_power - 5 || tx_power > phy->cur_radio_power + 5) { - phy->cur_radio_power = tx_power; - float radio_tx_power = phy->cur_radio_power; - gain = phy->get_radio()->set_tx_power(radio_tx_power); - } - } - return gain; -} - /************ * * Configuration Functions diff --git a/srsue/src/phy/phy.cc b/srsue/src/phy/phy.cc index ee64c97d2..4279b16f2 100644 --- a/srsue/src/phy/phy.cc +++ b/srsue/src/phy/phy.cc @@ -42,13 +42,12 @@ using namespace asn1::rrc; namespace srsue { -phy::phy() : workers_pool(MAX_WORKERS), workers(0), common(MAX_WORKERS) +phy::phy() : workers_pool(MAX_WORKERS), workers(0), common(MAX_WORKERS), scell_sync() { tdd_config = {}; prach_cfg = {}; args = {}; ZERO_OBJECT(scell_earfcn); - ZERO_OBJECT(scell_sync); n_ta = 0; initiated = false; } @@ -194,7 +193,9 @@ void phy::run_thread() // Load Asynchronous SCell objects for (int i = 0; i < (int)args.nof_radios - 1; i++) { - scell_sync[i].init(&radio[i + 1], &common, log_h); + auto t = async_scell_recv_ptr(new async_scell_recv()); + t->init(radio, &common, log_h); + scell_sync.push_back(std::move(t)); } // Warning this must be initialized after all workers have been added to the pool @@ -205,7 +206,7 @@ void phy::run_thread() &common, log_h, log_phy_lib_h, - scell_sync, + &scell_sync, SF_RECV_THREAD_PRIO, args.sync_cpu_affinity); @@ -229,7 +230,7 @@ void phy::stop() if (initiated) { sfsync.stop(); for (uint32_t i = 0; i < args.nof_radios - 1; i++) { - scell_sync[i].stop(); + scell_sync.at(i)->stop(); } workers_pool.stop(); @@ -489,14 +490,16 @@ void phy::set_config_scell(asn1::rrc::scell_to_add_mod_r10_s* scell_config) // If SCell does not share synchronism with PCell ... if (m->radio_idx > 0) { - scell_sync[m->radio_idx - 1].set_scell_cell(cc_idx, &cell, earfcn); + scell_sync.at(m->radio_idx - 1)->set_scell_cell(cc_idx, &cell, earfcn); } else { // Change frequency only if the earfcn was modified if (scell_earfcn[cc_idx - 1] != earfcn) { float dl_freq = srslte_band_fd(earfcn) * 1e6f; float ul_freq = srslte_band_fu(srslte_band_ul_earfcn(earfcn)) * 1e6f; - radio->set_rx_freq(m->channel_idx, dl_freq); - radio->set_tx_freq(m->channel_idx, ul_freq); + for (uint32_t p = 0; p < common.args->nof_rx_ant; p++) { + radio->set_rx_freq(m->radio_idx, m->channel_idx + p, dl_freq); + radio->set_tx_freq(m->radio_idx, m->channel_idx + p, ul_freq); + } } } diff --git a/srsue/src/phy/phy_common.cc b/srsue/src/phy/phy_common.cc index d3ea1c19f..262b39f8f 100644 --- a/srsue/src/phy/phy_common.cc +++ b/srsue/src/phy/phy_common.cc @@ -565,16 +565,16 @@ void phy_common::worker_end(uint32_t tti, // For each radio, transmit for (uint32_t i = 0; i < args->nof_radios; i++) { if (tx_enable && !srslte_timestamp_iszero(&tx_time[i])) { - radio_h[i].tx(buffer[i], nof_samples[i], tx_time[i]); + radio_h->tx(i, buffer[i], nof_samples[i], tx_time[i]); is_first_of_burst[i] = false; } else { - if (radio_h[i].is_continuous_tx()) { + if (radio_h->is_continuous_tx()) { if (!is_first_of_burst[i]) { - radio_h[i].tx(zeros_multi, nof_samples[i], tx_time[i]); + radio_h->tx(i, zeros_multi, nof_samples[i], tx_time[i]); } } else { if (!is_first_of_burst[i]) { - radio_h[i].tx_end(); + radio_h->tx_end(); is_first_of_burst[i] = true; } } diff --git a/srsue/src/phy/sf_worker.cc b/srsue/src/phy/sf_worker.cc index 8faa85bc7..2c481cbec 100644 --- a/srsue/src/phy/sf_worker.cc +++ b/srsue/src/phy/sf_worker.cc @@ -331,7 +331,7 @@ void sf_worker::update_measurements() } if (!rssi_read_cnt) { - phy->rx_gain_offset = phy->get_radio()->get_rx_gain() + phy->args->rx_gain_offset; + phy->rx_gain_offset = phy->get_radio()->get_rx_gain(0) + phy->args->rx_gain_offset; } rssi_read_cnt++; if (rssi_read_cnt == 1000) { diff --git a/srsue/src/phy/sync.cc b/srsue/src/phy/sync.cc index e86ca15a7..d81f59b7e 100644 --- a/srsue/src/phy/sync.cc +++ b/srsue/src/phy/sync.cc @@ -66,7 +66,7 @@ void sync::init(radio_interface_phy* _radio, phy_common* _worker_com, srslte::log* _log_h, srslte::log* _log_phy_lib_h, - async_scell_recv* scell_sync_, + async_scell_recv_vector* scell_sync_, uint32_t prio, int sync_cpu_affinity) { @@ -476,8 +476,8 @@ void sync::run_thread() srslte_timestamp_init(&tx_time, 0, 0); // Request TTI aligment - if (scell_sync[i].tti_align(tti)) { - scell_sync[i].read_sf(buffer[i + 1], &tx_time); + if (scell_sync->at(i)->tti_align(tti)) { + scell_sync->at(i)->read_sf(buffer[i + 1], &tx_time); srslte_timestamp_add(&tx_time, 0, TX_DELAY * 1e-3 - time_adv_sec); } else { // Failed, keep default Timestamp @@ -572,7 +572,7 @@ void sync::run_thread() } Debug("Discarting %d samples\n", nsamples); srslte_timestamp_t rx_time; - if (!radio_h->rx_now(dummy_buffer, nsamples, &rx_time)) { + if (!radio_h->rx_now(0, dummy_buffer, nsamples, &rx_time)) { log_h->console("SYNC: Receiving from radio while in IDLE_RX\n"); } // If radio is in locked state returns inmidiatetly. In that case, do a 1 ms sleep @@ -699,12 +699,9 @@ void sync::set_agc_enable(bool enable) do_agc = enable; if (do_agc) { if (running && radio_h) { - srslte_rf_info_t *rf_info = radio_h->get_info(); - srslte_ue_sync_start_agc(&ue_sync, - callback_set_rx_gain, - rf_info->min_rx_gain, - rf_info->max_rx_gain, - radio_h->get_rx_gain()); + srslte_rf_info_t* rf_info = radio_h->get_info(0); + srslte_ue_sync_start_agc( + &ue_sync, callback_set_rx_gain, rf_info->min_rx_gain, rf_info->max_rx_gain, radio_h->get_rx_gain(0)); search_p.set_agc_enable(true); } else { ERROR("Error setting AGC: PHY not initiatec\n"); @@ -852,11 +849,11 @@ bool sync::set_frequency() carrier_map_t* m = &worker_com->args->carrier_map[0]; for (uint32_t i = 0; i < worker_com->args->nof_rx_ant; i++) { - radio_h->set_rx_freq(m->channel_idx + i, set_dl_freq); - radio_h->set_tx_freq(m->channel_idx + i, set_ul_freq); + radio_h->set_rx_freq(m->radio_idx, m->channel_idx + i, set_dl_freq); + radio_h->set_tx_freq(m->radio_idx, m->channel_idx + i, set_ul_freq); } - ul_dl_factor = (float)(radio_h->get_tx_freq() / radio_h->get_rx_freq()); + ul_dl_factor = (float)(radio_h->get_tx_freq(m->radio_idx) / radio_h->get_rx_freq(m->radio_idx)); srslte_ue_sync_reset(&ue_sync); @@ -875,23 +872,9 @@ void sync::set_sampling_rate() current_srate = new_srate; Info("SYNC: Setting sampling rate %.2f MHz\n", current_srate/1000000); -#if 0 - if (((int) current_srate / 1000) % 3072 == 0) { - radio_h->set_master_clock_rate(30.72e6); - } else { - radio_h->set_master_clock_rate(23.04e6); - } -#else - if (current_srate < 10e6) { - radio_h->set_master_clock_rate(4 * current_srate); - } else { - radio_h->set_master_clock_rate(current_srate); - } -#endif - srate_mode = SRATE_CAMP; - radio_h->set_rx_srate(current_srate); - radio_h->set_tx_srate(current_srate); + radio_h->set_rx_srate(0, current_srate); + radio_h->set_tx_srate(0, current_srate); } else { Error("Error setting sampling rate for cell with %d PRBs\n", cell.nof_prb); } @@ -914,7 +897,7 @@ void sync::get_current_cell(srslte_cell_t* cell, uint32_t* earfcn) int sync::radio_recv_fnc(cf_t* data[SRSLTE_MAX_PORTS], uint32_t nsamples, srslte_timestamp_t* rx_time) { - if (radio_h->rx_now(data, nsamples, rx_time)) { + if (radio_h->rx_now(0, data, nsamples, rx_time)) { int offset = nsamples - current_sflen; if (abs(offset) < 10 && offset != 0) { next_offset += offset; @@ -987,12 +970,12 @@ float sync::search::get_last_cfo() void sync::search::set_agc_enable(bool enable) { if (enable) { - srslte_rf_info_t *rf_info = p->radio_h->get_info(); + srslte_rf_info_t* rf_info = p->radio_h->get_info(0); srslte_ue_sync_start_agc(&ue_mib_sync.ue_sync, callback_set_rx_gain, rf_info->min_rx_gain, rf_info->max_rx_gain, - p->radio_h->get_rx_gain()); + p->radio_h->get_rx_gain(0)); } else { ERROR("Error stop AGC not implemented\n"); } @@ -1014,8 +997,8 @@ sync::search::ret_code sync::search::run(srslte_cell_t* cell) if (p->srate_mode != SRATE_FIND) { p->srate_mode = SRATE_FIND; - p->radio_h->set_rx_srate(1.92e6); - p->radio_h->set_tx_srate(1.92e6); + p->radio_h->set_rx_srate(0, 1.92e6); + p->radio_h->set_tx_srate(0, 1.92e6); Info("SYNC: Setting Cell Search sampling rate\n"); } diff --git a/srsue/src/radio/ue_radio.cc b/srsue/src/radio/ue_radio.cc index e6c800a49..3cee1f140 100644 --- a/srsue/src/radio/ue_radio.cc +++ b/srsue/src/radio/ue_radio.cc @@ -71,14 +71,14 @@ int ue_radio::init(const rf_args_t& args_, srslte::logger* logger_) } // Init and start Radio - char* dev_name = NULL; - if (args.device_name.compare("auto")) { + char* dev_name = nullptr; + if (args.device_name != "auto") { dev_name = (char*)args.device_name.c_str(); } - char* dev_args[SRSLTE_MAX_RADIOS] = {NULL}; + char* dev_args[SRSLTE_MAX_RADIOS] = {nullptr}; for (int i = 0; i < SRSLTE_MAX_RADIOS; i++) { - if (args.device_args[0].compare("auto")) { + if (args.device_args[i] != "auto") { dev_args[i] = (char*)args.device_args[i].c_str(); } } @@ -93,17 +93,16 @@ int ue_radio::init(const rf_args_t& args_, srslte::logger* logger_) } // Set RF options - if (args.time_adv_nsamples.compare("auto")) { - int t = atoi(args.time_adv_nsamples.c_str()); + if (args.time_adv_nsamples == "auto") { + int t = (int)strtol(args.time_adv_nsamples.c_str(), nullptr, 10); radio->set_tx_adv(abs(t)); radio->set_tx_adv_neg(t < 0); } - if (args.burst_preamble.compare("auto")) { - radio->set_burst_preamble(atof(args.burst_preamble.c_str())); + if (args.burst_preamble == "auto") { + radio->set_burst_preamble(strtof(args.burst_preamble.c_str(), nullptr)); } - if (args.continuous_tx.compare("auto")) { - log.console("set continuous %s\n", args.continuous_tx.c_str()); - radio->set_continuous_tx(args.continuous_tx.compare("yes") ? false : true); + if (args.continuous_tx == "auto") { + radio->set_continuous_tx(!(args.continuous_tx == "yes")); } // Set PHY options diff --git a/srsue/src/stack/mac/mac.cc b/srsue/src/stack/mac/mac.cc index bc1276430..6d3ef6b6c 100644 --- a/srsue/src/stack/mac/mac.cc +++ b/srsue/src/stack/mac/mac.cc @@ -37,24 +37,24 @@ using namespace asn1::rrc; namespace srsue { -mac::mac() : - timers(64), - pdu_process_thread(&demux_unit), - mch_msg(10), - dl_harq(SRSLTE_MAX_CARRIERS), - ul_harq(SRSLTE_MAX_CARRIERS), - running(false), - pcap(NULL) +mac::mac() : timers(64), pdu_process_thread(&demux_unit), mch_msg(10), running(false), pcap(nullptr) { + // Create PCell HARQ entities + auto ul = ul_harq_entity_ptr(new ul_harq_entity()); + auto dl = dl_harq_entity_ptr(new dl_harq_entity()); + + ul_harq.clear(); + dl_harq.clear(); + + ul_harq.push_back(std::move(ul)); + dl_harq.push_back(std::move(dl)); + + // Keep initialising members bzero(&metrics, sizeof(mac_metrics_t)); clear_rntis(); } -bool mac::init(phy_interface_mac_lte* phy, - rlc_interface_mac* rlc, - rrc_interface_mac* rrc, - srslte::log* log_h_, - uint32_t nof_carriers) +bool mac::init(phy_interface_mac_lte* phy, rlc_interface_mac* rlc, rrc_interface_mac* rrc, srslte::log* log_h_) { phy_h = phy; rlc_h = rlc; @@ -75,10 +75,9 @@ bool mac::init(phy_interface_mac_lte* phy, phy_h, rrc, log_h, &uernti, timers.get(timer_alignment), timers.get(contention_resolution_timer), &mux_unit); sr_procedure.init(phy_h, rrc, log_h); - for (uint32_t r = 0; r < nof_carriers; r++) { - ul_harq[r].init(log_h, &uernti, &ra_procedure, &mux_unit); - dl_harq[r].init(log_h, &uernti, timers.get(timer_alignment), &demux_unit); - } + // Create UL/DL unique HARQ pointers + ul_harq.at(0)->init(log_h, &uernti, &ra_procedure, &mux_unit); + dl_harq.at(0)->init(log_h, &uernti, timers.get(timer_alignment), &demux_unit); reset(); @@ -103,19 +102,32 @@ void mac::stop() void mac::start_pcap(srslte::mac_pcap* pcap_) { pcap = pcap_; - for (uint32_t r = 0; r < dl_harq.size(); r++) { - dl_harq[r].start_pcap(pcap); + for (auto& r : dl_harq) { + r->start_pcap(pcap); } - for (uint32_t r = 0; r < ul_harq.size(); r++) { - ul_harq[r].start_pcap(pcap); + for (auto& r : ul_harq) { + r->start_pcap(pcap); } ra_procedure.start_pcap(pcap); } // Implement Section 5.8 -void mac::reconfiguration() +void mac::reconfiguration(const uint32_t& cc_idx, const bool& enable) { - + if (cc_idx < SRSLTE_MAX_CARRIERS) { + // Create as many HARQ entities as carriers required + while (ul_harq.size() < cc_idx + 1) { + auto ul = ul_harq_entity_ptr(new ul_harq_entity()); + ul->init(log_h, &uernti, &ra_procedure, &mux_unit); + ul->set_config(ul_harq_cfg); + ul_harq.push_back(std::move(ul)); + } + while (dl_harq.size() < cc_idx + 1) { + auto dl = dl_harq_entity_ptr(new dl_harq_entity()); + dl->init(log_h, &uernti, timers.get(timer_alignment), &demux_unit); + dl_harq.push_back(std::move(dl)); + } + } } void mac::wait_uplink() { @@ -138,11 +150,11 @@ void mac::reset() timer_alignment_expire(); - for (uint32_t r = 0; r < dl_harq.size(); r++) { - dl_harq[r].reset(); + for (auto& r : dl_harq) { + r->reset(); } - for (uint32_t r = 0; r < ul_harq.size(); r++) { - ul_harq[r].reset(); + for (auto& r : ul_harq) { + r->reset(); } mux_unit.msg3_flush(); @@ -210,9 +222,7 @@ void mac::run_thread() void mac::bcch_start_rx(int si_window_start, int si_window_length) { if (si_window_length >= 0 && si_window_start >= 0) { - for (uint32_t r = 0; r < dl_harq.size(); r++) { - dl_harq[r].set_si_window_start(si_window_start); - } + dl_harq.at(0)->set_si_window_start(si_window_start); this->si_window_length = si_window_length; this->si_window_start = si_window_start; } else { @@ -383,7 +393,7 @@ void mac::tb_decoded(uint32_t cc_idx, mac_grant_dl_t grant, bool ack[SRSLTE_MAX_ } } else { - dl_harq[cc_idx].tb_decoded(grant, ack); + dl_harq.at(cc_idx)->tb_decoded(grant, ack); pdu_process_thread.notify(); for (uint32_t tb = 0; tb < SRSLTE_MAX_CODEWORDS; tb++) { @@ -423,7 +433,7 @@ void mac::new_grant_dl(uint32_t cc_idx, if (grant.rnti == uernti.crnti && ra_procedure.is_contention_resolution()) { ra_procedure.pdcch_to_crnti(false); } - dl_harq[cc_idx].new_grant_dl(grant, action); + dl_harq.at(cc_idx)->new_grant_dl(grant, action); } else { /* Discard */ Info("Discarding dci in CC %d, RNTI=0x%x\n", cc_idx, grant.rnti); @@ -438,8 +448,8 @@ uint32_t mac::get_current_tti() void mac::reset_harq(uint32_t cc_idx) { if (cc_idx < dl_harq.size()) { - dl_harq[cc_idx].reset(); - ul_harq[cc_idx].reset(); + dl_harq.at(cc_idx)->reset(); + ul_harq.at(cc_idx)->reset(); } } @@ -457,14 +467,14 @@ void mac::new_grant_ul(uint32_t cc_idx, is_first_ul_grant = false; phr_procedure.start_timer(); } - ul_harq[cc_idx].new_grant_ul(grant, action); + ul_harq.at(cc_idx)->new_grant_ul(grant, action); metrics[cc_idx].tx_pkts++; if (grant.phich_available) { if (!grant.hi_value) { metrics[cc_idx].tx_errors++; } else { - metrics[cc_idx].tx_brate += ul_harq[cc_idx].get_current_tbs(grant.pid) * 8; + metrics[cc_idx].tx_brate += ul_harq.at(cc_idx)->get_current_tbs(grant.pid) * 8; } } } @@ -503,11 +513,11 @@ void mac::timer_expired(uint32_t timer_id) void mac::timer_alignment_expire() { rrc_h->release_pucch_srs(); - for (uint32_t r = 0; r < dl_harq.size(); r++) { - dl_harq[r].reset(); + for (auto& r : dl_harq) { + r->reset(); } - for (uint32_t r = 0; r < ul_harq.size(); r++) { - ul_harq[r].reset(); + for (auto& r : ul_harq) { + r->reset(); } } @@ -539,8 +549,11 @@ void mac::set_config(mac_cfg_t& mac_cfg) phr_procedure.set_config(mac_cfg.get_phr_cfg()); sr_procedure.set_config(mac_cfg.get_sr_cfg()); ra_procedure.set_config(mac_cfg.get_rach_cfg()); - for (uint32_t i = 0; i < ul_harq.size(); i++) { - ul_harq[i].set_config(mac_cfg.get_harq_cfg()); + ul_harq_cfg = mac_cfg.get_harq_cfg(); + for (auto& i : ul_harq) { + if (i != nullptr) { + i->set_config(ul_harq_cfg); + } } setup_timers(mac_cfg.get_time_alignment_timer()); } @@ -572,7 +585,7 @@ void mac::get_metrics(mac_metrics_t m[SRSLTE_MAX_CARRIERS]) int dl_avg_ret_count = 0; int ul_avg_ret_count = 0; - for (uint32_t r = 0; r < SRSLTE_MAX_CARRIERS; r++) { + for (uint32_t r = 0; r < dl_harq.size(); r++) { tx_pkts += metrics[r].tx_pkts; tx_errors += metrics[r].tx_errors; tx_brate += metrics[r].tx_brate; @@ -582,7 +595,7 @@ void mac::get_metrics(mac_metrics_t m[SRSLTE_MAX_CARRIERS]) ul_buffer += metrics[r].ul_buffer; if (metrics[r].rx_pkts) { - dl_avg_ret += dl_harq[r].get_average_retx(); + dl_avg_ret += dl_harq.at(r)->get_average_retx(); dl_avg_ret_count++; } } @@ -595,7 +608,7 @@ void mac::get_metrics(mac_metrics_t m[SRSLTE_MAX_CARRIERS]) rx_pkts ? ((float)100 * rx_errors / rx_pkts) : 0.0f, dl_avg_ret, tx_pkts ? ((float)100 * tx_errors / tx_pkts) : 0.0f, - ul_harq[0].get_average_retx()); + ul_harq.at(0)->get_average_retx()); metrics[0].ul_buffer = (int)bsr_procedure.get_buffer_state(); memcpy(m, metrics, sizeof(mac_metrics_t) * SRSLTE_MAX_CARRIERS); diff --git a/srsue/src/stack/rrc/rrc.cc b/srsue/src/stack/rrc/rrc.cc index d8b6dbfba..2c1725ff1 100644 --- a/srsue/src/stack/rrc/rrc.cc +++ b/srsue/src/stack/rrc/rrc.cc @@ -1617,14 +1617,28 @@ bool rrc::con_reconfig(asn1::rrc::rrc_conn_recfg_s* reconfig) rrc_conn_recfg_v920_ies_s* reconfig_r920 = &reconfig_r890->non_crit_ext; if (reconfig_r920->non_crit_ext_present) { rrc_conn_recfg_v1020_ies_s* reconfig_r1020 = &reconfig_r920->non_crit_ext; + + // Handle Add/Modify SCell list if (reconfig_r1020->s_cell_to_add_mod_list_r10_present) { for (uint32_t i = 0; i < reconfig_r1020->s_cell_to_add_mod_list_r10.size(); i++) { - phy->set_config_scell(&reconfig_r1020->s_cell_to_add_mod_list_r10[i]); + auto scell_config = &reconfig_r1020->s_cell_to_add_mod_list_r10[i]; + // Call mac reconfiguration + mac->reconfiguration(scell_config->s_cell_idx_r10, true); + + // Call phy reconfiguration + phy->set_config_scell(scell_config); } } + // Handle Remove SCell list if (reconfig_r1020->s_cell_to_release_list_r10_present) { - rrc_log->console("s_cell_to_release_list_r10 not handled\n"); + for (uint32_t i = 0; i < reconfig_r1020->s_cell_to_release_list_r10.size(); i++) { + // Call mac reconfiguration + mac->reconfiguration(reconfig_r1020->s_cell_to_release_list_r10[i], false); + + // Call phy reconfiguration + // TODO: Implement phy layer cell removal + } } } }