SRSENB: enabled multiple cells from rr.cfg

This commit is contained in:
Xavier Arteaga 2020-01-22 18:03:50 +01:00 committed by Xavier Arteaga
parent e5b1673b3b
commit b08c1f003e
15 changed files with 261 additions and 181 deletions

View File

@ -90,10 +90,10 @@ public:
virtual int ack_info(uint32_t tti, uint16_t rnti, uint32_t tb_idx, bool ack) = 0;
virtual int crc_info(uint32_t tti, uint16_t rnti, uint32_t nof_bytes, bool crc_res) = 0;
virtual int get_dl_sched(uint32_t tti, dl_sched_t* dl_sched_res) = 0;
virtual int get_mch_sched(uint32_t tti, bool is_mcch, dl_sched_t* dl_sched_res) = 0;
virtual int get_ul_sched(uint32_t tti, ul_sched_t* ul_sched_res) = 0;
virtual void set_sched_dl_tti_mask(uint8_t* tti_mask, uint32_t nof_sfs) = 0;
virtual int get_dl_sched(uint32_t tti, dl_sched_list_t& dl_sched_res) = 0;
virtual int get_mch_sched(uint32_t tti, bool is_mcch, dl_sched_list_t& dl_sched_res) = 0;
virtual int get_ul_sched(uint32_t tti, ul_sched_list_t& ul_sched_res) = 0;
virtual void set_sched_dl_tti_mask(uint8_t* tti_mask, uint32_t nof_sfs) = 0;
// Radio-Link status
virtual void rl_failure(uint16_t rnti) = 0;

View File

@ -25,7 +25,6 @@
#include <string.h>
#include "phy_common.h"
#include "srslte/srslte.h"
#define LOG_EXECTIME

View File

