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