sched rand test refactor: creation of abstract sched simulator class for testing

master
Francisco 4 years ago committed by Andre Puschmann
parent aed36eb273
commit cba0cc457f

@ -246,8 +246,8 @@ public:
virtual bool ue_exists(uint16_t rnti) = 0; virtual bool ue_exists(uint16_t rnti) = 0;
/* Manages UE bearers and associated configuration */ /* Manages UE bearers and associated configuration */
virtual int bearer_ue_cfg(uint16_t rnti, uint32_t lc_id, ue_bearer_cfg_t* cfg) = 0; virtual int bearer_ue_cfg(uint16_t rnti, uint32_t lc_id, const ue_bearer_cfg_t& cfg) = 0;
virtual int bearer_ue_rem(uint16_t rnti, uint32_t lc_id) = 0; virtual int bearer_ue_rem(uint16_t rnti, uint32_t lc_id) = 0;
virtual uint32_t get_ul_buffer(uint16_t rnti) = 0; virtual uint32_t get_ul_buffer(uint16_t rnti) = 0;
virtual uint32_t get_dl_buffer(uint16_t rnti) = 0; virtual uint32_t get_dl_buffer(uint16_t rnti) = 0;

@ -49,7 +49,7 @@ public:
void phy_config_enabled(uint16_t rnti, bool enabled); void phy_config_enabled(uint16_t rnti, bool enabled);
int bearer_ue_cfg(uint16_t rnti, uint32_t lc_id, ue_bearer_cfg_t* cfg) final; int bearer_ue_cfg(uint16_t rnti, uint32_t lc_id, const ue_bearer_cfg_t& cfg) final;
int bearer_ue_rem(uint16_t rnti, uint32_t lc_id) final; int bearer_ue_rem(uint16_t rnti, uint32_t lc_id) final;
uint32_t get_ul_buffer(uint16_t rnti) final; uint32_t get_ul_buffer(uint16_t rnti) final;

@ -158,7 +158,7 @@ int mac::bearer_ue_cfg(uint16_t rnti, uint32_t lc_id, sched_interface::ue_bearer
int ret = -1; int ret = -1;
srslte::rwlock_read_guard lock(rwlock); srslte::rwlock_read_guard lock(rwlock);
if (ue_db.count(rnti)) { if (ue_db.count(rnti)) {
ret = scheduler.bearer_ue_cfg(rnti, lc_id, cfg); ret = scheduler.bearer_ue_cfg(rnti, lc_id, *cfg);
} else { } else {
Error("User rnti=0x%x not found\n", rnti); Error("User rnti=0x%x not found\n", rnti);
} }

@ -138,9 +138,9 @@ void sched::phy_config_enabled(uint16_t rnti, bool enabled)
rnti, [this, enabled](sched_ue& ue) { ue.phy_config_enabled(last_tti, enabled); }, __PRETTY_FUNCTION__); rnti, [this, enabled](sched_ue& ue) { ue.phy_config_enabled(last_tti, enabled); }, __PRETTY_FUNCTION__);
} }
int sched::bearer_ue_cfg(uint16_t rnti, uint32_t lc_id, sched_interface::ue_bearer_cfg_t* cfg_) int sched::bearer_ue_cfg(uint16_t rnti, uint32_t lc_id, const sched_interface::ue_bearer_cfg_t& cfg_)
{ {
return ue_db_access(rnti, [lc_id, cfg_](sched_ue& ue) { ue.set_bearer_cfg(lc_id, *cfg_); }); return ue_db_access(rnti, [lc_id, cfg_](sched_ue& ue) { ue.set_bearer_cfg(lc_id, cfg_); });
} }
int sched::bearer_ue_rem(uint16_t rnti, uint32_t lc_id) int sched::bearer_ue_rem(uint16_t rnti, uint32_t lc_id)

