sched,nr: nr_phy_test now uses the whole mac class rather than just the scheduler

This commit is contained in:
Francisco Paisana 2021-08-26 18:25:07 +02:00
parent 05a5f4115f
commit 04e5c81edf
19 changed files with 257 additions and 171 deletions

View File

@ -27,23 +27,6 @@
namespace srsenb {
/*****************************
* MAC INTERFACES
****************************/
class mac_interface_rrc_nr
{
public:
// Provides cell configuration including SIB periodicity, etc.
virtual int cell_cfg(srsenb::sched_interface::cell_cfg_t* cell_cfg) = 0;
/// Allocates a new user/RNTI at MAC. Returns RNTI on success or SRSRAN_INVALID_RNTI otherwise.
virtual uint16_t reserve_rnti() = 0;
};
// NR interface is identical to EUTRA interface
class mac_interface_rlc_nr : public mac_interface_rlc
{};
/*****************************
* RLC INTERFACES
****************************/
@ -164,8 +147,7 @@ public:
// NR interface identical to EUTRA version
class rrc_interface_pdcp_nr : public rrc_interface_pdcp
{
};
{};
class phy_interface_rrc_nr
{
@ -295,7 +277,7 @@ public:
virtual int get_dl_sched(const srsran_slot_cfg_t& slot_cfg, dl_sched_t& dl_sched) = 0;
virtual int get_ul_sched(const srsran_slot_cfg_t& slot_cfg, ul_sched_t& ul_sched) = 0;
virtual int pucch_info(const srsran_slot_cfg_t& slot_cfg, const pucch_info_t& pucch_info) = 0;
virtual int pusch_info(const srsran_slot_cfg_t& slot_cfg, pusch_info_t& pusch_info) = 0;
virtual int pusch_info(const srsran_slot_cfg_t& slot_cfg, pusch_info_t& pusch_info) = 0;
virtual void rach_detected(const rach_info_t& rach_info) = 0;
};

View File

@ -0,0 +1,39 @@
/**
*
* \section COPYRIGHT
*
* Copyright 2013-2021 Software Radio Systems Limited
*
* By using this file, you agree to the terms and conditions set
* forth in the LICENSE file which can be found at the top level of
* the distribution.
*
*/
#ifndef SRSRAN_GNB_MAC_INTERFACES_H
#define SRSRAN_GNB_MAC_INTERFACES_H
#include "srsenb/hdr/stack/mac/nr/sched_nr_interface.h"
namespace srsenb {
class mac_interface_rrc_nr
{
public:
// Provides cell configuration including SIB periodicity, etc.
virtual int cell_cfg(const sched_interface::cell_cfg_t& cell,
srsran::const_span<sched_nr_interface::cell_cfg_t> nr_cells) = 0;
/// Allocates a new user/RNTI at MAC. Returns RNTI on success or SRSRAN_INVALID_RNTI otherwise.
virtual uint16_t reserve_rnti(uint32_t enb_cc_idx) = 0;
virtual int ue_cfg(uint16_t rnti, const sched_nr_interface::ue_cfg_t& ue_cfg) = 0;
};
// NR interface is identical to EUTRA interface
class mac_interface_rlc_nr : public mac_interface_rlc
{};
} // namespace srsenb
#endif // SRSRAN_GNB_MAC_INTERFACES_H

View File

@ -23,21 +23,21 @@
#include "srsran/common/task_scheduler.h"
#include "srsran/interfaces/enb_metrics_interface.h"
#include "srsran/interfaces/enb_rlc_interfaces.h"
#include "srsran/interfaces/gnb_interfaces.h"
#include "srsran/interfaces/gnb_mac_interfaces.h"
namespace srsenb {
struct mac_nr_args_t {
srsran::phy_cfg_nr_t phy_base_cfg = {};
int fixed_dl_mcs = -1;
int fixed_ul_mcs = -1;
srsenb::pcap_args_t pcap;
int fixed_dl_mcs = -1;
int fixed_ul_mcs = -1;
srsenb::pcap_args_t pcap;
};
class mac_nr final : public mac_interface_phy_nr, public mac_interface_rrc_nr, public mac_interface_rlc_nr
{
public:
mac_nr(srsran::task_sched_handle task_sched_);
mac_nr(srsran::task_sched_handle task_sched_, const srsenb::sched_nr_interface::sched_cfg_t& sched_cfg = {});
~mac_nr();
int init(const mac_nr_args_t& args_,
@ -50,9 +50,11 @@ public:
void get_metrics(srsenb::mac_metrics_t& metrics);
// MAC interface for RRC
int cell_cfg(srsenb::sched_interface::cell_cfg_t* cell_cfg) override;
uint16_t reserve_rnti() override;
int read_pdu_bcch_bch(uint8_t* payload);
int cell_cfg(const sched_interface::cell_cfg_t& cell,
srsran::const_span<sched_nr_interface::cell_cfg_t> nr_cells) override;
uint16_t reserve_rnti(uint32_t enb_cc_idx) override;
int read_pdu_bcch_bch(uint8_t* payload);
int ue_cfg(uint16_t rnti, const sched_nr_interface::ue_cfg_t& ue_cfg) override;
// MAC interface for RLC
// TODO:
@ -68,7 +70,8 @@ public:
void rach_detected(const rach_info_t& rach_info) override;
private:
uint16_t add_ue(uint32_t enb_cc_idx);
uint16_t add_ue_(uint32_t enb_cc_idx);
uint16_t alloc_ue(uint32_t enb_cc_idx);
int remove_ue(uint16_t rnti);
// internal misc helpers
@ -91,7 +94,7 @@ private:
rrc_interface_mac_nr* rrc = nullptr;
// args
srsran::task_sched_handle task_sched;
srsran::task_sched_handle task_sched;
srsran::task_multiqueue::queue_handle stack_task_queue;
std::unique_ptr<srsran::mac_pcap> pcap = nullptr;
@ -100,17 +103,17 @@ private:
std::atomic<bool> started = {false};
const static uint32_t NUMEROLOGY_IDX = 0; /// only 15kHz supported at this stage
const static uint32_t NUMEROLOGY_IDX = 0; /// only 15kHz supported at this stage
srsran::slot_point pdsch_slot, pusch_slot;
srsenb::sched_nr sched;
srsenb::sched_interface::cell_cfg_t cfg = {};
// Map of active UEs
pthread_rwlock_t rwlock = {};
static const uint16_t FIRST_RNTI = 0x4601;
pthread_rwlock_t rwlock = {};
static const uint16_t FIRST_RNTI = 0x4601;
srsran::static_circular_map<uint16_t, std::unique_ptr<ue_nr>, SRSENB_MAX_UES> ue_db;
std::atomic<uint16_t> ue_counter;
std::atomic<uint16_t> ue_counter;
// BCH buffers
struct sib_info_t {

View File

@ -53,8 +53,13 @@ class ra_sched
public:
explicit ra_sched(const bwp_params& bwp_cfg_);
int dl_rach_info(const dl_sched_rar_info_t& rar_info);
/// Addition of detected PRACH into the queue
int dl_rach_info(const dl_sched_rar_info_t& rar_info);
/// Allocate pending RARs
void run_slot(bwp_slot_allocator& slot_grid);
/// Check if there are pending RARs
bool empty() const { return pending_rars.empty(); }
private:

View File

@ -44,15 +44,16 @@ struct bwp_slot_grid {
uint32_t slot_idx;
const bwp_params* cfg;
bwp_rb_bitmap dl_prbs;
bwp_rb_bitmap ul_prbs;
pdcch_dl_list_t dl_pdcchs;
pdcch_ul_list_t ul_pdcchs;
pdsch_list_t pdschs;
rar_list_t rar;
slot_coreset_list coresets;
pusch_list_t puschs;
harq_ack_list_t pending_acks;
bwp_rb_bitmap dl_prbs;
bwp_rb_bitmap ul_prbs;
pdcch_dl_list_t dl_pdcchs;
pdcch_ul_list_t ul_pdcchs;
pdsch_list_t pdschs;
rar_list_t rar;
slot_coreset_list coresets;
pusch_list_t puschs;
harq_ack_list_t pending_acks;
srsran_softbuffer_tx_t rar_softbuffer;
bwp_slot_grid() = default;
explicit bwp_slot_grid(const bwp_params& bwp_params, uint32_t slot_idx_);

View File

@ -91,7 +91,7 @@ public:
uint32_t freq_idx;
uint32_t ta_cmd;
uint16_t temp_crnti;
uint32_t msg3_size;
uint32_t msg3_size = 7;
slot_point prach_slot;
};

View File

@ -28,6 +28,7 @@
#include "srsran/interfaces/enb_rlc_interfaces.h"
#include "srsran/interfaces/enb_rrc_interfaces.h"
#include "srsran/interfaces/gnb_interfaces.h"
#include "srsran/interfaces/gnb_mac_interfaces.h"
#include "srsran/interfaces/gnb_ngap_interfaces.h"
#include "srsran/interfaces/gnb_rrc_nr_interfaces.h"
#include <map>
@ -118,8 +119,8 @@ public:
int pack_nr_radio_bearer_config(asn1::dyn_octstring& packed_nr_bearer_config);
// state
rrc_nr_state_t state = rrc_nr_state_t::RRC_IDLE;
uint8_t transaction_id = 0;
rrc_nr_state_t state = rrc_nr_state_t::RRC_IDLE;
uint8_t transaction_id = 0;
uint32_t drb1_lcid = 4;
};
@ -128,12 +129,12 @@ private:
rrc_nr_cfg_t cfg = {};
// interfaces
phy_interface_stack_nr* phy = nullptr;
mac_interface_rrc_nr* mac = nullptr;
phy_interface_stack_nr* phy = nullptr;
mac_interface_rrc_nr* mac = nullptr;
rlc_interface_rrc* rlc = nullptr;
pdcp_interface_rrc* pdcp = nullptr;
gtpu_interface_rrc_nr* gtpu = nullptr;
ngap_interface_rrc_nr* ngap = nullptr;
gtpu_interface_rrc_nr* gtpu = nullptr;
ngap_interface_rrc_nr* ngap = nullptr;
rrc_eutra_interface_rrc_nr* rrc_eutra = nullptr;
// args

View File

@ -14,6 +14,7 @@
#define SRSENB_RLC_NR_H
#include "srsran/interfaces/gnb_interfaces.h"
#include "srsran/interfaces/gnb_mac_interfaces.h"
#include "srsran/rlc/rlc.h"
#include <map>

View File

@ -11,7 +11,7 @@ set(SOURCES mac_nr.cc
sched_nr.cc
sched_nr_ue.cc
sched_nr_worker.cc
sched_nr_grant_allocator.cc
sched_nr_grant_allocator.cc
sched_nr_harq.cc
sched_nr_pdcch.cc
sched_nr_cfg.cc

View File

@ -24,10 +24,10 @@
namespace srsenb {
mac_nr::mac_nr(srsran::task_sched_handle task_sched_) :
mac_nr::mac_nr(srsran::task_sched_handle task_sched_, const sched_nr_interface::sched_cfg_t& sched_cfg) :
logger(srslog::fetch_basic_logger("MAC-NR")),
task_sched(task_sched_),
sched(srsenb::sched_nr_interface::sched_cfg_t{}),
sched(sched_cfg),
bcch_bch_payload(srsran::make_byte_buffer())
{
stack_task_queue = task_sched.make_task_queue();
@ -56,12 +56,6 @@ int mac_nr::init(const mac_nr_args_t& args_,
pcap->open(args.pcap.filename);
}
// configure scheduler for 1 carrier
std::vector<srsenb::sched_nr_interface::cell_cfg_t> cells_cfg = srsenb::get_default_cells_cfg(1);
sched.cell_cfg(cells_cfg);
detected_rachs.resize(cells_cfg.size());
logger.info("Started");
started = true;
@ -82,16 +76,19 @@ void mac_nr::stop()
void mac_nr::get_metrics(srsenb::mac_metrics_t& metrics) {}
int mac_nr::cell_cfg(srsenb::sched_interface::cell_cfg_t* cell_cfg)
int mac_nr::cell_cfg(const sched_interface::cell_cfg_t& cell,
srsran::const_span<sched_nr_interface::cell_cfg_t> nr_cells)
{
cfg = *cell_cfg;
cfg = cell;
sched.cell_cfg(nr_cells);
detected_rachs.resize(nr_cells.size());
// read SIBs from RRC (SIB1 for now only)
for (int i = 0; i < 1 /* srsenb::sched_interface::MAX_SIBS */; i++) {
if (cell_cfg->sibs->len > 0) {
if (cell.sibs->len > 0) {
sib_info_t sib = {};
sib.index = i;
sib.periodicity = cell_cfg->sibs->period_rf;
sib.periodicity = cell.sibs->period_rf;
sib.payload = srsran::make_byte_buffer();
if (sib.payload == nullptr) {
logger.error("Couldn't allocate PDU in %s().", __FUNCTION__);
@ -109,6 +106,34 @@ int mac_nr::cell_cfg(srsenb::sched_interface::cell_cfg_t* cell_cfg)
return SRSRAN_SUCCESS;
}
int mac_nr::ue_cfg(uint16_t rnti, const sched_nr_interface::ue_cfg_t& ue_cfg)
{
sched.ue_cfg(rnti, ue_cfg);
return SRSRAN_SUCCESS;
}
uint16_t mac_nr::reserve_rnti(uint32_t enb_cc_idx)
{
uint16_t rnti = alloc_ue(enb_cc_idx);
if (rnti == SRSRAN_INVALID_RNTI) {
return rnti;
}
// Add new user to the scheduler so that it can RX/TX SRB0
srsenb::sched_nr_interface::ue_cfg_t ue_cfg = srsenb::get_default_ue_cfg(1);
ue_cfg.fixed_dl_mcs = args.fixed_dl_mcs;
ue_cfg.fixed_ul_mcs = args.fixed_ul_mcs;
sched.ue_cfg(rnti, ue_cfg);
// Register new user in RRC
if (rrc->add_user(rnti) == SRSRAN_ERROR) {
// ue_rem(rnti);
return SRSRAN_SUCCESS;
}
return rnti;
}
void mac_nr::rach_detected(const rach_info_t& rach_info)
{
static srsran::mutexed_tprof<srsran::avg_time_stats> rach_tprof("rach_tprof", "MAC-NR", 1);
@ -117,12 +142,8 @@ void mac_nr::rach_detected(const rach_info_t& rach_info)
uint32_t enb_cc_idx = 0;
stack_task_queue.push([this, rach_info, enb_cc_idx, rach_tprof_meas]() mutable {
uint16_t rnti = add_ue(enb_cc_idx);
if (rnti == SRSRAN_INVALID_RNTI) {
return;
}
rach_tprof_meas.defer_stop();
uint16_t rnti = reserve_rnti(enb_cc_idx);
// TODO: Generate RAR data
// ..
@ -130,25 +151,14 @@ void mac_nr::rach_detected(const rach_info_t& rach_info)
// Log this event.
++detected_rachs[enb_cc_idx];
// Add new user to the scheduler so that it can RX/TX SRB0
srsenb::sched_nr_interface::ue_cfg_t ue_cfg = srsenb::get_default_ue_cfg(1);
ue_cfg.fixed_dl_mcs = args.fixed_dl_mcs;
ue_cfg.fixed_ul_mcs = args.fixed_ul_mcs;
sched.ue_cfg(rnti, ue_cfg);
// Register new user in RRC
if (rrc->add_user(rnti) == SRSRAN_ERROR) {
// ue_rem(rnti);
return;
}
// Trigger scheduler RACH
srsenb::sched_nr_interface::dl_sched_rar_info_t rar_info = {};
rar_info.preamble_idx = rach_info.preamble;
rar_info.temp_crnti = rnti;
rar_info.ta_cmd = rach_info.time_adv;
rar_info.prach_slot = slot_point{NUMEROLOGY_IDX, rach_info.slot_index};
// TODO: fill remaining fields as required
// sched.dl_rach_info(enb_cc_idx, rar_info);
sched.dl_rach_info(enb_cc_idx, rar_info);
logger.info("RACH: slot=%d, cc=%d, preamble=%d, offset=%d, temp_crnti=0x%x",
rach_info.slot_index,
@ -165,7 +175,7 @@ void mac_nr::rach_detected(const rach_info_t& rach_info)
});
}
uint16_t mac_nr::add_ue(uint32_t enb_cc_idx)
uint16_t mac_nr::alloc_ue(uint32_t enb_cc_idx)
{
ue_nr* inserted_ue = nullptr;
uint16_t rnti = SRSRAN_INVALID_RNTI;
@ -216,16 +226,6 @@ int mac_nr::remove_ue(uint16_t rnti)
return SRSRAN_SUCCESS;
}
uint16_t mac_nr::reserve_rnti()
{
uint16_t rnti = add_ue(0);
if (rnti == SRSRAN_INVALID_RNTI) {
return rnti;
}
return rnti;
}
bool mac_nr::is_rnti_valid_unsafe(uint16_t rnti)
{
if (not started) {

View File

@ -29,6 +29,7 @@ bwp_slot_grid::bwp_slot_grid(const bwp_params& bwp_cfg_, uint32_t slot_idx_) :
coresets[cs_id].emplace(*cfg, cs_id, slot_idx_, dl_pdcchs, ul_pdcchs);
}
}
srsran_softbuffer_tx_init_guru(&rar_softbuffer, SRSRAN_SCH_NR_MAX_NOF_CB_LDPC, SRSRAN_LDPC_MAX_LEN_ENCODED_CB);
}
void bwp_slot_grid::reset()
@ -147,6 +148,7 @@ alloc_result bwp_slot_allocator::alloc_rar_and_msg3(uint16_t
slot_cfg.idx = pdcch_slot.slot_idx();
bool success = phy_cfg.get_pdsch_cfg(slot_cfg, pdcch.dci, pdsch.sch);
srsran_assert(success, "Error converting DCI to grant");
pdsch.sch.grant.tb[0].softbuffer.tx = &bwp_pdcch_slot.rar_softbuffer;
// Generate Msg3 grants in PUSCH
uint32_t last_msg3 = msg3_rbs.start();

View File

@ -12,6 +12,7 @@
#include "srsenb/hdr/stack/rrc/rrc_nr.h"
#include "srsenb/hdr/common/common_enb.h"
#include "srsenb/test/mac/nr/sched_nr_cfg_generators.h"
#include "srsran/asn1/rrc_nr_utils.h"
#include "srsran/common/common_nr.h"
#include "srsran/common/phy_cfg_nr_default.h"
@ -210,23 +211,25 @@ void rrc_nr::config_phy()
void rrc_nr::config_mac()
{
// Fill MAC scheduler configuration for SIBs
srsenb::sched_interface::cell_cfg_t sched_cfg;
set_sched_cell_cfg_sib1(&sched_cfg, cfg.sib1);
// TODO: use parsed cell NR cfg configuration
std::vector<srsenb::sched_nr_interface::cell_cfg_t> sched_cells_cfg = {srsenb::get_default_cells_cfg(1)};
sched_interface::cell_cfg_t cell_cfg;
set_sched_cell_cfg_sib1(&cell_cfg, cfg.sib1);
// set SIB length
for (uint32_t i = 0; i < nof_si_messages + 1; i++) {
sched_cfg.sibs[i].len = sib_buffer[i]->N_bytes;
cell_cfg.sibs[i].len = sib_buffer[i]->N_bytes;
}
// PUCCH width
sched_cfg.nrb_pucch = SRSRAN_MAX(cfg.sr_cfg.nof_prb, cfg.cqi_cfg.nof_prb);
logger.info("Allocating %d PRBs for PUCCH", sched_cfg.nrb_pucch);
cell_cfg.nrb_pucch = SRSRAN_MAX(cfg.sr_cfg.nof_prb, cfg.cqi_cfg.nof_prb);
logger.info("Allocating %d PRBs for PUCCH", cell_cfg.nrb_pucch);
// Copy Cell configuration
sched_cfg.cell = cfg.cell;
cell_cfg.cell = cfg.cell;
// Configure MAC scheduler
mac->cell_cfg(&sched_cfg);
mac->cell_cfg(cell_cfg, sched_cells_cfg);
}
int32_t rrc_nr::generate_sibs()
@ -405,7 +408,7 @@ int rrc_nr::sgnb_addition_request(uint16_t eutra_rnti)
{
task_sched.defer_task([this, eutra_rnti]() {
// try to allocate new user
uint16_t nr_rnti = mac->reserve_rnti();
uint16_t nr_rnti = mac->reserve_rnti(0);
if (nr_rnti == SRSRAN_INVALID_RNTI) {
logger.error("Failed to allocate RNTI at MAC");
rrc_eutra->sgnb_addition_reject(eutra_rnti);

View File

@ -14,18 +14,38 @@
#define SRSRAN_DUMMY_NR_CLASSES_H
#include "srsran/interfaces/gnb_interfaces.h"
#include "srsran/interfaces/gnb_mac_interfaces.h"
namespace srsenb {
class mac_dummy : public mac_interface_rrc_nr
class rrc_nr_dummy : public rrc_interface_mac_nr
{
public:
int cell_cfg(srsenb::sched_interface::cell_cfg_t* cell_cfg_)
int read_pdu_bcch_bch(const uint32_t tti, srsran::unique_byte_buffer_t& buffer) { return SRSRAN_SUCCESS; }
int read_pdu_bcch_dlsch(uint32_t sib_index, srsran::unique_byte_buffer_t& buffer) { return SRSRAN_SUCCESS; }
int add_user(uint16_t rnti) { return SRSRAN_SUCCESS; }
};
class rlc_nr_dummy : public rlc_interface_mac_nr
{
public:
int read_pdu(uint16_t rnti, uint32_t lcid, uint8_t* payload, uint32_t nof_bytes) override { return SRSRAN_SUCCESS; }
void read_pdu_pcch(uint8_t* payload, uint32_t buffer_size) override {}
void write_pdu(uint16_t rnti, uint32_t lcid, uint8_t* payload, uint32_t nof_bytes) override {}
};
class mac_nr_dummy : public mac_interface_rrc_nr
{
public:
int cell_cfg(const sched_interface::cell_cfg_t& cell,
srsran::const_span<sched_nr_interface::cell_cfg_t> nr_cells) override
{
cellcfgobj = *cell_cfg_;
cellcfgobj = cell;
return SRSRAN_SUCCESS;
}
uint16_t reserve_rnti() { return 0x4601; }
uint16_t reserve_rnti(uint32_t enb_cc_idx) override { return 0x4601; }
int ue_cfg(uint16_t rnti, const sched_nr_interface::ue_cfg_t& ue_cfg) override { return SRSRAN_SUCCESS; }
srsenb::sched_interface::cell_cfg_t cellcfgobj;
};

View File

@ -0,0 +1,28 @@
/**
*
* \section COPYRIGHT
*
* Copyright 2013-2021 Software Radio Systems Limited
*
* By using this file, you agree to the terms and conditions set
* forth in the LICENSE file which can be found at the top level of
* the distribution.
*
*/
#ifndef SRSRAN_RLC_TEST_DUMMY_H
#define SRSRAN_RLC_TEST_DUMMY_H
#include "srsran/interfaces/enb_rlc_interfaces.h"
namespace srsenb {
class rlc_dummy : public rlc_interface_mac
{
int read_pdu(uint16_t rnti, uint32_t lcid, uint8_t* payload, uint32_t nof_bytes) { return SRSRAN_SUCCESS; }
void write_pdu(uint16_t rnti, uint32_t lcid, uint8_t* payload, uint32_t nof_bytes) {}
};
} // namespace srsenb
#endif // SRSRAN_RLC_TEST_DUMMY_H

View File

@ -18,7 +18,7 @@
namespace srsenb {
srsran_coreset_t get_default_coreset0(uint32_t nof_prb)
inline srsran_coreset_t get_default_coreset0(uint32_t nof_prb)
{
srsran_coreset_t coreset{};
coreset.id = 0;
@ -30,8 +30,8 @@ srsran_coreset_t get_default_coreset0(uint32_t nof_prb)
return coreset;
}
sched_nr_interface::cell_cfg_t get_default_cell_cfg(const srsran::phy_cfg_nr_t& phy_cfg = srsran::phy_cfg_nr_default_t{
srsran::phy_cfg_nr_default_t::reference_cfg_t{}})
inline sched_nr_interface::cell_cfg_t get_default_cell_cfg(
const srsran::phy_cfg_nr_t& phy_cfg = srsran::phy_cfg_nr_default_t{srsran::phy_cfg_nr_default_t::reference_cfg_t{}})
{
sched_nr_interface::cell_cfg_t cell_cfg{};
@ -65,7 +65,7 @@ sched_nr_interface::cell_cfg_t get_default_cell_cfg(const srsran::phy_cfg_nr_t&
return cell_cfg;
}
std::vector<sched_nr_interface::cell_cfg_t> get_default_cells_cfg(
inline std::vector<sched_nr_interface::cell_cfg_t> get_default_cells_cfg(
uint32_t nof_sectors,
const srsran::phy_cfg_nr_t& phy_cfg = srsran::phy_cfg_nr_default_t{srsran::phy_cfg_nr_default_t::reference_cfg_t{}})
{
@ -77,9 +77,9 @@ std::vector<sched_nr_interface::cell_cfg_t> get_default_cells_cfg(
return cells;
}
sched_nr_interface::ue_cfg_t get_default_ue_cfg(uint32_t nof_cc,
const srsran::phy_cfg_nr_t& phy_cfg = srsran::phy_cfg_nr_default_t{
srsran::phy_cfg_nr_default_t::reference_cfg_t{}})
inline sched_nr_interface::ue_cfg_t get_default_ue_cfg(
uint32_t nof_cc,
const srsran::phy_cfg_nr_t& phy_cfg = srsran::phy_cfg_nr_default_t{srsran::phy_cfg_nr_default_t::reference_cfg_t{}})
{
sched_nr_interface::ue_cfg_t uecfg{};
uecfg.carriers.resize(nof_cc);

View File

@ -38,10 +38,10 @@ int test_sib_generation()
{
srsran::task_scheduler task_sched;
mac_dummy mac_obj;
rlc_dummy rlc_obj;
pdcp_dummy pdcp_obj;
rrc_nr rrc_obj(&task_sched);
mac_nr_dummy mac_obj;
rlc_dummy rlc_obj;
pdcp_dummy pdcp_obj;
rrc_nr rrc_obj(&task_sched);
// set cfg
rrc_nr_cfg_t default_cfg = {};
@ -67,10 +67,10 @@ int test_rrc_setup()
{
srsran::task_scheduler task_sched;
mac_dummy mac_obj;
rlc_dummy rlc_obj;
pdcp_dummy pdcp_obj;
rrc_nr rrc_obj(&task_sched);
mac_nr_dummy mac_obj;
rlc_dummy rlc_obj;
pdcp_dummy pdcp_obj;
rrc_nr rrc_obj(&task_sched);
// set cfg
rrc_nr_cfg_t default_cfg = {};

View File

@ -18,6 +18,7 @@ if (RF_FOUND AND ENABLE_SRSUE AND ENABLE_SRSENB)
srsran_radio
srsenb_phy
srsgnb_mac
srsran_mac
${CMAKE_THREAD_LIBS_INIT}
${Boost_LIBRARIES}
${CMAKE_THREAD_LIBS_INIT}
@ -73,6 +74,7 @@ if (RF_FOUND AND ENABLE_SRSUE AND ENABLE_SRSENB)
add_nr_test(nr_phy_test_${NR_PHY_TEST_BW}_bidir_sched nr_phy_test
--reference=carrier=${NR_PHY_TEST_BW}
--duration=100 # 100 slots
--rnti=17921 # 0x4601
--gnb.stack.pdsch.slots=0,1,2,3,4,5 # All possible DL slots
--gnb.stack.pdsch.start=0 # Start at RB 0
--gnb.stack.pdsch.length=52 # Full 10 MHz BW

View File

@ -15,7 +15,10 @@
#include "dummy_rx_harq_proc.h"
#include "dummy_tx_harq_proc.h"
#include "srsenb/hdr/stack/mac/mac_nr.h"
#include "srsenb/hdr/stack/mac/nr/sched_nr.h"
#include "srsenb/test/common/dummy_classes_nr.h"
#include "srsenb/test/common/rlc_test_dummy.h"
#include "srsenb/test/mac/nr/sched_nr_cfg_generators.h"
#include <mutex>
#include <set>
@ -73,9 +76,12 @@ private:
srsran::phy_cfg_nr_t phy_cfg = {};
bool valid = false;
std::unique_ptr<srsenb::sched_nr> sched;
srsran::slot_point pdsch_slot, pusch_slot;
srslog::basic_logger& sched_logger;
srsran::task_scheduler task_sched;
srsenb::rrc_nr_dummy rrc_obj;
srsenb::rlc_dummy rlc_obj;
std::unique_ptr<srsenb::mac_nr> mac;
srsran::slot_point pdsch_slot, pusch_slot;
srslog::basic_logger& sched_logger;
std::mutex metrics_mutex;
metrics_t metrics = {};
@ -291,8 +297,6 @@ private:
metrics.mac.tx_errors += tb_count;
logger.debug("NACK received!");
}
sched->dl_ack_info(rnti, 0, ack_bit->pid, 0, is_ok);
}
// Process SR
@ -305,13 +309,14 @@ private:
public:
struct args_t {
srsran::phy_cfg_nr_t phy_cfg; ///< Physical layer configuration
bool use_dummy_sched = true; ///< Use dummy or real NR scheduler
uint16_t rnti = 0x1234; ///< C-RNTI
uint32_t ss_id = 1; ///< Search Space identifier
uint32_t pdcch_aggregation_level = 0; ///< PDCCH aggregation level
uint32_t pdcch_dl_candidate = 0; ///< PDCCH DL DCI candidate index
uint32_t pdcch_ul_candidate = 1; ///< PDCCH UL DCI candidate index
srsran::phy_cfg_nr_t phy_cfg; ///< Physical layer configuration
bool use_dummy_sched = true; ///< Use dummy or real NR scheduler
bool wait_preamble = false; ///< Whether a UE is created automatically or the stack waits for a PRACH
uint16_t rnti = 0x1234; ///< C-RNTI
uint32_t ss_id = 1; ///< Search Space identifier
uint32_t pdcch_aggregation_level = 0; ///< PDCCH aggregation level
uint32_t pdcch_dl_candidate = 0; ///< PDCCH DL DCI candidate index
uint32_t pdcch_ul_candidate = 1; ///< PDCCH UL DCI candidate index
struct {
uint32_t rb_start = 0; ///< Start frequency domain resource block
uint32_t rb_length = 10; ///< Number of frequency domain resource blocks
@ -335,15 +340,20 @@ public:
srsenb::sched_nr_interface::sched_cfg_t sched_cfg{};
sched_cfg.pdsch_enabled = args.pdsch.slots != "" and args.pdsch.slots != "none";
sched_cfg.pusch_enabled = args.pusch.slots != "" and args.pusch.slots != "none";
sched.reset(new srsenb::sched_nr{sched_cfg});
mac.reset(new srsenb::mac_nr{&task_sched, sched_cfg});
mac->init(srsenb::mac_nr_args_t{}, nullptr, nullptr, &rlc_obj, &rrc_obj);
std::vector<srsenb::sched_nr_interface::cell_cfg_t> cells_cfg = srsenb::get_default_cells_cfg(1, phy_cfg);
sched->cell_cfg(cells_cfg);
mac->cell_cfg(srsenb::sched_interface::cell_cfg_t{}, cells_cfg);
// add UE to scheduler
srsenb::sched_nr_interface::ue_cfg_t ue_cfg = srsenb::get_default_ue_cfg(1, phy_cfg);
ue_cfg.fixed_dl_mcs = args.pdsch.mcs;
ue_cfg.fixed_ul_mcs = args.pusch.mcs;
sched->ue_cfg(args.rnti, ue_cfg);
if (not use_dummy_sched and not args.wait_preamble) {
mac->reserve_rnti(0);
srsenb::sched_nr_interface::ue_cfg_t ue_cfg = srsenb::get_default_ue_cfg(1, phy_cfg);
ue_cfg.fixed_dl_mcs = args.pdsch.mcs;
ue_cfg.fixed_ul_mcs = args.pusch.mcs;
mac->ue_cfg(args.rnti, ue_cfg);
}
dl.mcs = args.pdsch.mcs;
ul.mcs = args.pusch.mcs;
@ -417,9 +427,7 @@ public:
}
if (not use_dummy_sched) {
srsenb::sched_nr_interface::dl_sched_res_t dl_res;
int ret = sched->get_dl_sched(pdsch_slot, 0, dl_res);
dl_sched = dl_res.dl_sched;
int ret = mac->get_dl_sched(slot_cfg, dl_sched);
for (pdsch_t& pdsch : dl_sched.pdsch) {
// Set TBS
@ -465,7 +473,7 @@ public:
}
if (not use_dummy_sched) {
int ret = sched->get_ul_sched(pusch_slot, 0, ul_sched);
int ret = mac->get_ul_sched(slot_cfg, ul_sched);
return ret;
}
@ -541,22 +549,12 @@ public:
return SRSRAN_SUCCESS;
}
void dl_ack_info(uint16_t rnti_, uint32_t cc, uint32_t pid, uint32_t tb_idx, bool ack)
{
if (not use_dummy_sched) {
sched->dl_ack_info(rnti_, cc, pid, tb_idx, ack);
}
}
void ul_crc_info(uint16_t rnti_, uint32_t cc, uint32_t pid, bool crc)
{
if (not use_dummy_sched) {
sched->ul_crc_info(rnti_, cc, pid, crc);
}
}
int pucch_info(const srsran_slot_cfg_t& slot_cfg, const pucch_info_t& pucch_info) override
{
if (not use_dummy_sched) {
mac->pucch_info(slot_cfg, pucch_info);
}
// Handle UCI data
if (not handle_uci_data(pucch_info.uci_data.cfg, pucch_info.uci_data.value)) {
logger.error("Error handling UCI data from PUCCH reception");
@ -588,6 +586,10 @@ public:
int pusch_info(const srsran_slot_cfg_t& slot_cfg, pusch_info_t& pusch_info) override
{
if (not use_dummy_sched) {
mac->pusch_info(slot_cfg, pusch_info);
}
// Handle UCI data
if (not handle_uci_data(pusch_info.uci_cfg, pusch_info.pusch_data.uci)) {
logger.error("Error handling UCI data from PUCCH reception");
@ -602,23 +604,19 @@ public:
metrics.mac.rx_brate += rx_harq_proc[pusch_info.pid].get_tbs();
metrics.mac.rx_pkts++;
ul_crc_info(rnti, 0, pusch_info.pid, pusch_info.pusch_data.tb[0].crc);
return SRSRAN_SUCCESS;
}
void rach_detected(const rach_info_t& rach_info) override
{
if (not use_dummy_sched) {
srsenb::sched_nr_interface::dl_sched_rar_info_t ra_info;
ra_info.preamble_idx = rach_info.preamble;
ra_info.ta_cmd = rach_info.time_adv;
ra_info.ofdm_symbol_idx = 0;
ra_info.msg3_size = 7;
ra_info.freq_idx = 0;
ra_info.prach_slot = pdsch_slot - TX_ENB_DELAY;
ra_info.temp_crnti = rnti;
sched->dl_rach_info(0, ra_info);
mac->rach_detected(rach_info);
task_sched.run_pending_tasks();
srsenb::sched_nr_interface::ue_cfg_t ue_cfg = srsenb::get_default_ue_cfg(1, phy_cfg);
ue_cfg.fixed_dl_mcs = ue_cfg.fixed_dl_mcs;
ue_cfg.fixed_ul_mcs = ue_cfg.fixed_ul_mcs;
mac->ue_cfg(rnti, ue_cfg);
}
std::unique_lock<std::mutex> lock(metrics_mutex);

View File

@ -115,8 +115,9 @@ test_bench::args_t::args_t(int argc, char** argv)
ue_stack.rnti = rnti;
gnb_stack.rnti = rnti;
gnb_stack.phy_cfg = phy_cfg;
gnb_stack.rnti = rnti;
gnb_stack.phy_cfg = phy_cfg;
gnb_stack.wait_preamble = ue_stack.prach_preamble > 0;
if (gnb_stack.pdsch.rb_length == 0) {
gnb_stack.pdsch.rb_length = phy_cfg.carrier.nof_prb;
@ -271,8 +272,8 @@ int main(int argc, char** argv)
}
// Assert metrics
TESTASSERT(metrics.gnb_stack.mac.tx_errors == 0);
TESTASSERT(metrics.gnb_stack.mac.rx_errors == 0);
TESTASSERT_EQ(0, metrics.gnb_stack.mac.tx_errors);
TESTASSERT_EQ(0, metrics.gnb_stack.mac.rx_errors);
TESTASSERT(metrics.ue_stack.sr_count == metrics.gnb_stack.sr_count);
// If reached here, the test is successful