diff --git a/srsue/hdr/ue.h b/srsue/hdr/ue.h index 6fb593d55..c69dbddeb 100644 --- a/srsue/hdr/ue.h +++ b/srsue/hdr/ue.h @@ -37,6 +37,7 @@ #include #include +#include "ue_base.h" #include "srslte/radio/radio_multi.h" #include "phy/phy.h" #include "mac/mac.h" @@ -56,89 +57,15 @@ namespace srsue { -/******************************************************************************* - UE Parameters -*******************************************************************************/ - -typedef struct { - float dl_freq; - float ul_freq; - float rx_gain; - float tx_gain; - uint32_t nof_rx_ant; - 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 { - bool enable; - std::string phy_filename; - std::string radio_filename; -}trace_args_t; - -typedef struct { - std::string phy_level; - std::string mac_level; - std::string rlc_level; - std::string pdcp_level; - std::string rrc_level; - std::string gw_level; - std::string nas_level; - std::string usim_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 gw_hex_limit; - int nas_hex_limit; - int usim_hex_limit; - int all_hex_limit; - std::string filename; -}log_args_t; - -typedef struct { - bool enable; -}gui_args_t; - -typedef struct { - phy_args_t phy; - float metrics_period_secs; - bool pregenerate_signals; - int ue_cateogry; - -}expert_args_t; - -typedef struct { - rf_args_t rf; - rf_cal_t rf_cal; - pcap_args_t pcap; - trace_args_t trace; - log_args_t log; - gui_args_t gui; - usim_args_t usim; - expert_args_t expert; -}all_args_t; - /******************************************************************************* Main UE class *******************************************************************************/ class ue - :public ue_interface - ,public ue_metrics_interface + :public ue_base { public: - static ue* get_instance(void); - static void cleanup(void); + ue(); bool init(all_args_t *args_); void stop(); @@ -158,8 +85,6 @@ public: private: - static ue *instance; - ue(); virtual ~ue(); srslte::radio_multi radio; @@ -189,8 +114,6 @@ private: all_args_t *args; bool started; rf_metrics_t rf_metrics; - - srslte::LOG_LEVEL_ENUM level(std::string l); bool check_srslte_version(); }; diff --git a/srsue/hdr/ue_base.h b/srsue/hdr/ue_base.h new file mode 100644 index 000000000..06c3f3e24 --- /dev/null +++ b/srsue/hdr/ue_base.h @@ -0,0 +1,164 @@ +/** + * + * \section COPYRIGHT + * + * Copyright 2013-2015 Software Radio Systems Limited + * + * \section LICENSE + * + * This file is part of the srsUE library. + * + * srsUE 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. + * + * srsUE 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: ue_base.h + * Description: Base class for UEs. + *****************************************************************************/ + +#ifndef UE_BASE_H +#define UE_BASE_H + +#include +#include +#include +#include "srslte/radio/radio_multi.h" +#include "phy/phy.h" +#include "upper/usim.h" +#include "srslte/interfaces/ue_interfaces.h" + +#include "srslte/common/logger.h" +#include "srslte/common/log_filter.h" + +#include "ue_metrics_interface.h" + +namespace srsue { + +/******************************************************************************* + UE Parameters +*******************************************************************************/ + +typedef struct { + float dl_freq; + float ul_freq; + float rx_gain; + float tx_gain; + uint32_t nof_rx_ant; + 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 { + bool enable; + std::string phy_filename; + std::string radio_filename; +}trace_args_t; + +typedef struct { + std::string phy_level; + std::string mac_level; + std::string rlc_level; + std::string pdcp_level; + std::string rrc_level; + std::string gw_level; + std::string nas_level; + std::string usim_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 gw_hex_limit; + int nas_hex_limit; + int usim_hex_limit; + int all_hex_limit; + std::string filename; +}log_args_t; + +typedef struct { + bool enable; +}gui_args_t; + +typedef struct { + phy_args_t phy; + float metrics_period_secs; + bool pregenerate_signals; + std::string ue_cateogry; +}expert_args_t; + +typedef struct { + rf_args_t rf; + rf_cal_t rf_cal; + pcap_args_t pcap; + trace_args_t trace; + log_args_t log; + gui_args_t gui; + usim_args_t usim; + expert_args_t expert; +}all_args_t; + +typedef enum { + LTE = 0, + SRSUE_INSTANCE_TYPE_NITEMS +} srsue_instance_type_t; +static const char srsue_instance_type_text[SRSUE_INSTANCE_TYPE_NITEMS][10] = { "LTE" }; + + +/******************************************************************************* + Main UE class +*******************************************************************************/ + +class ue_base + :public ue_interface + ,public ue_metrics_interface +{ +public: + ue_base() {} + virtual ~ue_base() {} + + static ue_base* get_instance(srsue_instance_type_t type); + + void cleanup(void); + + virtual bool init(all_args_t *args_) = 0; + virtual void stop() = 0; + virtual bool is_attached() = 0; + virtual void start_plot() = 0; + + void handle_rf_msg(srslte_rf_error_t error); + + // UE metrics interface + virtual bool get_metrics(ue_metrics_t &m) = 0; + + virtual void pregenerate_signals(bool enable) = 0; + + srslte::log_filter rf_log; + rf_metrics_t rf_metrics; + srslte::LOG_LEVEL_ENUM level(std::string l); +}; + +} // namespace srsue + +#endif // UE_BASE_H + diff --git a/srsue/src/CMakeLists.txt b/srsue/src/CMakeLists.txt index 4b2a7e282..3a3b9ebfe 100644 --- a/srsue/src/CMakeLists.txt +++ b/srsue/src/CMakeLists.txt @@ -31,7 +31,7 @@ if (RPATH) set(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE) endif (RPATH) -add_executable(srsue main.cc ue.cc metrics_stdout.cc) +add_executable(srsue main.cc ue_base.cc ue.cc metrics_stdout.cc) target_link_libraries(srsue srsue_mac srsue_phy srsue_upper diff --git a/srsue/src/main.cc b/srsue/src/main.cc index f114c0606..16e0cb59f 100644 --- a/srsue/src/main.cc +++ b/srsue/src/main.cc @@ -126,7 +126,7 @@ void parse_args(all_args_t *args, int argc, char *argv[]) { "index of the core used by the sync thread") ("expert.ue_category", - bpo::value(&args->expert.ue_cateogry)->default_value(4), + bpo::value(&args->expert.ue_cateogry)->default_value("4"), "UE Category (1 to 5)") ("expert.metrics_period_secs", @@ -342,18 +342,26 @@ void *input_loop(void *m) { return NULL; } -int main(int argc, char *argv[]) { +int main(int argc, char *argv[]) +{ signal(SIGINT, sig_int_handler); all_args_t args; - metrics_stdout metrics; - ue *ue = ue::get_instance(); - - cout << "--- Software Radio Systems LTE UE ---" << endl << endl; - parse_args(&args, argc, argv); + + + srsue_instance_type_t type = LTE; + ue_base *ue = ue_base::get_instance(type); + if (!ue) { + cout << "Error creating UE instance." << endl << endl; + exit(1); + } + + cout << "--- Software Radio Systems " << srsue_instance_type_text[type] << " UE ---" << endl << endl; if (!ue->init(&args)) { exit(1); } + + metrics_stdout metrics; metrics.init(ue, args.expert.metrics_period_secs); pthread_t input; diff --git a/srsue/src/ue.cc b/srsue/src/ue.cc index 97f59c15e..dea1c3751 100644 --- a/srsue/src/ue.cc +++ b/srsue/src/ue.cc @@ -26,7 +26,6 @@ #include "ue.h" -//#include "srslte_version_check.h" #include "srslte/srslte.h" #include #include @@ -38,28 +37,6 @@ using namespace srslte; namespace srsue{ -ue* ue::instance = NULL; -pthread_mutex_t ue_instance_mutex = PTHREAD_MUTEX_INITIALIZER; - -ue* ue::get_instance(void) -{ - pthread_mutex_lock(&ue_instance_mutex); - if(NULL == instance) { - instance = new ue(); - } - pthread_mutex_unlock(&ue_instance_mutex); - return(instance); -} -void ue::cleanup(void) -{ - pthread_mutex_lock(&ue_instance_mutex); - if(NULL != instance) { - delete instance; - instance = NULL; - } - pthread_mutex_unlock(&ue_instance_mutex); -} - ue::ue() :started(false) { @@ -188,7 +165,7 @@ bool ue::init(all_args_t *args_) pdcp.init(&rlc, &rrc, &gw, &pdcp_log, SECURITY_DIRECTION_UPLINK); rrc.init(&phy, &mac, &rlc, &pdcp, &nas, &usim, &mac, &rrc_log); - rrc.set_ue_category(args->expert.ue_cateogry); + rrc.set_ue_category(atoi(args->expert.ue_cateogry.c_str())); nas.init(&usim, &rrc, &gw, &nas_log); gw.init(&pdcp, &rrc, this, &gw_log); @@ -271,49 +248,8 @@ bool ue::get_metrics(ue_metrics_t &m) void ue::rf_msg(srslte_rf_error_t error) { - ue *u = ue::get_instance(); - u->handle_rf_msg(error); -} - -void ue::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(str); - } -} - -srslte::LOG_LEVEL_ENUM ue::level(std::string l) -{ - std::transform(l.begin(), l.end(), l.begin(), ::toupper); - if("NONE" == l){ - return srslte::LOG_LEVEL_NONE; - }else if("ERROR" == l){ - return srslte::LOG_LEVEL_ERROR; - }else if("WARNING" == l){ - return srslte::LOG_LEVEL_WARNING; - }else if("INFO" == l){ - return srslte::LOG_LEVEL_INFO; - }else if("DEBUG" == l){ - return srslte::LOG_LEVEL_DEBUG; - }else{ - return srslte::LOG_LEVEL_NONE; - } + ue_base *ue = ue_base::get_instance(LTE); + ue->handle_rf_msg(error); } } // namespace srsue diff --git a/srsue/src/ue_base.cc b/srsue/src/ue_base.cc new file mode 100644 index 000000000..61cbafb2c --- /dev/null +++ b/srsue/src/ue_base.cc @@ -0,0 +1,111 @@ +/** + * + * \section COPYRIGHT + * + * Copyright 2013-2015 Software Radio Systems Limited + * + * \section LICENSE + * + * This file is part of the srsUE library. + * + * srsUE 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. + * + * srsUE 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 "ue_base.h" +#include "ue.h" +#include "srslte/srslte.h" +#include +#include +#include +#include +#include + +using namespace srslte; + +namespace srsue{ + +static ue_base* instance = NULL; +pthread_mutex_t ue_instance_mutex = PTHREAD_MUTEX_INITIALIZER; + +ue_base* ue_base::get_instance(srsue_instance_type_t type) +{ + pthread_mutex_lock(&ue_instance_mutex); + if(NULL == instance) { + switch (type) { + case LTE: + instance = new ue(); + break; + default: + perror("Unknown UE type.\n"); + } + } + pthread_mutex_unlock(&ue_instance_mutex); + return(instance); +} + +void ue_base::cleanup(void) +{ + pthread_mutex_lock(&ue_instance_mutex); + if(NULL != instance) { + delete instance; + instance = NULL; + } + pthread_mutex_unlock(&ue_instance_mutex); +} + +void ue_base::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(str); + } +} + +srslte::LOG_LEVEL_ENUM ue_base::level(std::string l) +{ + std::transform(l.begin(), l.end(), l.begin(), ::toupper); + if("NONE" == l){ + return srslte::LOG_LEVEL_NONE; + }else if("ERROR" == l){ + return srslte::LOG_LEVEL_ERROR; + }else if("WARNING" == l){ + return srslte::LOG_LEVEL_WARNING; + }else if("INFO" == l){ + return srslte::LOG_LEVEL_INFO; + }else if("DEBUG" == l){ + return srslte::LOG_LEVEL_DEBUG; + }else{ + return srslte::LOG_LEVEL_NONE; + } +} + +} // namespace srsue