mirror of https://github.com/PentHertz/srsLTE.git
sched,nr: nr_phy_test now uses the whole mac class rather than just the scheduler
This commit is contained in:
parent
05a5f4115f
commit
04e5c81edf
|
@ -27,23 +27,6 @@
|
||||||
|
|
||||||
namespace srsenb {
|
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
|
* RLC INTERFACES
|
||||||
****************************/
|
****************************/
|
||||||
|
@ -164,8 +147,7 @@ public:
|
||||||
|
|
||||||
// NR interface identical to EUTRA version
|
// NR interface identical to EUTRA version
|
||||||
class rrc_interface_pdcp_nr : public rrc_interface_pdcp
|
class rrc_interface_pdcp_nr : public rrc_interface_pdcp
|
||||||
{
|
{};
|
||||||
};
|
|
||||||
|
|
||||||
class phy_interface_rrc_nr
|
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_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 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 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;
|
virtual void rach_detected(const rach_info_t& rach_info) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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
|
|
@ -23,21 +23,21 @@
|
||||||
#include "srsran/common/task_scheduler.h"
|
#include "srsran/common/task_scheduler.h"
|
||||||
#include "srsran/interfaces/enb_metrics_interface.h"
|
#include "srsran/interfaces/enb_metrics_interface.h"
|
||||||
#include "srsran/interfaces/enb_rlc_interfaces.h"
|
#include "srsran/interfaces/enb_rlc_interfaces.h"
|
||||||
#include "srsran/interfaces/gnb_interfaces.h"
|
#include "srsran/interfaces/gnb_mac_interfaces.h"
|
||||||
|
|
||||||
namespace srsenb {
|
namespace srsenb {
|
||||||
|
|
||||||
struct mac_nr_args_t {
|
struct mac_nr_args_t {
|
||||||
srsran::phy_cfg_nr_t phy_base_cfg = {};
|
srsran::phy_cfg_nr_t phy_base_cfg = {};
|
||||||
int fixed_dl_mcs = -1;
|
int fixed_dl_mcs = -1;
|
||||||
int fixed_ul_mcs = -1;
|
int fixed_ul_mcs = -1;
|
||||||
srsenb::pcap_args_t pcap;
|
srsenb::pcap_args_t pcap;
|
||||||
};
|
};
|
||||||
|
|
||||||
class mac_nr final : public mac_interface_phy_nr, public mac_interface_rrc_nr, public mac_interface_rlc_nr
|
class mac_nr final : public mac_interface_phy_nr, public mac_interface_rrc_nr, public mac_interface_rlc_nr
|
||||||
{
|
{
|
||||||
public:
|
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();
|
~mac_nr();
|
||||||
|
|
||||||
int init(const mac_nr_args_t& args_,
|
int init(const mac_nr_args_t& args_,
|
||||||
|
@ -50,9 +50,11 @@ public:
|
||||||
void get_metrics(srsenb::mac_metrics_t& metrics);
|
void get_metrics(srsenb::mac_metrics_t& metrics);
|
||||||
|
|
||||||
// MAC interface for RRC
|
// MAC interface for RRC
|
||||||
int cell_cfg(srsenb::sched_interface::cell_cfg_t* cell_cfg) override;
|
int cell_cfg(const sched_interface::cell_cfg_t& cell,
|
||||||
uint16_t reserve_rnti() override;
|
srsran::const_span<sched_nr_interface::cell_cfg_t> nr_cells) override;
|
||||||
int read_pdu_bcch_bch(uint8_t* payload);
|
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
|
// MAC interface for RLC
|
||||||
// TODO:
|
// TODO:
|
||||||
|
@ -68,7 +70,8 @@ public:
|
||||||
void rach_detected(const rach_info_t& rach_info) override;
|
void rach_detected(const rach_info_t& rach_info) override;
|
||||||
|
|
||||||
private:
|
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);
|
int remove_ue(uint16_t rnti);
|
||||||
|
|
||||||
// internal misc helpers
|
// internal misc helpers
|
||||||
|
@ -91,7 +94,7 @@ private:
|
||||||
rrc_interface_mac_nr* rrc = nullptr;
|
rrc_interface_mac_nr* rrc = nullptr;
|
||||||
|
|
||||||
// args
|
// args
|
||||||
srsran::task_sched_handle task_sched;
|
srsran::task_sched_handle task_sched;
|
||||||
srsran::task_multiqueue::queue_handle stack_task_queue;
|
srsran::task_multiqueue::queue_handle stack_task_queue;
|
||||||
|
|
||||||
std::unique_ptr<srsran::mac_pcap> pcap = nullptr;
|
std::unique_ptr<srsran::mac_pcap> pcap = nullptr;
|
||||||
|
@ -100,17 +103,17 @@ private:
|
||||||
|
|
||||||
std::atomic<bool> started = {false};
|
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;
|
srsran::slot_point pdsch_slot, pusch_slot;
|
||||||
srsenb::sched_nr sched;
|
srsenb::sched_nr sched;
|
||||||
srsenb::sched_interface::cell_cfg_t cfg = {};
|
srsenb::sched_interface::cell_cfg_t cfg = {};
|
||||||
|
|
||||||
// Map of active UEs
|
// Map of active UEs
|
||||||
pthread_rwlock_t rwlock = {};
|
pthread_rwlock_t rwlock = {};
|
||||||
static const uint16_t FIRST_RNTI = 0x4601;
|
static const uint16_t FIRST_RNTI = 0x4601;
|
||||||
srsran::static_circular_map<uint16_t, std::unique_ptr<ue_nr>, SRSENB_MAX_UES> ue_db;
|
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
|
// BCH buffers
|
||||||
struct sib_info_t {
|
struct sib_info_t {
|
||||||
|
|
|
@ -53,8 +53,13 @@ class ra_sched
|
||||||
public:
|
public:
|
||||||
explicit ra_sched(const bwp_params& bwp_cfg_);
|
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);
|
void run_slot(bwp_slot_allocator& slot_grid);
|
||||||
|
|
||||||
|
/// Check if there are pending RARs
|
||||||
bool empty() const { return pending_rars.empty(); }
|
bool empty() const { return pending_rars.empty(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -44,15 +44,16 @@ struct bwp_slot_grid {
|
||||||
uint32_t slot_idx;
|
uint32_t slot_idx;
|
||||||
const bwp_params* cfg;
|
const bwp_params* cfg;
|
||||||
|
|
||||||
bwp_rb_bitmap dl_prbs;
|
bwp_rb_bitmap dl_prbs;
|
||||||
bwp_rb_bitmap ul_prbs;
|
bwp_rb_bitmap ul_prbs;
|
||||||
pdcch_dl_list_t dl_pdcchs;
|
pdcch_dl_list_t dl_pdcchs;
|
||||||
pdcch_ul_list_t ul_pdcchs;
|
pdcch_ul_list_t ul_pdcchs;
|
||||||
pdsch_list_t pdschs;
|
pdsch_list_t pdschs;
|
||||||
rar_list_t rar;
|
rar_list_t rar;
|
||||||
slot_coreset_list coresets;
|
slot_coreset_list coresets;
|
||||||
pusch_list_t puschs;
|
pusch_list_t puschs;
|
||||||
harq_ack_list_t pending_acks;
|
harq_ack_list_t pending_acks;
|
||||||
|
srsran_softbuffer_tx_t rar_softbuffer;
|
||||||
|
|
||||||
bwp_slot_grid() = default;
|
bwp_slot_grid() = default;
|
||||||
explicit bwp_slot_grid(const bwp_params& bwp_params, uint32_t slot_idx_);
|
explicit bwp_slot_grid(const bwp_params& bwp_params, uint32_t slot_idx_);
|
||||||
|
|
|
@ -91,7 +91,7 @@ public:
|
||||||
uint32_t freq_idx;
|
uint32_t freq_idx;
|
||||||
uint32_t ta_cmd;
|
uint32_t ta_cmd;
|
||||||
uint16_t temp_crnti;
|
uint16_t temp_crnti;
|
||||||
uint32_t msg3_size;
|
uint32_t msg3_size = 7;
|
||||||
slot_point prach_slot;
|
slot_point prach_slot;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
#include "srsran/interfaces/enb_rlc_interfaces.h"
|
#include "srsran/interfaces/enb_rlc_interfaces.h"
|
||||||
#include "srsran/interfaces/enb_rrc_interfaces.h"
|
#include "srsran/interfaces/enb_rrc_interfaces.h"
|
||||||
#include "srsran/interfaces/gnb_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_ngap_interfaces.h"
|
||||||
#include "srsran/interfaces/gnb_rrc_nr_interfaces.h"
|
#include "srsran/interfaces/gnb_rrc_nr_interfaces.h"
|
||||||
#include <map>
|
#include <map>
|
||||||
|
@ -118,8 +119,8 @@ public:
|
||||||
int pack_nr_radio_bearer_config(asn1::dyn_octstring& packed_nr_bearer_config);
|
int pack_nr_radio_bearer_config(asn1::dyn_octstring& packed_nr_bearer_config);
|
||||||
|
|
||||||
// state
|
// state
|
||||||
rrc_nr_state_t state = rrc_nr_state_t::RRC_IDLE;
|
rrc_nr_state_t state = rrc_nr_state_t::RRC_IDLE;
|
||||||
uint8_t transaction_id = 0;
|
uint8_t transaction_id = 0;
|
||||||
|
|
||||||
uint32_t drb1_lcid = 4;
|
uint32_t drb1_lcid = 4;
|
||||||
};
|
};
|
||||||
|
@ -128,12 +129,12 @@ private:
|
||||||
rrc_nr_cfg_t cfg = {};
|
rrc_nr_cfg_t cfg = {};
|
||||||
|
|
||||||
// interfaces
|
// interfaces
|
||||||
phy_interface_stack_nr* phy = nullptr;
|
phy_interface_stack_nr* phy = nullptr;
|
||||||
mac_interface_rrc_nr* mac = nullptr;
|
mac_interface_rrc_nr* mac = nullptr;
|
||||||
rlc_interface_rrc* rlc = nullptr;
|
rlc_interface_rrc* rlc = nullptr;
|
||||||
pdcp_interface_rrc* pdcp = nullptr;
|
pdcp_interface_rrc* pdcp = nullptr;
|
||||||
gtpu_interface_rrc_nr* gtpu = nullptr;
|
gtpu_interface_rrc_nr* gtpu = nullptr;
|
||||||
ngap_interface_rrc_nr* ngap = nullptr;
|
ngap_interface_rrc_nr* ngap = nullptr;
|
||||||
rrc_eutra_interface_rrc_nr* rrc_eutra = nullptr;
|
rrc_eutra_interface_rrc_nr* rrc_eutra = nullptr;
|
||||||
|
|
||||||
// args
|
// args
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
#define SRSENB_RLC_NR_H
|
#define SRSENB_RLC_NR_H
|
||||||
|
|
||||||
#include "srsran/interfaces/gnb_interfaces.h"
|
#include "srsran/interfaces/gnb_interfaces.h"
|
||||||
|
#include "srsran/interfaces/gnb_mac_interfaces.h"
|
||||||
#include "srsran/rlc/rlc.h"
|
#include "srsran/rlc/rlc.h"
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@ set(SOURCES mac_nr.cc
|
||||||
sched_nr.cc
|
sched_nr.cc
|
||||||
sched_nr_ue.cc
|
sched_nr_ue.cc
|
||||||
sched_nr_worker.cc
|
sched_nr_worker.cc
|
||||||
sched_nr_grant_allocator.cc
|
sched_nr_grant_allocator.cc
|
||||||
sched_nr_harq.cc
|
sched_nr_harq.cc
|
||||||
sched_nr_pdcch.cc
|
sched_nr_pdcch.cc
|
||||||
sched_nr_cfg.cc
|
sched_nr_cfg.cc
|
||||||
|
|
|
@ -24,10 +24,10 @@
|
||||||
|
|
||||||
namespace srsenb {
|
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")),
|
logger(srslog::fetch_basic_logger("MAC-NR")),
|
||||||
task_sched(task_sched_),
|
task_sched(task_sched_),
|
||||||
sched(srsenb::sched_nr_interface::sched_cfg_t{}),
|
sched(sched_cfg),
|
||||||
bcch_bch_payload(srsran::make_byte_buffer())
|
bcch_bch_payload(srsran::make_byte_buffer())
|
||||||
{
|
{
|
||||||
stack_task_queue = task_sched.make_task_queue();
|
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);
|
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");
|
logger.info("Started");
|
||||||
|
|
||||||
started = true;
|
started = true;
|
||||||
|
@ -82,16 +76,19 @@ void mac_nr::stop()
|
||||||
|
|
||||||
void mac_nr::get_metrics(srsenb::mac_metrics_t& metrics) {}
|
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)
|
// read SIBs from RRC (SIB1 for now only)
|
||||||
for (int i = 0; i < 1 /* srsenb::sched_interface::MAX_SIBS */; i++) {
|
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_info_t sib = {};
|
||||||
sib.index = i;
|
sib.index = i;
|
||||||
sib.periodicity = cell_cfg->sibs->period_rf;
|
sib.periodicity = cell.sibs->period_rf;
|
||||||
sib.payload = srsran::make_byte_buffer();
|
sib.payload = srsran::make_byte_buffer();
|
||||||
if (sib.payload == nullptr) {
|
if (sib.payload == nullptr) {
|
||||||
logger.error("Couldn't allocate PDU in %s().", __FUNCTION__);
|
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;
|
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)
|
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);
|
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;
|
uint32_t enb_cc_idx = 0;
|
||||||
stack_task_queue.push([this, rach_info, enb_cc_idx, rach_tprof_meas]() mutable {
|
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();
|
rach_tprof_meas.defer_stop();
|
||||||
|
uint16_t rnti = reserve_rnti(enb_cc_idx);
|
||||||
|
|
||||||
// TODO: Generate RAR data
|
// TODO: Generate RAR data
|
||||||
// ..
|
// ..
|
||||||
|
@ -130,25 +151,14 @@ void mac_nr::rach_detected(const rach_info_t& rach_info)
|
||||||
// Log this event.
|
// Log this event.
|
||||||
++detected_rachs[enb_cc_idx];
|
++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
|
// Trigger scheduler RACH
|
||||||
srsenb::sched_nr_interface::dl_sched_rar_info_t rar_info = {};
|
srsenb::sched_nr_interface::dl_sched_rar_info_t rar_info = {};
|
||||||
rar_info.preamble_idx = rach_info.preamble;
|
rar_info.preamble_idx = rach_info.preamble;
|
||||||
rar_info.temp_crnti = rnti;
|
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};
|
rar_info.prach_slot = slot_point{NUMEROLOGY_IDX, rach_info.slot_index};
|
||||||
// TODO: fill remaining fields as required
|
// 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",
|
logger.info("RACH: slot=%d, cc=%d, preamble=%d, offset=%d, temp_crnti=0x%x",
|
||||||
rach_info.slot_index,
|
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;
|
ue_nr* inserted_ue = nullptr;
|
||||||
uint16_t rnti = SRSRAN_INVALID_RNTI;
|
uint16_t rnti = SRSRAN_INVALID_RNTI;
|
||||||
|
@ -216,16 +226,6 @@ int mac_nr::remove_ue(uint16_t rnti)
|
||||||
return SRSRAN_SUCCESS;
|
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)
|
bool mac_nr::is_rnti_valid_unsafe(uint16_t rnti)
|
||||||
{
|
{
|
||||||
if (not started) {
|
if (not started) {
|
||||||
|
|
|
@ -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);
|
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()
|
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();
|
slot_cfg.idx = pdcch_slot.slot_idx();
|
||||||
bool success = phy_cfg.get_pdsch_cfg(slot_cfg, pdcch.dci, pdsch.sch);
|
bool success = phy_cfg.get_pdsch_cfg(slot_cfg, pdcch.dci, pdsch.sch);
|
||||||
srsran_assert(success, "Error converting DCI to grant");
|
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
|
// Generate Msg3 grants in PUSCH
|
||||||
uint32_t last_msg3 = msg3_rbs.start();
|
uint32_t last_msg3 = msg3_rbs.start();
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
|
|
||||||
#include "srsenb/hdr/stack/rrc/rrc_nr.h"
|
#include "srsenb/hdr/stack/rrc/rrc_nr.h"
|
||||||
#include "srsenb/hdr/common/common_enb.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/asn1/rrc_nr_utils.h"
|
||||||
#include "srsran/common/common_nr.h"
|
#include "srsran/common/common_nr.h"
|
||||||
#include "srsran/common/phy_cfg_nr_default.h"
|
#include "srsran/common/phy_cfg_nr_default.h"
|
||||||
|
@ -210,23 +211,25 @@ void rrc_nr::config_phy()
|
||||||
void rrc_nr::config_mac()
|
void rrc_nr::config_mac()
|
||||||
{
|
{
|
||||||
// Fill MAC scheduler configuration for SIBs
|
// Fill MAC scheduler configuration for SIBs
|
||||||
srsenb::sched_interface::cell_cfg_t sched_cfg;
|
// TODO: use parsed cell NR cfg configuration
|
||||||
set_sched_cell_cfg_sib1(&sched_cfg, cfg.sib1);
|
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
|
// set SIB length
|
||||||
for (uint32_t i = 0; i < nof_si_messages + 1; i++) {
|
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
|
// PUCCH width
|
||||||
sched_cfg.nrb_pucch = SRSRAN_MAX(cfg.sr_cfg.nof_prb, cfg.cqi_cfg.nof_prb);
|
cell_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);
|
logger.info("Allocating %d PRBs for PUCCH", cell_cfg.nrb_pucch);
|
||||||
|
|
||||||
// Copy Cell configuration
|
// Copy Cell configuration
|
||||||
sched_cfg.cell = cfg.cell;
|
cell_cfg.cell = cfg.cell;
|
||||||
|
|
||||||
// Configure MAC scheduler
|
// Configure MAC scheduler
|
||||||
mac->cell_cfg(&sched_cfg);
|
mac->cell_cfg(cell_cfg, sched_cells_cfg);
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t rrc_nr::generate_sibs()
|
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]() {
|
task_sched.defer_task([this, eutra_rnti]() {
|
||||||
// try to allocate new user
|
// 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) {
|
if (nr_rnti == SRSRAN_INVALID_RNTI) {
|
||||||
logger.error("Failed to allocate RNTI at MAC");
|
logger.error("Failed to allocate RNTI at MAC");
|
||||||
rrc_eutra->sgnb_addition_reject(eutra_rnti);
|
rrc_eutra->sgnb_addition_reject(eutra_rnti);
|
||||||
|
|
|
@ -14,18 +14,38 @@
|
||||||
#define SRSRAN_DUMMY_NR_CLASSES_H
|
#define SRSRAN_DUMMY_NR_CLASSES_H
|
||||||
|
|
||||||
#include "srsran/interfaces/gnb_interfaces.h"
|
#include "srsran/interfaces/gnb_interfaces.h"
|
||||||
|
#include "srsran/interfaces/gnb_mac_interfaces.h"
|
||||||
|
|
||||||
namespace srsenb {
|
namespace srsenb {
|
||||||
|
|
||||||
class mac_dummy : public mac_interface_rrc_nr
|
class rrc_nr_dummy : public rrc_interface_mac_nr
|
||||||
{
|
{
|
||||||
public:
|
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;
|
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;
|
srsenb::sched_interface::cell_cfg_t cellcfgobj;
|
||||||
};
|
};
|
||||||
|
|
|
@ -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
|
|
@ -18,7 +18,7 @@
|
||||||
|
|
||||||
namespace srsenb {
|
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{};
|
srsran_coreset_t coreset{};
|
||||||
coreset.id = 0;
|
coreset.id = 0;
|
||||||
|
@ -30,8 +30,8 @@ srsran_coreset_t get_default_coreset0(uint32_t nof_prb)
|
||||||
return coreset;
|
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{
|
inline sched_nr_interface::cell_cfg_t get_default_cell_cfg(
|
||||||
srsran::phy_cfg_nr_default_t::reference_cfg_t{}})
|
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{};
|
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;
|
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,
|
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{}})
|
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;
|
return cells;
|
||||||
}
|
}
|
||||||
|
|
||||||
sched_nr_interface::ue_cfg_t get_default_ue_cfg(uint32_t nof_cc,
|
inline sched_nr_interface::ue_cfg_t get_default_ue_cfg(
|
||||||
const srsran::phy_cfg_nr_t& phy_cfg = srsran::phy_cfg_nr_default_t{
|
uint32_t nof_cc,
|
||||||
srsran::phy_cfg_nr_default_t::reference_cfg_t{}})
|
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{};
|
sched_nr_interface::ue_cfg_t uecfg{};
|
||||||
uecfg.carriers.resize(nof_cc);
|
uecfg.carriers.resize(nof_cc);
|
||||||
|
|
|
@ -38,10 +38,10 @@ int test_sib_generation()
|
||||||
{
|
{
|
||||||
srsran::task_scheduler task_sched;
|
srsran::task_scheduler task_sched;
|
||||||
|
|
||||||
mac_dummy mac_obj;
|
mac_nr_dummy mac_obj;
|
||||||
rlc_dummy rlc_obj;
|
rlc_dummy rlc_obj;
|
||||||
pdcp_dummy pdcp_obj;
|
pdcp_dummy pdcp_obj;
|
||||||
rrc_nr rrc_obj(&task_sched);
|
rrc_nr rrc_obj(&task_sched);
|
||||||
|
|
||||||
// set cfg
|
// set cfg
|
||||||
rrc_nr_cfg_t default_cfg = {};
|
rrc_nr_cfg_t default_cfg = {};
|
||||||
|
@ -67,10 +67,10 @@ int test_rrc_setup()
|
||||||
{
|
{
|
||||||
srsran::task_scheduler task_sched;
|
srsran::task_scheduler task_sched;
|
||||||
|
|
||||||
mac_dummy mac_obj;
|
mac_nr_dummy mac_obj;
|
||||||
rlc_dummy rlc_obj;
|
rlc_dummy rlc_obj;
|
||||||
pdcp_dummy pdcp_obj;
|
pdcp_dummy pdcp_obj;
|
||||||
rrc_nr rrc_obj(&task_sched);
|
rrc_nr rrc_obj(&task_sched);
|
||||||
|
|
||||||
// set cfg
|
// set cfg
|
||||||
rrc_nr_cfg_t default_cfg = {};
|
rrc_nr_cfg_t default_cfg = {};
|
||||||
|
|
|
@ -18,6 +18,7 @@ if (RF_FOUND AND ENABLE_SRSUE AND ENABLE_SRSENB)
|
||||||
srsran_radio
|
srsran_radio
|
||||||
srsenb_phy
|
srsenb_phy
|
||||||
srsgnb_mac
|
srsgnb_mac
|
||||||
|
srsran_mac
|
||||||
${CMAKE_THREAD_LIBS_INIT}
|
${CMAKE_THREAD_LIBS_INIT}
|
||||||
${Boost_LIBRARIES}
|
${Boost_LIBRARIES}
|
||||||
${CMAKE_THREAD_LIBS_INIT}
|
${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
|
add_nr_test(nr_phy_test_${NR_PHY_TEST_BW}_bidir_sched nr_phy_test
|
||||||
--reference=carrier=${NR_PHY_TEST_BW}
|
--reference=carrier=${NR_PHY_TEST_BW}
|
||||||
--duration=100 # 100 slots
|
--duration=100 # 100 slots
|
||||||
|
--rnti=17921 # 0x4601
|
||||||
--gnb.stack.pdsch.slots=0,1,2,3,4,5 # All possible DL slots
|
--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.start=0 # Start at RB 0
|
||||||
--gnb.stack.pdsch.length=52 # Full 10 MHz BW
|
--gnb.stack.pdsch.length=52 # Full 10 MHz BW
|
||||||
|
|
|
@ -15,7 +15,10 @@
|
||||||
|
|
||||||
#include "dummy_rx_harq_proc.h"
|
#include "dummy_rx_harq_proc.h"
|
||||||
#include "dummy_tx_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/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 "srsenb/test/mac/nr/sched_nr_cfg_generators.h"
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <set>
|
#include <set>
|
||||||
|
@ -73,9 +76,12 @@ private:
|
||||||
srsran::phy_cfg_nr_t phy_cfg = {};
|
srsran::phy_cfg_nr_t phy_cfg = {};
|
||||||
bool valid = false;
|
bool valid = false;
|
||||||
|
|
||||||
std::unique_ptr<srsenb::sched_nr> sched;
|
srsran::task_scheduler task_sched;
|
||||||
srsran::slot_point pdsch_slot, pusch_slot;
|
srsenb::rrc_nr_dummy rrc_obj;
|
||||||
srslog::basic_logger& sched_logger;
|
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;
|
std::mutex metrics_mutex;
|
||||||
metrics_t metrics = {};
|
metrics_t metrics = {};
|
||||||
|
@ -291,8 +297,6 @@ private:
|
||||||
metrics.mac.tx_errors += tb_count;
|
metrics.mac.tx_errors += tb_count;
|
||||||
logger.debug("NACK received!");
|
logger.debug("NACK received!");
|
||||||
}
|
}
|
||||||
|
|
||||||
sched->dl_ack_info(rnti, 0, ack_bit->pid, 0, is_ok);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Process SR
|
// Process SR
|
||||||
|
@ -305,13 +309,14 @@ private:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
struct args_t {
|
struct args_t {
|
||||||
srsran::phy_cfg_nr_t phy_cfg; ///< Physical layer configuration
|
srsran::phy_cfg_nr_t phy_cfg; ///< Physical layer configuration
|
||||||
bool use_dummy_sched = true; ///< Use dummy or real NR scheduler
|
bool use_dummy_sched = true; ///< Use dummy or real NR scheduler
|
||||||
uint16_t rnti = 0x1234; ///< C-RNTI
|
bool wait_preamble = false; ///< Whether a UE is created automatically or the stack waits for a PRACH
|
||||||
uint32_t ss_id = 1; ///< Search Space identifier
|
uint16_t rnti = 0x1234; ///< C-RNTI
|
||||||
uint32_t pdcch_aggregation_level = 0; ///< PDCCH aggregation level
|
uint32_t ss_id = 1; ///< Search Space identifier
|
||||||
uint32_t pdcch_dl_candidate = 0; ///< PDCCH DL DCI candidate index
|
uint32_t pdcch_aggregation_level = 0; ///< PDCCH aggregation level
|
||||||
uint32_t pdcch_ul_candidate = 1; ///< PDCCH UL DCI candidate index
|
uint32_t pdcch_dl_candidate = 0; ///< PDCCH DL DCI candidate index
|
||||||
|
uint32_t pdcch_ul_candidate = 1; ///< PDCCH UL DCI candidate index
|
||||||
struct {
|
struct {
|
||||||
uint32_t rb_start = 0; ///< Start frequency domain resource block
|
uint32_t rb_start = 0; ///< Start frequency domain resource block
|
||||||
uint32_t rb_length = 10; ///< Number of frequency domain resource blocks
|
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{};
|
srsenb::sched_nr_interface::sched_cfg_t sched_cfg{};
|
||||||
sched_cfg.pdsch_enabled = args.pdsch.slots != "" and args.pdsch.slots != "none";
|
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_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);
|
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
|
// add UE to scheduler
|
||||||
srsenb::sched_nr_interface::ue_cfg_t ue_cfg = srsenb::get_default_ue_cfg(1, phy_cfg);
|
if (not use_dummy_sched and not args.wait_preamble) {
|
||||||
ue_cfg.fixed_dl_mcs = args.pdsch.mcs;
|
mac->reserve_rnti(0);
|
||||||
ue_cfg.fixed_ul_mcs = args.pusch.mcs;
|
|
||||||
sched->ue_cfg(args.rnti, ue_cfg);
|
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;
|
dl.mcs = args.pdsch.mcs;
|
||||||
ul.mcs = args.pusch.mcs;
|
ul.mcs = args.pusch.mcs;
|
||||||
|
@ -417,9 +427,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
if (not use_dummy_sched) {
|
if (not use_dummy_sched) {
|
||||||
srsenb::sched_nr_interface::dl_sched_res_t dl_res;
|
int ret = mac->get_dl_sched(slot_cfg, dl_sched);
|
||||||
int ret = sched->get_dl_sched(pdsch_slot, 0, dl_res);
|
|
||||||
dl_sched = dl_res.dl_sched;
|
|
||||||
|
|
||||||
for (pdsch_t& pdsch : dl_sched.pdsch) {
|
for (pdsch_t& pdsch : dl_sched.pdsch) {
|
||||||
// Set TBS
|
// Set TBS
|
||||||
|
@ -465,7 +473,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
if (not use_dummy_sched) {
|
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;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -541,22 +549,12 @@ public:
|
||||||
return SRSRAN_SUCCESS;
|
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
|
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
|
// Handle UCI data
|
||||||
if (not handle_uci_data(pucch_info.uci_data.cfg, pucch_info.uci_data.value)) {
|
if (not handle_uci_data(pucch_info.uci_data.cfg, pucch_info.uci_data.value)) {
|
||||||
logger.error("Error handling UCI data from PUCCH reception");
|
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
|
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
|
// Handle UCI data
|
||||||
if (not handle_uci_data(pusch_info.uci_cfg, pusch_info.pusch_data.uci)) {
|
if (not handle_uci_data(pusch_info.uci_cfg, pusch_info.pusch_data.uci)) {
|
||||||
logger.error("Error handling UCI data from PUCCH reception");
|
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_brate += rx_harq_proc[pusch_info.pid].get_tbs();
|
||||||
metrics.mac.rx_pkts++;
|
metrics.mac.rx_pkts++;
|
||||||
|
|
||||||
ul_crc_info(rnti, 0, pusch_info.pid, pusch_info.pusch_data.tb[0].crc);
|
|
||||||
|
|
||||||
return SRSRAN_SUCCESS;
|
return SRSRAN_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
void rach_detected(const rach_info_t& rach_info) override
|
void rach_detected(const rach_info_t& rach_info) override
|
||||||
{
|
{
|
||||||
if (not use_dummy_sched) {
|
if (not use_dummy_sched) {
|
||||||
srsenb::sched_nr_interface::dl_sched_rar_info_t ra_info;
|
mac->rach_detected(rach_info);
|
||||||
ra_info.preamble_idx = rach_info.preamble;
|
task_sched.run_pending_tasks();
|
||||||
ra_info.ta_cmd = rach_info.time_adv;
|
|
||||||
ra_info.ofdm_symbol_idx = 0;
|
srsenb::sched_nr_interface::ue_cfg_t ue_cfg = srsenb::get_default_ue_cfg(1, phy_cfg);
|
||||||
ra_info.msg3_size = 7;
|
ue_cfg.fixed_dl_mcs = ue_cfg.fixed_dl_mcs;
|
||||||
ra_info.freq_idx = 0;
|
ue_cfg.fixed_ul_mcs = ue_cfg.fixed_ul_mcs;
|
||||||
ra_info.prach_slot = pdsch_slot - TX_ENB_DELAY;
|
mac->ue_cfg(rnti, ue_cfg);
|
||||||
ra_info.temp_crnti = rnti;
|
|
||||||
sched->dl_rach_info(0, ra_info);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_lock<std::mutex> lock(metrics_mutex);
|
std::unique_lock<std::mutex> lock(metrics_mutex);
|
||||||
|
|
|
@ -115,8 +115,9 @@ test_bench::args_t::args_t(int argc, char** argv)
|
||||||
|
|
||||||
ue_stack.rnti = rnti;
|
ue_stack.rnti = rnti;
|
||||||
|
|
||||||
gnb_stack.rnti = rnti;
|
gnb_stack.rnti = rnti;
|
||||||
gnb_stack.phy_cfg = phy_cfg;
|
gnb_stack.phy_cfg = phy_cfg;
|
||||||
|
gnb_stack.wait_preamble = ue_stack.prach_preamble > 0;
|
||||||
|
|
||||||
if (gnb_stack.pdsch.rb_length == 0) {
|
if (gnb_stack.pdsch.rb_length == 0) {
|
||||||
gnb_stack.pdsch.rb_length = phy_cfg.carrier.nof_prb;
|
gnb_stack.pdsch.rb_length = phy_cfg.carrier.nof_prb;
|
||||||
|
@ -271,8 +272,8 @@ int main(int argc, char** argv)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Assert metrics
|
// Assert metrics
|
||||||
TESTASSERT(metrics.gnb_stack.mac.tx_errors == 0);
|
TESTASSERT_EQ(0, metrics.gnb_stack.mac.tx_errors);
|
||||||
TESTASSERT(metrics.gnb_stack.mac.rx_errors == 0);
|
TESTASSERT_EQ(0, metrics.gnb_stack.mac.rx_errors);
|
||||||
TESTASSERT(metrics.ue_stack.sr_count == metrics.gnb_stack.sr_count);
|
TESTASSERT(metrics.ue_stack.sr_count == metrics.gnb_stack.sr_count);
|
||||||
|
|
||||||
// If reached here, the test is successful
|
// If reached here, the test is successful
|
||||||
|
|
Loading…
Reference in New Issue