@ -36,15 +36,6 @@
namespace srsenb {
struct phy_cfg_t {
srslte_cell_t cell;
asn1::rrc::prach_cfg_sib_s prach_cnfg;
asn1::rrc::pdsch_cfg_common_s pdsch_cnfg;
asn1::rrc::pusch_cfg_common_s pusch_cnfg;
asn1::rrc::pucch_cfg_common_s pucch_cnfg;
asn1::rrc::srs_ul_cfg_common_c srs_ul_cnfg;
};
class phy : public enb_phy_base, public phy_interface_stack_lte, public srslte::phy_interface_radio
{
public:

View File

@ -22,6 +22,7 @@
#ifndef SRSENB_PHCH_COMMON_H
#define SRSENB_PHCH_COMMON_H
#include "phy_interfaces.h"
#include "srslte/common/gen_mch_tables.h"
#include "srslte/common/interfaces_common.h"
#include "srslte/common/log.h"
@ -38,25 +39,6 @@
namespace srsenb {
typedef struct {
std::string type;
srslte::phy_log_args_t log;
uint32_t nof_carriers;
float max_prach_offset_us;
int pusch_max_its;
bool pusch_8bit_decoder;
float tx_amplitude;
int nof_phy_threads;
std::string equalizer_mode;
float estimator_fil_w;
bool pregenerate_signals;
srslte::channel::args_t dl_channel_args;
srslte::channel::args_t ul_channel_args;
} phy_args_t;
class phy_common
{
public:
@ -65,7 +47,8 @@ public:
void set_nof_workers(uint32_t nof_workers);
bool init(const srslte_cell_t& cell_, srslte::radio_interface_phy* radio_handler, stack_interface_phy_lte* mac);
bool
init(const phy_cell_cfg_list_t& cell_list_, srslte::radio_interface_phy* radio_handler, stack_interface_phy_lte* mac);
void reset();
void stop();
@ -73,8 +56,12 @@ public:
worker_end(uint32_t tx_mutex_cnt, cf_t* buffer[SRSLTE_MAX_PORTS], uint32_t nof_samples, srslte_timestamp_t tx_time);
// Common objects
srslte_cell_t cell = {};
phy_args_t params = {};
phy_cell_cfg_list_t cell_list;
phy_args_t params = {};
uint32_t get_nof_carriers() { return (uint32_t)cell_list.size(); };
uint32_t get_nof_prb() { return (uint32_t)cell_list[0].cell.nof_prb; };
uint32_t get_nof_ports() { return (uint32_t)cell_list[0].cell.nof_ports; };
// Physical Uplink Config common
srslte_ul_cfg_t ul_cfg_com = {};
@ -87,8 +74,8 @@ public:
srslte::channel_ptr dl_channel = nullptr;
// Common objects for schedulign grants
stack_interface_phy_lte::ul_sched_t ul_grants[TTIMOD_SZ] = {};
stack_interface_phy_lte::dl_sched_t dl_grants[TTIMOD_SZ] = {};
stack_interface_phy_lte::ul_sched_list_t ul_grants[TTIMOD_SZ] = {};
stack_interface_phy_lte::dl_sched_list_t dl_grants[TTIMOD_SZ] = {};
// Map of pending ACKs for each user
typedef struct {
@ -130,12 +117,12 @@ private:
uint32_t nof_workers = 0;
uint32_t max_workers = 0;
pthread_mutex_t user_mutex = {};
std::mutex user_mutex = {};
bool have_mtch_stop = false;
pthread_mutex_t mtch_mutex = {};
pthread_cond_t mtch_cvar = {};
phy_interface_stack_lte::phy_cfg_mbsfn_t mbsfn;
bool have_mtch_stop = false;
pthread_mutex_t mtch_mutex = {};
pthread_cond_t mtch_cvar = {};
phy_interface_stack_lte::phy_cfg_mbsfn_t mbsfn = {};
bool sib13_configured = false;
bool mcch_configured = false;
uint8_t mch_table[40] = {};

View File

@ -0,0 +1,75 @@
/*
* Copyright 2013-2019 Software Radio Systems Limited
*
* This file is part of srsLTE.
*
* srsLTE is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of
* the License, or (at your option) any later version.
*
* srsLTE is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* A copy of the GNU Affero General Public License can be found in
* the LICENSE file in the top-level directory of this distribution
* and at http://www.gnu.org/licenses/.
*
*/
#ifndef SRSENB_PHY_INTERFACES_H_
#define SRSENB_PHY_INTERFACES_H_
#include <inttypes.h>
#include <srslte/asn1/rrc_asn1.h>
#include <srslte/common/interfaces_common.h>
#include <srslte/phy/channel/channel.h>
#include <vector>
namespace srsenb {
struct phy_cell_cfg_t {
srslte_cell_t cell;
uint32_t rf_port;
uint32_t cell_id;
uint32_t dl_earfcn;
uint32_t ul_earfcn;
uint32_t root_seq_idx;
};
typedef std::vector<phy_cell_cfg_t> phy_cell_cfg_list_t;
struct phy_args_t {
std::string type;
srslte::phy_log_args_t log;
float max_prach_offset_us;
int pusch_max_its;
bool pusch_8bit_decoder;
float tx_amplitude;
int nof_phy_threads;
std::string equalizer_mode;
float estimator_fil_w;
bool pregenerate_signals;
srslte::channel::args_t dl_channel_args;
srslte::channel::args_t ul_channel_args;
};
struct phy_cfg_t {
// Individual cell/sector configuration list
phy_cell_cfg_list_t phy_cell_cfg;
// Common configuration for all cells
asn1::rrc::prach_cfg_sib_s prach_cnfg;
asn1::rrc::pdsch_cfg_common_s pdsch_cnfg;
asn1::rrc::pusch_cfg_common_s pusch_cnfg;
asn1::rrc::pucch_cfg_common_s pucch_cnfg;
asn1::rrc::srs_ul_cfg_common_c srs_ul_cnfg;
};
} // namespace srsenb
#endif // SRSENB_PHY_INTERFACES_H_

View File

@ -79,12 +79,12 @@ public:
{
return mac.crc_info(tti, rnti, nof_bytes, crc_res);
}
int get_dl_sched(uint32_t tti, dl_sched_t* dl_sched_res) final { return mac.get_dl_sched(tti, dl_sched_res); }
int get_mch_sched(uint32_t tti, bool is_mcch, dl_sched_t* dl_sched_res) final
int get_dl_sched(uint32_t tti, dl_sched_list_t& dl_sched_res) final { return mac.get_dl_sched(tti, dl_sched_res); }
int get_mch_sched(uint32_t tti, bool is_mcch, dl_sched_list_t& dl_sched_res) final
{
return mac.get_mch_sched(tti, is_mcch, dl_sched_res);
}
int get_ul_sched(uint32_t tti, ul_sched_t* ul_sched_res) final { return mac.get_ul_sched(tti, ul_sched_res); }
int get_ul_sched(uint32_t tti, ul_sched_list_t& ul_sched_res) final { return mac.get_ul_sched(tti, ul_sched_res); }
void set_sched_dl_tti_mask(uint8_t* tti_mask, uint32_t nof_sfs) final
{
mac.set_sched_dl_tti_mask(tti_mask, nof_sfs);

View File

@ -65,9 +65,9 @@ public:
int ack_info(uint32_t tti, uint16_t rnti, uint32_t tb_idx, bool ack);
int crc_info(uint32_t tti, uint16_t rnti, uint32_t nof_bytes, bool crc_res);
int get_dl_sched(uint32_t tti, dl_sched_t* dl_sched_res);
int get_ul_sched(uint32_t tti, ul_sched_t* ul_sched_res);
int get_mch_sched(uint32_t tti, bool is_mcch, dl_sched_t* dl_sched_res);
int get_dl_sched(uint32_t tti, dl_sched_list_t& dl_sched_res);
int get_ul_sched(uint32_t tti, ul_sched_list_t& ul_sched_res);
int get_mch_sched(uint32_t tti, bool is_mcch, dl_sched_list_t& dl_sched_res);
void set_sched_dl_tti_mask(uint8_t* tti_mask, uint32_t nof_sfs) final
{
scheduler.set_dl_tti_mask(tti_mask, nof_sfs);

View File

@ -792,9 +792,9 @@ int parse_cell_cfg(all_args_t* args_, srslte_cell_t* cell)
int parse_cfg_files(all_args_t* args_, rrc_cfg_t* rrc_cfg_, phy_cfg_t* phy_cfg_)
{
// Parse config files
srslte_cell_t cell_cfg = {};
srslte_cell_t cell_common_cfg = {};
if (enb_conf_sections::parse_cell_cfg(args_, &cell_cfg) != SRSLTE_SUCCESS) {
if (enb_conf_sections::parse_cell_cfg(args_, &cell_common_cfg) != SRSLTE_SUCCESS) {
fprintf(stderr, "Error parsing Cell configuration\n");
return SRSLTE_ERROR;
}
@ -812,11 +812,28 @@ int parse_cfg_files(all_args_t* args_, rrc_cfg_t* rrc_cfg_, phy_cfg_t* phy_cfg_)
}
// Set fields derived from others, and check for correctness of the parsed configuration
return enb_conf_sections::set_derived_args(args_, rrc_cfg_, phy_cfg_, &cell_cfg);
return enb_conf_sections::set_derived_args(args_, rrc_cfg_, phy_cfg_, &cell_common_cfg);
}
int set_derived_args(all_args_t* args_, rrc_cfg_t* rrc_cfg_, phy_cfg_t* phy_cfg_, srslte_cell_t* cell_cfg_)
{
// Copy cell struct to rrc and phy
rrc_cfg_->cell = *cell_cfg_;
// Create dedicated cell configuration from RRC configuration
for (auto& cfg : rrc_cfg_->cell_list) {
phy_cell_cfg_t phy_cell_cfg = {};
phy_cell_cfg.cell = *cell_cfg_;
phy_cell_cfg.cell.id = cfg.pci;
phy_cell_cfg.cell_id = cfg.cell_id;
phy_cell_cfg.root_seq_idx = cfg.root_seq_idx;
phy_cell_cfg.dl_earfcn = cfg.dl_earfcn;
phy_cell_cfg.ul_earfcn = cfg.ul_earfcn;
phy_cell_cfg.rf_port = cfg.rf_port;
phy_cfg_->phy_cell_cfg.push_back(phy_cell_cfg);
}
if (args_->enb.transmission_mode == 1) {
phy_cfg_->pdsch_cnfg.p_b = 0; // Default TM1
rrc_cfg_->sibs[1].sib2().rr_cfg_common.pdsch_cfg_common.p_b = 0;
@ -888,13 +905,9 @@ int set_derived_args(all_args_t* args_, rrc_cfg_t* rrc_cfg_, phy_cfg_t* phy_cfg_
}
}
// Copy cell struct to rrc and phy
rrc_cfg_->cell = *cell_cfg_;
phy_cfg_->cell = *cell_cfg_;
// Patch certain args that are not exposed yet
args_->rf.nof_radios = 1;
args_->rf.nof_rf_channels = args_->phy.nof_carriers;
args_->rf.nof_rf_channels = rrc_cfg_->cell_list.size();
args_->rf.nof_rx_ant = args_->enb.nof_ports;
return SRSLTE_SUCCESS;
@ -1371,7 +1384,6 @@ int parse_sibs(all_args_t* args_, rrc_cfg_t* rrc_cfg_, srsenb::phy_cfg_t* phy_co
}
// Copy PHY common configuration
phy_config_common->cell = {};
phy_config_common->prach_cnfg = sib2->rr_cfg_common.prach_cfg;
phy_config_common->pdsch_cnfg = sib2->rr_cfg_common.pdsch_cfg_common;
phy_config_common->pusch_cnfg = sib2->rr_cfg_common.pusch_cfg_common;

View File

@ -184,7 +184,6 @@ void parse_args(all_args_t* args, int argc, char* argv[])
("expert.print_buffer_state", bpo::value<bool>(&args->general.print_buffer_state)->default_value(false), "Prints on the console the buffer state every 10 seconds")
("expert.eea_pref_list", bpo::value<string>(&args->general.eea_pref_list)->default_value("EEA0, EEA2, EEA1"), "Ordered preference list for the selection of encryption algorithm (EEA) (default: EEA0, EEA2, EEA1).")
("expert.eia_pref_list", bpo::value<string>(&args->general.eia_pref_list)->default_value("EIA2, EIA1, EIA0"), "Ordered preference list for the selection of integrity algorithm (EIA) (default: EIA2, EIA1, EIA0).")
("expert.nof_carriers", bpo::value<uint32_t>(&args->phy.nof_carriers)->default_value(1), "Number of carriers")
// eMBMS section
("embms.enable", bpo::value<bool>(&args->stack.embms.enable)->default_value(false), "Enables MBMS in the eNB")

View File

@ -86,38 +86,40 @@ FILE* f;
void cc_worker::init(phy_common* phy_, srslte::log* log_h_, uint32_t cc_idx_)
{
phy = phy_;
log_h = log_h_;
cc_idx = cc_idx_;
srslte_cell_t cell = phy_->cell_list[cc_idx_].cell;
uint32_t nof_prb = phy_->get_nof_prb();
phy = phy_;
log_h = log_h_;
cc_idx = cc_idx_;
// Init cell here
for (int p = 0; p < SRSLTE_MAX_PORTS; p++) {
signal_buffer_rx[p] = (cf_t*)srslte_vec_malloc(2 * SRSLTE_SF_LEN_PRB(phy->cell.nof_prb) * sizeof(cf_t));
signal_buffer_rx[p] = srslte_vec_cf_malloc(2 * SRSLTE_SF_LEN_PRB(nof_prb));
if (!signal_buffer_rx[p]) {
ERROR("Error allocating memory\n");
return;
}
bzero(signal_buffer_rx[p], 2 * SRSLTE_SF_LEN_PRB(phy->cell.nof_prb) * sizeof(cf_t));
signal_buffer_tx[p] = (cf_t*)srslte_vec_malloc(2 * SRSLTE_SF_LEN_PRB(phy->cell.nof_prb) * sizeof(cf_t));
bzero(signal_buffer_rx[p], 2 * SRSLTE_SF_LEN_PRB(phy->get_nof_prb()) * sizeof(cf_t));
signal_buffer_tx[p] = (cf_t*)srslte_vec_malloc(2 * SRSLTE_SF_LEN_PRB(nof_prb) * sizeof(cf_t));
if (!signal_buffer_tx[p]) {
ERROR("Error allocating memory\n");
return;
}
bzero(signal_buffer_tx[p], 2 * SRSLTE_SF_LEN_PRB(phy->cell.nof_prb) * sizeof(cf_t));
bzero(signal_buffer_tx[p], 2 * SRSLTE_SF_LEN_PRB(nof_prb) * sizeof(cf_t));
}
if (srslte_enb_dl_init(&enb_dl, signal_buffer_tx, phy->cell.nof_prb)) {
if (srslte_enb_dl_init(&enb_dl, signal_buffer_tx, phy->get_nof_prb())) {
ERROR("Error initiating ENB DL\n");
return;
}
if (srslte_enb_dl_set_cell(&enb_dl, phy->cell)) {
if (srslte_enb_dl_set_cell(&enb_dl, cell)) {
ERROR("Error initiating ENB DL\n");
return;
}
if (srslte_enb_ul_init(&enb_ul, signal_buffer_rx[0], phy->cell.nof_prb)) {
if (srslte_enb_ul_init(&enb_ul, signal_buffer_rx[0], phy->get_nof_prb())) {
ERROR("Error initiating ENB UL\n");
return;
}
if (srslte_enb_ul_set_cell(&enb_ul, phy->cell, &phy->ul_cfg_com.dmrs)) {
if (srslte_enb_ul_set_cell(&enb_ul, cell, &phy->ul_cfg_com.dmrs)) {
ERROR("Error initiating ENB UL\n");
return;
}
@ -133,14 +135,14 @@ void cc_worker::init(phy_common* phy_, srslte::log* log_h_, uint32_t cc_idx_)
add_rnti(1 + i, false);
}
if (srslte_softbuffer_tx_init(&temp_mbsfn_softbuffer, phy->cell.nof_prb)) {
if (srslte_softbuffer_tx_init(&temp_mbsfn_softbuffer, nof_prb)) {
ERROR("Error initiating soft buffer\n");
exit(-1);
}
srslte_softbuffer_tx_reset(&temp_mbsfn_softbuffer);
Info("Component Carrier Worker %d configured cell %d PRB\n", cc_idx, phy->cell.nof_prb);
Info("Component Carrier Worker %d configured cell %d PRB\n", cc_idx, nof_prb);
if (phy->params.pusch_8bit_decoder) {
enb_ul.pusch.llr_is_8bit = true;
@ -214,15 +216,21 @@ void cc_worker::rem_rnti(uint16_t rnti)
srslte_enb_ul_rem_rnti(&enb_ul, rnti);
// remove any pending dci for each subframe
for (uint32_t i = 0; i < TTIMOD_SZ; i++) {
for (uint32_t j = 0; j < phy->ul_grants[i].nof_grants; j++) {
if (phy->ul_grants[i].pusch[j].dci.rnti == rnti) {
phy->ul_grants[i].pusch[j].dci.rnti = 0;
for (auto& list : phy->ul_grants) {
for (auto& q : list) {
for (uint32_t j = 0; j < q.nof_grants; j++) {
if (q.pusch[j].dci.rnti == rnti) {
q.pusch[j].dci.rnti = 0;
}
}
}
for (uint32_t j = 0; j < phy->dl_grants[i].nof_grants; j++) {
if (phy->dl_grants[i].pdsch[j].dci.rnti == rnti) {
phy->dl_grants[i].pdsch[j].dci.rnti = 0;
}
for (auto& list : phy->dl_grants) {
for (auto& q : list) {
for (uint32_t j = 0; j < q.nof_grants; j++) {
if (q.pdsch[j].dci.rnti == rnti) {
q.pdsch[j].dci.rnti = 0;
}
}
}
}
@ -476,7 +484,7 @@ int cc_worker::decode_pusch(stack_interface_phy_lte::ul_sched_grant_t* grants, u
// Compute UL grant
srslte_pusch_grant_t* grant = &ue_db[rnti]->ul_cfg.pusch.grant;
if (srslte_ra_ul_dci_to_grant(&phy->cell, &ul_sf, &ue_db[rnti]->ul_cfg.hopping, &grants[i].dci, grant)) {
if (srslte_ra_ul_dci_to_grant(&enb_ul.cell, &ul_sf, &ue_db[rnti]->ul_cfg.hopping, &grants[i].dci, grant)) {
Error("Computing PUSCH dci\n");
return SRSLTE_ERROR;
}
@ -643,8 +651,8 @@ int cc_worker::encode_pmch(stack_interface_phy_lte::dl_sched_grant_t* grant, srs
{
srslte_pmch_cfg_t pmch_cfg;
ZERO_OBJECT(pmch_cfg);
srslte_configure_pmch(&pmch_cfg, &phy->cell, mbsfn_cfg);
srslte_ra_dl_compute_nof_re(&phy->cell, &dl_sf, &pmch_cfg.pdsch_cfg.grant);
srslte_configure_pmch(&pmch_cfg, &enb_dl.cell, mbsfn_cfg);
srslte_ra_dl_compute_nof_re(&enb_dl.cell, &dl_sf, &pmch_cfg.pdsch_cfg.grant);
// Set soft buffer
pmch_cfg.pdsch_cfg.softbuffers.tx[0] = &temp_mbsfn_softbuffer;
@ -680,7 +688,7 @@ int cc_worker::encode_pdsch(stack_interface_phy_lte::dl_sched_grant_t* grants, u
// Compute DL grant
if (srslte_ra_dl_dci_to_grant(
&phy->cell, &dl_sf, ue_db[rnti]->dl_cfg.tm, false, &grants[i].dci, &ue_db[rnti]->dl_cfg.pdsch.grant)) {
&enb_dl.cell, &dl_sf, ue_db[rnti]->dl_cfg.tm, false, &grants[i].dci, &ue_db[rnti]->dl_cfg.pdsch.grant)) {
Error("Computing DL grant\n");
}
@ -730,8 +738,7 @@ uint32_t cc_worker::get_metrics(phy_metrics_t metrics[ENB_METRICS_MAX_USERS])
std::lock_guard<std::mutex> lock(mutex);
uint32_t cnt = 0;
for (auto& ue : ue_db) {
if ((SRSLTE_RNTI_ISUSER(ue.first) || ue.first == SRSLTE_MRNTI) &&
cnt < ENB_METRICS_MAX_USERS) {
if ((SRSLTE_RNTI_ISUSER(ue.first) || ue.first == SRSLTE_MRNTI) && cnt < ENB_METRICS_MAX_USERS) {
ue.second->metrics_read(&metrics[cnt]);
cnt++;
}
@ -764,19 +771,19 @@ void cc_worker::ue::metrics_ul(uint32_t mcs, float rssi, float sinr, float turbo
int cc_worker::read_ce_abs(float* ce_abs)
{
int sz = srslte_symbol_sz(phy->cell.nof_prb);
int sz = srslte_symbol_sz(phy->get_nof_prb());
bzero(ce_abs, sizeof(float) * sz);
int g = (sz - 12 * phy->cell.nof_prb) / 2;
srslte_vec_abs_dB_cf(enb_ul.chest_res.ce, -80.0f, &ce_abs[g], SRSLTE_NRE * phy->cell.nof_prb);
int g = (sz - SRSLTE_NRE * phy->get_nof_prb()) / 2;
srslte_vec_abs_dB_cf(enb_ul.chest_res.ce, -80.0f, &ce_abs[g], SRSLTE_NRE * phy->get_nof_prb());
return sz;
}
int cc_worker::read_ce_arg(float* ce_arg)
{
int sz = srslte_symbol_sz(phy->cell.nof_prb);
int sz = srslte_symbol_sz(phy->get_nof_prb());
bzero(ce_arg, sizeof(float) * sz);
int g = (sz - 12 * phy->cell.nof_prb) / 2;
srslte_vec_arg_deg_cf(enb_ul.chest_res.ce, -80.0f, &ce_arg[g], SRSLTE_NRE * phy->cell.nof_prb);
int g = (sz - SRSLTE_NRE * phy->get_nof_prb()) / 2;
srslte_vec_arg_deg_cf(enb_ul.chest_res.ce, -80.0f, &ce_arg[g], SRSLTE_NRE * phy->get_nof_prb());
return sz;
}

View File

@ -141,7 +141,7 @@ int phy::init(const phy_args_t& args,
workers_common.params = args;
workers_common.init(cfg.cell, radio, stack_);
workers_common.init(cfg.phy_cell_cfg, radio, stack_);
parse_config(cfg);
@ -152,8 +152,9 @@ int phy::init(const phy_args_t& args,
}
// For each carrier, initialise PRACH worker
for (uint32_t cc = 0; cc < args.nof_carriers; cc++) {
prach.init(cc, cfg.cell, prach_cfg, stack_, log_vec.at(0).get(), PRACH_WORKER_THREAD_PRIO);
for (uint32_t cc = 0; cc < cfg.phy_cell_cfg.size(); cc++) {
prach_cfg.root_seq_idx = cfg.phy_cell_cfg[cc].root_seq_idx;
prach.init(cc, cfg.phy_cell_cfg[cc].cell, prach_cfg, stack_, log_vec.at(0).get(), PRACH_WORKER_THREAD_PRIO);
}
prach.set_max_prach_offset_us(args.max_prach_offset_us);

View File

@ -46,11 +46,9 @@ using namespace asn1::rrc;
namespace srsenb {
phy_common::phy_common(uint32_t max_workers_) : tx_sem(max_workers_)
phy_common::phy_common(uint32_t max_workers_) : tx_sem(max_workers_), cell_list()
{
nof_workers = 0;
params.max_prach_offset_us = 20;
have_mtch_stop = false;
max_workers = max_workers_;
for (uint32_t i = 0; i < max_workers; i++) {
@ -76,35 +74,30 @@ void phy_common::reset()
bzero(dl_grants, sizeof(stack_interface_phy_lte::dl_sched_t) * TTIMOD_SZ);
}
bool phy_common::init(const srslte_cell_t& cell_,
bool phy_common::init(const phy_cell_cfg_list_t& cell_list_,
srslte::radio_interface_phy* radio_h_,
stack_interface_phy_lte* stack_)
{
radio = radio_h_;
stack = stack_;
cell = cell_;
radio = radio_h_;
stack = stack_;
cell_list = cell_list_;
pthread_mutex_init(&user_mutex, nullptr);
pthread_mutex_init(&mtch_mutex, nullptr);
pthread_cond_init(&mtch_cvar, nullptr);
// Instantiate UL channel emulator
// Instantiate DL channel emulator
if (params.ul_channel_args.enable) {
dl_channel = srslte::channel_ptr(new srslte::channel(params.dl_channel_args, 1));
dl_channel->set_srate((uint32_t)srslte_sampling_freq_hz(cell_list[0].cell.nof_prb));
}
dl_channel->set_srate((uint32_t)srslte_sampling_freq_hz(cell.nof_prb));
// Create grants
for (auto& q : dl_grants) {
q.resize(cell_list_.size());
}
is_first_tx = true;
// Instantiate UL channel emulator
if (params.ul_channel_args.enable) {
dl_channel = srslte::channel_ptr(new srslte::channel(params.dl_channel_args, 1));
dl_channel->set_srate((uint32_t)srslte_sampling_freq_hz(cell.nof_prb));
}
is_first_tx = true;
reset();
return true;
}
@ -166,11 +159,10 @@ void phy_common::ue_db_clear(uint32_t tti)
void phy_common::ue_db_add_rnti(uint16_t rnti)
{
pthread_mutex_lock(&user_mutex);
std::lock_guard<std::mutex> lock(user_mutex);
if (!common_ue_db.count(rnti)) {
add_rnti(rnti);
}
pthread_mutex_unlock(&user_mutex);
}
// Private function not mutexed
@ -185,27 +177,25 @@ void phy_common::add_rnti(uint16_t rnti)
void phy_common::ue_db_rem_rnti(uint16_t rnti)
{
pthread_mutex_lock(&user_mutex);
std::lock_guard<std::mutex> lock(user_mutex);
if (!common_ue_db.count(rnti)) {
common_ue_db.erase(rnti);
}
pthread_mutex_unlock(&user_mutex);
}
void phy_common::ue_db_set_ack_pending(uint32_t tti, uint16_t rnti, uint32_t tb_idx, uint32_t last_n_pdcch)
{
pthread_mutex_lock(&user_mutex);
std::lock_guard<std::mutex> lock(user_mutex);
if (common_ue_db.count(rnti)) {
common_ue_db[rnti].pending_ack.is_pending[TTIMOD(tti)][tb_idx] = true;
common_ue_db[rnti].pending_ack.n_pdcch[TTIMOD(tti)] = (uint16_t)last_n_pdcch;
}
pthread_mutex_unlock(&user_mutex);
}
bool phy_common::ue_db_is_ack_pending(uint32_t tti, uint16_t rnti, uint32_t tb_idx, uint32_t* last_n_pdcch)
{
bool ret = false;
pthread_mutex_lock(&user_mutex);
bool ret = false;
std::lock_guard<std::mutex> lock(user_mutex);
if (common_ue_db.count(rnti)) {
ret = common_ue_db[rnti].pending_ack.is_pending[TTIMOD(tti)][tb_idx];
common_ue_db[rnti].pending_ack.is_pending[TTIMOD(tti)][tb_idx] = false;
@ -214,48 +204,43 @@ bool phy_common::ue_db_is_ack_pending(uint32_t tti, uint16_t rnti, uint32_t tb_i
*last_n_pdcch = common_ue_db[rnti].pending_ack.n_pdcch[TTIMOD(tti)];
}
}
pthread_mutex_unlock(&user_mutex);
return ret;
}
void phy_common::ue_db_set_ri(uint16_t rnti, uint8_t ri)
{
pthread_mutex_lock(&user_mutex);
std::lock_guard<std::mutex> lock(user_mutex);
if (common_ue_db.count(rnti)) {
common_ue_db[rnti].ri = ri;
}
pthread_mutex_unlock(&user_mutex);
}
uint8_t phy_common::ue_db_get_ri(uint16_t rnti)
{
pthread_mutex_lock(&user_mutex);
uint8_t ret = 0;
std::lock_guard<std::mutex> lock(user_mutex);
uint8_t ret = 0;
if (common_ue_db.count(rnti)) {
ret = common_ue_db[rnti].ri;
}
pthread_mutex_unlock(&user_mutex);
return ret;
}
void phy_common::ue_db_set_last_ul_tb(uint16_t rnti, uint32_t pid, srslte_ra_tb_t tb)
{
pthread_mutex_lock(&user_mutex);
std::lock_guard<std::mutex> lock(user_mutex);
if (!common_ue_db.count(rnti)) {
add_rnti(rnti);
}
common_ue_db[rnti].last_tb[pid % SRSLTE_MAX_HARQ_PROC] = tb;
pthread_mutex_unlock(&user_mutex);
}
srslte_ra_tb_t phy_common::ue_db_get_last_ul_tb(uint16_t rnti, uint32_t pid)
{
pthread_mutex_lock(&user_mutex);
srslte_ra_tb_t ret = {};
std::lock_guard<std::mutex> lock(user_mutex);
srslte_ra_tb_t ret = {};
if (common_ue_db.count(rnti)) {
ret = common_ue_db[rnti].last_tb[pid % SRSLTE_FDD_NOF_HARQ];
}
pthread_mutex_unlock(&user_mutex);
return ret;
}

View File

@ -78,7 +78,7 @@ void sf_worker::init(phy_common* phy_, srslte::log* log_h_)
log_h = log_h_;
// Initialise each component carrier workers
for (uint32_t i = 0; i < phy->params.nof_carriers; i++) {
for (uint32_t i = 0; i < phy->get_nof_carriers(); i++) {
// Create pointer
auto q = new cc_worker();
@ -89,14 +89,14 @@ void sf_worker::init(phy_common* phy_, srslte::log* log_h_)
cc_workers.push_back(std::unique_ptr<cc_worker>(q));
}
if (srslte_softbuffer_tx_init(&temp_mbsfn_softbuffer, phy->cell.nof_prb)) {
if (srslte_softbuffer_tx_init(&temp_mbsfn_softbuffer, phy->get_nof_prb())) {
ERROR("Error initiating soft buffer\n");
exit(-1);
}
srslte_softbuffer_tx_reset(&temp_mbsfn_softbuffer);
Info("Worker %d configured cell %d PRB\n", get_id(), phy->cell.nof_prb);
Info("Worker %d configured cell %d PRB\n", get_id(), phy->get_nof_prb());
initiated = true;
running = true;
@ -178,9 +178,9 @@ void sf_worker::work_imp()
srslte_mbsfn_cfg_t mbsfn_cfg;
srslte_sf_t sf_type = phy->is_mbsfn_sf(&mbsfn_cfg, tti_tx_dl) ? SRSLTE_SF_MBSFN : SRSLTE_SF_NORM;
stack_interface_phy_lte::ul_sched_t* ul_grants = phy->ul_grants;
stack_interface_phy_lte::dl_sched_t* dl_grants = phy->dl_grants;
stack_interface_phy_lte* stack = phy->stack;
stack_interface_phy_lte::ul_sched_list_t* ul_grants = phy->ul_grants;
stack_interface_phy_lte::dl_sched_list_t* dl_grants = phy->dl_grants;
stack_interface_phy_lte* stack = phy->stack;
log_h->step(tti_rx);
@ -190,56 +190,56 @@ void sf_worker::work_imp()
ul_sf.tti = tti_rx;
// Process UL
for (auto& w : cc_workers) {
w->work_ul(&ul_sf, &phy->ul_grants[t_rx]);
for (auto& q : phy->dl_grants[t_tx_dl]) {
q.cfi = mbsfn_cfg.non_mbsfn_region_length;
}
// Get DL scheduling for the TX TTI from MAC
if (sf_type == SRSLTE_SF_NORM) {
if (stack->get_dl_sched(tti_tx_dl, &dl_grants[t_tx_dl]) < 0) {
if (stack->get_dl_sched(tti_tx_dl, dl_grants[t_tx_dl]) < 0) {
Error("Getting DL scheduling from MAC\n");
return;
}
} else {
dl_grants[t_tx_dl].cfi = mbsfn_cfg.non_mbsfn_region_length;
if (stack->get_mch_sched(tti_tx_dl, mbsfn_cfg.is_mcch, &dl_grants[t_tx_dl])) {
dl_grants[t_tx_dl][0].cfi = mbsfn_cfg.non_mbsfn_region_length;
if (stack->get_mch_sched(tti_tx_dl, mbsfn_cfg.is_mcch, dl_grants[t_tx_dl])) {
Error("Getting MCH packets from MAC\n");
return;
}
}
if (dl_grants[t_tx_dl].cfi < 1 || dl_grants[t_tx_dl].cfi > 3) {
Error("Invalid CFI=%d\n", dl_grants[t_tx_dl].cfi);
if (dl_grants[t_tx_dl][0].cfi < 1 || dl_grants[t_tx_dl][0].cfi > 3) {
Error("Invalid CFI=%d\n", dl_grants[t_tx_dl][0].cfi);
return;
}
// Get UL scheduling for the TX TTI from MAC
if (stack->get_ul_sched(tti_tx_ul, &ul_grants[t_tx_ul]) < 0) {
if (stack->get_ul_sched(tti_tx_ul, ul_grants[t_tx_ul]) < 0) {
Error("Getting UL scheduling from MAC\n");
return;
}
// Configure DL subframe
dl_sf.tti = tti_tx_dl;
dl_sf.cfi = dl_grants[t_tx_dl].cfi;
dl_sf.cfi = dl_grants[t_tx_dl][0].cfi;
dl_sf.sf_type = sf_type;
dl_sf.non_mbsfn_region = mbsfn_cfg.non_mbsfn_region_length;
// Process DL
for (auto& w : cc_workers) {
w->work_dl(&dl_sf, &phy->dl_grants[t_tx_dl], &phy->ul_grants[t_tx_ul], &mbsfn_cfg);
for (uint32_t cc = 0; cc < cc_workers.size(); cc++) {
cc_workers[cc]->work_dl(&dl_sf, &phy->dl_grants[t_tx_dl][cc], &phy->ul_grants[t_tx_ul][cc], &mbsfn_cfg);
}
// Get Transmission buffers
for (uint32_t cc = 0, i = 0; cc < phy->params.nof_carriers; cc++) {
for (uint32_t ant = 0; ant < phy->cell.nof_ports; ant++, i++) {
for (uint32_t cc = 0, i = 0; cc < phy->get_nof_carriers(); cc++) {
for (uint32_t ant = 0; ant < phy->get_nof_ports(); ant++, i++) {
signal_buffer_tx[i] = cc_workers[cc]->get_buffer_tx(ant);
}
}
Debug("Sending to radio\n");
phy->worker_end(tx_worker_cnt, signal_buffer_tx, SRSLTE_SF_LEN_PRB(phy->cell.nof_prb), tx_time);
phy->worker_end(tx_worker_cnt, signal_buffer_tx, SRSLTE_SF_LEN_PRB(phy->get_nof_prb()), tx_time);
#ifdef DEBUG_WRITE_FILE
fwrite(signal_buffer_tx, SRSLTE_SF_LEN_PRB(phy->cell.nof_prb) * sizeof(cf_t), 1, f);
@ -265,7 +265,7 @@ uint32_t sf_worker::get_metrics(phy_metrics_t metrics[ENB_METRICS_MAX_USERS])
{
uint32_t cnt = 0;
phy_metrics_t _metrics[ENB_METRICS_MAX_USERS] = {};
for (uint32_t cc = 0; cc < phy->params.nof_carriers; cc++) {
for (uint32_t cc = 0; cc < phy->get_nof_carriers(); cc++) {
cnt = cc_workers[cc]->get_metrics(_metrics);
for (uint32_t r = 0; r < cnt; r++) {
phy_metrics_t* m = &metrics[r];

View File

@ -68,7 +68,8 @@ bool txrx::init(srslte::radio_interface_phy* radio_h_,
nof_workers = workers_pool->get_nof_workers();
worker_com->set_nof_workers(nof_workers);
if (worker_com->params.dl_channel_args.enable) {
// Instantiate UL channel emulator
if (worker_com->params.ul_channel_args.enable) {
ul_channel = srslte::channel_ptr(new srslte::channel(worker_com->params.ul_channel_args, 1));
}
@ -88,20 +89,49 @@ void txrx::run_thread()
cf_t* buffer[SRSLTE_MAX_PORTS] = {};
srslte_timestamp_t rx_time = {};
srslte_timestamp_t tx_time = {};
uint32_t sf_len = SRSLTE_SF_LEN_PRB(worker_com->cell.nof_prb);
uint32_t sf_len = SRSLTE_SF_LEN_PRB(worker_com->get_nof_prb());
float samp_rate = srslte_sampling_freq_hz(worker_com->cell.nof_prb);
float samp_rate = srslte_sampling_freq_hz(worker_com->get_nof_prb());
log_h->console("Setting Sampling frequency %.2f MHz\n", (float)samp_rate / 1000000);
// Configure radio
radio_h->set_rx_srate(0, samp_rate);
radio_h->set_tx_srate(0, samp_rate);
if (ul_channel) {
ul_channel->set_srate(samp_rate);
for (auto& cfg : worker_com->cell_list) {
// If there is no UL-EARDCN, deduce it from DL-EARFCN
if (cfg.ul_earfcn == 0) {
cfg.ul_earfcn = srslte_band_ul_earfcn(cfg.dl_earfcn);
}
// Set Tx/Rx frequencies
float tx_freq_hz = 1e6 * srslte_band_fd(cfg.dl_earfcn);
float rx_freq_hz = 1e6 * srslte_band_fd(cfg.ul_earfcn);
for (uint32_t i = 0; i < worker_com->get_nof_ports(); i++) {
radio_h->set_tx_freq(0, cfg.rf_port + i, tx_freq_hz);
radio_h->set_rx_freq(0, cfg.rf_port + i, rx_freq_hz);
}
}
log_h->info("Starting RX/TX thread nof_prb=%d, sf_len=%d\n", worker_com->cell.nof_prb, sf_len);
if (ul_channel) {
ul_channel->set_srate(static_cast<uint32_t>(samp_rate));
for (auto& cfg : worker_com->cell_list) {
// If there is no UL-EARDCN, deduce it from DL-EARFCN
if (cfg.ul_earfcn == 0) {
cfg.ul_earfcn = srslte_band_ul_earfcn(cfg.dl_earfcn);
}
// Set Tx/Rx frequencies
float tx_freq_hz = 1e6 * srslte_band_fd(cfg.dl_earfcn);
float rx_freq_hz = 1e6 * srslte_band_fd(cfg.ul_earfcn);
for (uint32_t i = 0; i < worker_com->get_nof_ports(); i++) {
radio_h->set_tx_freq(0, cfg.rf_port + i, tx_freq_hz);
radio_h->set_rx_freq(0, cfg.rf_port + i, rx_freq_hz);
}
}
}
log_h->info("Starting RX/TX thread nof_prb=%d, sf_len=%d\n", worker_com->get_nof_prb(), sf_len);
// Set TTI so that first TX is at tti=0
tti = 10235;
@ -111,9 +141,10 @@ void txrx::run_thread()
tti = (tti + 1) % 10240;
worker = (sf_worker*)workers_pool->wait_worker(tti);
if (worker) {
for (uint32_t c = 0, i = 0; c < worker_com->params.nof_carriers; c++) {
for (uint32_t p = 0; p < worker_com->cell.nof_ports; p++, i++) {
buffer[i] = worker->get_buffer_rx(c, p);
for (uint32_t cc = 0; cc < worker_com->get_nof_carriers(); cc++) {
uint32_t rf_port = worker_com->cell_list[cc].rf_port;
for (uint32_t p = 0; p < worker_com->get_nof_ports(); p++) {
buffer[rf_port + p] = worker->get_buffer_rx(cc, p);
}
}
@ -141,8 +172,8 @@ void txrx::run_thread()
workers_pool->start_worker(worker);
// Trigger prach worker execution
for (uint32_t cc = 0; cc < worker_com->params.nof_carriers; cc++) {
prach->new_tti(cc, tti, buffer[cc * worker_com->cell.nof_ports]);
for (uint32_t cc = 0; cc < worker_com->get_nof_carriers(); cc++) {
prach->new_tti(cc, tti, buffer[worker_com->cell_list[cc].rf_port * worker_com->get_nof_ports()]);
}
} else {
// wait_worker() only returns NULL if it's being closed. Quit now to avoid unnecessary loops here

View File

@ -216,7 +216,7 @@ int mac::ue_cfg(uint16_t rnti, sched_interface::ue_cfg_t* cfg)
}
// Update Scheduler configuration
if ((cfg != NULL) ? scheduler.ue_cfg(rnti, cfg) : false) {
if ((cfg != nullptr) ? scheduler.ue_cfg(rnti, cfg) : false) {
Error("Registering new UE rnti=0x%x to SCHED\n", rnti);
} else {
ret = 0;
@ -514,7 +514,7 @@ int mac::rach_detected(uint32_t tti, uint32_t enb_cc_idx, uint32_t preamble_idx,
return 0;
}
int mac::get_dl_sched(uint32_t tti, dl_sched_t* dl_sched_res)
int mac::get_dl_sched(uint32_t tti, dl_sched_list_t& dl_sched_res_list)
{
if (!started) {
return 0;
@ -522,10 +522,6 @@ int mac::get_dl_sched(uint32_t tti, dl_sched_t* dl_sched_res)
log_h->step(tti);
if (!dl_sched_res) {
return SRSLTE_ERROR_INVALID_INPUTS;
}
// Run scheduler with current info
sched_interface::dl_sched_res_t sched_result = {};
if (scheduler.dl_sched(tti, 0, sched_result) < 0) {
@ -533,8 +529,8 @@ int mac::get_dl_sched(uint32_t tti, dl_sched_t* dl_sched_res)
return SRSLTE_ERROR;
}
int n = 0;
int n = 0;
dl_sched_t* dl_sched_res = &dl_sched_res_list[0];
pthread_rwlock_rdlock(&rwlock);
// Copy data grants
@ -568,7 +564,7 @@ int mac::get_dl_sched(uint32_t tti, dl_sched_t* dl_sched_res)
} else {
/* TB not enabled OR no data to send: set pointers to NULL */
dl_sched_res->pdsch[n].data[tb] = NULL;
dl_sched_res->pdsch[n].data[tb] = nullptr;
}
}
n++;
@ -668,8 +664,9 @@ void mac::build_mch_sched(uint32_t tbs)
}
}
int mac::get_mch_sched(uint32_t tti, bool is_mcch, dl_sched_t* dl_sched_res)
int mac::get_mch_sched(uint32_t tti, bool is_mcch, dl_sched_list_t& dl_sched_res_list)
{
dl_sched_t* dl_sched_res = &dl_sched_res_list[0];
log_h->step(tti);
srslte_ra_tb_t mcs = {};
srslte_ra_tb_t mcs_data = {};
@ -728,7 +725,7 @@ int mac::get_mch_sched(uint32_t tti, bool is_mcch, dl_sched_t* dl_sched_res)
}
} else {
dl_sched_res->pdsch[0].dci.rnti = 0;
dl_sched_res->pdsch[0].data[0] = NULL;
dl_sched_res->pdsch[0].data[0] = nullptr;
}
mch.current_sf_allocation_num++;
}
@ -760,7 +757,7 @@ uint8_t* mac::assemble_rar(sched_interface::dl_sched_rar_grant_t* grants,
return rar_payload[rar_idx].msg;
} else {
Error("Assembling RAR: pdu_len > rar_payload_len (%d>%d)\n", pdu_len, rar_payload_len);
return NULL;
return nullptr;
}
}
@ -770,19 +767,15 @@ uint8_t* mac::assemble_si(uint32_t index)
return bcch_dlsch_payload;
}
int mac::get_ul_sched(uint32_t tti, ul_sched_t* ul_sched_res)
int mac::get_ul_sched(uint32_t tti, ul_sched_list_t& ul_sched_res_list)
{
ul_sched_t* ul_sched_res = &ul_sched_res_list[0];
log_h->step(tti);
if (!started) {
return 0;
}
if (!ul_sched_res) {
return SRSLTE_ERROR_INVALID_INPUTS;
}
// Run scheduler with current info
sched_interface::ul_sched_res_t sched_result = {};
if (scheduler.ul_sched(tti, 0, sched_result) < 0) {