diff --git a/lib/include/srslte/common/interfaces_common.h b/lib/include/srslte/common/interfaces_common.h index 493ab3e87..118ad0953 100644 --- a/lib/include/srslte/common/interfaces_common.h +++ b/lib/include/srslte/common/interfaces_common.h @@ -28,6 +28,35 @@ namespace srslte { +typedef struct { + std::string phy_level; + std::string phy_lib_level; + int phy_hex_limit; +} phy_log_args_t; + +// RF/radio args +typedef struct { + std::string type; + std::string log_level; + float dl_freq; + float ul_freq; + 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 + uint32_t nof_tx_ports; // Number of Tx ports for MIMO + std::string device_name; + std::string device_args[SRSLTE_MAX_RADIOS]; + std::string time_adv_nsamples; + std::string burst_preamble; + std::string continuous_tx; +} rf_args_t; + class srslte_gw_config_t { public: diff --git a/lib/include/srslte/interfaces/common_interfaces.h b/lib/include/srslte/interfaces/common_interfaces.h new file mode 100644 index 000000000..b183b924a --- /dev/null +++ b/lib/include/srslte/interfaces/common_interfaces.h @@ -0,0 +1,82 @@ +/* + * Copyright 2013-2019 Software Radio Systems Limited + * + * This file is part of srsLTE. + * + * srsLTE is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * srsLTE is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * A copy of the GNU Affero General Public License can be found in + * the LICENSE file in the top-level directory of this distribution + * and at http://www.gnu.org/licenses/. + * + */ + +/****************************************************************************** + * File: common_interfaces.h + * Description: Common interface for eNB/UE for PHY and radio + *****************************************************************************/ + +#ifndef SRSLTE_COMMON_INTERFACES_H +#define SRSLTE_COMMON_INTERFACES_H + +#include "srslte/phy/common/phy_common.h" +#include "srslte/phy/common/timestamp.h" +#include "srslte/phy/rf/rf.h" + +namespace srslte { + +class radio_interface_phy +{ +public: + // trx functions + 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(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 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_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; + 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 +{ +public: + virtual void radio_overflow() = 0; + virtual void radio_failure() = 0; +}; + +} // namespace srslte + +#endif // SRSLTE_COMMON_INTERFACES_H diff --git a/lib/include/srslte/interfaces/enb_metrics_interface.h b/lib/include/srslte/interfaces/enb_metrics_interface.h index 651b2d444..38a878264 100644 --- a/lib/include/srslte/interfaces/enb_metrics_interface.h +++ b/lib/include/srslte/interfaces/enb_metrics_interface.h @@ -30,17 +30,11 @@ #include "srsenb/hdr/stack/upper/common_enb.h" #include "srsenb/hdr/stack/upper/s1ap_metrics.h" #include "srslte/common/metrics_hub.h" +#include "srslte/radio/radio_metrics.h" #include "srslte/upper/rlc_metrics.h" #include "srsue/hdr/stack/upper/gw_metrics.h" namespace srsenb { - -typedef struct { - uint32_t rf_o; - uint32_t rf_u; - uint32_t rf_l; - bool rf_error; -}rf_metrics_t; struct stack_metrics_t { mac_metrics_t mac[ENB_METRICS_MAX_USERS]; @@ -49,7 +43,7 @@ struct stack_metrics_t { }; typedef struct { - rf_metrics_t rf; + srslte::rf_metrics_t rf; phy_metrics_t phy[ENB_METRICS_MAX_USERS]; stack_metrics_t stack; bool running; diff --git a/lib/include/srslte/interfaces/ue_interfaces.h b/lib/include/srslte/interfaces/ue_interfaces.h index a7ff06136..ca6221133 100644 --- a/lib/include/srslte/interfaces/ue_interfaces.h +++ b/lib/include/srslte/interfaces/ue_interfaces.h @@ -669,27 +669,6 @@ public: virtual void wait_uplink() = 0; }; -// RF/radio args -typedef struct { - std::string type; - std::string log_level; - - 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 - std::string device_name; - std::string device_args[SRSLTE_MAX_RADIOS]; - std::string time_adv_nsamples; - std::string burst_preamble; - std::string continuous_tx; -} rf_args_t; - /** PHY interface * */ @@ -699,15 +678,9 @@ typedef struct { uint32_t channel_idx; } carrier_map_t; -typedef struct { - std::string phy_level; - std::string phy_lib_level; - int phy_hex_limit; -} phy_log_args_t; - typedef struct { std::string type; - phy_log_args_t log; + srslte::phy_log_args_t log; std::string dl_earfcn; // comma-separated list of EARFCNs std::vector earfcn_list; // vectorized version of dl_earfcn that gets populated during init @@ -878,50 +851,6 @@ public: virtual void enable_pregen_signals(bool enable) = 0; }; -class radio_interface_phy -{ -public: - // trx functions - 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(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 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_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; - 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 -{ -public: - virtual void radio_overflow() = 0; - virtual void radio_failure() = 0; -}; - // STACK interface for GW class stack_interface_gw : public pdcp_interface_gw { diff --git a/lib/include/srslte/radio/radio.h b/lib/include/srslte/radio/radio.h index e64d9c414..4fa0e848e 100644 --- a/lib/include/srslte/radio/radio.h +++ b/lib/include/srslte/radio/radio.h @@ -121,8 +121,6 @@ class radio { float get_rssi(); bool has_rssi(); - void set_tti(uint32_t tti); - bool is_first_of_burst(); bool is_init(); diff --git a/srsue/hdr/radio/ue_radio_base.h b/lib/include/srslte/radio/radio_base.h similarity index 69% rename from srsue/hdr/radio/ue_radio_base.h rename to lib/include/srslte/radio/radio_base.h index bd6bddc10..1ef9cfaab 100644 --- a/srsue/hdr/radio/ue_radio_base.h +++ b/lib/include/srslte/radio/radio_base.h @@ -20,37 +20,34 @@ */ /****************************************************************************** - * File: ue_radio_base.h - * Description: Base class for all UE Radios. + * File: radio_base.h + * Description: Base class for all eNB/UE radios. *****************************************************************************/ -#ifndef SRSUE_UE_RADIO_BASE_H -#define SRSUE_UE_RADIO_BASE_H +#ifndef SRSLTE_RADIO_BASE_H +#define SRSLTE_RADIO_BASE_H +#include "srslte/common/interfaces_common.h" #include "srslte/common/logger.h" -#include "srslte/interfaces/ue_interfaces.h" -#include "srsue/hdr/ue_metrics_interface.h" -#include -#include +#include "srslte/interfaces/common_interfaces.h" +#include "srslte/radio/radio_metrics.h" -namespace srsue { +namespace srslte { -class ue_radio_base +class radio_base { public: - ue_radio_base(){}; - virtual ~ue_radio_base(){}; + radio_base(srslte::logger* logger_){}; + virtual ~radio_base(){}; virtual std::string get_type() = 0; - virtual int init(const srsue::rf_args_t& args_, srslte::logger* logger_) = 0; + virtual int init(const rf_args_t& args_, phy_interface_radio* phy_) = 0; virtual void stop() = 0; virtual bool get_metrics(rf_metrics_t* metrics) = 0; - -private: }; -} // namespace srsue +} // namespace srslte -#endif // SRSUE_UE_RADIO_BASE_H +#endif // SRSLTE_RADIO_BASE_H diff --git a/lib/include/srslte/radio/radio_metrics.h b/lib/include/srslte/radio/radio_metrics.h new file mode 100644 index 000000000..5f121d0cc --- /dev/null +++ b/lib/include/srslte/radio/radio_metrics.h @@ -0,0 +1,36 @@ +/* + * Copyright 2013-2019 Software Radio Systems Limited + * + * This file is part of srsLTE. + * + * srsLTE is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * srsLTE is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * A copy of the GNU Affero General Public License can be found in + * the LICENSE file in the top-level directory of this distribution + * and at http://www.gnu.org/licenses/. + * + */ + +#ifndef SRSLTE_RADIO_METRICS_H +#define SRSLTE_RADIO_METRICS_H + +namespace srslte { + +typedef struct { + uint32_t rf_o; + uint32_t rf_u; + uint32_t rf_l; + bool rf_error; +} rf_metrics_t; + +} // namespace srslte + +#endif // SRSLTE_RADIO_METRICS_H diff --git a/srsue/hdr/radio/ue_radio.h b/lib/include/srslte/radio/radio_multi.h similarity index 78% rename from srsue/hdr/radio/ue_radio.h rename to lib/include/srslte/radio/radio_multi.h index 3ad0b7969..93aa34371 100644 --- a/srsue/hdr/radio/ue_radio.h +++ b/lib/include/srslte/radio/radio_multi.h @@ -20,34 +20,31 @@ */ /****************************************************************************** - * File: ue_radio_multi.h - * Description: UE radio module using the srslte_radio_multi() object. + * File: radio_multi.h + * Description: Class for using multiple srslte::radio's for both eNB/UE *****************************************************************************/ -#ifndef SRSUE_UE_RADIO_MULTI_H -#define SRSUE_UE_RADIO_MULTI_H +#ifndef SRSLTE_RADIO_MULTI_H +#define SRSLTE_RADIO_MULTI_H -#include "srslte/common/log_filter.h" +#include "srslte/common/logger.h" +#include "srslte/interfaces/common_interfaces.h" +#include "srslte/phy/rf/rf.h" #include "srslte/radio/radio.h" -#include "srsue/hdr/radio/ue_radio_base.h" -#include "srsue/hdr/ue_metrics_interface.h" +#include "srslte/radio/radio_base.h" +#include "srslte/radio/radio_metrics.h" -namespace srsue { +namespace srslte { -/******************************************************************************* - Main UE stack class -*******************************************************************************/ - -class ue_radio : public ue_radio_base, public radio_interface_phy +class radio_multi : public radio_base, public radio_interface_phy { public: - ue_radio(); - ~ue_radio() override; + radio_multi(srslte::logger* logger_); + ~radio_multi() override; std::string get_type() override; - 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_); + int init(const rf_args_t& args_, phy_interface_radio* phy_); void stop() override; @@ -103,19 +100,18 @@ public: } 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; +protected: + rf_args_t args = {}; - std::vector > radios; + std::vector > radios; - srslte::logger* logger; + srslte::logger* logger = nullptr; srslte::log_filter log; - bool running; + bool running = false; - rf_metrics_t rf_metrics; - phy_interface_radio* phy; + srslte::rf_metrics_t rf_metrics = {}; + phy_interface_radio* phy = nullptr; }; +} // namespace srslte -} // namespace srsue - -#endif // SRSUE_UE_RADIO_MULTI_H +#endif // SRSLTE_RADIO_MULTI_H diff --git a/lib/src/radio/CMakeLists.txt b/lib/src/radio/CMakeLists.txt index 0ab4e430c..053951b18 100644 --- a/lib/src/radio/CMakeLists.txt +++ b/lib/src/radio/CMakeLists.txt @@ -19,7 +19,7 @@ # if(RF_FOUND) - add_library(srslte_radio STATIC radio.cc) + add_library(srslte_radio STATIC radio.cc radio_multi.cc) target_link_libraries(srslte_radio srslte_rf) install(TARGETS srslte_radio DESTINATION ${LIBRARY_DIR}) endif(RF_FOUND) diff --git a/lib/src/radio/radio.cc b/lib/src/radio/radio.cc index caf4c9af2..51ce5f93c 100644 --- a/lib/src/radio/radio.cc +++ b/lib/src/radio/radio.cc @@ -255,10 +255,6 @@ void radio::tx_end() } } -void radio::set_tti(uint32_t tti_) { - tti = tti_; -} - void radio::set_freq_offset(double freq) { freq_offset = freq; } diff --git a/srsue/src/radio/ue_radio.cc b/lib/src/radio/radio_multi.cc similarity index 81% rename from srsue/src/radio/ue_radio.cc rename to lib/src/radio/radio_multi.cc index 5e259d59d..5549588ea 100644 --- a/srsue/src/radio/ue_radio.cc +++ b/lib/src/radio/radio_multi.cc @@ -19,47 +19,34 @@ * */ -#include "srsue/hdr/radio/ue_radio.h" +#include "srslte/radio/radio_multi.h" #include -using namespace srslte; +namespace srslte { -namespace srsue { +std::mutex radio_instance_mutex; +static radio_multi* instance; -std::mutex instance_mutex; -static ue_radio* instance; - -ue_radio::ue_radio() : args(), logger(nullptr), running(false), phy(nullptr), rf_metrics(), radios() +radio_multi::radio_multi(srslte::logger* logger_) : logger(logger_), radio_base(logger_) { - std::lock_guard lock(instance_mutex); + std::lock_guard lock(radio_instance_mutex); instance = this; } -ue_radio::~ue_radio() +radio_multi::~radio_multi() { stop(); } -std::string ue_radio::get_type() +std::string radio_multi::get_type() { - return "radio"; -} - -int ue_radio::init(const rf_args_t& args_, srslte::logger* logger_, phy_interface_radio* phy_) -{ - if (init(args_, logger_)) { - return SRSLTE_ERROR; - } - - phy = phy_; - - return SRSLTE_SUCCESS; + return "radio_multi"; } -int ue_radio::init(const rf_args_t& args_, srslte::logger* logger_) +int radio_multi::init(const rf_args_t& args_, phy_interface_radio* phy_) { args = args_; - logger = logger_; + phy = phy_; // Init log log.init("RF ", logger); @@ -130,10 +117,10 @@ int ue_radio::init(const rf_args_t& args_, srslte::logger* logger_) return SRSLTE_SUCCESS; } -void ue_radio::stop() +void radio_multi::stop() { if (running) { - std::lock_guard lock(instance_mutex); + std::lock_guard lock(radio_instance_mutex); instance = nullptr; for (auto& radio : radios) { @@ -144,22 +131,22 @@ void ue_radio::stop() } } -bool ue_radio::get_metrics(rf_metrics_t* metrics) +bool radio_multi::get_metrics(rf_metrics_t* metrics) { *metrics = rf_metrics; rf_metrics = {}; return true; } -void ue_radio::rf_msg(srslte_rf_error_t error) +void radio_multi::rf_msg(srslte_rf_error_t error) { - std::lock_guard lock(instance_mutex); + std::lock_guard lock(radio_instance_mutex); if (instance) { instance->handle_rf_msg(error); } } -void ue_radio::handle_rf_msg(srslte_rf_error_t error) +void radio_multi::handle_rf_msg(srslte_rf_error_t error) { if (error.type == srslte_rf_error_t::SRSLTE_RF_ERROR_OVERFLOW) { rf_metrics.rf_o++; @@ -188,4 +175,4 @@ void ue_radio::handle_rf_msg(srslte_rf_error_t error) } } -} // namespace srsue +} // namespace srslte diff --git a/srsenb/hdr/enb.h b/srsenb/hdr/enb.h index 374bb70fe..aad242df5 100644 --- a/srsenb/hdr/enb.h +++ b/srsenb/hdr/enb.h @@ -35,11 +35,15 @@ #include "phy/phy.h" #include "srsenb/hdr/stack/rrc/rrc.h" -#include "srslte/radio/radio.h" +#include "srslte/radio/radio_base.h" +#include "srsenb/hdr/phy/enb_phy_base.h" #include "srsenb/hdr/stack/enb_stack_base.h" +#include "srsenb/hdr/stack/enb_stack_lte.h" + #include "srslte/common/bcd_helpers.h" #include "srslte/common/buffer_pool.h" +#include "srslte/common/interfaces_common.h" #include "srslte/common/log_filter.h" #include "srslte/common/logger_file.h" #include "srslte/common/mac_pcap.h" @@ -55,7 +59,8 @@ namespace srsenb { *******************************************************************************/ struct enb_args_t { - s1ap_args_t s1ap; + uint32_t dl_earfcn; + uint32_t ul_earfcn; uint32_t n_prb; uint32_t pci; uint32_t nof_ports; @@ -69,41 +74,13 @@ struct enb_files_t { std::string drb_config; }; -typedef struct { - uint32_t dl_earfcn; - uint32_t ul_earfcn; - float dl_freq; - float ul_freq; - float rx_gain; - float tx_gain; - std::string device_name; - std::string device_args; - std::string time_adv_nsamples; - std::string burst_preamble; -}rf_args_t; - -typedef struct { - bool enable; - std::string filename; -}pcap_args_t; - typedef struct { std::string phy_level; std::string phy_lib_level; - std::string mac_level; - std::string rlc_level; - std::string pdcp_level; - std::string rrc_level; - std::string gtpu_level; - std::string s1ap_level; + std::string all_level; int phy_hex_limit; - int mac_hex_limit; - int rlc_hex_limit; - int pdcp_hex_limit; - int rrc_hex_limit; - int gtpu_hex_limit; - int s1ap_hex_limit; + int all_hex_limit; int file_max_size; std::string filename; @@ -115,7 +92,6 @@ struct gui_args_t { struct expert_args_t { phy_args_t phy; - mac_args_t mac; uint32_t rrc_inactivity_timer; float metrics_period_secs; bool metrics_csv_enable; @@ -131,11 +107,12 @@ struct expert_args_t { struct all_args_t { enb_args_t enb; enb_files_t enb_files; - rf_args_t rf; + srslte::rf_args_t rf; pcap_args_t pcap; log_args_t log; gui_args_t gui; expert_args_t expert; + stack_args_t stack; }; /******************************************************************************* @@ -149,7 +126,7 @@ public: static void cleanup(void); - bool init(all_args_t *args_); + int init(const all_args_t& args_); void stop(); @@ -174,23 +151,29 @@ private: virtual ~enb(); - std::unique_ptr stack; - srslte::radio radio; - srsenb::phy phy; + int parse_args(const all_args_t& args_); + + // eNB components + std::unique_ptr stack = nullptr; + std::unique_ptr radio = nullptr; + std::unique_ptr phy = nullptr; srslte::logger_stdout logger_stdout; srslte::logger_file logger_file; - srslte::logger *logger; + srslte::logger* logger = nullptr; + srslte::log_filter log; // Own logger for eNB srslte::log_filter rf_log; std::vector phy_log; srslte::log_filter pool_log; - srslte::byte_buffer_pool *pool; + srslte::byte_buffer_pool* pool = nullptr; + + all_args_t args = {}; + bool started = false; - all_args_t *args; - bool started; - rf_metrics_t rf_metrics; + phy_cfg_t phy_cfg = {}; + rrc_cfg_t rrc_cfg = {}; srslte::LOG_LEVEL_ENUM level(std::string l); diff --git a/srsenb/hdr/phy/enb_lte_phy_base.h b/srsenb/hdr/phy/enb_lte_phy_base.h new file mode 100644 index 000000000..3cc610188 --- /dev/null +++ b/srsenb/hdr/phy/enb_lte_phy_base.h @@ -0,0 +1,52 @@ +/* + * Copyright 2013-2019 Software Radio Systems Limited + * + * This file is part of srsLTE. + * + * srsLTE is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * srsLTE is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * A copy of the GNU Affero General Public License can be found in + * the LICENSE file in the top-level directory of this distribution + * and at http://www.gnu.org/licenses/. + * + */ + +/****************************************************************************** + * File: enb_lte_phy_base.h + * Description: Base class for eNB LTE PHYs. + *****************************************************************************/ + +#ifndef SRSENB_LTE_PHY_BASE_H +#define SRSENB_LTE_PHY_BASE_H + +#include "srsenb/hdr/phy/enb_phy_base.h" +#include "srslte/interfaces/common_interfaces.h" + +namespace srsenb { + +class enb_lte_phy_base : public enb_phy_base, public phy_interface_stack_lte, public srslte::phy_interface_radio +{ +public: + enb_lte_phy_base(){}; + virtual ~enb_lte_phy_base(){}; + + virtual std::string get_type() = 0; + + virtual void stop() = 0; + + virtual void start_plot() = 0; + + virtual void get_metrics(phy_metrics_t* m) = 0; +}; + +} // namespace srsenb + +#endif // SRSENB_LTE_PHY_BASE_H diff --git a/srsenb/hdr/phy/enb_phy_base.h b/srsenb/hdr/phy/enb_phy_base.h new file mode 100644 index 000000000..17b0209fd --- /dev/null +++ b/srsenb/hdr/phy/enb_phy_base.h @@ -0,0 +1,51 @@ +/* + * Copyright 2013-2019 Software Radio Systems Limited + * + * This file is part of srsLTE. + * + * srsLTE is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * srsLTE is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * A copy of the GNU Affero General Public License can be found in + * the LICENSE file in the top-level directory of this distribution + * and at http://www.gnu.org/licenses/. + * + */ + +/****************************************************************************** + * File: enb_phy_base.h + * Description: Base class for all eNB PHYs. + *****************************************************************************/ + +#ifndef SRSENB_PHY_BASE_H +#define SRSENB_PHY_BASE_H + +#include "srsue/hdr/phy/phy_metrics.h" + +namespace srsenb { + +class enb_phy_base +{ +public: + enb_phy_base(){}; + virtual ~enb_phy_base(){}; + + virtual std::string get_type() = 0; + + virtual void stop() = 0; + + virtual void start_plot() = 0; + + virtual void get_metrics(phy_metrics_t* m) = 0; +}; + +} // namespace srsenb + +#endif // SRSENB_PHY_BASE_H diff --git a/srsenb/hdr/phy/phy.h b/srsenb/hdr/phy/phy.h index 2e472332c..414e54089 100644 --- a/srsenb/hdr/phy/phy.h +++ b/srsenb/hdr/phy/phy.h @@ -24,9 +24,11 @@ #include "phy_common.h" #include "sf_worker.h" +#include "srsenb/hdr/phy/enb_lte_phy_base.h" #include "srslte/common/log.h" #include "srslte/common/log_filter.h" #include "srslte/common/trace.h" +#include "srslte/interfaces/common_interfaces.h" #include "srslte/interfaces/enb_interfaces.h" #include "srslte/interfaces/enb_metrics_interface.h" #include "srslte/radio/radio.h" @@ -43,23 +45,20 @@ typedef struct { asn1::rrc::srs_ul_cfg_common_c srs_ul_cnfg; } phy_cfg_t; -class phy : public phy_interface_stack_lte +class phy : public enb_lte_phy_base { public: + phy(srslte::logger* logger_); + ~phy(); - phy(); - bool init(phy_args_t* args, - phy_cfg_t* common_cfg, - srslte::radio* radio_handler, - stack_interface_phy_lte* stack, - srslte::log_filter* log_h); - bool init(phy_args_t* args, - phy_cfg_t* common_cfg, - srslte::radio* radio_handler, - stack_interface_phy_lte* stack, - std::vector log_vec); + int init(const phy_args_t& args, + const phy_cfg_t& cfg, + srslte::radio_interface_phy* radio_, + stack_interface_phy_lte* stack_); void stop(); - + + std::string get_type() { return "lte"; }; + /* MAC->PHY interface */ int add_rnti(uint16_t rnti, bool is_temporal = false); void rem_rnti(uint16_t rnti); @@ -75,30 +74,38 @@ public: void set_config_dedicated(uint16_t rnti, asn1::rrc::phys_cfg_ded_s* dedicated); void get_metrics(phy_metrics_t metrics[ENB_METRICS_MAX_USERS]); - + + void radio_overflow(){}; + void radio_failure(){}; + private: - phy_rrc_cfg_t phy_rrc_config; - uint32_t nof_workers; - + phy_rrc_cfg_t phy_rrc_config = {}; + uint32_t nof_workers = 0; + const static int MAX_WORKERS = 4; const static int DEFAULT_WORKERS = 2; const static int PRACH_WORKER_THREAD_PRIO = 3; const static int SF_RECV_THREAD_PRIO = 1; const static int WORKERS_THREAD_PRIO = 2; - - srslte::radio *radio_handler; - srslte::log *log_h; + + srslte::radio_interface_phy* radio = nullptr; + + srslte::logger* logger = nullptr; + std::vector > log_vec; + srslte::log* log_h = nullptr; + srslte::thread_pool workers_pool; std::vector workers; phy_common workers_common; - prach_worker prach; - txrx tx_rx; - - srslte_prach_cfg_t prach_cfg; - - void parse_config(phy_cfg_t* cfg); - + prach_worker prach; + txrx tx_rx; + + bool initialized = false; + + srslte_prach_cfg_t prach_cfg = {}; + + void parse_config(const phy_cfg_t& cfg); }; } // namespace srsenb diff --git a/srsenb/hdr/phy/phy_common.h b/srsenb/hdr/phy/phy_common.h index 9506d7090..9e531c47a 100644 --- a/srsenb/hdr/phy/phy_common.h +++ b/srsenb/hdr/phy/phy_common.h @@ -22,20 +22,25 @@ #ifndef SRSENB_PHCH_COMMON_H #define SRSENB_PHCH_COMMON_H -#include -#include -#include "srslte/interfaces/enb_interfaces.h" -#include "srslte/interfaces/enb_metrics_interface.h" #include "srslte/common/gen_mch_tables.h" +#include "srslte/common/interfaces_common.h" #include "srslte/common/log.h" -#include "srslte/common/threads.h" #include "srslte/common/thread_pool.h" +#include "srslte/common/threads.h" +#include "srslte/interfaces/common_interfaces.h" +#include "srslte/interfaces/enb_interfaces.h" +#include "srslte/interfaces/enb_metrics_interface.h" #include "srslte/radio/radio.h" +#include +#include #include namespace srsenb { typedef struct { + std::string type; + srslte::phy_log_args_t log; + float max_prach_offset_us; int pusch_max_its; bool pusch_8bit_decoder; @@ -54,7 +59,7 @@ public: void set_nof_workers(uint32_t nof_workers); - bool init(srslte_cell_t* cell, srslte::radio* radio_handler, stack_interface_phy_lte* mac); + bool init(const srslte_cell_t& cell_, srslte::radio_interface_phy* radio_handler, stack_interface_phy_lte* mac); void reset(); void stop(); @@ -70,7 +75,7 @@ public: // Physical Downlink Config common srslte_dl_cfg_t dl_cfg_com; - srslte::radio *radio; + srslte::radio_interface_phy* radio; stack_interface_phy_lte* stack; // Common objects for schedulign grants diff --git a/srsenb/hdr/phy/prach_worker.h b/srsenb/hdr/phy/prach_worker.h index a0bee4382..0f93acc50 100644 --- a/srsenb/hdr/phy/prach_worker.h +++ b/srsenb/hdr/phy/prach_worker.h @@ -53,11 +53,11 @@ public: bzero(&prach_cfg, sizeof(prach_cfg)); } - int init(srslte_cell_t* cell, - srslte_prach_cfg_t* prach_cfg, - stack_interface_phy_lte* mac, - srslte::log* log_h, - int priority); + int init(const srslte_cell_t& cell_, + const srslte_prach_cfg_t& prach_cfg_, + stack_interface_phy_lte* mac, + srslte::log* log_h, + int priority); int new_tti(uint32_t tti, cf_t *buffer); void set_max_prach_offset_us(float delay_us); void stop(); diff --git a/srsenb/hdr/phy/txrx.h b/srsenb/hdr/phy/txrx.h index 99142bb9d..136aaeed5 100644 --- a/srsenb/hdr/phy/txrx.h +++ b/srsenb/hdr/phy/txrx.h @@ -37,19 +37,18 @@ class txrx : public thread { public: txrx(); - bool init(srslte::radio* radio_handler, - srslte::thread_pool* _workers_pool, - phy_common* worker_com, - prach_worker* prach, - srslte::log* log_h, - uint32_t prio); + bool init(srslte::radio_interface_phy* radio_handler, + srslte::thread_pool* _workers_pool, + phy_common* worker_com, + prach_worker* prach, + srslte::log* log_h, + uint32_t prio); void stop(); private: - - void run_thread(); - - srslte::radio *radio_h; + void run_thread(); + + srslte::radio_interface_phy* radio_h; srslte::log *log_h; srslte::thread_pool *workers_pool; prach_worker* prach; diff --git a/srsenb/hdr/radio/enb_radio_multi.h b/srsenb/hdr/radio/enb_radio_multi.h new file mode 100644 index 000000000..4bbe1bf7f --- /dev/null +++ b/srsenb/hdr/radio/enb_radio_multi.h @@ -0,0 +1,49 @@ + +/* + * Copyright 2013-2019 Software Radio Systems Limited + * + * This file is part of srsLTE. + * + * srsLTE is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * srsLTE is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * A copy of the GNU Affero General Public License can be found in + * the LICENSE file in the top-level directory of this distribution + * and at http://www.gnu.org/licenses/. + * + */ + +/****************************************************************************** + * File: enb_radio_multi.h + * Description: Header-only class for eNB to set DL/UL freq during init + *****************************************************************************/ + +#ifndef SRSENB_RADIO_MULTI_H +#define SRSENB_RADIO_MULTI_H + +#include "srslte/common/logger.h" +#include "srslte/interfaces/common_interfaces.h" +#include "srslte/phy/rf/rf.h" +#include "srslte/radio/radio_base.h" +#include "srslte/radio/radio_metrics.h" +#include "srslte/radio/radio_multi.h" + +namespace srsenb { + +class enb_radio_multi : public srslte::radio_multi +{ +public: + enb_radio_multi(srslte::logger* logger_); + ~enb_radio_multi() override; + int init(const srslte::rf_args_t& args_, srslte::phy_interface_radio* phy_); +}; +} // namespace srsenb + +#endif // SRSENB_RADIO_MULTI_H diff --git a/srsenb/hdr/stack/enb_stack_base.h b/srsenb/hdr/stack/enb_stack_base.h index 6b0a8cc02..7ab4a20f4 100644 --- a/srsenb/hdr/stack/enb_stack_base.h +++ b/srsenb/hdr/stack/enb_stack_base.h @@ -26,6 +26,41 @@ namespace srsenb { +typedef struct { + bool enable; + std::string filename; +} pcap_args_t; + +typedef struct { + bool enable_mbsfn; + std::string m1u_multiaddr; + std::string m1u_if_addr; +} stack_expert_args_t; + +typedef struct { + std::string mac_level; + std::string rlc_level; + std::string pdcp_level; + std::string rrc_level; + std::string gtpu_level; + std::string s1ap_level; + + int mac_hex_limit; + int rlc_hex_limit; + int pdcp_hex_limit; + int rrc_hex_limit; + int gtpu_hex_limit; + int s1ap_hex_limit; +} stack_log_args_t; + +typedef struct { + mac_args_t mac; + s1ap_args_t s1ap; + pcap_args_t pcap; + stack_log_args_t log; + stack_expert_args_t expert; +} stack_args_t; + struct stack_metrics_t; class enb_stack_base diff --git a/srsenb/hdr/stack/enb_stack_lte.h b/srsenb/hdr/stack/enb_stack_lte.h index 602c2a93b..75bc263e9 100644 --- a/srsenb/hdr/stack/enb_stack_lte.h +++ b/srsenb/hdr/stack/enb_stack_lte.h @@ -45,26 +45,12 @@ namespace srsenb { class enb_stack_lte final : public enb_stack_base, public stack_interface_phy_lte { public: - struct args_t { - struct stack_expert_args_t { - mac_args_t mac; - bool enable_mbsfn; - std::string m1u_multiaddr; - std::string m1u_if_addr; - }; - - enb_args_t enb; - pcap_args_t pcap; - log_args_t log; - stack_expert_args_t expert; - }; - - enb_stack_lte(); + enb_stack_lte(srslte::logger* logger_); ~enb_stack_lte() final; // eNB stack base interface - int init(const args_t& args_, const rrc_cfg_t& rrc_cfg_, srslte::logger* logger_, phy_interface_stack_lte* phy_); - int init(const args_t& args_, const rrc_cfg_t& rrc_cfg_, srslte::logger* logger_); + int init(const stack_args_t& args_, const rrc_cfg_t& rrc_cfg_, phy_interface_stack_lte* phy_); + int init(const stack_args_t& args_, const rrc_cfg_t& rrc_cfg_); void stop() final; std::string get_type() final; bool get_metrics(stack_metrics_t* metrics) final; @@ -99,9 +85,9 @@ public: void tti_clock() final { mac.tti_clock(); } private: - args_t args; - rrc_cfg_t rrc_cfg; - bool started; + stack_args_t args = {}; + rrc_cfg_t rrc_cfg = {}; + bool started = false; srsenb::mac mac; srslte::mac_pcap mac_pcap; @@ -111,7 +97,7 @@ private: srsenb::gtpu gtpu; srsenb::s1ap s1ap; - srslte::logger* logger; + srslte::logger* logger = nullptr; // Radio and PHY log are in enb.cc srslte::log_filter mac_log; @@ -122,7 +108,7 @@ private: srslte::log_filter gtpu_log; // RAT-specific interfaces - phy_interface_stack_lte* phy; + phy_interface_stack_lte* phy = nullptr; }; } // namespace srsenb diff --git a/srsenb/hdr/stack/mac/scheduler_grid.h b/srsenb/hdr/stack/mac/scheduler_grid.h index 20d57c17a..cd49c7714 100644 --- a/srsenb/hdr/stack/mac/scheduler_grid.h +++ b/srsenb/hdr/stack/mac/scheduler_grid.h @@ -87,16 +87,16 @@ private: // consts srslte::log* log_h = nullptr; sched_ue::sched_dci_cce_t* common_locations = nullptr; - sched_ue::sched_dci_cce_t* rar_locations[10]; - uint32_t cce_size_array[nof_cfis]; + sched_ue::sched_dci_cce_t* rar_locations[10] = {nullptr}; + uint32_t cce_size_array[nof_cfis] = {0}; // tti vars - uint32_t tti_rx; - uint32_t sf_idx; - uint32_t current_cfix; - size_t prev_start, prev_end; + uint32_t tti_rx = 0; + uint32_t sf_idx = 0; + uint32_t current_cfix = 0; + size_t prev_start, prev_end = 0; std::vector dci_alloc_tree; - size_t nof_dci_allocs; + size_t nof_dci_allocs = 0; }; class tti_grid_t @@ -130,21 +130,21 @@ private: // consts srslte::log* log_h = nullptr; sched_interface::cell_cfg_t* cell_cfg = nullptr; - uint32_t nof_prbs; - uint32_t nof_rbgs; - uint32_t si_n_rbg, rar_n_rbg; + uint32_t nof_prbs = 0; + uint32_t nof_rbgs = 0; + uint32_t si_n_rbg, rar_n_rbg = 0; // tti const uint32_t tti_rx = 10241; // derived - uint32_t tti_tx_dl, tti_tx_ul; - uint32_t sfn; - pdcch_grid_t pdcch_alloc; + uint32_t tti_tx_dl, tti_tx_ul = 0; + uint32_t sfn = 0; + pdcch_grid_t pdcch_alloc = {}; // internal state uint32_t avail_rbg = 0; - rbgmask_t dl_mask; - prbmask_t ul_mask; + rbgmask_t dl_mask = {}; + prbmask_t ul_mask = {}; }; } // namespace srsenb diff --git a/srsenb/src/CMakeLists.txt b/srsenb/src/CMakeLists.txt index 194fe0cc8..7ef4bcd85 100644 --- a/srsenb/src/CMakeLists.txt +++ b/srsenb/src/CMakeLists.txt @@ -18,6 +18,7 @@ # and at http://www.gnu.org/licenses/. # +add_subdirectory(radio) add_subdirectory(phy) add_subdirectory(stack) @@ -34,7 +35,8 @@ endif (RPATH) add_executable(srsenb main.cc enb.cc parser.cc enb_cfg_parser.cc metrics_stdout.cc metrics_csv.cc) -target_link_libraries(srsenb srsenb_phy +target_link_libraries(srsenb srsenb_radio + srsenb_phy srsenb_stack srsenb_upper srsenb_mac diff --git a/srsenb/src/enb.cc b/srsenb/src/enb.cc index 3121fb642..373ca3bd8 100644 --- a/srsenb/src/enb.cc +++ b/srsenb/src/enb.cc @@ -20,6 +20,7 @@ */ #include "srsenb/hdr/enb.h" +#include "srsenb/hdr/radio/enb_radio_multi.h" #include "srsenb/hdr/stack/enb_stack_lte.h" #include "srslte/build_info.h" #include @@ -52,17 +53,12 @@ void enb::cleanup() pthread_mutex_unlock(&enb_instance_mutex); } -enb::enb() : started(false) { +enb::enb() : started(false), pool(srslte::byte_buffer_pool::get_instance(ENB_POOL_SIZE)) +{ // print build info std::cout << std::endl << get_build_string() << std::endl; srslte_dft_load(); - pool = srslte::byte_buffer_pool::get_instance(ENB_POOL_SIZE); - - logger = nullptr; - args = nullptr; - - bzero(&rf_metrics, sizeof(rf_metrics)); } enb::~enb() @@ -72,27 +68,37 @@ enb::~enb() } } -bool enb::init(all_args_t *args_) +int enb::init(const all_args_t& args_) { - args = args_; + // Init UE log + log.init("UE ", logger); + log.set_level(srslte::LOG_LEVEL_INFO); + log.info("%s", get_build_string().c_str()); + + // Validate arguments + if (parse_args(args_)) { + log.console("Error processing arguments.\n"); + return SRSLTE_ERROR; + } - if (args->log.filename == "stdout") { + // set logger + if (args.log.filename == "stdout") { logger = &logger_stdout; } else { - logger_file.init(args->log.filename, args->log.file_max_size); + logger_file.init(args.log.filename, args.log.file_max_size); logger_file.log("\n\n"); logger_file.log(get_build_string().c_str()); logger = &logger_file; } - rf_log.init("RF ", logger); - - // Create array of pointers to phy_logs - for (int i=0;iexpert.phy.nof_phy_threads;i++) { + // Create array of pointers to phy_logs + for (int i = 0; i < args.expert.phy.nof_phy_threads; i++) { auto* mylog = new srslte::log_filter; char tmp[16]; sprintf(tmp, "PHY%d",i); mylog->init(tmp, logger, true); + mylog->set_level(level(args.log.phy_level)); + mylog->set_hex_limit(args.log.phy_hex_limit); phy_log.push_back(mylog); } @@ -100,60 +106,119 @@ bool enb::init(all_args_t *args_) pool_log.set_level(srslte::LOG_LEVEL_ERROR); pool->set_log(&pool_log); - // Init logs - rf_log.set_level(srslte::LOG_LEVEL_INFO); - for (int i=0;iexpert.phy.nof_phy_threads;i++) { - ((srslte::log_filter*) phy_log[i])->set_level(level(args->log.phy_level)); + // Create layers + std::unique_ptr lte_stack(new enb_stack_lte(logger)); + if (!lte_stack) { + log.console("Error creating eNB stack.\n"); + return SRSLTE_ERROR; } - for (int i=0;iexpert.phy.nof_phy_threads;i++) { - ((srslte::log_filter*) phy_log[i])->set_hex_limit(args->log.phy_hex_limit); + std::unique_ptr lte_radio = std::unique_ptr(new enb_radio_multi(logger)); + if (!lte_radio) { + log.console("Error creating radio multi instance.\n"); + return SRSLTE_ERROR; } + std::unique_ptr lte_phy = std::unique_ptr(new srsenb::phy(logger)); + if (!lte_phy) { + log.console("Error creating LTE PHY instance.\n"); + return SRSLTE_ERROR; + } + + // Init layers + if (lte_radio->init(args.rf, lte_phy.get())) { + log.console("Error initializing radio.\n"); + return SRSLTE_ERROR; + } + + if (lte_phy->init(args.expert.phy, phy_cfg, lte_radio.get(), lte_stack.get())) { + log.console("Error initializing PHY.\n"); + return SRSLTE_ERROR; + } + + if (lte_stack->init(args.stack, rrc_cfg, lte_phy.get())) { + log.console("Error initializing stack.\n"); + return SRSLTE_ERROR; + } + + stack = std::move(lte_stack); + phy = std::move(lte_phy); + radio = std::move(lte_radio); + + log.console("\n==== eNodeB started ===\n"); + log.console("Type to view trace\n"); + + started = true; + + return SRSLTE_SUCCESS; +} + +void enb::stop() +{ + if (started) { + // tear down in reverse order + if (phy) { + phy->stop(); + } + + if (stack) { + stack->stop(); + } + + if (radio) { + radio->stop(); + } + + started = false; + } +} + +int enb::parse_args(const all_args_t& args_) +{ + // set member variable + args = args_; + // Parse config files - srslte_cell_t cell_cfg; - phy_cfg_t phy_cfg; - rrc_cfg_t rrc_cfg; + srslte_cell_t cell_cfg = {}; - if (parse_cell_cfg(args, &cell_cfg)) { + if (parse_cell_cfg(&args, &cell_cfg)) { fprintf(stderr, "Error parsing Cell configuration\n"); - return false; + return SRSLTE_ERROR; } - if (parse_sibs(args, &rrc_cfg, &phy_cfg)) { + if (parse_sibs(&args, &rrc_cfg, &phy_cfg)) { fprintf(stderr, "Error parsing SIB configuration\n"); - return false; + return SRSLTE_ERROR; } - if (parse_rr(args, &rrc_cfg)) { + if (parse_rr(&args, &rrc_cfg)) { fprintf(stderr, "Error parsing Radio Resources configuration\n"); - return false; + return SRSLTE_ERROR; } - if (parse_drb(args, &rrc_cfg)) { + if (parse_drb(&args, &rrc_cfg)) { fprintf(stderr, "Error parsing DRB configuration\n"); - return false; + return SRSLTE_ERROR; } - if (args->enb.transmission_mode == 1) { + if (args.enb.transmission_mode == 1) { phy_cfg.pdsch_cnfg.p_b = 0; // Default TM1 } else { phy_cfg.pdsch_cnfg.p_b = 1; // Default TM2,3,4 } - rrc_cfg.inactivity_timeout_ms = args->expert.rrc_inactivity_timer; - rrc_cfg.enable_mbsfn = args->expert.enable_mbsfn; + rrc_cfg.inactivity_timeout_ms = args.expert.rrc_inactivity_timer; + rrc_cfg.enable_mbsfn = args.expert.enable_mbsfn; // Check number of control symbols - if (cell_cfg.nof_prb < 50 && args->expert.mac.sched.nof_ctrl_symbols != 3) { - args->expert.mac.sched.nof_ctrl_symbols = 3; + if (cell_cfg.nof_prb < 50 && args.stack.mac.sched.nof_ctrl_symbols != 3) { + args.stack.mac.sched.nof_ctrl_symbols = 3; fprintf(stdout, "Setting number of control symbols to %d for %d PRB cell.\n", - args->expert.mac.sched.nof_ctrl_symbols, + args.stack.mac.sched.nof_ctrl_symbols, cell_cfg.nof_prb); } // Parse EEA preference list std::vector eea_pref_list; - boost::split(eea_pref_list, args->expert.eea_pref_list, - boost::is_any_of(",")); + boost::split(eea_pref_list, args.expert.eea_pref_list, boost::is_any_of(",")); int i = 0; for (auto it = eea_pref_list.begin(); it != eea_pref_list.end() && i < srslte::CIPHERING_ALGORITHM_ID_N_ITEMS; it++) { boost::trim_left(*it); @@ -167,16 +232,14 @@ bool enb::init(all_args_t *args_) rrc_cfg.eea_preference_list[i] = srslte::CIPHERING_ALGORITHM_ID_128_EEA2; i++; } else { - fprintf(stderr, "Failed to parse EEA prefence list %s \n", - args->expert.eea_pref_list.c_str()); - return false; + fprintf(stderr, "Failed to parse EEA prefence list %s \n", args.expert.eea_pref_list.c_str()); + return SRSLTE_ERROR; } } // Parse EIA preference list std::vector eia_pref_list; - boost::split(eia_pref_list, args->expert.eia_pref_list, - boost::is_any_of(",")); + boost::split(eia_pref_list, args.expert.eia_pref_list, boost::is_any_of(",")); i = 0; for (auto it = eia_pref_list.begin(); it != eia_pref_list.end() && i < srslte::INTEGRITY_ALGORITHM_ID_N_ITEMS; it++) { boost::trim_left(*it); @@ -190,87 +253,23 @@ bool enb::init(all_args_t *args_) rrc_cfg.eia_preference_list[i] = srslte::INTEGRITY_ALGORITHM_ID_128_EIA2; i++; } else { - fprintf(stderr, "Failed to parse EIA prefence list %s \n", - args->expert.eia_pref_list.c_str()); - return false; + fprintf(stderr, "Failed to parse EIA prefence list %s \n", args.expert.eia_pref_list.c_str()); + return SRSLTE_ERROR; } } // Copy cell struct to rrc and phy - memcpy(&rrc_cfg.cell, &cell_cfg, sizeof(srslte_cell_t)); - memcpy(&phy_cfg.cell, &cell_cfg, sizeof(srslte_cell_t)); - - // Init layers - - /* Start Radio */ - char* dev_name = nullptr; - if (args->rf.device_name != "auto") { - dev_name = (char*) args->rf.device_name.c_str(); - } - - char* dev_args = nullptr; - if (args->rf.device_args != "auto") { - dev_args = (char*) args->rf.device_args.c_str(); - } - - if (!radio.init(phy_log[0], dev_args, dev_name, args->enb.nof_ports)) { - phy_log[0]->console( - "Failed to find device %s with args %s\n", args->rf.device_name.c_str(), args->rf.device_args.c_str()); - return false; - } - - // Set RF options - if (args->rf.time_adv_nsamples != "auto") { - radio.set_tx_adv((int)strtol(args->rf.time_adv_nsamples.c_str(), nullptr, 10)); - } - if (args->rf.burst_preamble != "auto") { - radio.set_burst_preamble(strtof(args->rf.burst_preamble.c_str(), nullptr)); - } - - radio.set_rx_gain(args->rf.rx_gain); - radio.set_tx_gain(args->rf.tx_gain); - ((srslte::log_filter*) phy_log[0])->console("Setting frequency: DL=%.1f Mhz, UL=%.1f MHz\n", args->rf.dl_freq/1e6, args->rf.ul_freq/1e6); - - radio.set_tx_freq(args->enb.nof_ports, args->rf.dl_freq); - radio.set_rx_freq(args->enb.nof_ports, args->rf.ul_freq); - - radio.register_error_handler(rf_msg); - - // Setup Stack Args - enb_stack_lte::args_t stack_args; - stack_args.enb = args->enb; - stack_args.expert.mac = args->expert.mac; - stack_args.expert.enable_mbsfn = args->expert.enable_mbsfn; - stack_args.expert.m1u_if_addr = args->expert.m1u_if_addr; - stack_args.expert.m1u_multiaddr = args->expert.m1u_multiaddr; - stack_args.log = args->log; - stack_args.pcap = args->pcap; - - // Init all layers - std::unique_ptr lte_stack(new enb_stack_lte()); - phy.init(&args->expert.phy, &phy_cfg, &radio, lte_stack.get(), phy_log); - if (lte_stack->init(stack_args, rrc_cfg, logger, &phy) != SRSLTE_SUCCESS) { - return false; - } - stack = std::move(lte_stack); + rrc_cfg.cell = cell_cfg; + phy_cfg.cell = cell_cfg; - started = true; - return true; -} + // Patch certain args that are not exposed yet + args.rf.nof_radios = args.rf.nof_rf_channels = args.rf.nof_rx_ant = 1; -void enb::stop() -{ - if(started) - { - phy.stop(); - stack->stop(); - radio.stop(); - started = false; - } + return SRSLTE_SUCCESS; } void enb::start_plot() { - phy.start_plot(); + phy->start_plot(); } void enb::print_pool() { @@ -279,46 +278,13 @@ void enb::print_pool() { bool enb::get_metrics(enb_metrics_t* m) { - m->rf = rf_metrics; - bzero(&rf_metrics, sizeof(rf_metrics_t)); - rf_metrics.rf_error = false; // Reset error flag - - phy.get_metrics(m->phy); + radio->get_metrics(&m->rf); + phy->get_metrics(m->phy); stack->get_metrics(&m->stack); - m->running = started; return true; } -void enb::rf_msg(srslte_rf_error_t error) -{ - enb *u = enb::get_instance(); - u->handle_rf_msg(error); -} - -void enb::handle_rf_msg(srslte_rf_error_t error) -{ - if(error.type == srslte_rf_error_t::SRSLTE_RF_ERROR_OVERFLOW) { - rf_metrics.rf_o++; - rf_metrics.rf_error = true; - rf_log.warning("Overflow\n"); - }else if(error.type == srslte_rf_error_t::SRSLTE_RF_ERROR_UNDERFLOW) { - rf_metrics.rf_u++; - rf_metrics.rf_error = true; - rf_log.warning("Underflow\n"); - } else if(error.type == srslte_rf_error_t::SRSLTE_RF_ERROR_LATE) { - rf_metrics.rf_l++; - rf_metrics.rf_error = true; - rf_log.warning("Late\n"); - } else if (error.type == srslte_rf_error_t::SRSLTE_RF_ERROR_OTHER) { - std::string str(error.msg); - str.erase(std::remove(str.begin(), str.end(), '\n'), str.end()); - str.erase(std::remove(str.begin(), str.end(), '\r'), str.end()); - str.push_back('\n'); - rf_log.info("%s\n", str.c_str()); - } -} - srslte::LOG_LEVEL_ENUM enb::level(std::string l) { boost::to_upper(l); diff --git a/srsenb/src/enb_cfg_parser.cc b/srsenb/src/enb_cfg_parser.cc index b41556f00..458bbfdcd 100644 --- a/srsenb/src/enb_cfg_parser.cc +++ b/srsenb/src/enb_cfg_parser.cc @@ -19,10 +19,10 @@ * */ +#include "enb_cfg_parser.h" #include "srsenb/hdr/cfg_parser.h" +#include "srslte/phy/common/phy_common.h" #include "srslte/srslte.h" - -#include "enb_cfg_parser.h" #include "srslte/asn1/rrc_asn1_utils.h" using namespace asn1::rrc; @@ -31,10 +31,11 @@ namespace srsenb { int enb::parse_cell_cfg(all_args_t* args, srslte_cell_t* cell) { - cell->id = args->enb.pci; - cell->cp = SRSLTE_CP_NORM; - cell->nof_ports = args->enb.nof_ports; - cell->nof_prb = args->enb.n_prb; + cell->frame_type = SRSLTE_FDD; + cell->id = args->enb.pci; + cell->cp = SRSLTE_CP_NORM; + cell->nof_ports = args->enb.nof_ports; + cell->nof_prb = args->enb.n_prb; phich_cfg_s phichcfg; @@ -49,7 +50,7 @@ int enb::parse_cell_cfg(all_args_t* args, srslte_cell_t* cell) cell->phich_resources = (srslte_phich_r_t)(int)phichcfg.phich_res; if (!srslte_cell_isvalid(cell)) { - fprintf(stderr, "Invalid cell parameters: nof_prb=%d, cell_id=%d\n", args->enb.n_prb, args->enb.s1ap.cell_id); + fprintf(stderr, "Invalid cell parameters: nof_prb=%d, cell_id=%d\n", args->enb.n_prb, args->stack.s1ap.cell_id); return -1; } @@ -622,17 +623,17 @@ int enb::parse_sibs(all_args_t* args, rrc_cfg_t* rrc_cfg, phy_cfg_t* phy_config_ // Fill rest of data from enb config sib_type1_s::cell_access_related_info_s_* cell_access = &sib1->cell_access_related_info; - cell_access->cell_id.from_number((args->enb.s1ap.enb_id << 8u) + args->enb.s1ap.cell_id); - cell_access->tac.from_number(args->enb.s1ap.tac); - sib1->freq_band_ind = (uint8_t)srslte_band_get_band(args->rf.dl_earfcn); + cell_access->cell_id.from_number((args->stack.s1ap.enb_id << 8u) + args->stack.s1ap.cell_id); + cell_access->tac.from_number(args->stack.s1ap.tac); + sib1->freq_band_ind = (uint8_t)srslte_band_get_band(args->enb.dl_earfcn); std::string mnc_str; - if (not srslte::mnc_to_string(args->enb.s1ap.mnc, &mnc_str)) { - ERROR("The provided mnc=%d is not valid", args->enb.s1ap.mnc); + if (not srslte::mnc_to_string(args->stack.s1ap.mnc, &mnc_str)) { + ERROR("The provided mnc=%d is not valid", args->stack.s1ap.mnc); return -1; } std::string mcc_str; - if (not srslte::mcc_to_string(args->enb.s1ap.mcc, &mcc_str)) { - ERROR("The provided mnc=%d is not valid", args->enb.s1ap.mcc); + if (not srslte::mcc_to_string(args->stack.s1ap.mcc, &mcc_str)) { + ERROR("The provided mnc=%d is not valid", args->stack.s1ap.mcc); return -1; } cell_access->plmn_id_list.resize(1); @@ -656,7 +657,7 @@ int enb::parse_sibs(all_args_t* args, rrc_cfg_t* rrc_cfg, phy_cfg_t* phy_config_ asn1::number_to_enum(sib2->freq_info.ul_bw, args->enb.n_prb); } if (sib2->freq_info.ul_carrier_freq_present) { - sib2->freq_info.ul_carrier_freq = (uint16_t)args->rf.ul_earfcn; + sib2->freq_info.ul_carrier_freq = (uint16_t)args->enb.ul_earfcn; } // Update MBSFN list counter. Only 1 supported diff --git a/srsenb/src/main.cc b/srsenb/src/main.cc index 78b0b8df8..4f20fb8f5 100644 --- a/srsenb/src/main.cc +++ b/srsenb/src/main.cc @@ -67,14 +67,14 @@ void parse_args(all_args_t *args, int argc, char* argv[]) { common.add_options() ("enb.enb_id", bpo::value(&enb_id)->default_value("0x0"), "eNodeB ID") - ("enb.name", bpo::value(&args->enb.s1ap.enb_name)->default_value("srsenb01"), "eNodeB Name") + ("enb.name", bpo::value(&args->stack.s1ap.enb_name)->default_value("srsenb01"), "eNodeB Name") ("enb.cell_id", bpo::value(&cell_id)->default_value("0x0"), "Cell ID") ("enb.tac", bpo::value(&tac)->default_value("0x0"), "Tracking Area Code") ("enb.mcc", bpo::value(&mcc)->default_value("001"), "Mobile Country Code") ("enb.mnc", bpo::value(&mnc)->default_value("01"), "Mobile Network Code") - ("enb.mme_addr", bpo::value(&args->enb.s1ap.mme_addr)->default_value("127.0.0.1"),"IP address of MME for S1 connection") - ("enb.gtp_bind_addr", bpo::value(&args->enb.s1ap.gtp_bind_addr)->default_value("192.168.3.1"), "Local IP address to bind for GTP connection") - ("enb.s1c_bind_addr", bpo::value(&args->enb.s1ap.s1c_bind_addr)->default_value("192.168.3.1"), "Local IP address to bind for S1AP connection") + ("enb.mme_addr", bpo::value(&args->stack.s1ap.mme_addr)->default_value("127.0.0.1"),"IP address of MME for S1 connection") + ("enb.gtp_bind_addr", bpo::value(&args->stack.s1ap.gtp_bind_addr)->default_value("192.168.3.1"), "Local IP address to bind for GTP connection") + ("enb.s1c_bind_addr", bpo::value(&args->stack.s1ap.s1c_bind_addr)->default_value("192.168.3.1"), "Local IP address to bind for S1AP connection") ("enb.phy_cell_id", bpo::value(&args->enb.pci)->default_value(0), "Physical Cell Identity (PCI)") ("enb.n_prb", bpo::value(&args->enb.n_prb)->default_value(25), "Number of PRB") ("enb.nof_ports", bpo::value(&args->enb.nof_ports)->default_value(1), "Number of ports") @@ -85,15 +85,15 @@ void parse_args(all_args_t *args, int argc, char* argv[]) { ("enb_files.rr_config", bpo::value(&args->enb_files.rr_config)->default_value("rr.conf"), "RR configuration files") ("enb_files.drb_config", bpo::value(&args->enb_files.drb_config)->default_value("drb.conf"), "DRB configuration files") - ("rf.dl_earfcn", bpo::value(&args->rf.dl_earfcn)->default_value(3400), "Downlink EARFCN") - ("rf.ul_earfcn", bpo::value(&args->rf.ul_earfcn)->default_value(0), "Uplink EARFCN (Default based on Downlink EARFCN)") + ("rf.dl_earfcn", bpo::value(&args->enb.dl_earfcn)->default_value(3400), "Downlink EARFCN") + ("rf.ul_earfcn", bpo::value(&args->enb.ul_earfcn)->default_value(0), "Uplink EARFCN (Default based on Downlink EARFCN)") ("rf.rx_gain", bpo::value(&args->rf.rx_gain)->default_value(50), "Front-end receiver gain") ("rf.tx_gain", bpo::value(&args->rf.tx_gain)->default_value(70), "Front-end transmitter gain") ("rf.dl_freq", bpo::value(&args->rf.dl_freq)->default_value(-1), "Downlink Frequency (if positive overrides EARFCN)") ("rf.ul_freq", bpo::value(&args->rf.ul_freq)->default_value(-1), "Uplink Frequency (if positive overrides EARFCN)") ("rf.device_name", bpo::value(&args->rf.device_name)->default_value("auto"), "Front-end device name") - ("rf.device_args", bpo::value(&args->rf.device_args)->default_value("auto"), "Front-end device arguments") + ("rf.device_args", bpo::value(&args->rf.device_args[0])->default_value("auto"), "Front-end device arguments") ("rf.time_adv_nsamples", bpo::value(&args->rf.time_adv_nsamples)->default_value("auto"), "Transmission time advance") ("rf.burst_preamble_us", bpo::value(&args->rf.burst_preamble)->default_value("auto"), "Transmission time advance") @@ -105,18 +105,18 @@ void parse_args(all_args_t *args, int argc, char* argv[]) { ("log.phy_level", bpo::value(&args->log.phy_level), "PHY log level") ("log.phy_hex_limit", bpo::value(&args->log.phy_hex_limit), "PHY log hex dump limit") ("log.phy_lib_level", bpo::value(&args->log.phy_lib_level)->default_value("none"), "PHY lib log level") - ("log.mac_level", bpo::value(&args->log.mac_level), "MAC log level") - ("log.mac_hex_limit", bpo::value(&args->log.mac_hex_limit), "MAC log hex dump limit") - ("log.rlc_level", bpo::value(&args->log.rlc_level), "RLC log level") - ("log.rlc_hex_limit", bpo::value(&args->log.rlc_hex_limit), "RLC log hex dump limit") - ("log.pdcp_level", bpo::value(&args->log.pdcp_level), "PDCP log level") - ("log.pdcp_hex_limit",bpo::value(&args->log.pdcp_hex_limit), "PDCP log hex dump limit") - ("log.rrc_level", bpo::value(&args->log.rrc_level), "RRC log level") - ("log.rrc_hex_limit", bpo::value(&args->log.rrc_hex_limit), "RRC log hex dump limit") - ("log.gtpu_level", bpo::value(&args->log.gtpu_level), "GTPU log level") - ("log.gtpu_hex_limit",bpo::value(&args->log.gtpu_hex_limit), "GTPU log hex dump limit") - ("log.s1ap_level", bpo::value(&args->log.s1ap_level), "S1AP log level") - ("log.s1ap_hex_limit",bpo::value(&args->log.s1ap_hex_limit), "S1AP log hex dump limit") + ("log.mac_level", bpo::value(&args->stack.log.mac_level), "MAC log level") + ("log.mac_hex_limit", bpo::value(&args->stack.log.mac_hex_limit), "MAC log hex dump limit") + ("log.rlc_level", bpo::value(&args->stack.log.rlc_level), "RLC log level") + ("log.rlc_hex_limit", bpo::value(&args->stack.log.rlc_hex_limit), "RLC log hex dump limit") + ("log.pdcp_level", bpo::value(&args->stack.log.pdcp_level), "PDCP log level") + ("log.pdcp_hex_limit",bpo::value(&args->stack.log.pdcp_hex_limit), "PDCP log hex dump limit") + ("log.rrc_level", bpo::value(&args->stack.log.rrc_level), "RRC log level") + ("log.rrc_hex_limit", bpo::value(&args->stack.log.rrc_hex_limit), "RRC log hex dump limit") + ("log.gtpu_level", bpo::value(&args->stack.log.gtpu_level), "GTPU log level") + ("log.gtpu_hex_limit",bpo::value(&args->stack.log.gtpu_hex_limit), "GTPU log hex dump limit") + ("log.s1ap_level", bpo::value(&args->stack.log.s1ap_level), "S1AP log level") + ("log.s1ap_hex_limit",bpo::value(&args->stack.log.s1ap_hex_limit), "S1AP log hex dump limit") ("log.all_level", bpo::value(&args->log.all_level)->default_value("info"), "ALL log level") ("log.all_hex_limit", bpo::value(&args->log.all_hex_limit)->default_value(32), "ALL log hex dump limit") @@ -125,11 +125,11 @@ void parse_args(all_args_t *args, int argc, char* argv[]) { ("log.file_max_size", bpo::value(&args->log.file_max_size)->default_value(-1), "Maximum file size (in kilobytes). When passed, multiple files are created. Default -1 (single file)") /* MCS section */ - ("scheduler.pdsch_mcs", bpo::value(&args->expert.mac.sched.pdsch_mcs)->default_value(-1), "Optional fixed PDSCH MCS (ignores reported CQIs if specified)") - ("scheduler.pdsch_max_mcs", bpo::value(&args->expert.mac.sched.pdsch_max_mcs)->default_value(-1), "Optional PDSCH MCS limit") - ("scheduler.pusch_mcs", bpo::value(&args->expert.mac.sched.pusch_mcs)->default_value(-1), "Optional fixed PUSCH MCS (ignores reported CQIs if specified)") - ("scheduler.pusch_max_mcs", bpo::value(&args->expert.mac.sched.pusch_max_mcs)->default_value(-1), "Optional PUSCH MCS limit") - ("scheduler.nof_ctrl_symbols", bpo::value(&args->expert.mac.sched.nof_ctrl_symbols)->default_value(3), "Number of control symbols") + ("scheduler.pdsch_mcs", bpo::value(&args->stack.mac.sched.pdsch_mcs)->default_value(-1), "Optional fixed PDSCH MCS (ignores reported CQIs if specified)") + ("scheduler.pdsch_max_mcs", bpo::value(&args->stack.mac.sched.pdsch_max_mcs)->default_value(-1), "Optional PDSCH MCS limit") + ("scheduler.pusch_mcs", bpo::value(&args->stack.mac.sched.pusch_mcs)->default_value(-1), "Optional fixed PUSCH MCS (ignores reported CQIs if specified)") + ("scheduler.pusch_max_mcs", bpo::value(&args->stack.mac.sched.pusch_max_mcs)->default_value(-1), "Optional PUSCH MCS limit") + ("scheduler.nof_ctrl_symbols", bpo::value(&args->stack.mac.sched.nof_ctrl_symbols)->default_value(3), "Number of control symbols") /* Expert section */ ("expert.metrics_period_secs", bpo::value(&args->expert.metrics_period_secs)->default_value(1.0), "Periodicity for metrics in seconds") @@ -140,7 +140,7 @@ void parse_args(all_args_t *args, int argc, char* argv[]) { ("expert.pusch_8bit_decoder", bpo::value(&args->expert.phy.pusch_8bit_decoder)->default_value(false), "Use 8-bit for LLR representation and turbo decoder trellis computation (Experimental)") ("expert.tx_amplitude", bpo::value(&args->expert.phy.tx_amplitude)->default_value(0.6), "Transmit amplitude factor") ("expert.nof_phy_threads", bpo::value(&args->expert.phy.nof_phy_threads)->default_value(3), "Number of PHY threads") - ("expert.link_failure_nof_err", bpo::value(&args->expert.mac.link_failure_nof_err)->default_value(100), "Number of PUSCH failures after which a radio-link failure is triggered") + ("expert.link_failure_nof_err", bpo::value(&args->stack.mac.link_failure_nof_err)->default_value(100), "Number of PUSCH failures after which a radio-link failure is triggered") ("expert.max_prach_offset_us", bpo::value(&args->expert.phy.max_prach_offset_us)->default_value(30), "Maximum allowed RACH offset (in us)") ("expert.equalizer_mode", bpo::value(&args->expert.phy.equalizer_mode)->default_value("mmse"), "Equalizer mode") ("expert.estimator_fil_w", bpo::value(&args->expert.phy.estimator_fil_w)->default_value(0.1), "Chooses the coefficients for the 3-tap channel estimator centered filter.") @@ -220,53 +220,53 @@ void parse_args(all_args_t *args, int argc, char* argv[]) { { std::stringstream sstr; sstr << std::hex << vm["enb.enb_id"].as(); - sstr >> args->enb.s1ap.enb_id; + sstr >> args->stack.s1ap.enb_id; } { std::stringstream sstr; sstr << std::hex << vm["enb.cell_id"].as(); uint16_t tmp; // Need intermediate uint16_t as uint8_t is treated as char sstr >> tmp; - args->enb.s1ap.cell_id = tmp; + args->stack.s1ap.cell_id = tmp; } { std::stringstream sstr; sstr << std::hex << vm["enb.tac"].as(); - sstr >> args->enb.s1ap.tac; + sstr >> args->stack.s1ap.tac; } // Convert MCC/MNC strings - if(!srslte::string_to_mcc(mcc, &args->enb.s1ap.mcc)) { + if (!srslte::string_to_mcc(mcc, &args->stack.s1ap.mcc)) { cout << "Error parsing enb.mcc:" << mcc << " - must be a 3-digit string." << endl; } - if(!srslte::string_to_mnc(mnc, &args->enb.s1ap.mnc)) { + if (!srslte::string_to_mnc(mnc, &args->stack.s1ap.mnc)) { cout << "Error parsing enb.mnc:" << mnc << " - must be a 2 or 3-digit string." << endl; } // Convert UL/DL EARFCN to frequency if needed if (args->rf.dl_freq < 0) { - args->rf.dl_freq = 1e6 * srslte_band_fd(args->rf.dl_earfcn); + args->rf.dl_freq = 1e6 * srslte_band_fd(args->enb.dl_earfcn); if (args->rf.dl_freq < 0) { - fprintf(stderr, "Error getting DL frequency for EARFCN=%d\n", args->rf.dl_earfcn); + fprintf(stderr, "Error getting DL frequency for EARFCN=%d\n", args->enb.dl_earfcn); exit(1); } } if (args->rf.ul_freq < 0) { - if (args->rf.ul_earfcn == 0) { - args->rf.ul_earfcn = srslte_band_ul_earfcn(args->rf.dl_earfcn); + if (args->enb.ul_earfcn == 0) { + args->enb.ul_earfcn = srslte_band_ul_earfcn(args->enb.dl_earfcn); } - args->rf.ul_freq = 1e6 * srslte_band_fu(args->rf.ul_earfcn); + args->rf.ul_freq = 1e6 * srslte_band_fu(args->enb.ul_earfcn); if (args->rf.ul_freq < 0) { - fprintf(stderr, "Error getting UL frequency for EARFCN=%d\n", args->rf.dl_earfcn); + fprintf(stderr, "Error getting UL frequency for EARFCN=%d\n", args->enb.dl_earfcn); exit(1); } } if (args->expert.enable_mbsfn) { - if (args->expert.mac.sched.nof_ctrl_symbols == 3) { + if (args->stack.mac.sched.nof_ctrl_symbols == 3) { fprintf(stderr, "nof_ctrl_symbols = %d, While using MBMS, please set number of control symbols to either 1 or 2, " "depending on the length of the non-mbsfn region\n", - args->expert.mac.sched.nof_ctrl_symbols); + args->stack.mac.sched.nof_ctrl_symbols); exit(1); } } @@ -280,22 +280,22 @@ void parse_args(all_args_t *args, int argc, char* argv[]) { args->log.phy_lib_level = args->log.all_level; } if(!vm.count("log.mac_level")) { - args->log.mac_level = args->log.all_level; + args->stack.log.mac_level = args->log.all_level; } if(!vm.count("log.rlc_level")) { - args->log.rlc_level = args->log.all_level; + args->stack.log.rlc_level = args->log.all_level; } if(!vm.count("log.pdcp_level")) { - args->log.pdcp_level = args->log.all_level; + args->stack.log.pdcp_level = args->log.all_level; } if(!vm.count("log.rrc_level")) { - args->log.rrc_level = args->log.all_level; + args->stack.log.rrc_level = args->log.all_level; } if(!vm.count("log.gtpu_level")) { - args->log.gtpu_level = args->log.all_level; + args->stack.log.gtpu_level = args->log.all_level; } if(!vm.count("log.s1ap_level")) { - args->log.s1ap_level = args->log.all_level; + args->stack.log.s1ap_level = args->log.all_level; } } @@ -305,22 +305,22 @@ void parse_args(all_args_t *args, int argc, char* argv[]) { args->log.phy_hex_limit = args->log.all_hex_limit; } if(!vm.count("log.mac_hex_limit")) { - args->log.mac_hex_limit = args->log.all_hex_limit; + args->stack.log.mac_hex_limit = args->log.all_hex_limit; } if(!vm.count("log.rlc_hex_limit")) { - args->log.rlc_hex_limit = args->log.all_hex_limit; + args->stack.log.rlc_hex_limit = args->log.all_hex_limit; } if(!vm.count("log.pdcp_hex_limit")) { - args->log.pdcp_hex_limit = args->log.all_hex_limit; + args->stack.log.pdcp_hex_limit = args->log.all_hex_limit; } if(!vm.count("log.rrc_hex_limit")) { - args->log.rrc_hex_limit = args->log.all_hex_limit; + args->stack.log.rrc_hex_limit = args->log.all_hex_limit; } if(!vm.count("log.gtpu_hex_limit")) { - args->log.gtpu_hex_limit = args->log.all_hex_limit; + args->stack.log.gtpu_hex_limit = args->log.all_hex_limit; } if(!vm.count("log.s1ap_hex_limit")) { - args->log.s1ap_hex_limit = args->log.all_hex_limit; + args->stack.log.s1ap_hex_limit = args->log.all_hex_limit; } } @@ -383,7 +383,7 @@ int main(int argc, char *argv[]) { signal(SIGINT, sig_int_handler); signal(SIGTERM, sig_int_handler); - all_args_t args; + all_args_t args = {}; srslte::metrics_hub metricshub; metrics_stdout metrics_screen; @@ -394,8 +394,9 @@ int main(int argc, char *argv[]) cout << "--- Software Radio Systems LTE eNodeB ---" << endl << endl; parse_args(&args, argc, argv); - if(!enb->init(&args)) { - exit(1); + if (enb->init(args)) { + enb->stop(); + return SRSLTE_ERROR; } metricshub.init(enb, args.expert.metrics_period_secs); @@ -412,12 +413,10 @@ int main(int argc, char *argv[]) pthread_t input; pthread_create(&input, NULL, &input_loop, &metrics_screen); - bool plot_started = false; - bool signals_pregenerated = false; - if(running) { - if (!plot_started && args.gui.enable) { + bool signals_pregenerated = false; + if (running) { + if (args.gui.enable) { enb->start_plot(); - plot_started = true; } } int cnt=0; @@ -436,5 +435,6 @@ int main(int argc, char *argv[]) enb->stop(); enb->cleanup(); cout << "--- exiting ---" << endl; - exit(0); + + return SRSLTE_SUCCESS; } diff --git a/srsenb/src/phy/phy.cc b/srsenb/src/phy/phy.cc index 8e11b223d..df7a3dea1 100644 --- a/srsenb/src/phy/phy.cc +++ b/srsenb/src/phy/phy.cc @@ -41,121 +41,137 @@ using namespace asn1::rrc; namespace srsenb { -phy::phy() : workers_pool(MAX_WORKERS), - workers(MAX_WORKERS), - workers_common(MAX_WORKERS), - nof_workers(0) +phy::phy(srslte::logger* logger_) : + logger(logger_), + workers_pool(MAX_WORKERS), + workers(MAX_WORKERS), + workers_common(MAX_WORKERS), + nof_workers(0) { - radio_handler = NULL; - bzero(&prach_cfg, sizeof(prach_cfg)); } -void phy::parse_config(phy_cfg_t* cfg) +phy::~phy() +{ + stop(); +} + +void phy::parse_config(const phy_cfg_t& cfg) { - // PRACH configuration ZERO_OBJECT(prach_cfg); - prach_cfg.config_idx = cfg->prach_cnfg.prach_cfg_info.prach_cfg_idx; - prach_cfg.hs_flag = cfg->prach_cnfg.prach_cfg_info.high_speed_flag; - prach_cfg.root_seq_idx = cfg->prach_cnfg.root_seq_idx; - prach_cfg.zero_corr_zone = cfg->prach_cnfg.prach_cfg_info.zero_correlation_zone_cfg; - prach_cfg.freq_offset = cfg->prach_cnfg.prach_cfg_info.prach_freq_offset; + prach_cfg.config_idx = cfg.prach_cnfg.prach_cfg_info.prach_cfg_idx; + prach_cfg.hs_flag = cfg.prach_cnfg.prach_cfg_info.high_speed_flag; + prach_cfg.root_seq_idx = cfg.prach_cnfg.root_seq_idx; + prach_cfg.zero_corr_zone = cfg.prach_cnfg.prach_cfg_info.zero_correlation_zone_cfg; + prach_cfg.freq_offset = cfg.prach_cnfg.prach_cfg_info.prach_freq_offset; // Uplink Physical common configuration ZERO_OBJECT(workers_common.ul_cfg_com); // DMRS - workers_common.ul_cfg_com.dmrs.cyclic_shift = cfg->pusch_cnfg.ul_ref_sigs_pusch.cyclic_shift; - workers_common.ul_cfg_com.dmrs.delta_ss = cfg->pusch_cnfg.ul_ref_sigs_pusch.group_assign_pusch; - workers_common.ul_cfg_com.dmrs.group_hopping_en = cfg->pusch_cnfg.ul_ref_sigs_pusch.group_hop_enabled; - workers_common.ul_cfg_com.dmrs.sequence_hopping_en = cfg->pusch_cnfg.ul_ref_sigs_pusch.seq_hop_enabled; + workers_common.ul_cfg_com.dmrs.cyclic_shift = cfg.pusch_cnfg.ul_ref_sigs_pusch.cyclic_shift; + workers_common.ul_cfg_com.dmrs.delta_ss = cfg.pusch_cnfg.ul_ref_sigs_pusch.group_assign_pusch; + workers_common.ul_cfg_com.dmrs.group_hopping_en = cfg.pusch_cnfg.ul_ref_sigs_pusch.group_hop_enabled; + workers_common.ul_cfg_com.dmrs.sequence_hopping_en = cfg.pusch_cnfg.ul_ref_sigs_pusch.seq_hop_enabled; // Hopping workers_common.ul_cfg_com.hopping.hop_mode = - cfg->pusch_cnfg.pusch_cfg_basic.hop_mode == + cfg.pusch_cnfg.pusch_cfg_basic.hop_mode == asn1::rrc::pusch_cfg_common_s::pusch_cfg_basic_s_::hop_mode_e_::intra_and_inter_sub_frame ? srslte_pusch_hopping_cfg_t::SRSLTE_PUSCH_HOP_MODE_INTRA_SF : srslte_pusch_hopping_cfg_t::SRSLTE_PUSCH_HOP_MODE_INTER_SF; ; - workers_common.ul_cfg_com.hopping.n_sb = cfg->pusch_cnfg.pusch_cfg_basic.n_sb; - workers_common.ul_cfg_com.hopping.hopping_offset = cfg->pusch_cnfg.pusch_cfg_basic.pusch_hop_offset; + workers_common.ul_cfg_com.hopping.n_sb = cfg.pusch_cnfg.pusch_cfg_basic.n_sb; + workers_common.ul_cfg_com.hopping.hopping_offset = cfg.pusch_cnfg.pusch_cfg_basic.pusch_hop_offset; workers_common.ul_cfg_com.pusch.max_nof_iterations = workers_common.params.pusch_max_its; workers_common.ul_cfg_com.pusch.csi_enable = false; workers_common.ul_cfg_com.pusch.meas_time_en = true; // PUCCH - workers_common.ul_cfg_com.pucch.delta_pucch_shift = cfg->pucch_cnfg.delta_pucch_shift.to_number(); - workers_common.ul_cfg_com.pucch.N_cs = cfg->pucch_cnfg.n_cs_an; - workers_common.ul_cfg_com.pucch.n_rb_2 = cfg->pucch_cnfg.n_rb_cqi; - workers_common.ul_cfg_com.pucch.N_pucch_1 = cfg->pucch_cnfg.n1_pucch_an; + workers_common.ul_cfg_com.pucch.delta_pucch_shift = cfg.pucch_cnfg.delta_pucch_shift.to_number(); + workers_common.ul_cfg_com.pucch.N_cs = cfg.pucch_cnfg.n_cs_an; + workers_common.ul_cfg_com.pucch.n_rb_2 = cfg.pucch_cnfg.n_rb_cqi; + workers_common.ul_cfg_com.pucch.N_pucch_1 = cfg.pucch_cnfg.n1_pucch_an; workers_common.ul_cfg_com.pucch.threshold_format1 = 0.8; // PDSCH configuration ZERO_OBJECT(workers_common.dl_cfg_com); workers_common.dl_cfg_com.tm = SRSLTE_TM1; - workers_common.dl_cfg_com.pdsch.rs_power = cfg->pdsch_cnfg.ref_sig_pwr; - workers_common.dl_cfg_com.pdsch.p_b = cfg->pdsch_cnfg.p_b; + workers_common.dl_cfg_com.pdsch.rs_power = cfg.pdsch_cnfg.ref_sig_pwr; + workers_common.dl_cfg_com.pdsch.p_b = cfg.pdsch_cnfg.p_b; workers_common.dl_cfg_com.pdsch.meas_time_en = true; } -bool phy::init(phy_args_t* args, - phy_cfg_t* cfg, - srslte::radio* radio_handler_, - stack_interface_phy_lte* stack_, - srslte::log_filter* log_h) +int phy::init(const phy_args_t& args, + const phy_cfg_t& cfg, + srslte::radio_interface_phy* radio_, + stack_interface_phy_lte* stack_) { + mlockall(MCL_CURRENT | MCL_FUTURE); - std::vector log_vec; - this->log_h = log_h; - for (int i=0;inof_phy_threads;i++) { - log_vec.push_back(log_h); + // Create array of pointers to phy_logs + for (int i = 0; i < args.nof_phy_threads; i++) { + auto mylog = std::unique_ptr(new srslte::log_filter); + char tmp[16] = {}; + sprintf(tmp, "PHY%d", i); + mylog->init(tmp, logger, true); + mylog->set_level(args.log.phy_level); + mylog->set_hex_limit(args.log.phy_hex_limit); + log_vec.push_back(std::move(mylog)); } - init(args, cfg, radio_handler_, stack_, log_vec); - return true; -} -bool phy::init(phy_args_t* args, - phy_cfg_t* cfg, - srslte::radio* radio_handler_, - stack_interface_phy_lte* stack_, - std::vector log_vec) -{ + // Add PHY lib log + if (log_vec.at(0)->get_level_from_string(args.log.phy_lib_level) != srslte::LOG_LEVEL_NONE) { + auto lib_log = std::unique_ptr(new srslte::log_filter); + char tmp[16] = {}; + sprintf(tmp, "PHY_LIB"); + lib_log->init(tmp, logger, true); + lib_log->set_level(args.log.phy_lib_level); + lib_log->set_hex_limit(args.log.phy_hex_limit); + log_vec.push_back(std::move(lib_log)); + } else { + log_vec.push_back(nullptr); + } - mlockall(MCL_CURRENT | MCL_FUTURE); - - radio_handler = radio_handler_; - nof_workers = args->nof_phy_threads; - this->log_h = (srslte::log*)log_vec[0]; - workers_common.params = *args; + radio = radio_; + nof_workers = args.nof_phy_threads; - workers_common.init(&cfg->cell, radio_handler, stack_); + workers_common.params = args; + + workers_common.init(cfg.cell, radio, stack_); parse_config(cfg); // Add workers to workers pool and start threads for (uint32_t i=0;icell, &prach_cfg, stack_, (srslte::log*)log_vec[0], PRACH_WORKER_THREAD_PRIO); - prach.set_max_prach_offset_us(args->max_prach_offset_us); - + prach.init(cfg.cell, prach_cfg, stack_, log_vec.at(0).get(), PRACH_WORKER_THREAD_PRIO); + prach.set_max_prach_offset_us(args.max_prach_offset_us); + // Warning this must be initialized after all workers have been added to the pool - tx_rx.init(radio_handler, &workers_pool, &workers_common, &prach, (srslte::log*) log_vec[0], SF_RECV_THREAD_PRIO); - - return true; + tx_rx.init(radio, &workers_pool, &workers_common, &prach, log_vec.at(0).get(), SF_RECV_THREAD_PRIO); + + initialized = true; + + return SRSLTE_SUCCESS; } void phy::stop() -{ - tx_rx.stop(); - for (uint32_t i=0;iset_tti(tti); - radio->tx(buffer, nof_samples, tx_time); + // always transmit on single radio + radio->tx(0, buffer, nof_samples, tx_time); // Allow next TTI to transmit sem_post(&tx_sem[(tti+1)%nof_workers]); diff --git a/srsenb/src/phy/prach_worker.cc b/srsenb/src/phy/prach_worker.cc index f9f3b774f..3715fa298 100644 --- a/srsenb/src/phy/prach_worker.cc +++ b/srsenb/src/phy/prach_worker.cc @@ -24,16 +24,16 @@ namespace srsenb { -int prach_worker::init(srslte_cell_t* cell_, - srslte_prach_cfg_t* prach_cfg_, - stack_interface_phy_lte* stack_, - srslte::log* log_h_, - int priority) +int prach_worker::init(const srslte_cell_t& cell_, + const srslte_prach_cfg_t& prach_cfg_, + stack_interface_phy_lte* stack_, + srslte::log* log_h_, + int priority) { log_h = log_h_; stack = stack_; - memcpy(&prach_cfg, prach_cfg_, sizeof(srslte_prach_cfg_t)); - memcpy(&cell, cell_, sizeof(srslte_cell_t)); + prach_cfg = prach_cfg_; + cell = cell_; max_prach_offset_us = 50; diff --git a/srsenb/src/phy/sf_worker.cc b/srsenb/src/phy/sf_worker.cc index cbe1f5e14..45a07ce4c 100644 --- a/srsenb/src/phy/sf_worker.cc +++ b/srsenb/src/phy/sf_worker.cc @@ -19,10 +19,9 @@ * */ -#include - #include "srslte/common/log.h" #include "srslte/common/threads.h" +#include "srslte/srslte.h" #include "srsenb/hdr/phy/sf_worker.h" diff --git a/srsenb/src/phy/txrx.cc b/srsenb/src/phy/txrx.cc index dcb966365..d1cae3889 100644 --- a/srsenb/src/phy/txrx.cc +++ b/srsenb/src/phy/txrx.cc @@ -21,8 +21,9 @@ #include -#include "srslte/common/threads.h" #include "srslte/common/log.h" +#include "srslte/common/threads.h" +#include "srslte/srslte.h" #include "srsenb/hdr/phy/sf_worker.h" #include "srsenb/hdr/phy/txrx.h" @@ -47,12 +48,12 @@ txrx::txrx() : tx_worker_cnt(0), nof_workers(0), tti(0), thread("TXRX") prach = NULL; } -bool txrx::init(srslte::radio* radio_h_, - srslte::thread_pool* workers_pool_, - phy_common* worker_com_, - prach_worker* prach_, - srslte::log* log_h_, - uint32_t prio_) +bool txrx::init(srslte::radio_interface_phy* radio_h_, + srslte::thread_pool* workers_pool_, + phy_common* worker_com_, + prach_worker* prach_, + srslte::log* log_h_, + uint32_t prio_) { radio_h = radio_h_; log_h = log_h_; @@ -85,18 +86,15 @@ void txrx::run_thread() float samp_rate = srslte_sampling_freq_hz(worker_com->cell.nof_prb); log_h->console("Setting Sampling frequency %.2f MHz\n", (float) samp_rate/1000000); - // Configure radio - radio_h->set_rx_srate(samp_rate); - radio_h->set_tx_srate(samp_rate); + // Configure radio + radio_h->set_rx_srate(0, samp_rate); + radio_h->set_tx_srate(0, samp_rate); log_h->info("Starting RX/TX thread nof_prb=%d, sf_len=%d\n", worker_com->cell.nof_prb, sf_len); // Set TTI so that first TX is at tti=0 tti = 10235; - log_h->console("\n==== eNodeB started ===\n"); - log_h->console("Type to view trace\n"); - // Main loop while (running) { tti = (tti + 1) % 10240; @@ -106,7 +104,7 @@ void txrx::run_thread() buffer[p] = worker->get_buffer_rx(p); } - radio_h->rx_now(buffer, sf_len, &rx_time); + radio_h->rx_now(0, buffer, sf_len, &rx_time); /* Compute TX time: Any transmission happens in TTI+4 thus advance 4 ms the reception time */ srslte_timestamp_copy(&tx_time, &rx_time); diff --git a/srsue/src/radio/CMakeLists.txt b/srsenb/src/radio/CMakeLists.txt similarity index 81% rename from srsue/src/radio/CMakeLists.txt rename to srsenb/src/radio/CMakeLists.txt index e39e0810a..e2ad78797 100644 --- a/srsue/src/radio/CMakeLists.txt +++ b/srsenb/src/radio/CMakeLists.txt @@ -18,10 +18,6 @@ # and at http://www.gnu.org/licenses/. # -set(SOURCES ue_radio.cc) - -add_library(srsue_radio STATIC ${SOURCES}) - -target_link_libraries(srsue_radio srslte_radio) - -install(TARGETS srsue_radio DESTINATION ${LIBRARY_DIR}) +file(GLOB SOURCES "*.cc") +add_library(srsenb_radio STATIC ${SOURCES}) +install(TARGETS srsenb_radio DESTINATION ${LIBRARY_DIR}) diff --git a/srsenb/src/radio/enb_radio_multi.cc b/srsenb/src/radio/enb_radio_multi.cc new file mode 100644 index 000000000..848f7f489 --- /dev/null +++ b/srsenb/src/radio/enb_radio_multi.cc @@ -0,0 +1,48 @@ +/* + * Copyright 2013-2019 Software Radio Systems Limited + * + * This file is part of srsLTE. + * + * srsLTE is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * srsLTE is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * A copy of the GNU Affero General Public License can be found in + * the LICENSE file in the top-level directory of this distribution + * and at http://www.gnu.org/licenses/. + * + */ + +#include "srsenb/hdr/radio/enb_radio_multi.h" +#include + +namespace srsenb { + +enb_radio_multi::enb_radio_multi(srslte::logger* logger_) : radio_multi(logger_) {} + +enb_radio_multi::~enb_radio_multi() {} + +int enb_radio_multi::init(const srslte::rf_args_t& args_, srslte::phy_interface_radio* phy_) +{ + int ret = radio_multi::init(args_, phy_); + + if (ret == SRSLTE_SUCCESS) { + ret = SRSLTE_ERROR; + if (radios.size() > 0) { + log.console("Setting frequency: DL=%.1f Mhz, UL=%.1f MHz\n", args_.dl_freq / 1e6, args_.ul_freq / 1e6); + radios.at(0)->set_tx_freq(args.nof_tx_ports, args.dl_freq); + radios.at(0)->set_rx_freq(args.nof_tx_ports, args.ul_freq); + ret = SRSLTE_SUCCESS; + } + } + + return ret; +} + +} // namespace srsenb diff --git a/srsenb/src/stack/enb_stack_lte.cc b/srsenb/src/stack/enb_stack_lte.cc index 4c5d4a015..f0d2dec95 100644 --- a/srsenb/src/stack/enb_stack_lte.cc +++ b/srsenb/src/stack/enb_stack_lte.cc @@ -28,7 +28,7 @@ using namespace srslte; namespace srsenb { -enb_stack_lte::enb_stack_lte() : args(), started(false), logger(nullptr), phy(nullptr), pdcp(&pdcp_log) {} +enb_stack_lte::enb_stack_lte(srslte::logger* logger_) : logger(logger_), pdcp(&pdcp_log) {} enb_stack_lte::~enb_stack_lte() { @@ -40,23 +40,19 @@ std::string enb_stack_lte::get_type() return "lte"; } -int enb_stack_lte::init(const args_t& args_, - const rrc_cfg_t& rrc_cfg_, - srslte::logger* logger_, - phy_interface_stack_lte* phy_) +int enb_stack_lte::init(const stack_args_t& args_, const rrc_cfg_t& rrc_cfg_, phy_interface_stack_lte* phy_) { phy = phy_; - if (init(args_, rrc_cfg_, logger_)) { + if (init(args_, rrc_cfg_)) { return SRSLTE_ERROR; } return SRSLTE_SUCCESS; } -int enb_stack_lte::init(const args_t& args_, const rrc_cfg_t& rrc_cfg_, srslte::logger* logger_) +int enb_stack_lte::init(const stack_args_t& args_, const rrc_cfg_t& rrc_cfg_) { args = args_; rrc_cfg = rrc_cfg_; - logger = logger_; // setup logging for each layer mac_log.init("MAC ", logger, true); @@ -101,7 +97,7 @@ int enb_stack_lte::init(const args_t& args_, const rrc_cfg_t& rrc_cfg_, srslte:: " Consider changing \"prach_freq_offset\" in sib.conf to a value between %d and %d.\n", lower_bound, upper_bound); - return false; + return SRSLTE_ERROR; } } else { // 6 PRB case if (prach_freq_offset + 6 > cell_cfg.nof_prb) { @@ -113,18 +109,18 @@ int enb_stack_lte::init(const args_t& args_, const rrc_cfg_t& rrc_cfg_, srslte:: fprintf( stderr, " Consider changing the \"prach_freq_offset\" value to 0 in the sib.conf file when using 6 PRBs.\n"); - return false; + return SRSLTE_ERROR; } } // Init all layers - mac.init(args.expert.mac, &cell_cfg, phy, &rlc, &rrc, &mac_log); + mac.init(args.mac, &cell_cfg, phy, &rlc, &rrc, &mac_log); rlc.init(&pdcp, &rrc, &mac, &mac, &rlc_log); pdcp.init(&rlc, &rrc, >pu); rrc.init(&rrc_cfg, phy, &mac, &rlc, &pdcp, &s1ap, >pu, &rrc_log); - s1ap.init(args.enb.s1ap, &rrc, &s1ap_log); - gtpu.init(args.enb.s1ap.gtp_bind_addr, - args.enb.s1ap.mme_addr, + s1ap.init(args.s1ap, &rrc, &s1ap_log); + gtpu.init(args.s1ap.gtp_bind_addr, + args.s1ap.mme_addr, args.expert.m1u_multiaddr, args.expert.m1u_if_addr, &pdcp, @@ -132,6 +128,7 @@ int enb_stack_lte::init(const args_t& args_, const rrc_cfg_t& rrc_cfg_, srslte:: args.expert.enable_mbsfn); started = true; + return SRSLTE_SUCCESS; } diff --git a/srsenb/src/stack/mac/mac.cc b/srsenb/src/stack/mac/mac.cc index 06bf21f49..409775b80 100644 --- a/srsenb/src/stack/mac/mac.cc +++ b/srsenb/src/stack/mac/mac.cc @@ -63,7 +63,7 @@ mac::mac() : timers_db(128), timers_thread(&timers_db), tti(0), last_rnti(0), mac::~mac() { - pthread_rwlock_unlock(&rwlock); + stop(); pthread_rwlock_destroy(&rwlock); } @@ -113,18 +113,20 @@ bool mac::init(const mac_args_t& args_, void mac::stop() { pthread_rwlock_wrlock(&rwlock); - - for (uint32_t i=0;ierror("Failed to close SCTP socket\n"); } - return; } void s1ap::get_metrics(s1ap_metrics_t &m) @@ -145,6 +144,7 @@ void s1ap::run_thread() s1ap_log->info_hex(pdu->msg, pdu->N_bytes, "Received S1AP PDU"); handle_s1ap_rx_pdu(pdu.get()); } + printf("%s ended\n", __PRETTY_FUNCTION__); } // Generate common S1AP protocol IEs from config args diff --git a/srsue/hdr/phy/phy.h b/srsue/hdr/phy/phy.h index 8ab78baed..a887e037a 100644 --- a/srsue/hdr/phy/phy.h +++ b/srsue/hdr/phy/phy.h @@ -22,13 +22,14 @@ #ifndef SRSUE_PHY_H #define SRSUE_PHY_H -#include "scell/async_scell_recv.h" #include "phy_common.h" #include "phy_metrics.h" #include "prach.h" +#include "scell/async_scell_recv.h" #include "sf_worker.h" #include "srslte/common/log_filter.h" #include "srslte/common/trace.h" +#include "srslte/interfaces/common_interfaces.h" #include "srslte/interfaces/ue_interfaces.h" #include "srslte/radio/radio.h" #include "srslte/srslte.h" @@ -49,10 +50,10 @@ public: int init(const phy_args_t& args_, srslte::logger* logger_) final; // Init for LTE PHYs - int init(const phy_args_t& args_, - srslte::logger* logger_, - stack_interface_phy_lte* stack_, - radio_interface_phy* radio_) final; + int init(const phy_args_t& args_, + srslte::logger* logger_, + stack_interface_phy_lte* stack_, + srslte::radio_interface_phy* radio_) final; void stop() final; @@ -142,7 +143,7 @@ private: const static int SF_RECV_THREAD_PRIO = 1; const static int WORKERS_THREAD_PRIO = 2; - radio_interface_phy* radio = nullptr; + srslte::radio_interface_phy* radio = nullptr; std::vector > log_vec; srslte::logger* logger = nullptr; diff --git a/srsue/hdr/phy/phy_common.h b/srsue/hdr/phy/phy_common.h index 78f325493..94b3c0897 100644 --- a/srsue/hdr/phy/phy_common.h +++ b/srsue/hdr/phy/phy_common.h @@ -27,6 +27,7 @@ #include "phy_metrics.h" #include "srslte/common/gen_mch_tables.h" #include "srslte/common/log.h" +#include "srslte/interfaces/common_interfaces.h" #include "srslte/interfaces/ue_interfaces.h" #include "srslte/radio/radio.h" #include "srslte/srslte.h" @@ -94,7 +95,7 @@ public: ~phy_common(); - void init(phy_args_t* args, srslte::log* _log, radio_interface_phy* _radio, stack_interface_phy_lte* _stack); + void init(phy_args_t* args, srslte::log* _log, srslte::radio_interface_phy* _radio, stack_interface_phy_lte* _stack); uint32_t ul_pidof(uint32_t tti, srslte_tdd_config_t* tdd_config); @@ -141,7 +142,7 @@ public: bool sr_enabled; int sr_last_tx_tti; - radio_interface_phy* get_radio(); + srslte::radio_interface_phy* get_radio(); void set_cell(const srslte_cell_t& c); uint32_t get_nof_prb(); @@ -174,7 +175,7 @@ private: uint32_t max_workers; bool is_first_of_burst[SRSLTE_MAX_RADIOS]; - radio_interface_phy* radio_h; + srslte::radio_interface_phy* radio_h; float cfo; srslte::log* log_h; srslte::channel_ptr ul_channel = nullptr; diff --git a/srsue/hdr/phy/scell/async_scell_recv.h b/srsue/hdr/phy/scell/async_scell_recv.h index 3fa450f3e..9f57b1eb3 100644 --- a/srsue/hdr/phy/scell/async_scell_recv.h +++ b/srsue/hdr/phy/scell/async_scell_recv.h @@ -38,7 +38,7 @@ public: async_scell_recv(); ~async_scell_recv(); - void init(radio_interface_phy* _radio_handler, phy_common* _worker_com, srslte::log* _log_h); + void init(srslte::radio_interface_phy* _radio_handler, phy_common* _worker_com, srslte::log* _log_h); void stop(); // from chest_feedback_itf @@ -141,7 +141,7 @@ private: // Pointers to other classes srslte::log* log_h; - radio_interface_phy* radio_h; + srslte::radio_interface_phy* radio_h; phy_common* worker_com; // pthread objects diff --git a/srsue/hdr/phy/sync.h b/srsue/hdr/phy/sync.h index 67e7876b9..40be6b405 100644 --- a/srsue/hdr/phy/sync.h +++ b/srsue/hdr/phy/sync.h @@ -42,69 +42,69 @@ #include namespace srsue { - + typedef _Complex float cf_t; class sync : public thread, public chest_feedback_itf { public: - sync() : thread("SYNC") {}; + sync() : thread("SYNC"){}; ~sync(); - void init(radio_interface_phy* radio_, - stack_interface_phy_lte* _stack, - prach* prach_buffer, - srslte::thread_pool* _workers_pool, - phy_common* _worker_com, - srslte::log* _log_h, - srslte::log* _log_phy_lib_h, - scell::async_recv_vector* scell_sync_, - uint32_t prio, - int sync_cpu_affinity = -1); + void init(srslte::radio_interface_phy* radio_, + stack_interface_phy_lte* _stack, + prach* prach_buffer, + srslte::thread_pool* _workers_pool, + phy_common* _worker_com, + srslte::log* _log_h, + srslte::log* _log_phy_lib_h, + scell::async_recv_vector* scell_sync_, + uint32_t prio, + int sync_cpu_affinity = -1); void stop(); void radio_overflow(); // RRC interface for controling the SYNC state phy_interface_rrc_lte::cell_search_ret_t cell_search(phy_interface_rrc_lte::phy_cell_t* cell); bool cell_select(phy_interface_rrc_lte::phy_cell_t* cell); - bool cell_is_camping(); + bool cell_is_camping(); // RRC interface for controlling the neighbour cell measurement - void meas_reset(); - int meas_start(uint32_t earfcn, int pci); - int meas_stop(uint32_t earfcn, int pci); + void meas_reset(); + int meas_start(uint32_t earfcn, int pci); + int meas_stop(uint32_t earfcn, int pci); // from chest_feedback_itf void in_sync() final; void out_of_sync() final; void set_cfo(float cfo) final; - void set_time_adv_sec(float time_adv_sec); + void set_time_adv_sec(float time_adv_sec); void get_current_cell(srslte_cell_t* cell, uint32_t* earfcn = nullptr); uint32_t get_current_tti(); // From UE configuration - void set_agc_enable(bool enable); - void set_earfcn(std::vector earfcn); - void force_freq(float dl_freq, float ul_freq); + void set_agc_enable(bool enable); + void set_earfcn(std::vector earfcn); + void force_freq(float dl_freq, float ul_freq); // Other functions double set_rx_gain(double gain); - int radio_recv_fnc(cf_t *data[SRSLTE_MAX_PORTS], uint32_t nsamples, srslte_timestamp_t *rx_time); + int radio_recv_fnc(cf_t* data[SRSLTE_MAX_PORTS], uint32_t nsamples, srslte_timestamp_t* rx_time); private: - // Class to run cell search - class search { + class search + { public: - typedef enum {CELL_NOT_FOUND, CELL_FOUND, ERROR, TIMEOUT} ret_code; + typedef enum { CELL_NOT_FOUND, CELL_FOUND, ERROR, TIMEOUT } ret_code; ~search(); void init(cf_t* buffer[SRSLTE_MAX_PORTS], srslte::log* log_h, uint32_t nof_rx_antennas, sync* parent); void reset(); float get_last_cfo(); void set_agc_enable(bool enable); - ret_code run(srslte_cell_t *cell); + ret_code run(srslte_cell_t* cell); private: sync* p = nullptr; @@ -116,9 +116,10 @@ private: }; // Class to synchronize system frame number - class sfn_sync { + class sfn_sync + { public: - typedef enum {IDLE, SFN_FOUND, SFX0_FOUND, SFN_NOFOUND, ERROR} ret_code; + typedef enum { IDLE, SFN_FOUND, SFX0_FOUND, SFN_NOFOUND, ERROR } ret_code; sfn_sync() = default; ~sfn_sync(); void init(srslte_ue_sync_t* ue_sync, @@ -127,7 +128,7 @@ private: uint32_t nof_subframes = SFN_SYNC_NOF_SUBFRAMES); void reset(); bool set_cell(srslte_cell_t cell); - ret_code run_subframe(srslte_cell_t *cell, uint32_t *tti_cnt, bool sfidx_only = false); + ret_code run_subframe(srslte_cell_t* cell, uint32_t* tti_cnt, bool sfidx_only = false); ret_code decode_mib(srslte_cell_t* cell, uint32_t* tti_cnt, cf_t* ext_buffer[SRSLTE_MAX_PORTS], bool sfidx_only = false); @@ -148,39 +149,39 @@ private: std::vector earfcn; - void reset(); - void radio_error(); - void set_ue_sync_opts(srslte_ue_sync_t *q, float cfo); - void run_thread() final; - float get_tx_cfo(); + void reset(); + void radio_error(); + void set_ue_sync_opts(srslte_ue_sync_t* q, float cfo); + void run_thread() final; + float get_tx_cfo(); - void set_sampling_rate(); - bool set_frequency(); - bool set_cell(); + void set_sampling_rate(); + bool set_frequency(); + bool set_cell(); bool radio_is_overflow = false; bool radio_overflow_return = false; bool running = false; // Objects for internal use - search search_p; - sfn_sync sfn_p; - scell::intra_measure intra_freq_meas; + search search_p; + sfn_sync sfn_p; + scell::intra_measure intra_freq_meas; uint32_t current_sflen = 0; int next_offset = 0; // Sample offset triggered by Time aligment commands int next_radio_offset[SRSLTE_MAX_RADIOS] = {}; // Sample offset triggered by SFO compensation // Pointers to other classes - stack_interface_phy_lte* stack = nullptr; - srslte::log* log_h = nullptr; - srslte::log* log_phy_lib_h = nullptr; - srslte::thread_pool* workers_pool = nullptr; - radio_interface_phy* radio_h = nullptr; - phy_common* worker_com = nullptr; - prach* prach_buffer = nullptr; - scell::async_recv_vector* scell_sync = nullptr; - srslte::channel_ptr channel_emulator = nullptr; + stack_interface_phy_lte* stack = nullptr; + srslte::log* log_h = nullptr; + srslte::log* log_phy_lib_h = nullptr; + srslte::thread_pool* workers_pool = nullptr; + srslte::radio_interface_phy* radio_h = nullptr; + phy_common* worker_com = nullptr; + prach* prach_buffer = nullptr; + scell::async_recv_vector* scell_sync = nullptr; + srslte::channel_ptr channel_emulator = nullptr; // Object for synchronization of the primary cell srslte_ue_sync_t ue_sync = {}; @@ -199,8 +200,9 @@ private: const static uint32_t NOF_IN_SYNC_SF = 10; // State machine for SYNC thread - class sync_state { - public: + class sync_state + { + public: typedef enum { IDLE = 0, CELL_SEARCH, @@ -211,7 +213,8 @@ private: /* Run_state is called by the main thread at the start of each loop. It updates the state * and returns the current state */ - state_t run_state() { + state_t run_state() + { std::lock_guard lg(inside); cur_state = next_state; if (state_setting) { @@ -223,7 +226,8 @@ private: } // Called by the main thread at the end of each state to indicate it has finished. - void state_exit(bool exit_ok = true) { + void state_exit(bool exit_ok = true) + { std::lock_guard lg(inside); if (cur_state == SFN_SYNC && exit_ok == true) { next_state = CAMPING; @@ -233,7 +237,8 @@ private: state_running = false; cvar.notify_all(); } - void force_sfn_sync() { + void force_sfn_sync() + { std::lock_guard lg(inside); next_state = SFN_SYNC; } @@ -243,34 +248,33 @@ private: * * These functions are mutexed and only 1 can be called at a time */ - void go_idle() { + void go_idle() + { std::lock_guard lg(outside); go_state(IDLE); } - void run_cell_search() { + void run_cell_search() + { std::lock_guard lg(outside); go_state(CELL_SEARCH); wait_state_run(); wait_state_next(); } - void run_sfn_sync() { + void run_sfn_sync() + { std::lock_guard lg(outside); go_state(SFN_SYNC); wait_state_run(); wait_state_next(); } - /* Helpers below this */ - bool is_idle() { - return cur_state == IDLE; - } - bool is_camping() { - return cur_state == CAMPING; - } + bool is_idle() { return cur_state == IDLE; } + bool is_camping() { return cur_state == CAMPING; } - const char *to_string() { - switch(cur_state) { + const char* to_string() + { + switch (cur_state) { case IDLE: return "IDLE"; case CELL_SEARCH: @@ -287,11 +291,12 @@ private: sync_state() = default; private: - void go_state(state_t s) { + void go_state(state_t s) + { std::unique_lock ul(inside); - next_state = s; + next_state = s; state_setting = true; - while(state_setting) { + while (state_setting) { cvar.wait(ul); } } @@ -325,20 +330,18 @@ private: sync_state phy_state; - search::ret_code cell_search_ret = search::CELL_NOT_FOUND; + 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; + enum { SRATE_NONE = 0, SRATE_FIND, SRATE_CAMP } srate_mode = SRATE_NONE; + float current_srate = 0; // This is the primary cell - srslte_cell_t cell = {}; - bool started = false; - float time_adv_sec = 0; + srslte_cell_t cell = {}; + bool started = false; + float time_adv_sec = 0; float next_time_adv_sec = 0; - uint32_t tti = 0; + uint32_t tti = 0; uint32_t tx_worker_cnt = 0; uint32_t nof_workers = 0; diff --git a/srsue/hdr/phy/ue_lte_phy_base.h b/srsue/hdr/phy/ue_lte_phy_base.h index 83402fcb1..e354a4234 100644 --- a/srsue/hdr/phy/ue_lte_phy_base.h +++ b/srsue/hdr/phy/ue_lte_phy_base.h @@ -31,7 +31,7 @@ namespace srsue { -class ue_lte_phy_base : public ue_phy_base, public phy_interface_stack_lte, public phy_interface_radio +class ue_lte_phy_base : public ue_phy_base, public phy_interface_stack_lte, public srslte::phy_interface_radio { public: ue_lte_phy_base(){}; @@ -40,10 +40,10 @@ public: virtual std::string get_type() = 0; virtual int init(const phy_args_t& args_, srslte::logger* logger_) = 0; - virtual int init(const phy_args_t& args_, - srslte::logger* logger_, - stack_interface_phy_lte* stack_, - radio_interface_phy* radio_) = 0; + virtual int init(const phy_args_t& args_, + srslte::logger* logger_, + stack_interface_phy_lte* stack_, + srslte::radio_interface_phy* radio_) = 0; virtual void stop() = 0; virtual void set_earfcn(std::vector earfcns) = 0; diff --git a/srsue/hdr/phy/ue_phy_base.h b/srsue/hdr/phy/ue_phy_base.h index 5d4fcf79d..4097c5d25 100644 --- a/srsue/hdr/phy/ue_phy_base.h +++ b/srsue/hdr/phy/ue_phy_base.h @@ -30,8 +30,6 @@ #include "srslte/common/logger.h" #include "srslte/interfaces/ue_interfaces.h" #include "srsue/hdr/phy/phy_metrics.h" -#include -#include namespace srsue { diff --git a/srsue/hdr/ue.h b/srsue/hdr/ue.h index 34973a31b..cf6b31a35 100644 --- a/srsue/hdr/ue.h +++ b/srsue/hdr/ue.h @@ -28,17 +28,17 @@ #ifndef SRSUE_UE_H #define SRSUE_UE_H +#include #include #include -#include #include "phy/ue_phy_base.h" -#include "radio/ue_radio_base.h" -#include "stack/ue_stack_base.h" #include "srslte/common/buffer_pool.h" -#include "srslte/interfaces/ue_interfaces.h" -#include "srslte/common/logger_file.h" #include "srslte/common/log_filter.h" +#include "srslte/common/logger_file.h" +#include "srslte/interfaces/ue_interfaces.h" +#include "srslte/radio/radio_base.h" +#include "stack/ue_stack_base.h" #include "ue_metrics_interface.h" @@ -72,10 +72,10 @@ typedef struct { } expert_args_t; typedef struct { - rf_args_t rf; - trace_args_t trace; - log_args_t log; - gui_args_t gui; + srslte::rf_args_t rf; + trace_args_t trace; + log_args_t log; + gui_args_t gui; phy_args_t phy; stack_args_t stack; @@ -109,13 +109,13 @@ public: private: // UE consists of a radio, a PHY and a stack element std::unique_ptr phy; - std::unique_ptr radio; + std::unique_ptr radio; std::unique_ptr stack; std::unique_ptr gw_inst; // Generic logger members - srslte::logger* logger = nullptr; - srslte::log_filter log; // Own logger for UE + srslte::logger* logger = nullptr; + srslte::log_filter log; // Own logger for UE all_args_t args; srslte::byte_buffer_pool* pool = nullptr; @@ -131,4 +131,3 @@ private: } // namespace srsue #endif // SRSUE_UE_H - diff --git a/srsue/hdr/ue_metrics_interface.h b/srsue/hdr/ue_metrics_interface.h index 28f66ef9a..6f54a5626 100644 --- a/srsue/hdr/ue_metrics_interface.h +++ b/srsue/hdr/ue_metrics_interface.h @@ -26,6 +26,7 @@ #include "phy/phy_metrics.h" #include "srslte/common/metrics_hub.h" +#include "srslte/radio/radio_metrics.h" #include "srslte/upper/rlc_metrics.h" #include "stack/mac/mac_metrics.h" #include "stack/upper/gw_metrics.h" @@ -33,13 +34,6 @@ namespace srsue { -typedef struct { - uint32_t rf_o; - uint32_t rf_u; - uint32_t rf_l; - bool rf_error; -} rf_metrics_t; - typedef struct { mac_metrics_t mac[SRSLTE_MAX_CARRIERS]; srslte::rlc_metrics_t rlc; @@ -47,7 +41,7 @@ typedef struct { } stack_metrics_t; typedef struct { - rf_metrics_t rf; + srslte::rf_metrics_t rf; phy_metrics_t phy; gw_metrics_t gw; stack_metrics_t stack; diff --git a/srsue/src/CMakeLists.txt b/srsue/src/CMakeLists.txt index ff4404fb9..6c5452b11 100644 --- a/srsue/src/CMakeLists.txt +++ b/srsue/src/CMakeLists.txt @@ -18,7 +18,6 @@ # and at http://www.gnu.org/licenses/. # -add_subdirectory(radio) add_subdirectory(phy) add_subdirectory(stack) @@ -32,14 +31,14 @@ if (RPATH) endif (RPATH) add_executable(srsue main.cc ue.cc metrics_stdout.cc metrics_csv.cc) -target_link_libraries(srsue srsue_radio - srsue_phy +target_link_libraries(srsue srsue_phy srsue_stack srsue_upper srsue_mac srsue_rrc srslte_common srslte_phy + srslte_radio srslte_upper rrc_asn1 ${CMAKE_THREAD_LIBS_INIT} diff --git a/srsue/src/phy/phy.cc b/srsue/src/phy/phy.cc index ad1ba2fb1..1f8eddaf0 100644 --- a/srsue/src/phy/phy.cc +++ b/srsue/src/phy/phy.cc @@ -101,10 +101,10 @@ bool phy::check_args(const phy_args_t& args) return true; } -int phy::init(const phy_args_t& args_, - srslte::logger* logger_, - stack_interface_phy_lte* stack_, - radio_interface_phy* radio_) +int phy::init(const phy_args_t& args_, + srslte::logger* logger_, + stack_interface_phy_lte* stack_, + srslte::radio_interface_phy* radio_) { stack = stack_; radio = radio_; diff --git a/srsue/src/phy/phy_common.cc b/srsue/src/phy/phy_common.cc index b5fd828a1..b5f8ffc22 100644 --- a/srsue/src/phy/phy_common.cc +++ b/srsue/src/phy/phy_common.cc @@ -114,10 +114,10 @@ void phy_common::set_nof_workers(uint32_t nof_workers) this->nof_workers = nof_workers; } -void phy_common::init(phy_args_t* _args, - srslte::log* _log, - radio_interface_phy* _radio, - stack_interface_phy_lte* _stack) +void phy_common::init(phy_args_t* _args, + srslte::log* _log, + srslte::radio_interface_phy* _radio, + stack_interface_phy_lte* _stack) { log_h = _log; radio_h = _radio; @@ -182,7 +182,7 @@ void phy_common::set_ue_ul_cfg(srslte_ue_ul_cfg_t* ue_ul_cfg) ue_ul_cfg->ul_cfg.pucch.ack_nack_feedback_mode = SRSLTE_PUCCH_ACK_NACK_FEEDBACK_MODE_NORMAL; } -radio_interface_phy* phy_common::get_radio() +srslte::radio_interface_phy* phy_common::get_radio() { return radio_h; } diff --git a/srsue/src/phy/scell/async_scell_recv.cc b/srsue/src/phy/scell/async_scell_recv.cc index 39ead977b..e183ddaf7 100644 --- a/srsue/src/phy/scell/async_scell_recv.cc +++ b/srsue/src/phy/scell/async_scell_recv.cc @@ -55,8 +55,8 @@ async_scell_recv::async_scell_recv() : thread("ASYNC_SCELL_RECV") ul_freq = -1; bzero(&cell, sizeof(srslte_cell_t)); bzero(sf_buffer, sizeof(sf_buffer)); - running = false; - radio_idx = 1; + running = false; + radio_idx = 1; current_sflen = 0; next_radio_offset = 0; } @@ -84,7 +84,7 @@ static double callback_set_rx_gain(void* h, double gain) return ((async_scell_recv*)h)->set_rx_gain(gain); } -void async_scell_recv::init(radio_interface_phy* _radio_handler, phy_common* _worker_com, srslte::log* _log_h) +void async_scell_recv::init(srslte::radio_interface_phy* _radio_handler, phy_common* _worker_com, srslte::log* _log_h) { // Get handlers radio_h = _radio_handler; diff --git a/srsue/src/phy/sync.cc b/srsue/src/phy/sync.cc index 11db44039..bda2993e9 100644 --- a/srsue/src/phy/sync.cc +++ b/srsue/src/phy/sync.cc @@ -42,16 +42,16 @@ double callback_set_rx_gain(void *h, double gain) { return ((sync*)h)->set_rx_gain(gain); } -void sync::init(radio_interface_phy* _radio, - stack_interface_phy_lte* _stack, - prach* _prach_buffer, - srslte::thread_pool* _workers_pool, - phy_common* _worker_com, - srslte::log* _log_h, - srslte::log* _log_phy_lib_h, - scell::async_recv_vector* scell_sync_, - uint32_t prio, - int sync_cpu_affinity) +void sync::init(srslte::radio_interface_phy* _radio, + stack_interface_phy_lte* _stack, + prach* _prach_buffer, + srslte::thread_pool* _workers_pool, + phy_common* _worker_com, + srslte::log* _log_h, + srslte::log* _log_phy_lib_h, + scell::async_recv_vector* scell_sync_, + uint32_t prio, + int sync_cpu_affinity) { radio_h = _radio; log_h = _log_h; diff --git a/srsue/src/ue.cc b/srsue/src/ue.cc index 6a35cbf59..00e992f64 100644 --- a/srsue/src/ue.cc +++ b/srsue/src/ue.cc @@ -21,9 +21,9 @@ #include "srsue/hdr/ue.h" #include "srslte/build_info.h" +#include "srslte/radio/radio_multi.h" #include "srslte/srslte.h" #include "srsue/hdr/phy/phy.h" -#include "srsue/hdr/radio/ue_radio.h" #include "srsue/hdr/stack/ue_stack_lte.h" #include #include @@ -92,14 +92,14 @@ int ue::init(const all_args_t& args_, srslte::logger* logger_) return SRSLTE_ERROR; } - std::unique_ptr lte_radio = std::unique_ptr(new ue_radio()); + std::unique_ptr lte_radio = std::unique_ptr(new radio_multi(logger)); if (!lte_radio) { log.console("Error creating radio multi instance.\n"); return SRSLTE_ERROR; } // init layers - if (lte_radio->init(args.rf, logger, lte_phy.get())) { + if (lte_radio->init(args.rf, lte_phy.get())) { log.console("Error initializing radio.\n"); return SRSLTE_ERROR; }