diff --git a/srsenb/hdr/stack/mac/scheduler_harq.h b/srsenb/hdr/stack/mac/scheduler_harq.h index 773a25d46..07f98fe4e 100644 --- a/srsenb/hdr/stack/mac/scheduler_harq.h +++ b/srsenb/hdr/stack/mac/scheduler_harq.h @@ -34,7 +34,6 @@ class harq_proc { public: void init(uint32_t id); - void set_cfg(uint32_t max_retx); void reset(uint32_t tb_idx); uint32_t get_id() const; bool is_empty() const; @@ -47,7 +46,7 @@ public: uint32_t max_nof_retx() const; protected: - void new_tx_common(uint32_t tb_idx, srslte::tti_point tti, int mcs, int tbs); + void new_tx_common(uint32_t tb_idx, srslte::tti_point tti, int mcs, int tbs, uint32_t max_retx_); void new_retx_common(uint32_t tb_idx, srslte::tti_point tti, int* mcs, int* tbs); bool has_pending_retx_common(uint32_t tb_idx) const; int set_ack_common(uint32_t tb_idx, bool ack); @@ -73,7 +72,13 @@ class dl_harq_proc : public harq_proc { public: dl_harq_proc(); - void new_tx(const rbgmask_t& new_mask, uint32_t tb_idx, uint32_t tti, int mcs, int tbs, uint32_t n_cce_); + void new_tx(const rbgmask_t& new_mask, + uint32_t tb_idx, + uint32_t tti, + int mcs, + int tbs, + uint32_t n_cce_, + uint32_t max_retx); void new_retx(const rbgmask_t& new_mask, uint32_t tb_idx, uint32_t tti_, int* mcs, int* tbs, uint32_t n_cce_); int set_ack(uint32_t tb_idx, bool ack); rbgmask_t get_rbgmask() const; @@ -117,7 +122,6 @@ public: harq_entity(size_t nof_dl_harqs, size_t nof_ul_harqs); void reset(); - void set_cfg(uint32_t max_retx); size_t nof_dl_harqs() const { return dl_harqs.size(); } size_t nof_ul_harqs() const { return ul_harqs.size(); } @@ -153,7 +157,7 @@ public: /** * Set ACK state for UL Harq Proc */ - std::pair set_ul_crc(srslte::tti_point tti_tx_ul, uint32_t tb_idx, bool ack_); + int set_ul_crc(srslte::tti_point tti_tx_ul, uint32_t tb_idx, bool ack_); //! Resets pending harq ACKs and cleans UL Harqs with maxretx == 0 void reset_pending_data(srslte::tti_point tti_rx); diff --git a/srsenb/src/stack/mac/scheduler_harq.cc b/srsenb/src/stack/mac/scheduler_harq.cc index 8af67655a..c0525ac57 100644 --- a/srsenb/src/stack/mac/scheduler_harq.cc +++ b/srsenb/src/stack/mac/scheduler_harq.cc @@ -43,11 +43,6 @@ void harq_proc::init(uint32_t id_) id = id_; } -void harq_proc::set_cfg(uint32_t max_retx_) -{ - max_retx = max_retx_; -} - void harq_proc::reset(uint32_t tb_idx) { ack_state[tb_idx] = NULL_ACK; @@ -98,11 +93,11 @@ int harq_proc::set_ack_common(uint32_t tb_idx, bool ack_) ack_state[tb_idx] = ack_ ? ACK : NACK; log_h->debug("ACK=%d received pid=%d, tb_idx=%d, n_rtx=%d, max_retx=%d\n", ack_, id, tb_idx, n_rtx[tb_idx], max_retx); if (!ack_ && (n_rtx[tb_idx] + 1 >= max_retx)) { - Warning("SCHED: discarding TB %d pid=%d, tti=%d, maximum number of retx exceeded (%d)\n", - tb_idx, - id, - tti.to_uint(), - max_retx); + Info("SCHED: discarding TB=%d pid=%d, tti=%d, maximum number of retx exceeded (%d)\n", + tb_idx, + id, + tti.to_uint(), + max_retx); active[tb_idx] = false; } else if (ack_) { active[tb_idx] = false; @@ -110,11 +105,12 @@ int harq_proc::set_ack_common(uint32_t tb_idx, bool ack_) return SRSLTE_SUCCESS; } -void harq_proc::new_tx_common(uint32_t tb_idx, tti_point tti_, int mcs, int tbs) +void harq_proc::new_tx_common(uint32_t tb_idx, tti_point tti_, int mcs, int tbs, uint32_t max_retx_) { reset(tb_idx); ndi[tb_idx] = !ndi[tb_idx]; tti = tti_; + max_retx = max_retx_; tx_cnt[tb_idx]++; last_mcs[tb_idx] = mcs; last_tbs[tb_idx] = tbs; @@ -174,11 +170,17 @@ dl_harq_proc::dl_harq_proc() : harq_proc() n_cce = 0; } -void dl_harq_proc::new_tx(const rbgmask_t& new_mask, uint32_t tb_idx, uint32_t tti, int mcs, int tbs, uint32_t n_cce_) +void dl_harq_proc::new_tx(const rbgmask_t& new_mask, + uint32_t tb_idx, + uint32_t tti, + int mcs, + int tbs, + uint32_t n_cce_, + uint32_t max_retx_) { n_cce = n_cce_; rbgmask = new_mask; - new_tx_common(tb_idx, tti_point{tti}, mcs, tbs); + new_tx_common(tb_idx, tti_point{tti}, mcs, tbs, max_retx_); } void dl_harq_proc::new_retx(const rbgmask_t& new_mask, @@ -245,10 +247,9 @@ bool ul_harq_proc::is_adaptive_retx() const void ul_harq_proc::new_tx(uint32_t tti_, int mcs, int tbs, prb_interval alloc, uint32_t max_retx_) { - max_retx = (uint32_t)max_retx_; is_adaptive = false; allocation = alloc; - new_tx_common(0, tti_point{tti_}, mcs, tbs); + new_tx_common(0, tti_point{tti_}, mcs, tbs, max_retx_); pending_data = tbs; pending_ack = NULL_ACK; } @@ -326,16 +327,6 @@ void harq_entity::reset() } } -void harq_entity::set_cfg(uint32_t max_retx) -{ - for (auto& h : dl_harqs) { - h.set_cfg(max_retx); - } - for (auto& h : ul_harqs) { - h.set_cfg(max_retx); - } -} - dl_harq_proc* harq_entity::get_empty_dl_harq(uint32_t tti_tx_dl) { if (not is_async) { @@ -374,11 +365,11 @@ ul_harq_proc* harq_entity::get_ul_harq(uint32_t tti_tx_ul) return &ul_harqs[tti_tx_ul % ul_harqs.size()]; } -std::pair harq_entity::set_ul_crc(srslte::tti_point tti_rx, uint32_t tb_idx, bool ack_) +int harq_entity::set_ul_crc(srslte::tti_point tti_rx, uint32_t tb_idx, bool ack_) { ul_harq_proc* h = get_ul_harq(tti_rx.to_uint()); uint32_t pid = h->get_id(); - return {h->set_ack(tb_idx, ack_), pid}; + return h->set_ack(tb_idx, ack_) ? pid : -1; } void harq_entity::reset_pending_data(srslte::tti_point tti_rx) diff --git a/srsenb/src/stack/mac/scheduler_ue.cc b/srsenb/src/stack/mac/scheduler_ue.cc index 1def88ea8..e87638240 100644 --- a/srsenb/src/stack/mac/scheduler_ue.cc +++ b/srsenb/src/stack/mac/scheduler_ue.cc @@ -321,8 +321,8 @@ void sched_ue::set_ul_crc(srslte::tti_point tti_rx, uint32_t enb_cc_idx, bool cr { cc_sched_ue* c = find_ue_carrier(enb_cc_idx); if (c != nullptr and c->cc_state() != cc_st::idle) { - auto ret = c->harq_ent.set_ul_crc(tti_rx, 0, crc_res); - if (not ret.first) { + int ret = c->harq_ent.set_ul_crc(tti_rx, 0, crc_res); + if (ret < 0) { log_h->warning("Received UL CRC for invalid tti_rx=%d\n", (int)tti_rx.to_uint()); } } else { @@ -476,7 +476,7 @@ std::pair sched_ue::allocate_new_dl_mac_pdu(sched::dl_sched_data_t* da // Allocate DL UE Harq if (rem_tbs != tbs) { - h->new_tx(user_mask, tb, tti_tx_dl, mcs, tbs, data->dci.location.ncce); + h->new_tx(user_mask, tb, tti_tx_dl, mcs, tbs, data->dci.location.ncce, get_ue_cfg().maxharq_tx); Debug("SCHED: Alloc DCI format%s new mcs=%d, tbs=%d, nof_prb=%d\n", dci_format, mcs, tbs, nof_prb); } else { Warning("SCHED: Failed to allocate DL harq pid=%d\n", h->get_id()); @@ -1328,9 +1328,6 @@ void cc_sched_ue::set_cfg(const sched_interface::ue_cfg_t& cfg_) cfg = &cfg_; cfg_tti = last_tti; - // Config HARQ processes - harq_ent.set_cfg(cfg->maxharq_tx); - if (ue_cc_idx == 0) { // PCell is always active cc_state_ = cc_st::active; diff --git a/srsenb/test/mac/CMakeLists.txt b/srsenb/test/mac/CMakeLists.txt index b5c93f12b..b2ffc4b40 100644 --- a/srsenb/test/mac/CMakeLists.txt +++ b/srsenb/test/mac/CMakeLists.txt @@ -18,7 +18,8 @@ # and at http://www.gnu.org/licenses/. # -add_library(scheduler_test_common STATIC scheduler_test_common.cc sched_common_test_suite.cc sched_ue_ded_test_suite.cc sched_sim_ue.cc) +add_library(scheduler_test_common STATIC scheduler_test_common.cc sched_common_test_suite.cc sched_ue_ded_test_suite.cc + sched_sim_ue.cc sched_sim_ue.cc) # Scheduler subcomponent testing add_executable(sched_grid_test sched_grid_test.cc) diff --git a/srsenb/test/mac/sched_sim_ue.cc b/srsenb/test/mac/sched_sim_ue.cc index 732a0a81c..934f13ea0 100644 --- a/srsenb/test/mac/sched_sim_ue.cc +++ b/srsenb/test/mac/sched_sim_ue.cc @@ -23,6 +23,22 @@ namespace srsenb { +using phich_t = sched_interface::ul_sched_phich_t; + +ue_sim::ue_sim(uint16_t rnti_, const sched_interface::ue_cfg_t& ue_cfg_, srslte::tti_point prach_tti_rx_) +{ + ctxt.rnti = rnti_; + ctxt.ue_cfg = ue_cfg_; + ctxt.prach_tti_rx = prach_tti_rx_; + ctxt.cc_list.resize(ue_cfg_.supported_cc_list.size()); +} + +void ue_sim::set_cfg(const sched_interface::ue_cfg_t& ue_cfg_) +{ + ctxt.ue_cfg = ue_cfg_; + ctxt.cc_list.resize(ue_cfg_.supported_cc_list.size()); +} + bool ue_sim::enqueue_pending_acks(srslte::tti_point tti_rx, pucch_feedback& feedback_list, std::bitset ack_val) @@ -58,6 +74,7 @@ bool ue_sim::enqueue_pending_acks(srslte::tti_point tti_rx, int ue_sim::update(const sf_output_res_t& sf_out) { + update_conn_state(sf_out); update_dl_harqs(sf_out); update_ul_harqs(sf_out); @@ -89,6 +106,7 @@ void ue_sim::update_dl_harqs(const sf_output_res_t& sf_out) void ue_sim::update_ul_harqs(const sf_output_res_t& sf_out) { + uint32_t pid = to_tx_ul(sf_out.tti_rx).to_uint() % (FDD_HARQ_DELAY_UL_MS + FDD_HARQ_DELAY_DL_MS); for (uint32_t cc = 0; cc < sf_out.cc_params.size(); ++cc) { // Update UL harqs with PHICH info for (uint32_t i = 0; i < sf_out.ul_cc_result[cc].nof_phich_elems; ++i) { @@ -100,9 +118,13 @@ void ue_sim::update_ul_harqs(const sf_output_res_t& sf_out) const auto *cc_cfg = ctxt.get_cc_cfg(cc), *start = &ctxt.ue_cfg.supported_cc_list[0]; uint32_t ue_cc_idx = std::distance(start, cc_cfg); auto& ue_cc_ctxt = ctxt.cc_list[ue_cc_idx]; - auto& h = ue_cc_ctxt.ul_harqs[to_tx_ul(sf_out.tti_rx).to_uint() % ue_cc_ctxt.ul_harqs.size()]; + auto& h = ue_cc_ctxt.ul_harqs[pid]; - if (phich.phich == sched_interface::ul_sched_phich_t::ACK or h.nof_retxs + 1 >= ctxt.ue_cfg.maxharq_tx) { + bool is_ack = phich.phich == phich_t::ACK; + bool is_msg3 = + h.nof_txs == h.nof_retxs + 1 and ctxt.msg3_tti_rx.is_valid() and h.first_tti_rx == ctxt.msg3_tti_rx; + bool last_retx = h.nof_retxs + 1 >= (is_msg3 ? sf_out.cc_params[0].cfg.maxharq_msg3tx : ctxt.ue_cfg.maxharq_tx); + if (is_ack or last_retx) { h.active = false; } } @@ -118,12 +140,13 @@ void ue_sim::update_ul_harqs(const sf_output_res_t& sf_out) if (h.nof_txs == 0 or h.ndi != data.dci.tb.ndi) { // newtx - h.active = true; - h.nof_retxs = 0; - h.ndi = data.dci.tb.ndi; + h.nof_retxs = 0; + h.ndi = data.dci.tb.ndi; + h.first_tti_rx = sf_out.tti_rx; } else { h.nof_retxs++; } + h.active = true; h.last_tti_rx = sf_out.tti_rx; h.riv = data.dci.type2_alloc.riv; h.nof_txs++; @@ -131,4 +154,49 @@ void ue_sim::update_ul_harqs(const sf_output_res_t& sf_out) } } +void ue_sim::update_conn_state(const sf_output_res_t& sf_out) +{ + if (not ctxt.msg3_tti_rx.is_valid()) { + auto& cc_result = sf_out.ul_cc_result[ctxt.ue_cfg.supported_cc_list[0].enb_cc_idx]; + for (uint32_t i = 0; i < cc_result.nof_dci_elems; ++i) { + if (cc_result.pusch[i].dci.rnti == ctxt.rnti) { + ctxt.msg3_tti_rx = sf_out.tti_rx; + } + } + } +} + +void ue_db_sim::add_user(uint16_t rnti, const sched_interface::ue_cfg_t& ue_cfg_, srslte::tti_point prach_tti_rx_) +{ + ue_db.insert(std::make_pair(rnti, ue_sim(rnti, ue_cfg_, prach_tti_rx_))); +} + +void ue_db_sim::ue_recfg(uint16_t rnti, const sched_interface::ue_cfg_t& ue_cfg_) +{ + ue_db.at(rnti).set_cfg(ue_cfg_); +} + +void ue_db_sim::rem_user(uint16_t rnti) +{ + ue_db.erase(rnti); +} + +void ue_db_sim::update(const sf_output_res_t& sf_out) +{ + for (auto& ue_pair : ue_db) { + ue_pair.second.update(sf_out); + } +} + +std::map ue_db_sim::get_ues_ctxt() const +{ + std::map ret; + + for (auto& ue_pair : ue_db) { + ret.insert(std::make_pair(ue_pair.first, &ue_pair.second.get_ctxt())); + } + + return ret; +} + } // namespace srsenb diff --git a/srsenb/test/mac/sched_sim_ue.h b/srsenb/test/mac/sched_sim_ue.h index 23ad9371d..3ca44d161 100644 --- a/srsenb/test/mac/sched_sim_ue.h +++ b/srsenb/test/mac/sched_sim_ue.h @@ -35,24 +35,25 @@ struct ue_harq_ctxt_t { uint32_t nof_txs = 0; uint32_t nof_retxs = 0; uint32_t riv = 0; - srslte::tti_point last_tti_rx; + srslte::tti_point last_tti_rx, first_tti_rx; }; struct ue_cc_ctxt_t { std::array dl_harqs; std::array ul_harqs; }; struct sim_ue_ctxt_t { - uint16_t rnti; - srslte::tti_point prach_tti_rx; - sched_interface::ue_cfg_t ue_cfg; - std::vector cc_list; + uint16_t rnti; + srslte::tti_point prach_tti_rx, msg3_tti_rx; + sched_interface::ue_cfg_t ue_cfg; + std::vector cc_list; + const sched_interface::ue_cfg_t::cc_cfg_t* get_cc_cfg(uint32_t enb_cc_idx) const; int enb_to_ue_cc_idx(uint32_t enb_cc_idx) const; }; struct sim_enb_ctxt_t { - std::vector cell_params; - std::map ue_db; + const std::vector* cell_params; + std::map ue_db; }; struct pucch_feedback { struct cc_data { @@ -67,7 +68,9 @@ struct pucch_feedback { class ue_sim { public: - ue_sim() = default; + ue_sim(uint16_t rnti_, const sched_interface::ue_cfg_t& ue_cfg_, srslte::tti_point prach_tti_rx); + + void set_cfg(const sched_interface::ue_cfg_t& ue_cfg_); int update(const sf_output_res_t& sf_out); @@ -76,14 +79,30 @@ public: std::bitset ack_val); const sim_ue_ctxt_t& get_ctxt() const { return ctxt; } + sim_ue_ctxt_t& get_ctxt() { return ctxt; } private: + void update_conn_state(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); sim_ue_ctxt_t ctxt; }; +class ue_db_sim +{ +public: + void add_user(uint16_t rnti, const sched_interface::ue_cfg_t& ue_cfg_, srslte::tti_point prach_tti_rx_); + void ue_recfg(uint16_t rnti, const sched_interface::ue_cfg_t& ue_cfg_); + void rem_user(uint16_t rnti); + + void update(const sf_output_res_t& sf_out); + std::map get_ues_ctxt() const; + +private: + std::map ue_db; +}; + } // namespace srsenb #endif // SRSLTE_SCHED_SIM_UE_H diff --git a/srsenb/test/mac/sched_ue_ded_test_suite.cc b/srsenb/test/mac/sched_ue_ded_test_suite.cc index 60fa24083..3014b81d0 100644 --- a/srsenb/test/mac/sched_ue_ded_test_suite.cc +++ b/srsenb/test/mac/sched_ue_ded_test_suite.cc @@ -80,9 +80,9 @@ int test_pdsch_grant(const sim_ue_ctxt_t& ue_ctxt, int test_ul_sched_result(const sim_enb_ctxt_t& enb_ctxt, const sf_output_res_t& sf_out) { - uint32_t pid = to_tx_ul(sf_out.tti_rx).to_uint() % SRSLTE_MAX_HARQ_PROC; + uint32_t pid = to_tx_ul(sf_out.tti_rx).to_uint() % (FDD_HARQ_DELAY_UL_MS + FDD_HARQ_DELAY_DL_MS); - for (uint32_t cc = 0; cc < enb_ctxt.cell_params.size(); ++cc) { + for (size_t cc = 0; cc < enb_ctxt.cell_params->size(); ++cc) { const auto* phich_begin = &sf_out.ul_cc_result[cc].phich[0]; const auto* phich_end = &sf_out.ul_cc_result[cc].phich[sf_out.ul_cc_result[cc].nof_phich_elems]; const auto* pusch_begin = &sf_out.ul_cc_result[cc].pusch[0]; @@ -101,7 +101,7 @@ int test_ul_sched_result(const sim_enb_ctxt_t& enb_ctxt, const sf_output_res_t& "Scheduled PUSCH does not have associated rnti."); for (const auto& ue_pair : enb_ctxt.ue_db) { - const auto& ue = ue_pair.second; + const auto& ue = *ue_pair.second; uint16_t rnti = ue.rnti; int ue_cc_idx = ue.enb_to_ue_cc_idx(cc); @@ -120,13 +120,18 @@ int test_ul_sched_result(const sim_enb_ctxt_t& enb_ctxt, const sf_output_res_t& const auto& h = ue.cc_list[ue_cc_idx].ul_harqs[pid]; CONDERROR( h.active and phich_ptr == nullptr, "PHICH not received for rnti=0x%x active UL HARQ pid=%d\n", rnti, pid); - CONDERROR( - not h.active and phich_ptr != nullptr, "PHICH received for rnti=0x%x inactive UL HARQ pid=%d\n", rnti, pid); + CONDERROR(not h.active and phich_ptr != nullptr, + "PHICH for rnti=0x%x corresponds to inactive UL HARQ pid=%d\n", + rnti, + pid); // TEST: absent PUSCH grants for active DL HARQs must be either ACKs, last retx, or interrupted HARQs if (phich_ptr != nullptr and pusch_ptr == nullptr) { - bool ack = phich_ptr->phich == phich_t::ACK, last_retx = h.nof_retxs + 1 >= ue.ue_cfg.maxharq_tx; - CONDERROR(not ack and not last_retx, "PHICH NACK received for rnti=0x%x but no PUSCH retx reallocated\n", rnti); + bool is_ack = phich_ptr->phich == phich_t::ACK; + bool is_msg3 = h.first_tti_rx == ue.msg3_tti_rx and h.nof_txs == h.nof_retxs + 1; + bool last_retx = h.nof_retxs + 1 >= (is_msg3 ? sf_out.cc_params[0].cfg.maxharq_msg3tx : ue.ue_cfg.maxharq_tx); + CONDERROR( + not is_ack and not last_retx, "PHICH NACK received for rnti=0x%x but no PUSCH retx reallocated\n", rnti); } if (pusch_ptr != nullptr) { @@ -138,8 +143,13 @@ int test_ul_sched_result(const sim_enb_ctxt_t& enb_ctxt, const sf_output_res_t& if (h.nof_txs == 0 or h.ndi != pusch_ptr->dci.tb.ndi) { // newtx CONDERROR(nof_retx != 0, "Invalid rv index for new tx\n"); + CONDERROR(pusch_ptr->current_tx_nb != 0, "UL HARQ retxs need to have been previously transmitted\n"); } else { - CONDERROR(not h.active, "retx for inactive UL harq pid=%d\n", h.pid); + CONDERROR(pusch_ptr->current_tx_nb == 0, "UL retx has to have nof tx > 0\n"); + if (not h.active) { + // the HARQ is being resumed + CONDERROR(not pusch_ptr->needs_pdcch, "Resumed UL HARQs need to be signalled in PDCCH\n"); + } if (pusch_ptr->needs_pdcch) { // adaptive retx } else { @@ -161,14 +171,15 @@ int test_ul_sched_result(const sim_enb_ctxt_t& enb_ctxt, const sf_output_res_t& int test_all_ues(const sim_enb_ctxt_t& enb_ctxt, const sf_output_res_t& sf_out) { - for (uint32_t cc = 0; cc < enb_ctxt.cell_params.size(); ++cc) { - for (uint32_t i = 0; i < sf_out.dl_cc_result[cc].nof_data_elems; ++i) { - const sched_interface::dl_sched_data_t& data = sf_out.dl_cc_result[cc].data[i]; - CONDERROR( - enb_ctxt.ue_db.count(data.dci.rnti) == 0, "Allocated DL grant for non-existent rnti=0x%x\n", data.dci.rnti); - TESTASSERT(test_pdsch_grant(enb_ctxt.ue_db.at(data.dci.rnti), sf_out.tti_rx, cc, data) == SRSLTE_SUCCESS); - } - } + // for (uint32_t cc = 0; cc < enb_ctxt.cell_params->size(); ++cc) { + // for (uint32_t i = 0; i < sf_out.dl_cc_result[cc].nof_data_elems; ++i) { + // const sched_interface::dl_sched_data_t& data = sf_out.dl_cc_result[cc].data[i]; + // CONDERROR( + // enb_ctxt.ue_db.count(data.dci.rnti) == 0, "Allocated DL grant for non-existent rnti=0x%x\n", + // data.dci.rnti); + // TESTASSERT(test_pdsch_grant(*enb_ctxt.ue_db.at(data.dci.rnti), sf_out.tti_rx, cc, data) == SRSLTE_SUCCESS); + // } + // } TESTASSERT(test_ul_sched_result(enb_ctxt, sf_out) == SRSLTE_SUCCESS); diff --git a/srsenb/test/mac/scheduler_test_common.cc b/srsenb/test/mac/scheduler_test_common.cc index 9d2926268..158215201 100644 --- a/srsenb/test/mac/scheduler_test_common.cc +++ b/srsenb/test/mac/scheduler_test_common.cc @@ -25,6 +25,7 @@ #include "srslte/mac/pdu.h" #include "sched_common_test_suite.h" +#include "sched_ue_ded_test_suite.h" #include "srslte/common/test_common.h" using namespace srsenb; @@ -402,7 +403,7 @@ int ue_ctxt_test::test_harqs(cc_result result) CONDERROR(sched_utils::get_rvidx(h.nof_retxs + 1) != (uint32_t)pusch.dci.tb.rv, "Invalid rv index for retx\n"); } CONDERROR(h.ndi != pusch.dci.tb.ndi, "Invalid ndi for retx\n"); - CONDERROR(not h.active, "retx for inactive UL harq pid=%d\n", h.pid); + CONDERROR(not h.active, "Re-tx allocated for rnti=0x%x inactive UL harq pid=%d\n", rnti, h.pid); CONDERROR(h.tti_tx > current_tti_rx, "UL harq pid=%d was reused too soon\n", h.pid); h.nof_retxs++; @@ -476,6 +477,8 @@ int user_state_sched_tester::add_user(uint16_t rnti, uint32_t preamble_idx, cons TESTASSERT(users.count(rnti) == 0); ue_ctxt_test ue{rnti, preamble_idx, srslte::tti_point{tic.to_uint()}, cfg_, cell_params}; users.insert(std::make_pair(rnti, ue)); + + sim_users.add_user(rnti, cfg_.ue_cfg, tic); return SRSLTE_SUCCESS; } @@ -483,6 +486,7 @@ int user_state_sched_tester::user_reconf(uint16_t rnti, const srsenb::sched_inte { TESTASSERT(users.count(rnti) > 0); users.at(rnti).set_cfg(ue_cfg); + sim_users.ue_recfg(rnti, ue_cfg); return SRSLTE_SUCCESS; } @@ -505,6 +509,7 @@ int user_state_sched_tester::bearer_cfg(uint16_t void user_state_sched_tester::rem_user(uint16_t rnti) { users.erase(rnti); + sim_users.rem_user(rnti); } /** @@ -545,14 +550,23 @@ int user_state_sched_tester::test_ctrl_info(uint32_t return SRSLTE_SUCCESS; } -int user_state_sched_tester::test_all(uint32_t enb_cc_idx, - const sched_interface::dl_sched_res_t& dl_result, - const sched_interface::ul_sched_res_t& ul_result) +int user_state_sched_tester::test_all(const sf_output_res_t& sf_out, uint32_t enb_cc_idx) { - TESTASSERT(test_ctrl_info(enb_cc_idx, dl_result, ul_result) == SRSLTE_SUCCESS); + // Perform UE-dedicated 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); + + TESTASSERT(test_ctrl_info(enb_cc_idx, sf_out.dl_cc_result[enb_cc_idx], sf_out.ul_cc_result[enb_cc_idx]) == + SRSLTE_SUCCESS); for (auto& u : users) { - TESTASSERT(u.second.test_sched_result(enb_cc_idx, dl_result, ul_result) == SRSLTE_SUCCESS); + TESTASSERT(u.second.test_sched_result( + enb_cc_idx, sf_out.dl_cc_result[enb_cc_idx], sf_out.ul_cc_result[enb_cc_idx]) == SRSLTE_SUCCESS); } return SRSLTE_SUCCESS; @@ -672,14 +686,15 @@ void common_sched_tester::new_test_tti() int common_sched_tester::process_results() { - for (uint32_t i = 0; i < sched_cell_params.size(); ++i) { - TESTASSERT(ue_tester->test_all(i, tti_info.dl_sched_result[i], tti_info.ul_sched_result[i]) == SRSLTE_SUCCESS); + // Perform common eNB result tests + sf_output_res_t sf_out{sched_cell_params, + srslte::tti_point{tti_info.tti_params.tti_rx}, + tti_info.ul_sched_result, + tti_info.dl_sched_result}; + TESTASSERT(test_all_common(sf_out) == SRSLTE_SUCCESS); - sf_output_res_t sf_out{sched_cell_params, - srslte::tti_point{tti_info.tti_params.tti_rx}, - tti_info.ul_sched_result, - tti_info.dl_sched_result}; - TESTASSERT(test_all_common(sf_out) == SRSLTE_SUCCESS); + for (uint32_t i = 0; i < sched_cell_params.size(); ++i) { + TESTASSERT(ue_tester->test_all(sf_out, i) == SRSLTE_SUCCESS); } sched_stats->process_results(tti_info.tti_params, tti_info.dl_sched_result, tti_info.ul_sched_result); diff --git a/srsenb/test/mac/scheduler_test_common.h b/srsenb/test/mac/scheduler_test_common.h index 518447372..79bb4f1c9 100644 --- a/srsenb/test/mac/scheduler_test_common.h +++ b/srsenb/test/mac/scheduler_test_common.h @@ -22,6 +22,7 @@ #ifndef SRSLTE_SCHEDULER_TEST_COMMON_H #define SRSLTE_SCHEDULER_TEST_COMMON_H +#include "sched_sim_ue.h" #include "scheduler_test_utils.h" #include "srsenb/hdr/stack/mac/scheduler.h" #include @@ -150,13 +151,12 @@ public: const sched_interface::dl_sched_res_t& dl_result, const sched_interface::ul_sched_res_t& ul_result); - int test_all(uint32_t enb_cc_idx, - const sched_interface::dl_sched_res_t& dl_result, - const sched_interface::ul_sched_res_t& ul_result); + int test_all(const sf_output_res_t& sf_out, uint32_t enb_cc_idx); private: const std::vector& cell_params; + ue_db_sim sim_users; std::map users; srslte::tti_point tic; }; diff --git a/srsenb/test/mac/scheduler_test_rand.cc b/srsenb/test/mac/scheduler_test_rand.cc index 41bc122be..a8c5d840e 100644 --- a/srsenb/test/mac/scheduler_test_rand.cc +++ b/srsenb/test/mac/scheduler_test_rand.cc @@ -38,6 +38,7 @@ #include "srslte/phy/utils/debug.h" #include "sched_common_test_suite.h" +#include "sched_sim_ue.h" #include "scheduler_test_common.h" #include "scheduler_test_utils.h" #include "srslte/common/test_common.h" @@ -201,8 +202,7 @@ int sched_tester::process_results() TESTASSERT(test_pdsch_collisions(sf_out, CARRIER_IDX, &cc_result->dl_mask) == SRSLTE_SUCCESS); // UE dedicated tests - TESTASSERT(ue_tester->test_all(0, tti_info.dl_sched_result[CARRIER_IDX], tti_info.ul_sched_result[CARRIER_IDX]) == - SRSLTE_SUCCESS); + TESTASSERT(ue_tester->test_all(sf_out, CARRIER_IDX) == SRSLTE_SUCCESS); assert_no_empty_allocs(); test_harqs(); update_ue_stats();