@ -122,11 +122,11 @@ int test_scell_activation(test_scell_activation_params params)
tti_ev::user_cfg_ev* user = generator.add_new_default_user(duration, sim_args.default_ue_sim_cfg.ue_cfg); tti_ev::user_cfg_ev* user = generator.add_new_default_user(duration, sim_args.default_ue_sim_cfg.ue_cfg);
user->rnti = rnti1; user->rnti = rnti1;
tester.test_next_ttis(generator.tti_events); tester.test_next_ttis(generator.tti_events);
TESTASSERT(tester.ue_tester->user_exists(rnti1)); TESTASSERT(tester.sched_sim->user_exists(rnti1));
// Event (TTI=prach_tti+msg4_tot_delay): First Tx (Msg4). Goes in SRB0 and contains ConRes // Event (TTI=prach_tti+msg4_tot_delay): First Tx (Msg4). Goes in SRB0 and contains ConRes
while (not tester.ue_tester->get_user_ctxt(rnti1)->get_ctxt().msg3_tti_rx.is_valid() or while (not tester.sched_sim->find_rnti(rnti1)->get_ctxt().msg3_tti_rx.is_valid() or
srsenb::to_tx_ul(tester.ue_tester->get_user_ctxt(rnti1)->get_ctxt().msg3_tti_rx).to_uint() > srsenb::to_tx_ul(tester.sched_sim->find_rnti(rnti1)->get_ctxt().msg3_tti_rx).to_uint() >
generator.tti_counter) { generator.tti_counter) {
generator.step_tti(); generator.step_tti();
tester.test_next_ttis(generator.tti_events); tester.test_next_ttis(generator.tti_events);
@ -134,7 +134,7 @@ int test_scell_activation(test_scell_activation_params params)
generator.step_tti(); generator.step_tti();
generator.add_dl_data(rnti1, msg4_size); generator.add_dl_data(rnti1, msg4_size);
tester.test_next_ttis(generator.tti_events); tester.test_next_ttis(generator.tti_events);
while (not tester.ue_tester->get_user_ctxt(rnti1)->get_ctxt().conres_rx) { while (not tester.sched_sim->find_rnti(rnti1)->get_ctxt().conres_rx) {
generator.step_tti(); generator.step_tti();
tester.test_next_ttis(generator.tti_events); tester.test_next_ttis(generator.tti_events);
} }

@ -12,6 +12,7 @@
#include "sched_sim_ue.h" #include "sched_sim_ue.h"
#include "lib/include/srslte/mac/pdu.h" #include "lib/include/srslte/mac/pdu.h"
#include "sched_test_utils.h"
namespace srsenb { namespace srsenb {
@ -46,7 +47,6 @@ ue_sim::ue_sim(uint16_t rnti_,
ctxt.rnti = rnti_; ctxt.rnti = rnti_;
ctxt.prach_tti_rx = prach_tti_rx_; ctxt.prach_tti_rx = prach_tti_rx_;
ctxt.preamble_idx = preamble_idx; ctxt.preamble_idx = preamble_idx;
pending_feedback.cc_list.resize(cell_params->size());
set_cfg(ue_cfg_); set_cfg(ue_cfg_);
} }
@ -67,108 +67,8 @@ void ue_sim::bearer_cfg(uint32_t lc_id, const sched_interface::ue_bearer_cfg_t&
ctxt.ue_cfg.ue_bearers.at(lc_id) = cfg; ctxt.ue_cfg.ue_bearers.at(lc_id) = cfg;
} }
ue_sim::sync_tti_events ue_sim::get_pending_events(srslte::tti_point tti_rx, sched_interface* sched)
{
pending_feedback.tti_rx = tti_rx;
for (uint32_t enb_cc_idx = 0; enb_cc_idx < pending_feedback.cc_list.size(); ++enb_cc_idx) {
auto& cc_feedback = pending_feedback.cc_list[enb_cc_idx];
cc_feedback = {};
if (ctxt.enb_to_ue_cc_idx(enb_cc_idx) < 0) {
continue;
}
cc_feedback.configured = true;
cc_feedback.ue_cc_idx = ctxt.enb_to_ue_cc_idx(enb_cc_idx);
for (uint32_t pid = 0; pid < SRSLTE_FDD_NOF_HARQ; ++pid) {
auto& dl_h = ctxt.cc_list[cc_feedback.ue_cc_idx].dl_harqs[pid];
auto& ul_h = ctxt.cc_list[cc_feedback.ue_cc_idx].ul_harqs[pid];
// Set default DL ACK
if (dl_h.active and to_tx_dl_ack(dl_h.last_tti_rx) == tti_rx) {
cc_feedback.dl_pid = pid;
cc_feedback.dl_ack = false; // default is NACK
}
// Set default UL ACK
if (ul_h.active and to_tx_ul(ul_h.last_tti_rx) == tti_rx) {
cc_feedback.ul_pid = pid;
cc_feedback.ul_ack = false;
}
// Set default DL CQI
if (srslte_cqi_periodic_send(
&ctxt.ue_cfg.supported_cc_list[cc_feedback.ue_cc_idx].dl_cfg.cqi_report, tti_rx.to_uint(), SRSLTE_FDD)) {
cc_feedback.dl_cqi = 0;
}
// TODO: UL CQI
}
}
return {this, sched};
}
void ue_sim::push_feedback(sched_interface* sched)
{
for (uint32_t enb_cc_idx = 0; enb_cc_idx < pending_feedback.cc_list.size(); ++enb_cc_idx) {
const auto& cc_feedback = pending_feedback.cc_list[enb_cc_idx];
if (not cc_feedback.configured) {
continue;
}
if (cc_feedback.dl_pid >= 0) {
auto& h = ctxt.cc_list[cc_feedback.ue_cc_idx].dl_harqs[cc_feedback.dl_pid];
if (cc_feedback.dl_ack) {
log_h->info(
"DL ACK rnti=0x%x tti_dl_tx=%u pid=%d\n", ctxt.rnti, to_tx_dl(h.last_tti_rx).to_uint(), cc_feedback.dl_pid);
}
// update scheduler
if (sched->dl_ack_info(
pending_feedback.tti_rx.to_uint(), ctxt.rnti, enb_cc_idx, cc_feedback.tb, cc_feedback.dl_ack) < 0) {
log_h->error("The ACKed DL Harq pid=%d does not exist.\n", cc_feedback.dl_pid);
error_count++;
}
// set UE sim context
if (cc_feedback.dl_ack or ctxt.is_last_dl_retx(cc_feedback.ue_cc_idx, cc_feedback.dl_pid)) {
h.active = false;
}
}
if (cc_feedback.ul_pid >= 0) {
auto& h = ctxt.cc_list[cc_feedback.ue_cc_idx].ul_harqs[cc_feedback.dl_pid];
if (cc_feedback.ul_ack) {
log_h->info(
"UL ACK rnti=0x%x tti_ul_tx=%u pid=%d\n", ctxt.rnti, to_tx_ul(h.last_tti_rx).to_uint(), cc_feedback.dl_pid);
}
// update scheduler
if (sched->ul_crc_info(pending_feedback.tti_rx.to_uint(), ctxt.rnti, enb_cc_idx, cc_feedback.ul_ack) < 0) {
log_h->error("The ACKed UL Harq pid=%d does not exist.\n", cc_feedback.ul_pid);
error_count++;
}
}
if (cc_feedback.dl_cqi >= 0) {
sched->dl_cqi_info(pending_feedback.tti_rx.to_uint(), ctxt.rnti, enb_cc_idx, cc_feedback.dl_cqi);
}
if (cc_feedback.ul_cqi >= 0) {
sched->ul_snr_info(pending_feedback.tti_rx.to_uint(), ctxt.rnti, enb_cc_idx, cc_feedback.ul_cqi, 0);
}
}
}
int ue_sim::update(const sf_output_res_t& sf_out) int ue_sim::update(const sf_output_res_t& sf_out)
{ {
if (error_count > 0) {
return SRSLTE_ERROR;
}
if (pending_feedback.tti_rx != sf_out.tti_rx) {
// generate default events
auto default_events = get_pending_events(sf_out.tti_rx, nullptr);
}
update_conn_state(sf_out); update_conn_state(sf_out);
update_dl_harqs(sf_out); update_dl_harqs(sf_out);
update_ul_harqs(sf_out); update_ul_harqs(sf_out);
@ -318,45 +218,182 @@ void ue_sim::update_conn_state(const sf_output_res_t& sf_out)
} }
} }
void ue_db_sim::add_user(uint16_t rnti, int sched_sim_base::add_user(uint16_t rnti, const sched_interface::ue_cfg_t& ue_cfg_, uint32_t preamble_idx)
const sched_interface::ue_cfg_t& ue_cfg_,
srslte::tti_point prach_tti_rx_,
uint32_t preamble_idx)
{ {
ue_db.insert(std::make_pair(rnti, ue_sim(rnti, *cell_params, ue_cfg_, prach_tti_rx_, preamble_idx))); CONDERROR(!srslte_prach_tti_opportunity_config_fdd(
(*cell_params)[ue_cfg_.supported_cc_list[0].enb_cc_idx].prach_config, current_tti_rx.to_uint(), -1),
"New user added in a non-PRACH TTI\n");
TESTASSERT(ue_db.count(rnti) == 0);
final_ue_cfg[rnti] = ue_cfg_;
auto rach_cfg = generate_rach_ue_cfg(ue_cfg_);
ue_db.insert(std::make_pair(rnti, ue_sim(rnti, *cell_params, rach_cfg, current_tti_rx, preamble_idx)));
CONDERROR(sched_ptr->ue_cfg(rnti, generate_rach_ue_cfg(ue_cfg_)) != SRSLTE_SUCCESS,
"Configuring new user rnti=0x%x to sched\n",
rnti);
sched_interface::dl_sched_rar_info_t rar_info = {};
rar_info.prach_tti = current_tti_rx.to_uint();
rar_info.temp_crnti = rnti;
rar_info.msg3_size = 7;
rar_info.preamble_idx = preamble_idx;
uint32_t pcell_idx = ue_cfg_.supported_cc_list[0].enb_cc_idx;
TESTASSERT(sched_ptr->dl_rach_info(pcell_idx, rar_info) == SRSLTE_SUCCESS);
return SRSLTE_SUCCESS;
} }
void ue_db_sim::ue_recfg(uint16_t rnti, const sched_interface::ue_cfg_t& ue_cfg_) int sched_sim_base::ue_recfg(uint16_t rnti, const sched_interface::ue_cfg_t& ue_cfg_)
{ {
ue_db.at(rnti).set_cfg(ue_cfg_); ue_db.at(rnti).set_cfg(ue_cfg_);
CONDERROR(ue_db.count(rnti) == 0, "User must already exist to be configured\n");
CONDERROR(sched_ptr->ue_cfg(rnti, ue_cfg_) != SRSLTE_SUCCESS, "Configuring new user rnti=0x%x to sched\n", rnti);
return SRSLTE_SUCCESS;
} }
void ue_db_sim::bearer_cfg(uint16_t rnti, uint32_t lc_id, const sched_interface::ue_bearer_cfg_t& cfg) int sched_sim_base::bearer_cfg(uint16_t rnti, uint32_t lc_id, const sched_interface::ue_bearer_cfg_t& cfg)
{ {
ue_db.at(rnti).bearer_cfg(lc_id, cfg); ue_db.at(rnti).bearer_cfg(lc_id, cfg);
return sched_ptr->bearer_ue_cfg(rnti, lc_id, cfg);
} }
void ue_db_sim::rem_user(uint16_t rnti) int sched_sim_base::rem_user(uint16_t rnti)
{ {
ue_db.erase(rnti); ue_db.erase(rnti);
return sched_ptr->ue_rem(rnti);
} }
void ue_db_sim::update(const sf_output_res_t& sf_out) void sched_sim_base::update(const sf_output_res_t& sf_out)
{ {
for (auto& ue_pair : ue_db) { for (auto& ue_pair : ue_db) {
ue_pair.second.update(sf_out); ue_pair.second.update(sf_out);
} }
} }
std::map<uint16_t, const sim_ue_ctxt_t*> ue_db_sim::get_ues_ctxt() const sim_enb_ctxt_t sched_sim_base::get_enb_ctxt() const
{ {
std::map<uint16_t, const sim_ue_ctxt_t*> ret; sim_enb_ctxt_t ctxt;
ctxt.cell_params = cell_params;
for (auto& ue_pair : ue_db) { for (auto& ue_pair : ue_db) {
ret.insert(std::make_pair(ue_pair.first, &ue_pair.second.get_ctxt())); ctxt.ue_db.insert(std::make_pair(ue_pair.first, &ue_pair.second.get_ctxt()));
} }
return ret; return ctxt;
}
void sched_sim_base::set_default_tti_events(const sim_ue_ctxt_t& ue_ctxt, ue_tti_events& pending_events)
{
pending_events.cc_list.clear();
pending_events.cc_list.resize(cell_params->size());
pending_events.tti_rx = current_tti_rx;
for (uint32_t enb_cc_idx = 0; enb_cc_idx < pending_events.cc_list.size(); ++enb_cc_idx) {
auto& cc_feedback = pending_events.cc_list[enb_cc_idx];
if (ue_ctxt.enb_to_ue_cc_idx(enb_cc_idx) < 0) {
continue;
}
cc_feedback.configured = true;
cc_feedback.ue_cc_idx = ue_ctxt.enb_to_ue_cc_idx(enb_cc_idx);
for (uint32_t pid = 0; pid < SRSLTE_FDD_NOF_HARQ; ++pid) {
auto& dl_h = ue_ctxt.cc_list[cc_feedback.ue_cc_idx].dl_harqs[pid];
auto& ul_h = ue_ctxt.cc_list[cc_feedback.ue_cc_idx].ul_harqs[pid];
// Set default DL ACK
if (dl_h.active and to_tx_dl_ack(dl_h.last_tti_rx) == current_tti_rx) {
cc_feedback.dl_pid = pid;
cc_feedback.dl_ack = true; // default is ACK
}
// Set default UL ACK
if (ul_h.active and to_tx_ul(ul_h.last_tti_rx) == current_tti_rx) {
cc_feedback.ul_pid = pid;
cc_feedback.ul_ack = true;
}
// Set default DL CQI
if (srslte_cqi_periodic_send(&ue_ctxt.ue_cfg.supported_cc_list[cc_feedback.ue_cc_idx].dl_cfg.cqi_report,
current_tti_rx.to_uint(),
SRSLTE_FDD)) {
cc_feedback.dl_cqi = 28;
}
// TODO: UL CQI
}
}
}
void sched_sim_base::apply_tti_events(sim_ue_ctxt_t& ue_ctxt, const ue_tti_events& events)
{
for (uint32_t enb_cc_idx = 0; enb_cc_idx < events.cc_list.size(); ++enb_cc_idx) {
const auto& cc_feedback = events.cc_list[enb_cc_idx];
if (not cc_feedback.configured) {
continue;
}
if (cc_feedback.dl_pid >= 0) {
auto& h = ue_ctxt.cc_list[cc_feedback.ue_cc_idx].dl_harqs[cc_feedback.dl_pid];
if (cc_feedback.dl_ack) {
log_h->info("DL ACK rnti=0x%x tti_dl_tx=%u pid=%d\n",
ue_ctxt.rnti,
to_tx_dl(h.last_tti_rx).to_uint(),
cc_feedback.dl_pid);
}
// update scheduler
if (sched_ptr->dl_ack_info(
events.tti_rx.to_uint(), ue_ctxt.rnti, enb_cc_idx, cc_feedback.tb, cc_feedback.dl_ack) < 0) {
log_h->error("The ACKed DL Harq pid=%d does not exist.\n", cc_feedback.dl_pid);
error_counter++;
}
// update UE sim context
if (cc_feedback.dl_ack or ue_ctxt.is_last_dl_retx(cc_feedback.ue_cc_idx, cc_feedback.dl_pid)) {
h.active = false;
}
}
if (cc_feedback.ul_pid >= 0) {
auto& h = ue_ctxt.cc_list[cc_feedback.ue_cc_idx].ul_harqs[cc_feedback.dl_pid];
if (cc_feedback.ul_ack) {
log_h->info("UL ACK rnti=0x%x tti_ul_tx=%u pid=%d\n",
ue_ctxt.rnti,
to_tx_ul(h.last_tti_rx).to_uint(),
cc_feedback.dl_pid);
}
// update scheduler
if (sched_ptr->ul_crc_info(events.tti_rx.to_uint(), ue_ctxt.rnti, enb_cc_idx, cc_feedback.ul_ack) < 0) {
log_h->error("The ACKed UL Harq pid=%d does not exist.\n", cc_feedback.ul_pid);
error_counter++;
}
}
if (cc_feedback.dl_cqi >= 0) {
sched_ptr->dl_cqi_info(events.tti_rx.to_uint(), ue_ctxt.rnti, enb_cc_idx, cc_feedback.dl_cqi);
}
if (cc_feedback.ul_cqi >= 0) {
sched_ptr->ul_snr_info(events.tti_rx.to_uint(), ue_ctxt.rnti, enb_cc_idx, cc_feedback.ul_cqi, 0);
}
}
}
void sched_sim_base::new_tti(srslte::tti_point tti_rx)
{
current_tti_rx = tti_rx;
for (auto& ue : ue_db) {
ue_tti_events events;
set_default_tti_events(ue.second.get_ctxt(), events);
before_sched(ue.second.get_ctxt(), events);
apply_tti_events(ue.second.get_ctxt(), events);
}
} }
} // namespace srsenb } // namespace srsenb

