mirror of https://github.com/PentHertz/srsLTE.git
introduce layerd architecture we use for UE to eNB
- this allows flexible use of different PHYs and radios - use common radio_multi (moved to lib)
This commit is contained in:
parent
2530894374
commit
4e86b2f6b2
|
@ -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:
|
||||
|
|
|
@ -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
|
|
@ -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;
|
||||
|
|
|
@ -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<uint32_t> 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
|
||||
{
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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 <memory>
|
||||
#include <vector>
|
||||
#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
|
|
@ -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
|
|
@ -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<std::unique_ptr<srslte::radio> > radios;
|
||||
std::vector<std::unique_ptr<radio> > 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
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -19,47 +19,34 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#include "srsue/hdr/radio/ue_radio.h"
|
||||
#include "srslte/radio/radio_multi.h"
|
||||
#include <mutex>
|
||||
|
||||
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<std::mutex> lock(instance_mutex);
|
||||
std::lock_guard<std::mutex> 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";
|
||||
return "radio_multi";
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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<std::mutex> lock(instance_mutex);
|
||||
std::lock_guard<std::mutex> 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<std::mutex> lock(instance_mutex);
|
||||
std::lock_guard<std::mutex> 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
|
|
@ -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<enb_stack_base> stack;
|
||||
srslte::radio radio;
|
||||
srsenb::phy phy;
|
||||
int parse_args(const all_args_t& args_);
|
||||
|
||||
// eNB components
|
||||
std::unique_ptr<enb_stack_base> stack = nullptr;
|
||||
std::unique_ptr<srslte::radio_base> radio = nullptr;
|
||||
std::unique_ptr<enb_phy_base> 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<srslte::log_filter*> phy_log;
|
||||
srslte::log_filter pool_log;
|
||||
|
||||
srslte::byte_buffer_pool *pool;
|
||||
srslte::byte_buffer_pool* pool = nullptr;
|
||||
|
||||
all_args_t *args;
|
||||
bool started;
|
||||
rf_metrics_t rf_metrics;
|
||||
all_args_t args = {};
|
||||
bool started = false;
|
||||
|
||||
phy_cfg_t phy_cfg = {};
|
||||
rrc_cfg_t rrc_cfg = {};
|
||||
|
||||
srslte::LOG_LEVEL_ENUM level(std::string l);
|
||||
|
||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -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<srslte::log_filter*> 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<std::unique_ptr<srslte::log_filter> > log_vec;
|
||||
srslte::log* log_h = nullptr;
|
||||
|
||||
srslte::thread_pool workers_pool;
|
||||
std::vector<sf_worker> 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
|
||||
|
|
|
@ -22,20 +22,25 @@
|
|||
#ifndef SRSENB_PHCH_COMMON_H
|
||||
#define SRSENB_PHCH_COMMON_H
|
||||
|
||||
#include <map>
|
||||
#include <semaphore.h>
|
||||
#include "srslte/common/gen_mch_tables.h"
|
||||
#include "srslte/common/interfaces_common.h"
|
||||
#include "srslte/common/log.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/common/gen_mch_tables.h"
|
||||
#include "srslte/common/log.h"
|
||||
#include "srslte/common/threads.h"
|
||||
#include "srslte/common/thread_pool.h"
|
||||
#include "srslte/radio/radio.h"
|
||||
#include <map>
|
||||
#include <semaphore.h>
|
||||
#include <string.h>
|
||||
|
||||
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
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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<tree_node_t> 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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 <boost/algorithm/string.hpp>
|
||||
|
@ -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());
|
||||
|
||||
if (args->log.filename == "stdout") {
|
||||
// Validate arguments
|
||||
if (parse_args(args_)) {
|
||||
log.console("Error processing arguments.\n");
|
||||
return SRSLTE_ERROR;
|
||||
}
|
||||
|
||||
// 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;i<args->expert.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;i<args->expert.phy.nof_phy_threads;i++) {
|
||||
((srslte::log_filter*) phy_log[i])->set_level(level(args->log.phy_level));
|
||||
// Create layers
|
||||
std::unique_ptr<enb_stack_lte> lte_stack(new enb_stack_lte(logger));
|
||||
if (!lte_stack) {
|
||||
log.console("Error creating eNB stack.\n");
|
||||
return SRSLTE_ERROR;
|
||||
}
|
||||
|
||||
for (int i=0;i<args->expert.phy.nof_phy_threads;i++) {
|
||||
((srslte::log_filter*) phy_log[i])->set_hex_limit(args->log.phy_hex_limit);
|
||||
std::unique_ptr<enb_radio_multi> lte_radio = std::unique_ptr<enb_radio_multi>(new enb_radio_multi(logger));
|
||||
if (!lte_radio) {
|
||||
log.console("Error creating radio multi instance.\n");
|
||||
return SRSLTE_ERROR;
|
||||
}
|
||||
|
||||
std::unique_ptr<srsenb::phy> lte_phy = std::unique_ptr<srsenb::phy>(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 <t> 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<std::string> 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<std::string> 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));
|
||||
rrc_cfg.cell = cell_cfg;
|
||||
phy_cfg.cell = cell_cfg;
|
||||
|
||||
// Init layers
|
||||
|
||||
/* Start Radio */
|
||||
char* dev_name = nullptr;
|
||||
if (args->rf.device_name != "auto") {
|
||||
dev_name = (char*) args->rf.device_name.c_str();
|
||||
}
|
||||
// Patch certain args that are not exposed yet
|
||||
args.rf.nof_radios = args.rf.nof_rf_channels = args.rf.nof_rx_ant = 1;
|
||||
|
||||
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<enb_stack_lte> 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);
|
||||
|
||||
started = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
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);
|
||||
|
|
|
@ -19,10 +19,10 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#include "srsenb/hdr/cfg_parser.h"
|
||||
#include "srslte/srslte.h"
|
||||
|
||||
#include "enb_cfg_parser.h"
|
||||
#include "srsenb/hdr/cfg_parser.h"
|
||||
#include "srslte/phy/common/phy_common.h"
|
||||
#include "srslte/srslte.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
|
||||
|
|
|
@ -67,14 +67,14 @@ void parse_args(all_args_t *args, int argc, char* argv[]) {
|
|||
common.add_options()
|
||||
|
||||
("enb.enb_id", bpo::value<string>(&enb_id)->default_value("0x0"), "eNodeB ID")
|
||||
("enb.name", bpo::value<string>(&args->enb.s1ap.enb_name)->default_value("srsenb01"), "eNodeB Name")
|
||||
("enb.name", bpo::value<string>(&args->stack.s1ap.enb_name)->default_value("srsenb01"), "eNodeB Name")
|
||||
("enb.cell_id", bpo::value<string>(&cell_id)->default_value("0x0"), "Cell ID")
|
||||
("enb.tac", bpo::value<string>(&tac)->default_value("0x0"), "Tracking Area Code")
|
||||
("enb.mcc", bpo::value<string>(&mcc)->default_value("001"), "Mobile Country Code")
|
||||
("enb.mnc", bpo::value<string>(&mnc)->default_value("01"), "Mobile Network Code")
|
||||
("enb.mme_addr", bpo::value<string>(&args->enb.s1ap.mme_addr)->default_value("127.0.0.1"),"IP address of MME for S1 connection")
|
||||
("enb.gtp_bind_addr", bpo::value<string>(&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<string>(&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<string>(&args->stack.s1ap.mme_addr)->default_value("127.0.0.1"),"IP address of MME for S1 connection")
|
||||
("enb.gtp_bind_addr", bpo::value<string>(&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<string>(&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<uint32_t>(&args->enb.pci)->default_value(0), "Physical Cell Identity (PCI)")
|
||||
("enb.n_prb", bpo::value<uint32_t>(&args->enb.n_prb)->default_value(25), "Number of PRB")
|
||||
("enb.nof_ports", bpo::value<uint32_t>(&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<string>(&args->enb_files.rr_config)->default_value("rr.conf"), "RR configuration files")
|
||||
("enb_files.drb_config", bpo::value<string>(&args->enb_files.drb_config)->default_value("drb.conf"), "DRB configuration files")
|
||||
|
||||
("rf.dl_earfcn", bpo::value<uint32_t>(&args->rf.dl_earfcn)->default_value(3400), "Downlink EARFCN")
|
||||
("rf.ul_earfcn", bpo::value<uint32_t>(&args->rf.ul_earfcn)->default_value(0), "Uplink EARFCN (Default based on Downlink EARFCN)")
|
||||
("rf.dl_earfcn", bpo::value<uint32_t>(&args->enb.dl_earfcn)->default_value(3400), "Downlink EARFCN")
|
||||
("rf.ul_earfcn", bpo::value<uint32_t>(&args->enb.ul_earfcn)->default_value(0), "Uplink EARFCN (Default based on Downlink EARFCN)")
|
||||
("rf.rx_gain", bpo::value<float>(&args->rf.rx_gain)->default_value(50), "Front-end receiver gain")
|
||||
("rf.tx_gain", bpo::value<float>(&args->rf.tx_gain)->default_value(70), "Front-end transmitter gain")
|
||||
("rf.dl_freq", bpo::value<float>(&args->rf.dl_freq)->default_value(-1), "Downlink Frequency (if positive overrides EARFCN)")
|
||||
("rf.ul_freq", bpo::value<float>(&args->rf.ul_freq)->default_value(-1), "Uplink Frequency (if positive overrides EARFCN)")
|
||||
|
||||
("rf.device_name", bpo::value<string>(&args->rf.device_name)->default_value("auto"), "Front-end device name")
|
||||
("rf.device_args", bpo::value<string>(&args->rf.device_args)->default_value("auto"), "Front-end device arguments")
|
||||
("rf.device_args", bpo::value<string>(&args->rf.device_args[0])->default_value("auto"), "Front-end device arguments")
|
||||
("rf.time_adv_nsamples", bpo::value<string>(&args->rf.time_adv_nsamples)->default_value("auto"), "Transmission time advance")
|
||||
("rf.burst_preamble_us", bpo::value<string>(&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<string>(&args->log.phy_level), "PHY log level")
|
||||
("log.phy_hex_limit", bpo::value<int>(&args->log.phy_hex_limit), "PHY log hex dump limit")
|
||||
("log.phy_lib_level", bpo::value<string>(&args->log.phy_lib_level)->default_value("none"), "PHY lib log level")
|
||||
("log.mac_level", bpo::value<string>(&args->log.mac_level), "MAC log level")
|
||||
("log.mac_hex_limit", bpo::value<int>(&args->log.mac_hex_limit), "MAC log hex dump limit")
|
||||
("log.rlc_level", bpo::value<string>(&args->log.rlc_level), "RLC log level")
|
||||
("log.rlc_hex_limit", bpo::value<int>(&args->log.rlc_hex_limit), "RLC log hex dump limit")
|
||||
("log.pdcp_level", bpo::value<string>(&args->log.pdcp_level), "PDCP log level")
|
||||
("log.pdcp_hex_limit",bpo::value<int>(&args->log.pdcp_hex_limit), "PDCP log hex dump limit")
|
||||
("log.rrc_level", bpo::value<string>(&args->log.rrc_level), "RRC log level")
|
||||
("log.rrc_hex_limit", bpo::value<int>(&args->log.rrc_hex_limit), "RRC log hex dump limit")
|
||||
("log.gtpu_level", bpo::value<string>(&args->log.gtpu_level), "GTPU log level")
|
||||
("log.gtpu_hex_limit",bpo::value<int>(&args->log.gtpu_hex_limit), "GTPU log hex dump limit")
|
||||
("log.s1ap_level", bpo::value<string>(&args->log.s1ap_level), "S1AP log level")
|
||||
("log.s1ap_hex_limit",bpo::value<int>(&args->log.s1ap_hex_limit), "S1AP log hex dump limit")
|
||||
("log.mac_level", bpo::value<string>(&args->stack.log.mac_level), "MAC log level")
|
||||
("log.mac_hex_limit", bpo::value<int>(&args->stack.log.mac_hex_limit), "MAC log hex dump limit")
|
||||
("log.rlc_level", bpo::value<string>(&args->stack.log.rlc_level), "RLC log level")
|
||||
("log.rlc_hex_limit", bpo::value<int>(&args->stack.log.rlc_hex_limit), "RLC log hex dump limit")
|
||||
("log.pdcp_level", bpo::value<string>(&args->stack.log.pdcp_level), "PDCP log level")
|
||||
("log.pdcp_hex_limit",bpo::value<int>(&args->stack.log.pdcp_hex_limit), "PDCP log hex dump limit")
|
||||
("log.rrc_level", bpo::value<string>(&args->stack.log.rrc_level), "RRC log level")
|
||||
("log.rrc_hex_limit", bpo::value<int>(&args->stack.log.rrc_hex_limit), "RRC log hex dump limit")
|
||||
("log.gtpu_level", bpo::value<string>(&args->stack.log.gtpu_level), "GTPU log level")
|
||||
("log.gtpu_hex_limit",bpo::value<int>(&args->stack.log.gtpu_hex_limit), "GTPU log hex dump limit")
|
||||
("log.s1ap_level", bpo::value<string>(&args->stack.log.s1ap_level), "S1AP log level")
|
||||
("log.s1ap_hex_limit",bpo::value<int>(&args->stack.log.s1ap_hex_limit), "S1AP log hex dump limit")
|
||||
|
||||
("log.all_level", bpo::value<string>(&args->log.all_level)->default_value("info"), "ALL log level")
|
||||
("log.all_hex_limit", bpo::value<int>(&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<int>(&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<int>(&args->expert.mac.sched.pdsch_mcs)->default_value(-1), "Optional fixed PDSCH MCS (ignores reported CQIs if specified)")
|
||||
("scheduler.pdsch_max_mcs", bpo::value<int>(&args->expert.mac.sched.pdsch_max_mcs)->default_value(-1), "Optional PDSCH MCS limit")
|
||||
("scheduler.pusch_mcs", bpo::value<int>(&args->expert.mac.sched.pusch_mcs)->default_value(-1), "Optional fixed PUSCH MCS (ignores reported CQIs if specified)")
|
||||
("scheduler.pusch_max_mcs", bpo::value<int>(&args->expert.mac.sched.pusch_max_mcs)->default_value(-1), "Optional PUSCH MCS limit")
|
||||
("scheduler.nof_ctrl_symbols", bpo::value<int>(&args->expert.mac.sched.nof_ctrl_symbols)->default_value(3), "Number of control symbols")
|
||||
("scheduler.pdsch_mcs", bpo::value<int>(&args->stack.mac.sched.pdsch_mcs)->default_value(-1), "Optional fixed PDSCH MCS (ignores reported CQIs if specified)")
|
||||
("scheduler.pdsch_max_mcs", bpo::value<int>(&args->stack.mac.sched.pdsch_max_mcs)->default_value(-1), "Optional PDSCH MCS limit")
|
||||
("scheduler.pusch_mcs", bpo::value<int>(&args->stack.mac.sched.pusch_mcs)->default_value(-1), "Optional fixed PUSCH MCS (ignores reported CQIs if specified)")
|
||||
("scheduler.pusch_max_mcs", bpo::value<int>(&args->stack.mac.sched.pusch_max_mcs)->default_value(-1), "Optional PUSCH MCS limit")
|
||||
("scheduler.nof_ctrl_symbols", bpo::value<int>(&args->stack.mac.sched.nof_ctrl_symbols)->default_value(3), "Number of control symbols")
|
||||
|
||||
/* Expert section */
|
||||
("expert.metrics_period_secs", bpo::value<float>(&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<bool>(&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<float>(&args->expert.phy.tx_amplitude)->default_value(0.6), "Transmit amplitude factor")
|
||||
("expert.nof_phy_threads", bpo::value<int>(&args->expert.phy.nof_phy_threads)->default_value(3), "Number of PHY threads")
|
||||
("expert.link_failure_nof_err", bpo::value<int>(&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<int>(&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<float>(&args->expert.phy.max_prach_offset_us)->default_value(30), "Maximum allowed RACH offset (in us)")
|
||||
("expert.equalizer_mode", bpo::value<string>(&args->expert.phy.equalizer_mode)->default_value("mmse"), "Equalizer mode")
|
||||
("expert.estimator_fil_w", bpo::value<float>(&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<std::string>();
|
||||
sstr >> args->enb.s1ap.enb_id;
|
||||
sstr >> args->stack.s1ap.enb_id;
|
||||
}
|
||||
{
|
||||
std::stringstream sstr;
|
||||
sstr << std::hex << vm["enb.cell_id"].as<std::string>();
|
||||
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<std::string>();
|
||||
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<enb_metrics_t> 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;
|
||||
}
|
||||
|
|
|
@ -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_)
|
||||
{
|
||||
|
||||
std::vector<srslte::log_filter*> log_vec;
|
||||
this->log_h = log_h;
|
||||
for (int i=0;i<args->nof_phy_threads;i++) {
|
||||
log_vec.push_back(log_h);
|
||||
}
|
||||
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<srslte::log_filter*> log_vec)
|
||||
{
|
||||
|
||||
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;
|
||||
|
||||
workers_common.init(&cfg->cell, radio_handler, stack_);
|
||||
// Create array of pointers to phy_logs
|
||||
for (int i = 0; i < args.nof_phy_threads; i++) {
|
||||
auto mylog = std::unique_ptr<srslte::log_filter>(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));
|
||||
}
|
||||
|
||||
// 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<srslte::log_filter>(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);
|
||||
}
|
||||
|
||||
radio = radio_;
|
||||
nof_workers = args.nof_phy_threads;
|
||||
|
||||
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;i<nof_workers;i++) {
|
||||
workers[i].init(&workers_common, (srslte::log*) log_vec[i]);
|
||||
workers[i].init(&workers_common, log_vec.at(i).get());
|
||||
workers_pool.init_worker(i, &workers[i], WORKERS_THREAD_PRIO);
|
||||
}
|
||||
|
||||
prach.init(&cfg->cell, &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;i<nof_workers;i++) {
|
||||
workers[i].stop();
|
||||
{
|
||||
if (initialized) {
|
||||
tx_rx.stop();
|
||||
for (uint32_t i = 0; i < nof_workers; i++) {
|
||||
workers[i].stop();
|
||||
}
|
||||
workers_common.stop();
|
||||
workers_pool.stop();
|
||||
prach.stop();
|
||||
|
||||
initialized = false;
|
||||
}
|
||||
workers_common.stop();
|
||||
workers_pool.stop();
|
||||
prach.stop();
|
||||
}
|
||||
|
||||
uint32_t phy::tti_to_SFN(uint32_t tti) {
|
||||
|
|
|
@ -75,11 +75,13 @@ void phy_common::reset()
|
|||
bzero(dl_grants, sizeof(stack_interface_phy_lte::dl_sched_t) * TTIMOD_SZ);
|
||||
}
|
||||
|
||||
bool phy_common::init(srslte_cell_t* cell_, srslte::radio* radio_h_, stack_interface_phy_lte* stack_)
|
||||
bool phy_common::init(const srslte_cell_t& cell_,
|
||||
srslte::radio_interface_phy* radio_h_,
|
||||
stack_interface_phy_lte* stack_)
|
||||
{
|
||||
radio = radio_h_;
|
||||
stack = stack_;
|
||||
memcpy(&cell, cell_, sizeof(srslte_cell_t));
|
||||
cell = cell_;
|
||||
|
||||
pthread_mutex_init(&user_mutex, NULL);
|
||||
pthread_mutex_init(&mtch_mutex, NULL);
|
||||
|
@ -122,8 +124,8 @@ void phy_common::worker_end(uint32_t tti,
|
|||
// Wait for the green light to transmit in the current TTI
|
||||
sem_wait(&tx_sem[tti%nof_workers]);
|
||||
|
||||
radio->set_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]);
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -19,10 +19,9 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include "srslte/common/log.h"
|
||||
#include "srslte/common/threads.h"
|
||||
#include "srslte/srslte.h"
|
||||
|
||||
#include "srsenb/hdr/phy/sf_worker.h"
|
||||
|
||||
|
|
|
@ -21,8 +21,9 @@
|
|||
|
||||
#include <unistd.h>
|
||||
|
||||
#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 <t> 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);
|
||||
|
|
|
@ -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})
|
|
@ -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 <mutex>
|
||||
|
||||
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
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;i<ue_db.size();i++) {
|
||||
delete ue_db[i];
|
||||
if (started) {
|
||||
for (uint32_t i = 0; i < ue_db.size(); i++) {
|
||||
delete ue_db[i];
|
||||
}
|
||||
for (int i = 0; i < NOF_BCCH_DLSCH_MSG; i++) {
|
||||
srslte_softbuffer_tx_free(&bcch_softbuffer_tx[i]);
|
||||
}
|
||||
srslte_softbuffer_tx_free(&pcch_softbuffer_tx);
|
||||
srslte_softbuffer_tx_free(&rar_softbuffer_tx);
|
||||
started = false;
|
||||
timers_thread.stop();
|
||||
pdu_process_thread.stop();
|
||||
}
|
||||
for (int i=0;i<NOF_BCCH_DLSCH_MSG;i++) {
|
||||
srslte_softbuffer_tx_free(&bcch_softbuffer_tx[i]);
|
||||
}
|
||||
srslte_softbuffer_tx_free(&pcch_softbuffer_tx);
|
||||
srslte_softbuffer_tx_free(&rar_softbuffer_tx);
|
||||
started = false;
|
||||
timers_thread.stop();
|
||||
pdu_process_thread.stop();
|
||||
pthread_rwlock_unlock(&rwlock);
|
||||
}
|
||||
|
||||
// Implement Section 5.9
|
||||
|
|
|
@ -79,7 +79,6 @@ void s1ap::stop()
|
|||
if(close(socket_fd) == -1) {
|
||||
s1ap_log->error("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
|
||||
|
|
|
@ -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<std::unique_ptr<srslte::log_filter> > log_vec;
|
||||
srslte::logger* logger = nullptr;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -42,69 +42,69 @@
|
|||
#include <srsue/hdr/phy/scell/intra_measure.h>
|
||||
|
||||
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<uint32_t> earfcn);
|
||||
void force_freq(float dl_freq, float ul_freq);
|
||||
void set_agc_enable(bool enable);
|
||||
void set_earfcn(std::vector<uint32_t> 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<uint32_t> 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<std::mutex> 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<std::mutex> 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<std::mutex> 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<std::mutex> lg(outside);
|
||||
go_state(IDLE);
|
||||
}
|
||||
void run_cell_search() {
|
||||
void run_cell_search()
|
||||
{
|
||||
std::lock_guard<std::mutex> lg(outside);
|
||||
go_state(CELL_SEARCH);
|
||||
wait_state_run();
|
||||
wait_state_next();
|
||||
}
|
||||
void run_sfn_sync() {
|
||||
void run_sfn_sync()
|
||||
{
|
||||
std::lock_guard<std::mutex> 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<std::mutex> 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;
|
||||
|
|
|
@ -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<uint32_t> earfcns) = 0;
|
||||
|
|
|
@ -30,8 +30,6 @@
|
|||
#include "srslte/common/logger.h"
|
||||
#include "srslte/interfaces/ue_interfaces.h"
|
||||
#include "srsue/hdr/phy/phy_metrics.h"
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
namespace srsue {
|
||||
|
||||
|
|
|
@ -28,17 +28,17 @@
|
|||
#ifndef SRSUE_UE_H
|
||||
#define SRSUE_UE_H
|
||||
|
||||
#include <pthread.h>
|
||||
#include <stdarg.h>
|
||||
#include <string>
|
||||
#include <pthread.h>
|
||||
|
||||
#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<ue_phy_base> phy;
|
||||
std::unique_ptr<ue_radio_base> radio;
|
||||
std::unique_ptr<srslte::radio_base> radio;
|
||||
std::unique_ptr<ue_stack_base> stack;
|
||||
std::unique_ptr<gw> 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
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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}
|
||||
|
|
|
@ -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_;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 <algorithm>
|
||||
#include <iostream>
|
||||
|
@ -92,14 +92,14 @@ int ue::init(const all_args_t& args_, srslte::logger* logger_)
|
|||
return SRSLTE_ERROR;
|
||||
}
|
||||
|
||||
std::unique_ptr<ue_radio> lte_radio = std::unique_ptr<ue_radio>(new ue_radio());
|
||||
std::unique_ptr<radio_multi> lte_radio = std::unique_ptr<radio_multi>(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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue