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_noncont_ho(uint32_t preamble_index, uint32_t prach_mask) = 0;
|
||||||
virtual void start_cont_ho() = 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 reset() = 0;
|
||||||
virtual void wait_uplink() = 0;
|
virtual void wait_uplink() = 0;
|
||||||
};
|
};
|
||||||
|
@ -669,6 +669,9 @@ typedef struct {
|
||||||
float freq_offset;
|
float freq_offset;
|
||||||
float rx_gain;
|
float rx_gain;
|
||||||
float tx_gain;
|
float tx_gain;
|
||||||
|
float tx_max_power;
|
||||||
|
float tx_gain_offset;
|
||||||
|
float rx_gain_offset;
|
||||||
uint32_t nof_radios;
|
uint32_t nof_radios;
|
||||||
uint32_t nof_rf_channels; // Number of RF channels per radio
|
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_rx_ant; // Number of RF channels for MIMO
|
||||||
|
@ -868,31 +871,37 @@ class radio_interface_phy
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
// trx functions
|
// 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 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
|
// setter
|
||||||
virtual void set_tx_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 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 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_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 uint32_t& radio_idx, const double& srate) = 0;
|
||||||
virtual void set_tx_srate(const double& srate) = 0;
|
virtual void set_rx_srate(const uint32_t& radio_idx, const double& srate) = 0;
|
||||||
virtual void set_rx_srate(const double& srate) = 0;
|
|
||||||
virtual float set_tx_power(const float& power) = 0;
|
|
||||||
|
|
||||||
// getter
|
// getter
|
||||||
virtual float get_rx_gain(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_freq_offset() = 0;
|
||||||
virtual double get_tx_freq(const uint32_t& radio_idx = 0) = 0;
|
virtual double get_tx_freq(const uint32_t& radio_idx) = 0;
|
||||||
virtual double get_rx_freq(const uint32_t& radio_idx = 0) = 0;
|
virtual double get_rx_freq(const uint32_t& radio_idx) = 0;
|
||||||
virtual float get_max_tx_power() = 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_continuous_tx() = 0;
|
||||||
virtual bool is_init() = 0;
|
virtual bool is_init() = 0;
|
||||||
virtual void reset() = 0;
|
virtual void reset() = 0;
|
||||||
virtual srslte_rf_info_t* get_info(const uint32_t& radio_idx = 0) = 0;
|
virtual srslte_rf_info_t* get_info(const uint32_t& radio_idx) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
class phy_interface_radio
|
class phy_interface_radio
|
||||||
|
|
|
@ -49,6 +49,7 @@ class radio {
|
||||||
burst_preamble_samples = 0;
|
burst_preamble_samples = 0;
|
||||||
burst_preamble_time_rounded = 0;
|
burst_preamble_time_rounded = 0;
|
||||||
|
|
||||||
|
master_clock_rate = 0;
|
||||||
cur_tx_srate = 0;
|
cur_tx_srate = 0;
|
||||||
tx_adv_sec = 0;
|
tx_adv_sec = 0;
|
||||||
tx_adv_nsamples = 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);
|
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()
|
float radio::get_max_tx_power()
|
||||||
{
|
{
|
||||||
return 40;
|
return 40;
|
||||||
|
@ -304,13 +290,21 @@ double radio::set_rx_gain_th(float gain)
|
||||||
|
|
||||||
void radio::set_master_clock_rate(double rate)
|
void radio::set_master_clock_rate(double rate)
|
||||||
{
|
{
|
||||||
|
if (rate != master_clock_rate) {
|
||||||
srslte_rf_stop_rx_stream(&rf_device);
|
srslte_rf_stop_rx_stream(&rf_device);
|
||||||
srslte_rf_set_master_clock_rate(&rf_device, rate);
|
srslte_rf_set_master_clock_rate(&rf_device, rate);
|
||||||
srslte_rf_start_rx_stream(&rf_device, false);
|
srslte_rf_start_rx_stream(&rf_device, false);
|
||||||
|
master_clock_rate = rate;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void radio::set_rx_srate(double srate)
|
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);
|
srslte_rf_set_rx_srate(&rf_device, srate);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -351,6 +345,11 @@ float radio::get_rx_gain()
|
||||||
|
|
||||||
void radio::set_tx_srate(double srate)
|
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);
|
cur_tx_srate = srslte_rf_set_tx_srate(&rf_device, srate);
|
||||||
burst_preamble_samples = (uint32_t) (cur_tx_srate * burst_preamble_sec);
|
burst_preamble_samples = (uint32_t) (cur_tx_srate * burst_preamble_sec);
|
||||||
if (burst_preamble_samples > burst_preamble_max_samples) {
|
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);
|
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
|
// Set Rx/Tx sampling rate
|
||||||
radio_h[r]->set_rx_srate(srate);
|
radio_h[r]->set_rx_srate(srate);
|
||||||
if (tx_enable) {
|
if (tx_enable) {
|
||||||
|
|
|
@ -82,20 +82,6 @@ void txrx::run_thread()
|
||||||
uint32_t sf_len = SRSLTE_SF_LEN_PRB(worker_com->cell.nof_prb);
|
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);
|
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);
|
log_h->console("Setting Sampling frequency %.2f MHz\n", (float) samp_rate/1000000);
|
||||||
|
|
||||||
// Configure radio
|
// Configure radio
|
||||||
|
|
|
@ -34,9 +34,17 @@
|
||||||
#include "srslte/radio/radio.h"
|
#include "srslte/radio/radio.h"
|
||||||
#include "srslte/srslte.h"
|
#include "srslte/srslte.h"
|
||||||
|
|
||||||
|
#include <cassert>
|
||||||
|
#include <cstdio>
|
||||||
|
#include <fstream>
|
||||||
|
#include <functional>
|
||||||
|
#include <iostream>
|
||||||
|
#include <memory>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
namespace srsue {
|
namespace srsue {
|
||||||
|
|
||||||
class async_scell_recv : public thread
|
class async_scell_recv : private thread
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
async_scell_recv();
|
async_scell_recv();
|
||||||
|
@ -75,14 +83,16 @@ private:
|
||||||
{
|
{
|
||||||
tti = 0;
|
tti = 0;
|
||||||
bzero(×tamp, sizeof(timestamp));
|
bzero(×tamp, sizeof(timestamp));
|
||||||
bzero(buffer, sizeof(buffer));
|
for (cf_t*& b : buffer) {
|
||||||
|
b = nullptr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
~phch_scell_recv_buffer()
|
~phch_scell_recv_buffer()
|
||||||
{
|
{
|
||||||
for (int i = 0; i < SRSLTE_MAX_PORTS; i++) {
|
for (cf_t*& b : buffer) {
|
||||||
if (buffer[i]) {
|
if (b) {
|
||||||
free(buffer[i]);
|
free(b);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -115,7 +125,6 @@ private:
|
||||||
void reset();
|
void reset();
|
||||||
void radio_error();
|
void radio_error();
|
||||||
void set_ue_sync_opts(srslte_ue_sync_t* q, float cfo);
|
void set_ue_sync_opts(srslte_ue_sync_t* q, float cfo);
|
||||||
void run_thread();
|
|
||||||
|
|
||||||
void state_decode_mib();
|
void state_decode_mib();
|
||||||
void state_write_buffer();
|
void state_write_buffer();
|
||||||
|
@ -130,6 +139,7 @@ private:
|
||||||
bool running;
|
bool running;
|
||||||
|
|
||||||
uint32_t tti;
|
uint32_t tti;
|
||||||
|
uint32_t radio_idx;
|
||||||
|
|
||||||
// Pointers to other classes
|
// Pointers to other classes
|
||||||
srslte::log* log_h;
|
srslte::log* log_h;
|
||||||
|
@ -168,8 +178,14 @@ private:
|
||||||
|
|
||||||
float dl_freq;
|
float dl_freq;
|
||||||
float ul_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
|
} // namespace srsue
|
||||||
|
|
||||||
#endif // SRSUE_ASYNCH_SCELL_RECV_H
|
#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_periodic_cqi(srslte_uci_data_t* uci_data);
|
||||||
void set_uci_aperiodic_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);
|
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();
|
uint32_t get_wideband_cqi();
|
||||||
srslte_cqi_report_mode_t aperiodic_mode(asn1::rrc::cqi_report_mode_aperiodic_e mode);
|
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);
|
void parse_antenna_info(asn1::rrc::phys_cfg_ded_s* dedicated);
|
||||||
|
|
|
@ -157,7 +157,7 @@ private:
|
||||||
std::vector<sf_worker*> workers;
|
std::vector<sf_worker*> workers;
|
||||||
phy_common common;
|
phy_common common;
|
||||||
sync sfsync;
|
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];
|
uint32_t scell_earfcn[SRSLTE_MAX_CARRIERS - 1];
|
||||||
prach prach_buffer;
|
prach prach_buffer;
|
||||||
|
|
||||||
|
|
|
@ -53,7 +53,7 @@ public:
|
||||||
phy_common* _worker_com,
|
phy_common* _worker_com,
|
||||||
srslte::log* _log_h,
|
srslte::log* _log_h,
|
||||||
srslte::log* _log_phy_lib_h,
|
srslte::log* _log_phy_lib_h,
|
||||||
async_scell_recv* scell_sync_,
|
async_scell_recv_vector* scell_sync_,
|
||||||
uint32_t prio,
|
uint32_t prio,
|
||||||
int sync_cpu_affinity = -1);
|
int sync_cpu_affinity = -1);
|
||||||
void stop();
|
void stop();
|
||||||
|
@ -279,7 +279,7 @@ private:
|
||||||
radio_interface_phy* radio_h;
|
radio_interface_phy* radio_h;
|
||||||
phy_common* worker_com;
|
phy_common* worker_com;
|
||||||
prach* prach_buffer;
|
prach* prach_buffer;
|
||||||
async_scell_recv* scell_sync;
|
async_scell_recv_vector* scell_sync;
|
||||||
|
|
||||||
// Object for synchronization of the primary cell
|
// Object for synchronization of the primary cell
|
||||||
srslte_ue_sync_t ue_sync;
|
srslte_ue_sync_t ue_sync;
|
||||||
|
|
|
@ -42,51 +42,66 @@ class ue_radio : public ue_radio_base, public radio_interface_phy
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ue_radio();
|
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_);
|
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);
|
static void rf_msg(srslte_rf_error_t error);
|
||||||
void handle_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
|
// radio_interface_phy
|
||||||
bool is_init() { return radios.at(0)->is_init(); }
|
bool is_init() override { return radios.at(0)->is_init(); }
|
||||||
void reset() { return radios.at(0)->reset(); }
|
void reset() override { return radios.at(0)->reset(); }
|
||||||
bool is_continuous_tx() { return radios.at(0)->is_continuous_tx(); }
|
bool is_continuous_tx() override { 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 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) {
|
return radios.at(radio_idx)->tx(buffer, nof_samples, tx_time);
|
||||||
radio->tx(buffer, nof_samples, tx_time);
|
|
||||||
}
|
}
|
||||||
return true;
|
void tx_end() override { return radios.at(0)->tx_end(); }
|
||||||
}
|
|
||||||
void tx_end() { 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); }
|
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) { return radios.at(0)->set_rx_gain_th(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) { return radios.at(radio_idx)->get_rx_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 double& freq) { radios.at(radio_idx)->set_tx_freq(0, freq); }
|
void set_tx_freq(const uint32_t& radio_idx, const uint32_t& channel_idx, const double& freq) override
|
||||||
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(); }
|
radios.at(radio_idx)->set_tx_freq(channel_idx, freq);
|
||||||
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(); }
|
void set_rx_freq(const uint32_t& radio_idx, const uint32_t& channel_idx, const double& freq) override
|
||||||
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); }
|
radios.at(radio_idx)->set_rx_freq(channel_idx, freq);
|
||||||
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); }
|
double get_freq_offset() override { return radios.at(0)->get_freq_offset(); }
|
||||||
float set_tx_power(const float& power) { return radios.at(0)->set_tx_power(power); }
|
double get_tx_freq(const uint32_t& radio_idx) override { return radios.at(radio_idx)->get_tx_freq(); }
|
||||||
srslte_rf_info_t* get_info(const uint32_t& radio_idx) { return radios.at(radio_idx)->get_info(); }
|
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:
|
private:
|
||||||
srsue::rf_args_t args;
|
srsue::rf_args_t args;
|
||||||
|
|
|
@ -41,8 +41,6 @@ public:
|
||||||
ue_radio_base(){};
|
ue_radio_base(){};
|
||||||
virtual ~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 std::string get_type() = 0;
|
||||||
|
|
||||||
virtual int init(const srsue::rf_args_t& args_, srslte::logger* logger_) = 0;
|
virtual int init(const srsue::rf_args_t& args_, srslte::logger* logger_) = 0;
|
||||||
|
|
|
@ -131,6 +131,9 @@ private:
|
||||||
uint64_t nof_pkts;
|
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
|
} // namespace srsue
|
||||||
|
|
||||||
#endif // SRSUE_DL_HARQ_H
|
#endif // SRSUE_DL_HARQ_H
|
||||||
|
|
|
@ -49,11 +49,7 @@ class mac : public mac_interface_phy_lte,
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
mac();
|
mac();
|
||||||
bool init(phy_interface_mac_lte* phy,
|
bool init(phy_interface_mac_lte* phy, rlc_interface_mac* rlc, rrc_interface_mac* rrc, srslte::log* log_h);
|
||||||
rlc_interface_mac* rlc,
|
|
||||||
rrc_interface_mac* rrc,
|
|
||||||
srslte::log* log_h,
|
|
||||||
uint32_t nof_carriers = 1);
|
|
||||||
void stop();
|
void stop();
|
||||||
|
|
||||||
void get_metrics(mac_metrics_t m[SRSLTE_MAX_CARRIERS]);
|
void get_metrics(mac_metrics_t m[SRSLTE_MAX_CARRIERS]);
|
||||||
|
@ -81,7 +77,7 @@ public:
|
||||||
void pcch_start_rx();
|
void pcch_start_rx();
|
||||||
void setup_lcid(uint32_t lcid, uint32_t lcg, uint32_t priority, int PBR_x_tti, uint32_t BSD);
|
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 mch_start_rx(uint32_t lcid);
|
||||||
void reconfiguration();
|
void reconfiguration(const uint32_t& cc_idx, const bool& enable);
|
||||||
void reset();
|
void reset();
|
||||||
void wait_uplink();
|
void wait_uplink();
|
||||||
|
|
||||||
|
@ -140,8 +136,9 @@ private:
|
||||||
demux demux_unit;
|
demux demux_unit;
|
||||||
|
|
||||||
/* DL/UL HARQ */
|
/* DL/UL HARQ */
|
||||||
std::vector<dl_harq_entity> dl_harq;
|
dl_harq_entity_vector dl_harq;
|
||||||
std::vector<ul_harq_entity> ul_harq;
|
ul_harq_entity_vector ul_harq;
|
||||||
|
ul_harq_cfg_t ul_harq_cfg;
|
||||||
|
|
||||||
/* MAC Uplink-related Procedures */
|
/* MAC Uplink-related Procedures */
|
||||||
ra_proc ra_procedure;
|
ra_proc ra_procedure;
|
||||||
|
|
|
@ -117,6 +117,9 @@ private:
|
||||||
ra_proc* ra_procedure;
|
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
|
} // namespace srsue
|
||||||
|
|
||||||
#endif // SRSUE_UL_HARQ_H
|
#endif // SRSUE_UL_HARQ_H
|
||||||
|
|
|
@ -45,7 +45,7 @@
|
||||||
|
|
||||||
namespace srsue {
|
namespace srsue {
|
||||||
|
|
||||||
async_scell_recv::async_scell_recv()
|
async_scell_recv::async_scell_recv() : thread()
|
||||||
{
|
{
|
||||||
initiated = false;
|
initiated = false;
|
||||||
buffer_write_idx = 0;
|
buffer_write_idx = 0;
|
||||||
|
@ -55,6 +55,7 @@ async_scell_recv::async_scell_recv()
|
||||||
bzero(&cell, sizeof(srslte_cell_t));
|
bzero(&cell, sizeof(srslte_cell_t));
|
||||||
bzero(sf_buffer, sizeof(sf_buffer));
|
bzero(sf_buffer, sizeof(sf_buffer));
|
||||||
running = false;
|
running = false;
|
||||||
|
radio_idx = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
async_scell_recv::~async_scell_recv()
|
async_scell_recv::~async_scell_recv()
|
||||||
|
@ -63,9 +64,9 @@ async_scell_recv::~async_scell_recv()
|
||||||
srslte_ue_sync_free(&ue_sync);
|
srslte_ue_sync_free(&ue_sync);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < SRSLTE_MAX_PORTS; i++) {
|
for (auto& b : sf_buffer) {
|
||||||
if (sf_buffer[i]) {
|
if (b) {
|
||||||
free(sf_buffer[i]);
|
free(b);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -113,7 +114,7 @@ void async_scell_recv::init(radio_interface_phy* _radio_handler, phy_common* _wo
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pthread_cond_init(&cvar_buffer, NULL)) {
|
if (pthread_cond_init(&cvar_buffer, nullptr)) {
|
||||||
fprintf(stderr, "Initiating condition var\n");
|
fprintf(stderr, "Initiating condition var\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -164,9 +165,9 @@ void async_scell_recv::set_agc_enable(bool enable)
|
||||||
do_agc = enable;
|
do_agc = enable;
|
||||||
if (do_agc) {
|
if (do_agc) {
|
||||||
if (radio_h) {
|
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(
|
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 {
|
} else {
|
||||||
fprintf(stderr, "Error setting Secondary cell AGC: PHY not initiated\n");
|
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;
|
int ret = 0;
|
||||||
|
|
||||||
if (running) {
|
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);
|
log_h->debug("SYNC: received %d samples from radio\n", nsamples);
|
||||||
ret = nsamples;
|
ret = nsamples;
|
||||||
} else {
|
} else {
|
||||||
|
@ -264,18 +265,17 @@ bool async_scell_recv::set_scell_cell(uint32_t carrier_idx, srslte_cell_t* _cell
|
||||||
// Get transceiver mapping
|
// Get transceiver mapping
|
||||||
carrier_map_t* m = &worker_com->args->carrier_map[carrier_idx];
|
carrier_map_t* m = &worker_com->args->carrier_map[carrier_idx];
|
||||||
uint32_t channel_idx = m->channel_idx;
|
uint32_t channel_idx = m->channel_idx;
|
||||||
|
radio_idx = m->radio_idx;
|
||||||
|
|
||||||
// Set radio frequency if frequency changed
|
// 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;
|
dl_freq = srslte_band_fd(dl_earfcn) * 1e6f;
|
||||||
ul_freq = srslte_band_fu(srslte_band_ul_earfcn(dl_earfcn)) * 1e6f;
|
ul_freq = srslte_band_fu(srslte_band_ul_earfcn(dl_earfcn)) * 1e6f;
|
||||||
radio_h->set_rx_freq(channel_idx, dl_freq);
|
for (uint32_t p = 0; p < worker_com->args->nof_rx_ant; p++) {
|
||||||
radio_h->set_tx_freq(channel_idx, ul_freq);
|
radio_h->set_rx_freq(m->radio_idx, m->channel_idx + p, dl_freq);
|
||||||
Info("Setting DL: %.1f MHz; UL %.1fMHz; Radio/Chan: %d/%d\n",
|
radio_h->set_tx_freq(m->radio_idx, m->channel_idx + p, ul_freq);
|
||||||
dl_freq / 1e6,
|
}
|
||||||
ul_freq / 1e6,
|
Info("Setting DL: %.1f MHz; UL %.1fMHz; Radio/Chan: %d/%d\n", dl_freq / 1e6, ul_freq / 1e6, radio_idx, channel_idx);
|
||||||
m->radio_idx,
|
|
||||||
m->channel_idx);
|
|
||||||
ul_dl_factor = ul_freq / dl_freq;
|
ul_dl_factor = ul_freq / dl_freq;
|
||||||
current_earfcn[channel_idx] = dl_earfcn;
|
current_earfcn[channel_idx] = dl_earfcn;
|
||||||
reset_ue_sync = true;
|
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
|
// Detect change in cell configuration
|
||||||
if (memcmp(&cell, _cell, sizeof(srslte_cell_t)) != 0) {
|
if (memcmp(&cell, _cell, sizeof(srslte_cell_t)) != 0) {
|
||||||
// Set sampling rate, if number of PRB changed
|
// 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);
|
double srate = srslte_sampling_freq_hz(_cell->nof_prb);
|
||||||
if (srate < 10e6) {
|
radio_h->set_rx_srate(radio_idx, srate);
|
||||||
radio_h->set_master_clock_rate(4 * srate);
|
radio_h->set_tx_srate(radio_idx, srate);
|
||||||
} else {
|
|
||||||
radio_h->set_master_clock_rate(srate);
|
|
||||||
}
|
|
||||||
radio_h->set_rx_srate(srate);
|
|
||||||
radio_h->set_tx_srate(srate);
|
|
||||||
Info("Setting SRate to %.2f MHz\n", srate / 1e6);
|
Info("Setting SRate to %.2f MHz\n", srate / 1e6);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -344,7 +339,7 @@ void async_scell_recv::state_decode_mib()
|
||||||
|
|
||||||
if (sfidx == 0) {
|
if (sfidx == 0) {
|
||||||
// Run only for sub-frame index 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) {
|
if (n < SRSLTE_SUCCESS) {
|
||||||
// Error decoding MIB, log error
|
// Error decoding MIB, log error
|
||||||
|
@ -502,10 +497,10 @@ bool async_scell_recv::tti_align(uint32_t tti)
|
||||||
bool timedout = false;
|
bool timedout = false;
|
||||||
|
|
||||||
while (!ret && !timedout && buffer_write_idx == buffer_read_idx && running) {
|
while (!ret && !timedout && buffer_write_idx == buffer_read_idx && running) {
|
||||||
struct timespec timeToWait;
|
struct timespec timeToWait = {};
|
||||||
struct timeval now;
|
struct timeval now = {};
|
||||||
|
|
||||||
gettimeofday(&now, NULL);
|
gettimeofday(&now, nullptr);
|
||||||
timeToWait.tv_sec = now.tv_sec;
|
timeToWait.tv_sec = now.tv_sec;
|
||||||
timeToWait.tv_nsec = (now.tv_usec + 1000UL) * 1000UL;
|
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.llr_is_8bit = true;
|
||||||
ue_dl.pdsch.dl_sch.llr_is_8bit = true;
|
ue_dl.pdsch.dl_sch.llr_is_8bit = true;
|
||||||
}
|
}
|
||||||
|
pregen_enabled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
cc_worker::~cc_worker()
|
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);
|
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
|
* Configuration Functions
|
||||||
|
|
|
@ -42,13 +42,12 @@ using namespace asn1::rrc;
|
||||||
|
|
||||||
namespace srsue {
|
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 = {};
|
tdd_config = {};
|
||||||
prach_cfg = {};
|
prach_cfg = {};
|
||||||
args = {};
|
args = {};
|
||||||
ZERO_OBJECT(scell_earfcn);
|
ZERO_OBJECT(scell_earfcn);
|
||||||
ZERO_OBJECT(scell_sync);
|
|
||||||
n_ta = 0;
|
n_ta = 0;
|
||||||
initiated = false;
|
initiated = false;
|
||||||
}
|
}
|
||||||
|
@ -194,7 +193,9 @@ void phy::run_thread()
|
||||||
|
|
||||||
// Load Asynchronous SCell objects
|
// Load Asynchronous SCell objects
|
||||||
for (int i = 0; i < (int)args.nof_radios - 1; i++) {
|
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
|
// Warning this must be initialized after all workers have been added to the pool
|
||||||
|
@ -205,7 +206,7 @@ void phy::run_thread()
|
||||||
&common,
|
&common,
|
||||||
log_h,
|
log_h,
|
||||||
log_phy_lib_h,
|
log_phy_lib_h,
|
||||||
scell_sync,
|
&scell_sync,
|
||||||
SF_RECV_THREAD_PRIO,
|
SF_RECV_THREAD_PRIO,
|
||||||
args.sync_cpu_affinity);
|
args.sync_cpu_affinity);
|
||||||
|
|
||||||
|
@ -229,7 +230,7 @@ void phy::stop()
|
||||||
if (initiated) {
|
if (initiated) {
|
||||||
sfsync.stop();
|
sfsync.stop();
|
||||||
for (uint32_t i = 0; i < args.nof_radios - 1; i++) {
|
for (uint32_t i = 0; i < args.nof_radios - 1; i++) {
|
||||||
scell_sync[i].stop();
|
scell_sync.at(i)->stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
workers_pool.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 SCell does not share synchronism with PCell ...
|
||||||
if (m->radio_idx > 0) {
|
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 {
|
} else {
|
||||||
// Change frequency only if the earfcn was modified
|
// Change frequency only if the earfcn was modified
|
||||||
if (scell_earfcn[cc_idx - 1] != earfcn) {
|
if (scell_earfcn[cc_idx - 1] != earfcn) {
|
||||||
float dl_freq = srslte_band_fd(earfcn) * 1e6f;
|
float dl_freq = srslte_band_fd(earfcn) * 1e6f;
|
||||||
float ul_freq = srslte_band_fu(srslte_band_ul_earfcn(earfcn)) * 1e6f;
|
float ul_freq = srslte_band_fu(srslte_band_ul_earfcn(earfcn)) * 1e6f;
|
||||||
radio->set_rx_freq(m->channel_idx, dl_freq);
|
for (uint32_t p = 0; p < common.args->nof_rx_ant; p++) {
|
||||||
radio->set_tx_freq(m->channel_idx, ul_freq);
|
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 each radio, transmit
|
||||||
for (uint32_t i = 0; i < args->nof_radios; i++) {
|
for (uint32_t i = 0; i < args->nof_radios; i++) {
|
||||||
if (tx_enable && !srslte_timestamp_iszero(&tx_time[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;
|
is_first_of_burst[i] = false;
|
||||||
} else {
|
} else {
|
||||||
if (radio_h[i].is_continuous_tx()) {
|
if (radio_h->is_continuous_tx()) {
|
||||||
if (!is_first_of_burst[i]) {
|
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 {
|
} else {
|
||||||
if (!is_first_of_burst[i]) {
|
if (!is_first_of_burst[i]) {
|
||||||
radio_h[i].tx_end();
|
radio_h->tx_end();
|
||||||
is_first_of_burst[i] = true;
|
is_first_of_burst[i] = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -331,7 +331,7 @@ void sf_worker::update_measurements()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!rssi_read_cnt) {
|
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++;
|
rssi_read_cnt++;
|
||||||
if (rssi_read_cnt == 1000) {
|
if (rssi_read_cnt == 1000) {
|
||||||
|
|
|
@ -66,7 +66,7 @@ void sync::init(radio_interface_phy* _radio,
|
||||||
phy_common* _worker_com,
|
phy_common* _worker_com,
|
||||||
srslte::log* _log_h,
|
srslte::log* _log_h,
|
||||||
srslte::log* _log_phy_lib_h,
|
srslte::log* _log_phy_lib_h,
|
||||||
async_scell_recv* scell_sync_,
|
async_scell_recv_vector* scell_sync_,
|
||||||
uint32_t prio,
|
uint32_t prio,
|
||||||
int sync_cpu_affinity)
|
int sync_cpu_affinity)
|
||||||
{
|
{
|
||||||
|
@ -476,8 +476,8 @@ void sync::run_thread()
|
||||||
srslte_timestamp_init(&tx_time, 0, 0);
|
srslte_timestamp_init(&tx_time, 0, 0);
|
||||||
|
|
||||||
// Request TTI aligment
|
// Request TTI aligment
|
||||||
if (scell_sync[i].tti_align(tti)) {
|
if (scell_sync->at(i)->tti_align(tti)) {
|
||||||
scell_sync[i].read_sf(buffer[i + 1], &tx_time);
|
scell_sync->at(i)->read_sf(buffer[i + 1], &tx_time);
|
||||||
srslte_timestamp_add(&tx_time, 0, TX_DELAY * 1e-3 - time_adv_sec);
|
srslte_timestamp_add(&tx_time, 0, TX_DELAY * 1e-3 - time_adv_sec);
|
||||||
} else {
|
} else {
|
||||||
// Failed, keep default Timestamp
|
// Failed, keep default Timestamp
|
||||||
|
@ -572,7 +572,7 @@ void sync::run_thread()
|
||||||
}
|
}
|
||||||
Debug("Discarting %d samples\n", nsamples);
|
Debug("Discarting %d samples\n", nsamples);
|
||||||
srslte_timestamp_t rx_time;
|
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");
|
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
|
// 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;
|
do_agc = enable;
|
||||||
if (do_agc) {
|
if (do_agc) {
|
||||||
if (running && radio_h) {
|
if (running && radio_h) {
|
||||||
srslte_rf_info_t *rf_info = radio_h->get_info();
|
srslte_rf_info_t* rf_info = radio_h->get_info(0);
|
||||||
srslte_ue_sync_start_agc(&ue_sync,
|
srslte_ue_sync_start_agc(
|
||||||
callback_set_rx_gain,
|
&ue_sync, callback_set_rx_gain, rf_info->min_rx_gain, rf_info->max_rx_gain, radio_h->get_rx_gain(0));
|
||||||
rf_info->min_rx_gain,
|
|
||||||
rf_info->max_rx_gain,
|
|
||||||
radio_h->get_rx_gain());
|
|
||||||
search_p.set_agc_enable(true);
|
search_p.set_agc_enable(true);
|
||||||
} else {
|
} else {
|
||||||
ERROR("Error setting AGC: PHY not initiatec\n");
|
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];
|
carrier_map_t* m = &worker_com->args->carrier_map[0];
|
||||||
for (uint32_t i = 0; i < worker_com->args->nof_rx_ant; i++) {
|
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_rx_freq(m->radio_idx, m->channel_idx + i, set_dl_freq);
|
||||||
radio_h->set_tx_freq(m->channel_idx + i, set_ul_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);
|
srslte_ue_sync_reset(&ue_sync);
|
||||||
|
|
||||||
|
@ -875,23 +872,9 @@ void sync::set_sampling_rate()
|
||||||
current_srate = new_srate;
|
current_srate = new_srate;
|
||||||
Info("SYNC: Setting sampling rate %.2f MHz\n", current_srate/1000000);
|
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;
|
srate_mode = SRATE_CAMP;
|
||||||
radio_h->set_rx_srate(current_srate);
|
radio_h->set_rx_srate(0, current_srate);
|
||||||
radio_h->set_tx_srate(current_srate);
|
radio_h->set_tx_srate(0, current_srate);
|
||||||
} else {
|
} else {
|
||||||
Error("Error setting sampling rate for cell with %d PRBs\n", cell.nof_prb);
|
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)
|
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;
|
int offset = nsamples - current_sflen;
|
||||||
if (abs(offset) < 10 && offset != 0) {
|
if (abs(offset) < 10 && offset != 0) {
|
||||||
next_offset += offset;
|
next_offset += offset;
|
||||||
|
@ -987,12 +970,12 @@ float sync::search::get_last_cfo()
|
||||||
void sync::search::set_agc_enable(bool enable)
|
void sync::search::set_agc_enable(bool enable)
|
||||||
{
|
{
|
||||||
if (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,
|
srslte_ue_sync_start_agc(&ue_mib_sync.ue_sync,
|
||||||
callback_set_rx_gain,
|
callback_set_rx_gain,
|
||||||
rf_info->min_rx_gain,
|
rf_info->min_rx_gain,
|
||||||
rf_info->max_rx_gain,
|
rf_info->max_rx_gain,
|
||||||
p->radio_h->get_rx_gain());
|
p->radio_h->get_rx_gain(0));
|
||||||
} else {
|
} else {
|
||||||
ERROR("Error stop AGC not implemented\n");
|
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) {
|
if (p->srate_mode != SRATE_FIND) {
|
||||||
p->srate_mode = SRATE_FIND;
|
p->srate_mode = SRATE_FIND;
|
||||||
p->radio_h->set_rx_srate(1.92e6);
|
p->radio_h->set_rx_srate(0, 1.92e6);
|
||||||
p->radio_h->set_tx_srate(1.92e6);
|
p->radio_h->set_tx_srate(0, 1.92e6);
|
||||||
Info("SYNC: Setting Cell Search sampling rate\n");
|
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
|
// Init and start Radio
|
||||||
char* dev_name = NULL;
|
char* dev_name = nullptr;
|
||||||
if (args.device_name.compare("auto")) {
|
if (args.device_name != "auto") {
|
||||||
dev_name = (char*)args.device_name.c_str();
|
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++) {
|
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();
|
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
|
// Set RF options
|
||||||
if (args.time_adv_nsamples.compare("auto")) {
|
if (args.time_adv_nsamples == "auto") {
|
||||||
int t = atoi(args.time_adv_nsamples.c_str());
|
int t = (int)strtol(args.time_adv_nsamples.c_str(), nullptr, 10);
|
||||||
radio->set_tx_adv(abs(t));
|
radio->set_tx_adv(abs(t));
|
||||||
radio->set_tx_adv_neg(t < 0);
|
radio->set_tx_adv_neg(t < 0);
|
||||||
}
|
}
|
||||||
if (args.burst_preamble.compare("auto")) {
|
if (args.burst_preamble == "auto") {
|
||||||
radio->set_burst_preamble(atof(args.burst_preamble.c_str()));
|
radio->set_burst_preamble(strtof(args.burst_preamble.c_str(), nullptr));
|
||||||
}
|
}
|
||||||
if (args.continuous_tx.compare("auto")) {
|
if (args.continuous_tx == "auto") {
|
||||||
log.console("set continuous %s\n", args.continuous_tx.c_str());
|
radio->set_continuous_tx(!(args.continuous_tx == "yes"));
|
||||||
radio->set_continuous_tx(args.continuous_tx.compare("yes") ? false : true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set PHY options
|
// Set PHY options
|
||||||
|
|
|
@ -37,24 +37,24 @@ using namespace asn1::rrc;
|
||||||
|
|
||||||
namespace srsue {
|
namespace srsue {
|
||||||
|
|
||||||
mac::mac() :
|
mac::mac() : timers(64), pdu_process_thread(&demux_unit), mch_msg(10), running(false), pcap(nullptr)
|
||||||
timers(64),
|
|
||||||
pdu_process_thread(&demux_unit),
|
|
||||||
mch_msg(10),
|
|
||||||
dl_harq(SRSLTE_MAX_CARRIERS),
|
|
||||||
ul_harq(SRSLTE_MAX_CARRIERS),
|
|
||||||
running(false),
|
|
||||||
pcap(NULL)
|
|
||||||
{
|
{
|
||||||
|
// 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));
|
bzero(&metrics, sizeof(mac_metrics_t));
|
||||||
clear_rntis();
|
clear_rntis();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool mac::init(phy_interface_mac_lte* phy,
|
bool mac::init(phy_interface_mac_lte* phy, rlc_interface_mac* rlc, rrc_interface_mac* rrc, srslte::log* log_h_)
|
||||||
rlc_interface_mac* rlc,
|
|
||||||
rrc_interface_mac* rrc,
|
|
||||||
srslte::log* log_h_,
|
|
||||||
uint32_t nof_carriers)
|
|
||||||
{
|
{
|
||||||
phy_h = phy;
|
phy_h = phy;
|
||||||
rlc_h = rlc;
|
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);
|
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);
|
sr_procedure.init(phy_h, rrc, log_h);
|
||||||
|
|
||||||
for (uint32_t r = 0; r < nof_carriers; r++) {
|
// Create UL/DL unique HARQ pointers
|
||||||
ul_harq[r].init(log_h, &uernti, &ra_procedure, &mux_unit);
|
ul_harq.at(0)->init(log_h, &uernti, &ra_procedure, &mux_unit);
|
||||||
dl_harq[r].init(log_h, &uernti, timers.get(timer_alignment), &demux_unit);
|
dl_harq.at(0)->init(log_h, &uernti, timers.get(timer_alignment), &demux_unit);
|
||||||
}
|
|
||||||
|
|
||||||
reset();
|
reset();
|
||||||
|
|
||||||
|
@ -103,19 +102,32 @@ void mac::stop()
|
||||||
void mac::start_pcap(srslte::mac_pcap* pcap_)
|
void mac::start_pcap(srslte::mac_pcap* pcap_)
|
||||||
{
|
{
|
||||||
pcap = pcap_;
|
pcap = pcap_;
|
||||||
for (uint32_t r = 0; r < dl_harq.size(); r++) {
|
for (auto& r : dl_harq) {
|
||||||
dl_harq[r].start_pcap(pcap);
|
r->start_pcap(pcap);
|
||||||
}
|
}
|
||||||
for (uint32_t r = 0; r < ul_harq.size(); r++) {
|
for (auto& r : ul_harq) {
|
||||||
ul_harq[r].start_pcap(pcap);
|
r->start_pcap(pcap);
|
||||||
}
|
}
|
||||||
ra_procedure.start_pcap(pcap);
|
ra_procedure.start_pcap(pcap);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Implement Section 5.8
|
// 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() {
|
void mac::wait_uplink() {
|
||||||
|
@ -138,11 +150,11 @@ void mac::reset()
|
||||||
|
|
||||||
timer_alignment_expire();
|
timer_alignment_expire();
|
||||||
|
|
||||||
for (uint32_t r = 0; r < dl_harq.size(); r++) {
|
for (auto& r : dl_harq) {
|
||||||
dl_harq[r].reset();
|
r->reset();
|
||||||
}
|
}
|
||||||
for (uint32_t r = 0; r < ul_harq.size(); r++) {
|
for (auto& r : ul_harq) {
|
||||||
ul_harq[r].reset();
|
r->reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
mux_unit.msg3_flush();
|
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)
|
void mac::bcch_start_rx(int si_window_start, int si_window_length)
|
||||||
{
|
{
|
||||||
if (si_window_length >= 0 && si_window_start >= 0) {
|
if (si_window_length >= 0 && si_window_start >= 0) {
|
||||||
for (uint32_t r = 0; r < dl_harq.size(); r++) {
|
dl_harq.at(0)->set_si_window_start(si_window_start);
|
||||||
dl_harq[r].set_si_window_start(si_window_start);
|
|
||||||
}
|
|
||||||
this->si_window_length = si_window_length;
|
this->si_window_length = si_window_length;
|
||||||
this->si_window_start = si_window_start;
|
this->si_window_start = si_window_start;
|
||||||
} else {
|
} else {
|
||||||
|
@ -383,7 +393,7 @@ void mac::tb_decoded(uint32_t cc_idx, mac_grant_dl_t grant, bool ack[SRSLTE_MAX_
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
dl_harq[cc_idx].tb_decoded(grant, ack);
|
dl_harq.at(cc_idx)->tb_decoded(grant, ack);
|
||||||
pdu_process_thread.notify();
|
pdu_process_thread.notify();
|
||||||
|
|
||||||
for (uint32_t tb = 0; tb < SRSLTE_MAX_CODEWORDS; tb++) {
|
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()) {
|
if (grant.rnti == uernti.crnti && ra_procedure.is_contention_resolution()) {
|
||||||
ra_procedure.pdcch_to_crnti(false);
|
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 {
|
} else {
|
||||||
/* Discard */
|
/* Discard */
|
||||||
Info("Discarding dci in CC %d, RNTI=0x%x\n", cc_idx, grant.rnti);
|
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)
|
void mac::reset_harq(uint32_t cc_idx)
|
||||||
{
|
{
|
||||||
if (cc_idx < dl_harq.size()) {
|
if (cc_idx < dl_harq.size()) {
|
||||||
dl_harq[cc_idx].reset();
|
dl_harq.at(cc_idx)->reset();
|
||||||
ul_harq[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;
|
is_first_ul_grant = false;
|
||||||
phr_procedure.start_timer();
|
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++;
|
metrics[cc_idx].tx_pkts++;
|
||||||
|
|
||||||
if (grant.phich_available) {
|
if (grant.phich_available) {
|
||||||
if (!grant.hi_value) {
|
if (!grant.hi_value) {
|
||||||
metrics[cc_idx].tx_errors++;
|
metrics[cc_idx].tx_errors++;
|
||||||
} else {
|
} 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()
|
void mac::timer_alignment_expire()
|
||||||
{
|
{
|
||||||
rrc_h->release_pucch_srs();
|
rrc_h->release_pucch_srs();
|
||||||
for (uint32_t r = 0; r < dl_harq.size(); r++) {
|
for (auto& r : dl_harq) {
|
||||||
dl_harq[r].reset();
|
r->reset();
|
||||||
}
|
}
|
||||||
for (uint32_t r = 0; r < ul_harq.size(); r++) {
|
for (auto& r : ul_harq) {
|
||||||
ul_harq[r].reset();
|
r->reset();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -539,8 +549,11 @@ void mac::set_config(mac_cfg_t& mac_cfg)
|
||||||
phr_procedure.set_config(mac_cfg.get_phr_cfg());
|
phr_procedure.set_config(mac_cfg.get_phr_cfg());
|
||||||
sr_procedure.set_config(mac_cfg.get_sr_cfg());
|
sr_procedure.set_config(mac_cfg.get_sr_cfg());
|
||||||
ra_procedure.set_config(mac_cfg.get_rach_cfg());
|
ra_procedure.set_config(mac_cfg.get_rach_cfg());
|
||||||
for (uint32_t i = 0; i < ul_harq.size(); i++) {
|
ul_harq_cfg = mac_cfg.get_harq_cfg();
|
||||||
ul_harq[i].set_config(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());
|
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 dl_avg_ret_count = 0;
|
||||||
int ul_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_pkts += metrics[r].tx_pkts;
|
||||||
tx_errors += metrics[r].tx_errors;
|
tx_errors += metrics[r].tx_errors;
|
||||||
tx_brate += metrics[r].tx_brate;
|
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;
|
ul_buffer += metrics[r].ul_buffer;
|
||||||
|
|
||||||
if (metrics[r].rx_pkts) {
|
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++;
|
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,
|
rx_pkts ? ((float)100 * rx_errors / rx_pkts) : 0.0f,
|
||||||
dl_avg_ret,
|
dl_avg_ret,
|
||||||
tx_pkts ? ((float)100 * tx_errors / tx_pkts) : 0.0f,
|
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();
|
metrics[0].ul_buffer = (int)bsr_procedure.get_buffer_state();
|
||||||
memcpy(m, metrics, sizeof(mac_metrics_t) * SRSLTE_MAX_CARRIERS);
|
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;
|
rrc_conn_recfg_v920_ies_s* reconfig_r920 = &reconfig_r890->non_crit_ext;
|
||||||
if (reconfig_r920->non_crit_ext_present) {
|
if (reconfig_r920->non_crit_ext_present) {
|
||||||
rrc_conn_recfg_v1020_ies_s* reconfig_r1020 = &reconfig_r920->non_crit_ext;
|
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) {
|
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++) {
|
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) {
|
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