@ -86,54 +86,38 @@ public:
const sim_ue_ctxt_t& get_ctxt() const { return ctxt; } const sim_ue_ctxt_t& get_ctxt() const { return ctxt; }
sim_ue_ctxt_t& get_ctxt() { return ctxt; } sim_ue_ctxt_t& get_ctxt() { return ctxt; }
class sync_tti_events
{
public:
sync_tti_events(ue_sim* ue_, sched_interface* sched_) : ue(ue_), sched(sched_) {}
sync_tti_events(const sync_tti_events&) = delete;
sync_tti_events(sync_tti_events&&) = default;
sync_tti_events& operator=(const sync_tti_events&) = delete;
sync_tti_events& operator=(sync_tti_events&&) = default;
~sync_tti_events() { ue->push_feedback(sched); }
ue_tti_events* operator->() { return &ue->pending_feedback; }
ue_tti_events* operator*() { return &ue->pending_feedback; }
private:
ue_sim* ue;
sched_interface* sched;
};
sync_tti_events get_pending_events(srslte::tti_point tti_rx, sched_interface* sched);
private: private:
void update_conn_state(const sf_output_res_t& sf_out); void update_conn_state(const sf_output_res_t& sf_out);
void update_dl_harqs(const sf_output_res_t& sf_out); void update_dl_harqs(const sf_output_res_t& sf_out);
void update_ul_harqs(const sf_output_res_t& sf_out); void update_ul_harqs(const sf_output_res_t& sf_out);
void push_feedback(sched_interface* sched);
srslte::log_ref log_h{"MAC"}; srslte::log_ref log_h{"MAC"};
const std::vector<sched_interface::cell_cfg_t>* cell_params; const std::vector<sched_interface::cell_cfg_t>* cell_params;
sim_ue_ctxt_t ctxt; sim_ue_ctxt_t ctxt;
ue_tti_events pending_feedback;
uint32_t error_count = 0;
}; };
class ue_db_sim class sched_sim_base
{ {
public: public:
ue_db_sim(const std::vector<sched_interface::cell_cfg_t>& cell_params_) : cell_params(&cell_params_) {} sched_sim_base(sched_interface* sched_ptr_, const std::vector<sched_interface::cell_cfg_t>& cell_params_) :
void add_user(uint16_t rnti, sched_ptr(sched_ptr_), cell_params(&cell_params_)
const sched_interface::ue_cfg_t& ue_cfg_, {
srslte::tti_point prach_tti_rx_, sched_ptr->cell_cfg(cell_params_); // call parent cfg
uint32_t preamble_idx); }
void ue_recfg(uint16_t rnti, const sched_interface::ue_cfg_t& ue_cfg_); virtual ~sched_sim_base() = default;
void bearer_cfg(uint16_t rnti, uint32_t lc_id, const sched_interface::ue_bearer_cfg_t& cfg);
void rem_user(uint16_t rnti); int add_user(uint16_t rnti, const sched_interface::ue_cfg_t& ue_cfg_, uint32_t preamble_idx);
int ue_recfg(uint16_t rnti, const sched_interface::ue_cfg_t& ue_cfg_);
void update(const sf_output_res_t& sf_out); int bearer_cfg(uint16_t rnti, uint32_t lc_id, const sched_interface::ue_bearer_cfg_t& cfg);
std::map<uint16_t, const sim_ue_ctxt_t*> get_ues_ctxt() const; int rem_user(uint16_t rnti);
ue_sim& at(uint16_t rnti) { return ue_db.at(rnti); }
const ue_sim& at(uint16_t rnti) const { return ue_db.at(rnti); } void new_tti(srslte::tti_point tti_rx);
ue_sim* find_rnti(uint16_t rnti) void update(const sf_output_res_t& sf_out);
sim_enb_ctxt_t get_enb_ctxt() const;
ue_sim& at(uint16_t rnti) { return ue_db.at(rnti); }
const ue_sim& at(uint16_t rnti) const { return ue_db.at(rnti); }
ue_sim* find_rnti(uint16_t rnti)
{ {
auto it = ue_db.find(rnti); auto it = ue_db.find(rnti);
return it != ue_db.end() ? &it->second : nullptr; return it != ue_db.end() ? &it->second : nullptr;
@ -143,13 +127,31 @@ public:
auto it = ue_db.find(rnti); auto it = ue_db.find(rnti);
return it != ue_db.end() ? &it->second : nullptr; return it != ue_db.end() ? &it->second : nullptr;
} }
bool user_exists(uint16_t rnti) const { return ue_db.count(rnti) > 0; }
const sched_interface::ue_cfg_t* get_user_cfg(uint16_t rnti) const
{
const ue_sim* ret = find_rnti(rnti);
return ret == nullptr ? nullptr : &ret->get_ctxt().ue_cfg;
}
std::map<uint16_t, ue_sim>::iterator begin() { return ue_db.begin(); } std::map<uint16_t, ue_sim>::iterator begin() { return ue_db.begin(); }
std::map<uint16_t, ue_sim>::iterator end() { return ue_db.end(); } std::map<uint16_t, ue_sim>::iterator end() { return ue_db.end(); }
// configurable by simulator concrete implementation
virtual void before_sched(const sim_ue_ctxt_t& ue_ctxt, ue_tti_events& pending_events) = 0;
private: private:
void set_default_tti_events(const sim_ue_ctxt_t& ue_ctxt, ue_tti_events& pending_events);
void apply_tti_events(sim_ue_ctxt_t& ue_ctxt, const ue_tti_events& events);
srslte::log_ref log_h{"MAC"};
sched_interface* sched_ptr;
const std::vector<sched_interface::cell_cfg_t>* cell_params; const std::vector<sched_interface::cell_cfg_t>* cell_params;
std::map<uint16_t, ue_sim> ue_db;
srslte::tti_point current_tti_rx;
std::map<uint16_t, ue_sim> ue_db;
std::map<uint16_t, sched_interface::ue_cfg_t> final_ue_cfg;
uint32_t error_counter = 0;
}; };
} // namespace srsenb } // namespace srsenb

@ -12,7 +12,6 @@
#include "sched_test_common.h" #include "sched_test_common.h"
#include "srsenb/hdr/stack/mac/sched.h" #include "srsenb/hdr/stack/mac/sched.h"
#include "srsenb/hdr/stack/mac/sched_helpers.h"
#include "srsenb/hdr/stack/upper/common_enb.h" #include "srsenb/hdr/stack/upper/common_enb.h"
#include "srslte/mac/pdu.h" #include "srslte/mac/pdu.h"
@ -48,103 +47,50 @@ std::default_random_engine& ::srsenb::get_rand_gen()
* User State Tester * User State Tester
***********************/ ***********************/
void user_state_sched_tester::new_tti(sched* sched_ptr, tti_point tti_rx) void sched_sim_random::before_sched(const sim_ue_ctxt_t& ue_ctxt, ue_tti_events& pending_events)
{ {
tic++; const auto& sim_cfg = ue_sim_cfg_map.at(ue_ctxt.rnti);
for (auto& u : sim_users) {
auto pending_feedback = u.second.get_pending_events(tti_rx, sched_ptr);
auto& ctxt = u.second.get_ctxt();
const auto& sim_cfg = ue_sim_cfg_map.at(u.first);
for (uint32_t enb_cc_idx = 0; enb_cc_idx < pending_feedback->cc_list.size(); ++enb_cc_idx) {
auto& cc_feedback = pending_feedback->cc_list[enb_cc_idx];
if (not cc_feedback.configured) {
continue;
}
// ACK DL HARQs
if (cc_feedback.dl_pid >= 0) {
auto& h = ctxt.cc_list[cc_feedback.ue_cc_idx].dl_harqs[cc_feedback.dl_pid];
cc_feedback.dl_ack = randf() < sim_cfg.prob_dl_ack_mask[h.nof_retxs % sim_cfg.prob_dl_ack_mask.size()];
}
// ACK UL HARQs
if (cc_feedback.ul_pid >= 0) {
auto& h = ctxt.cc_list[cc_feedback.ue_cc_idx].ul_harqs[cc_feedback.ul_pid];
cc_feedback.ul_ack = randf() < sim_cfg.prob_ul_ack_mask[h.nof_retxs % sim_cfg.prob_ul_ack_mask.size()];
}
// DL CQI
if (cc_feedback.dl_cqi >= 0) {
cc_feedback.dl_cqi = std::uniform_int_distribution<uint32_t>{5, 24}(get_rand_gen());
}
// UL CQI for (uint32_t enb_cc_idx = 0; enb_cc_idx < pending_events.cc_list.size(); ++enb_cc_idx) {
if (cc_feedback.ul_cqi >= 0) { auto& cc_feedback = pending_events.cc_list[enb_cc_idx];
cc_feedback.ul_cqi = std::uniform_int_distribution<uint32_t>{5, 40}(get_rand_gen()); if (not cc_feedback.configured) {
} continue;
} }
}
}
int user_state_sched_tester::add_user(uint16_t rnti, uint32_t preamble_idx, const ue_ctxt_test_cfg& cfg_) // ACK DL HARQs
{ if (cc_feedback.dl_pid >= 0) {
CONDERROR(!srslte_prach_tti_opportunity_config_fdd( auto& h = ue_ctxt.cc_list[cc_feedback.ue_cc_idx].dl_harqs[cc_feedback.dl_pid];
cell_params[cfg_.ue_cfg.supported_cc_list[0].enb_cc_idx].prach_config, tic.to_uint(), -1), cc_feedback.dl_ack = randf() < sim_cfg.prob_dl_ack_mask[h.nof_retxs % sim_cfg.prob_dl_ack_mask.size()];
"New user added in a non-PRACH TTI\n"); }
TESTASSERT(sim_users.find_rnti(rnti) == nullptr);
sim_users.add_user(rnti, generate_rach_ue_cfg(cfg_.ue_cfg), tic, preamble_idx);
ue_sim_cfg_map[rnti] = cfg_;
return SRSLTE_SUCCESS; // ACK UL HARQs
} if (cc_feedback.ul_pid >= 0) {
auto& h = ue_ctxt.cc_list[cc_feedback.ue_cc_idx].ul_harqs[cc_feedback.ul_pid];
cc_feedback.ul_ack = randf() < sim_cfg.prob_ul_ack_mask[h.nof_retxs % sim_cfg.prob_ul_ack_mask.size()];
}
int user_state_sched_tester::user_reconf(uint16_t rnti, const srsenb::sched_interface::ue_cfg_t& ue_cfg) // DL CQI
{ if (cc_feedback.dl_cqi >= 0) {
TESTASSERT(sim_users.find_rnti(rnti) != nullptr); cc_feedback.dl_cqi = std::uniform_int_distribution<uint32_t>{5, 24}(get_rand_gen());
sim_users.ue_recfg(rnti, ue_cfg); }
return SRSLTE_SUCCESS;
}
int user_state_sched_tester::bearer_cfg(uint16_t rnti, // UL CQI
uint32_t lcid, if (cc_feedback.ul_cqi >= 0) {
const srsenb::sched_interface::ue_bearer_cfg_t& bearer_cfg) cc_feedback.ul_cqi = std::uniform_int_distribution<uint32_t>{5, 40}(get_rand_gen());
{ }
sim_users.bearer_cfg(rnti, lcid, bearer_cfg); }
return SRSLTE_SUCCESS;
} }
bool user_state_sched_tester::is_drb_cfg(uint16_t rnti) const bool is_drb_cfg(const sched_interface::ue_cfg_t& ue_cfg)
{ {
const ue_sim& ue = sim_users.at(rnti); for (uint32_t i = 2; i < ue_cfg.ue_bearers.size(); ++i) {
for (uint32_t i = 2; i < ue.get_ctxt().ue_cfg.ue_bearers.size(); ++i) { if (ue_cfg.ue_bearers[i].direction != sched_interface::ue_bearer_cfg_t::IDLE) {
if (ue.get_ctxt().ue_cfg.ue_bearers[i].direction != sched_interface::ue_bearer_cfg_t::IDLE) {
return true; return true;
} }
} }
return false; return false;
} }
void user_state_sched_tester::rem_user(uint16_t rnti)
{
sim_users.rem_user(rnti);
ue_sim_cfg_map.erase(rnti);
}
int user_state_sched_tester::test_all(const sf_output_res_t& sf_out)
{
// Perform UE-dedicated sched result tests
sim_enb_ctxt_t enb_ctxt;
enb_ctxt.cell_params = &cell_params;
enb_ctxt.ue_db = sim_users.get_ues_ctxt();
TESTASSERT(test_all_ues(enb_ctxt, sf_out) == SRSLTE_SUCCESS);
// Update Simulated UEs state
sim_users.update(sf_out);
return SRSLTE_SUCCESS;
}
/*********************** /***********************
* Sim Stats Storage * Sim Stats Storage
**********************/ **********************/
@ -183,17 +129,16 @@ sched_result_stats::user_stats* sched_result_stats::get_user(uint16_t rnti)
const sched::ue_cfg_t* common_sched_tester::get_current_ue_cfg(uint16_t rnti) const const sched::ue_cfg_t* common_sched_tester::get_current_ue_cfg(uint16_t rnti) const
{ {
return ue_tester->get_user_cfg(rnti); return sched_sim->get_user_cfg(rnti);
} }
int common_sched_tester::sim_cfg(sim_sched_args args) int common_sched_tester::sim_cfg(sim_sched_args args)
{ {
sim_args0 = std::move(args); sim_args0 = std::move(args);
sched::cell_cfg(sim_args0.cell_cfg); // call parent cfg
sched::set_sched_cfg(&sim_args0.sched_args); sched::set_sched_cfg(&sim_args0.sched_args);
ue_tester.reset(new user_state_sched_tester{sim_args0.cell_cfg}); sched_sim.reset(new sched_sim_random{this, sim_args0.cell_cfg});
sched_stats.reset(new sched_result_stats{sim_args0.cell_cfg}); sched_stats.reset(new sched_result_stats{sim_args0.cell_cfg});
tester_log = sim_args0.sim_log; tester_log = sim_args0.sim_log;
@ -203,40 +148,21 @@ int common_sched_tester::sim_cfg(sim_sched_args args)
int common_sched_tester::add_user(uint16_t rnti, const ue_ctxt_test_cfg& ue_cfg_) int common_sched_tester::add_user(uint16_t rnti, const ue_ctxt_test_cfg& ue_cfg_)
{ {
CONDERROR(ue_cfg(rnti, generate_rach_ue_cfg(ue_cfg_.ue_cfg)) != SRSLTE_SUCCESS,
"Configuring new user rnti=0x%x to sched\n",
rnti);
// CONDERROR(!srslte_prach_tti_opportunity_config_fdd(
// sched_cell_params[CARRIER_IDX].cfg.prach_config, tti_info.tti_params.tti_rx, -1),
// "New user added in a non-PRACH TTI\n");
dl_sched_rar_info_t rar_info = {};
rar_info.prach_tti = tti_rx.to_uint();
rar_info.temp_crnti = rnti;
rar_info.msg3_size = 7;
rar_info.preamble_idx = tti_info.nof_prachs++;
uint32_t pcell_idx = ue_cfg_.ue_cfg.supported_cc_list[0].enb_cc_idx;
dl_rach_info(pcell_idx, rar_info);
ue_tester->add_user(rnti, rar_info.preamble_idx, ue_cfg_);
tester_log->info("Adding user rnti=0x%x\n", rnti); tester_log->info("Adding user rnti=0x%x\n", rnti);
return SRSLTE_SUCCESS; sched_sim->ue_sim_cfg_map[rnti] = ue_cfg_;
return sched_sim->add_user(rnti, ue_cfg_.ue_cfg, tti_info.nof_prachs++);
} }
int common_sched_tester::reconf_user(uint16_t rnti, const sched_interface::ue_cfg_t& ue_cfg_) int common_sched_tester::reconf_user(uint16_t rnti, const sched_interface::ue_cfg_t& ue_cfg_)
{ {
CONDERROR(not ue_tester->user_exists(rnti), "User must already exist to be configured\n"); return sched_sim->ue_recfg(rnti, ue_cfg_);
CONDERROR(ue_cfg(rnti, ue_cfg_) != SRSLTE_SUCCESS, "Configuring new user rnti=0x%x to sched\n", rnti);
ue_tester->user_reconf(rnti, ue_cfg_);
return SRSLTE_SUCCESS;
} }
void common_sched_tester::rem_user(uint16_t rnti) int common_sched_tester::rem_user(uint16_t rnti)
{ {
tester_log->info("Removing user rnti=0x%x\n", rnti); tester_log->info("Removing user rnti=0x%x\n", rnti);
sched::ue_rem(rnti); sched_sim->ue_sim_cfg_map.erase(rnti);
ue_tester->rem_user(rnti); return sched_sim->rem_user(rnti);
} }
void common_sched_tester::new_test_tti() void common_sched_tester::new_test_tti()
@ -256,13 +182,23 @@ void common_sched_tester::new_test_tti()
tester_log->step(tti_rx.to_uint()); tester_log->step(tti_rx.to_uint());
} }
int common_sched_tester::run_ue_ded_tests_and_update_ctxt(const sf_output_res_t& sf_out)
{
// Perform UE-dedicated sched result tests
sim_enb_ctxt_t enb_ctxt = sched_sim->get_enb_ctxt();
TESTASSERT(test_all_ues(enb_ctxt, sf_out) == SRSLTE_SUCCESS);
// Update Simulated UEs state
sched_sim->update(sf_out);
return SRSLTE_SUCCESS;
}
int common_sched_tester::process_results() int common_sched_tester::process_results()
{ {
// Perform common eNB result tests // Perform common eNB result tests
sf_output_res_t sf_out{sched_cell_params, tti_rx, tti_info.ul_sched_result, tti_info.dl_sched_result}; sf_output_res_t sf_out{sched_cell_params, tti_rx, tti_info.ul_sched_result, tti_info.dl_sched_result};
TESTASSERT(test_all_common(sf_out) == SRSLTE_SUCCESS); TESTASSERT(test_all_common(sf_out) == SRSLTE_SUCCESS);
TESTASSERT(run_ue_ded_tests_and_update_ctxt(sf_out) == SRSLTE_SUCCESS);
TESTASSERT(ue_tester->test_all(sf_out) == SRSLTE_SUCCESS);
sched_stats->process_results(tti_rx, tti_info.dl_sched_result, tti_info.ul_sched_result); sched_stats->process_results(tti_rx, tti_info.dl_sched_result, tti_info.ul_sched_result);
@ -274,7 +210,7 @@ int common_sched_tester::process_tti_events(const tti_ev& tti_ev)
for (const tti_ev::user_cfg_ev& ue_ev : tti_ev.user_updates) { for (const tti_ev::user_cfg_ev& ue_ev : tti_ev.user_updates) {
// There is a new configuration // There is a new configuration
if (ue_ev.ue_sim_cfg != nullptr) { if (ue_ev.ue_sim_cfg != nullptr) {
if (not ue_tester->user_exists(ue_ev.rnti)) { if (not sched_sim->user_exists(ue_ev.rnti)) {
// new user // new user
TESTASSERT(add_user(ue_ev.rnti, *ue_ev.ue_sim_cfg) == SRSLTE_SUCCESS); TESTASSERT(add_user(ue_ev.rnti, *ue_ev.ue_sim_cfg) == SRSLTE_SUCCESS);
} else { } else {
@ -285,17 +221,17 @@ int common_sched_tester::process_tti_events(const tti_ev& tti_ev)
// There is a user to remove // There is a user to remove
if (ue_ev.rem_user) { if (ue_ev.rem_user) {
rem_user(ue_ev.rnti); TESTASSERT(rem_user(ue_ev.rnti) == SRSLTE_SUCCESS);
} }
// configure bearers // configure bearers
if (ue_ev.bearer_cfg != nullptr) { if (ue_ev.bearer_cfg != nullptr) {
CONDERROR(not ue_tester->user_exists(ue_ev.rnti), "User rnti=0x%x does not exist\n", ue_ev.rnti); CONDERROR(not sched_sim->user_exists(ue_ev.rnti), "User rnti=0x%x does not exist\n", ue_ev.rnti);
// TODO: Instantiate more bearers // TODO: Instantiate more bearers
bearer_ue_cfg(ue_ev.rnti, 0, ue_ev.bearer_cfg.get()); TESTASSERT(sched_sim->bearer_cfg(ue_ev.rnti, 0, *ue_ev.bearer_cfg) == SRSLTE_SUCCESS);
} }
const ue_sim* user = ue_tester->get_user_ctxt(ue_ev.rnti); const ue_sim* user = sched_sim->find_rnti(ue_ev.rnti);
if (user != nullptr) { if (user != nullptr) {
const auto& ue_sim_ctxt = user->get_ctxt(); const auto& ue_sim_ctxt = user->get_ctxt();
@ -303,7 +239,8 @@ int common_sched_tester::process_tti_events(const tti_ev& tti_ev)
to_tx_ul(ue_sim_ctxt.msg3_tti_rx) <= tti_rx) { to_tx_ul(ue_sim_ctxt.msg3_tti_rx) <= tti_rx) {
// Msg3 has been received but Msg4 has not been yet transmitted // Msg3 has been received but Msg4 has not been yet transmitted
// Setup default UE config // Setup default UE config
reconf_user(ue_sim_ctxt.rnti, generate_setup_ue_cfg(sim_args0.default_ue_sim_cfg.ue_cfg)); TESTASSERT(reconf_user(ue_sim_ctxt.rnti, generate_setup_ue_cfg(sim_args0.default_ue_sim_cfg.ue_cfg)) ==
SRSLTE_SUCCESS);
// Schedule RRC Setup and ConRes CE // Schedule RRC Setup and ConRes CE
uint32_t pending_dl_new_data = ue_db[ue_ev.rnti].get_pending_dl_rlc_data(); uint32_t pending_dl_new_data = ue_db[ue_ev.rnti].get_pending_dl_rlc_data();
@ -325,16 +262,15 @@ int common_sched_tester::process_tti_events(const tti_ev& tti_ev)
// If Msg4 has already been tx and there DL data to transmit // If Msg4 has already been tx and there DL data to transmit
uint32_t lcid = RB_ID_DRB1; uint32_t lcid = RB_ID_DRB1;
uint32_t pending_dl_new_data = ue_db[ue_ev.rnti].get_pending_dl_rlc_data(); uint32_t pending_dl_new_data = ue_db[ue_ev.rnti].get_pending_dl_rlc_data();
if (ue_tester->is_drb_cfg(ue_ev.rnti) or pending_dl_new_data == 0) { if (is_drb_cfg(sched_sim->find_rnti(ue_ev.rnti)->get_ctxt().ue_cfg) or pending_dl_new_data == 0) {
// If RRCSetup finished // If RRCSetup finished
if (not ue_tester->is_drb_cfg(ue_ev.rnti)) { if (not is_drb_cfg(sched_sim->find_rnti(ue_ev.rnti)->get_ctxt().ue_cfg)) {
reconf_user(ue_sim_ctxt.rnti, sim_args0.default_ue_sim_cfg.ue_cfg); reconf_user(ue_sim_ctxt.rnti, sim_args0.default_ue_sim_cfg.ue_cfg);
// setup lcid==drb1 bearer // setup lcid==drb1 bearer
sched::ue_bearer_cfg_t cfg = {}; sched::ue_bearer_cfg_t cfg = {};
cfg.direction = ue_bearer_cfg_t::BOTH; cfg.direction = ue_bearer_cfg_t::BOTH;
cfg.group = 1; cfg.group = 1;
ue_tester->bearer_cfg(ue_ev.rnti, lcid, cfg); TESTASSERT(sched_sim->bearer_cfg(ue_ev.rnti, lcid, cfg) == SRSLTE_SUCCESS);
bearer_ue_cfg(ue_ev.rnti, lcid, &cfg);
} }
// DRB is set. Update DL buffer // DRB is set. Update DL buffer
uint32_t tot_dl_data = pending_dl_new_data + ue_ev.buffer_ev->dl_data; // TODO: derive pending based on rx uint32_t tot_dl_data = pending_dl_new_data + ue_ev.buffer_ev->dl_data; // TODO: derive pending based on rx
@ -344,7 +280,7 @@ int common_sched_tester::process_tti_events(const tti_ev& tti_ev)
} }
} }
if (ue_ev.buffer_ev->sr_data > 0 and ue_tester->is_drb_cfg(ue_ev.rnti)) { if (ue_ev.buffer_ev->sr_data > 0 and is_drb_cfg(sched_sim->find_rnti(ue_ev.rnti)->get_ctxt().ue_cfg)) {
uint32_t tot_ul_data = uint32_t tot_ul_data =
ue_db[ue_ev.rnti].get_pending_ul_new_data(to_tx_ul(tti_rx), -1) + ue_ev.buffer_ev->sr_data; ue_db[ue_ev.rnti].get_pending_ul_new_data(to_tx_ul(tti_rx), -1) + ue_ev.buffer_ev->sr_data;
uint32_t lcg = 1; uint32_t lcg = 1;
@ -360,7 +296,7 @@ int common_sched_tester::run_tti(const tti_ev& tti_events)
new_test_tti(); new_test_tti();
tester_log->info("---- tti=%u | nof_ues=%zd ----\n", tti_rx.to_uint(), ue_db.size()); tester_log->info("---- tti=%u | nof_ues=%zd ----\n", tti_rx.to_uint(), ue_db.size());
ue_tester->new_tti(this, tti_rx); sched_sim->new_tti(tti_rx);
process_tti_events(tti_events); process_tti_events(tti_events);
before_sched(); before_sched();

@ -35,38 +35,12 @@ std::default_random_engine& get_rand_gen();
using dl_sched_res_list = std::vector<sched_interface::dl_sched_res_t>; using dl_sched_res_list = std::vector<sched_interface::dl_sched_res_t>;
using ul_sched_res_list = std::vector<sched_interface::ul_sched_res_t>; using ul_sched_res_list = std::vector<sched_interface::ul_sched_res_t>;
class user_state_sched_tester class sched_sim_random : public sched_sim_base
{ {
public: public:
explicit user_state_sched_tester(const std::vector<srsenb::sched::cell_cfg_t>& cell_params_) : using sched_sim_base::sched_sim_base;
cell_params(cell_params_), sim_users(cell_params_) void before_sched(const sim_ue_ctxt_t& ue_ctxt, ue_tti_events& pending_events) override;
{}
void new_tti(sched* sched_ptr, tti_point tti_rx);
bool user_exists(uint16_t rnti) const { return sim_users.find_rnti(rnti) != nullptr; }
const ue_sim* get_user_ctxt(uint16_t rnti) const { return sim_users.find_rnti(rnti); }
const sched::ue_cfg_t* get_user_cfg(uint16_t rnti) const
{
const ue_sim* ue = get_user_ctxt(rnti);
return ue == nullptr ? nullptr : &ue->get_ctxt().ue_cfg;
}
/* Config users */
int add_user(uint16_t rnti, uint32_t preamble_idx, const ue_ctxt_test_cfg& cfg);
int user_reconf(uint16_t rnti, const srsenb::sched_interface::ue_cfg_t& ue_cfg);
int bearer_cfg(uint16_t rnti, uint32_t lcid, const srsenb::sched_interface::ue_bearer_cfg_t& bearer_cfg);
void rem_user(uint16_t rnti);
int test_all(const sf_output_res_t& sf_out);
bool is_drb_cfg(uint16_t rnti) const;
private:
const std::vector<srsenb::sched::cell_cfg_t>& cell_params;
ue_db_sim sim_users;
std::map<uint16_t, ue_ctxt_test_cfg> ue_sim_cfg_map; std::map<uint16_t, ue_ctxt_test_cfg> ue_sim_cfg_map;
srslte::tti_point tic;
}; };
class sched_result_stats class sched_result_stats
@ -108,16 +82,18 @@ public:
const ue_cfg_t* get_current_ue_cfg(uint16_t rnti) const; const ue_cfg_t* get_current_ue_cfg(uint16_t rnti) const;
int sim_cfg(sim_sched_args args); int sim_cfg(sim_sched_args args);
virtual int add_user(uint16_t rnti, const ue_ctxt_test_cfg& ue_cfg_); virtual int add_user(uint16_t rnti, const ue_ctxt_test_cfg& ue_cfg_);
virtual int reconf_user(uint16_t rnti, const sched_interface::ue_cfg_t& ue_cfg_); virtual int reconf_user(uint16_t rnti, const sched_interface::ue_cfg_t& ue_cfg_);
virtual void rem_user(uint16_t rnti); virtual int rem_user(uint16_t rnti);
virtual int process_results(); virtual int process_results();
int process_tti_events(const tti_ev& tti_ev); int process_tti_events(const tti_ev& tti_ev);
int test_next_ttis(const std::vector<tti_ev>& tti_events); int test_next_ttis(const std::vector<tti_ev>& tti_events);
int run_tti(const tti_ev& tti_events); int run_tti(const tti_ev& tti_events);
int run_ue_ded_tests_and_update_ctxt(const sf_output_res_t& sf_out);
// args // args
sim_sched_args sim_args0; ///< arguments used to generate TTI events sim_sched_args sim_args0; ///< arguments used to generate TTI events
srslte::log* tester_log = nullptr; srslte::log* tester_log = nullptr;
@ -127,9 +103,11 @@ public:
tti_point tti_rx; tti_point tti_rx;
uint32_t tti_count = 0; uint32_t tti_count = 0;
// testers // eNB+UE state handlers
std::unique_ptr<user_state_sched_tester> ue_tester; std::unique_ptr<sched_sim_random> sched_sim;
std::unique_ptr<sched_result_stats> sched_stats;
// statistics
std::unique_ptr<sched_result_stats> sched_stats;
protected: protected:
virtual void new_test_tti(); virtual void new_test_tti();

@ -128,9 +128,9 @@ struct sched_tester : public srsenb::common_sched_tester {
// sched results // sched results
sched_tti_data tti_data; sched_tti_data tti_data;
void rem_user(uint16_t rnti) override; int rem_user(uint16_t rnti) override;
int assert_no_empty_allocs(); int assert_no_empty_allocs();
int test_harqs(); int test_harqs();
private: private:
void new_test_tti() override; void new_test_tti() override;
@ -139,10 +139,10 @@ private:
int update_ue_stats(); int update_ue_stats();
}; };
void sched_tester::rem_user(uint16_t rnti) int sched_tester::rem_user(uint16_t rnti)
{ {
common_sched_tester::rem_user(rnti);
tti_data.ue_data.erase(rnti); tti_data.ue_data.erase(rnti);
return common_sched_tester::rem_user(rnti);
} }
void sched_tester::new_test_tti() void sched_tester::new_test_tti()
@ -203,7 +203,7 @@ int sched_tester::process_results()
TESTASSERT(test_pdsch_collisions(sf_out, CARRIER_IDX, &cc_result->dl_mask) == SRSLTE_SUCCESS); TESTASSERT(test_pdsch_collisions(sf_out, CARRIER_IDX, &cc_result->dl_mask) == SRSLTE_SUCCESS);
// UE dedicated tests // UE dedicated tests
TESTASSERT(ue_tester->test_all(sf_out) == SRSLTE_SUCCESS); TESTASSERT(run_ue_ded_tests_and_update_ctxt(sf_out) == SRSLTE_SUCCESS);
assert_no_empty_allocs(); assert_no_empty_allocs();
test_harqs(); test_harqs();
update_ue_stats(); update_ue_stats();

Loading…
Cancel
Save