mirror of https://github.com/pvnis/srsRAN_4G.git
moved harq tests from scheduler_test_common.cc to separate test suite file. Created a class ue_sim, whose role is to emulate a UE behavior
parent
2be85217fd
commit
eb327183d3
@ -0,0 +1,134 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2013-2020 Software Radio Systems Limited
|
||||||
|
*
|
||||||
|
* This file is part of srsLTE.
|
||||||
|
*
|
||||||
|
* srsLTE is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* srsLTE is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* A copy of the GNU Affero General Public License can be found in
|
||||||
|
* the LICENSE file in the top-level directory of this distribution
|
||||||
|
* and at http://www.gnu.org/licenses/.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "sched_sim_ue.h"
|
||||||
|
|
||||||
|
namespace srsenb {
|
||||||
|
|
||||||
|
bool ue_sim::enqueue_pending_acks(srslte::tti_point tti_rx,
|
||||||
|
pucch_feedback& feedback_list,
|
||||||
|
std::bitset<SRSLTE_MAX_CARRIERS> ack_val)
|
||||||
|
{
|
||||||
|
bool ack_added = false;
|
||||||
|
for (uint32_t ue_cc_idx = 0; ue_cc_idx < ctxt.cc_list.size(); ++ue_cc_idx) {
|
||||||
|
uint32_t enb_cc_idx = ctxt.ue_cfg.supported_cc_list[ue_cc_idx].enb_cc_idx;
|
||||||
|
auto& ue_cc = ctxt.cc_list[ue_cc_idx];
|
||||||
|
|
||||||
|
for (uint32_t pid = 0; pid < SRSLTE_FDD_NOF_HARQ; ++pid) {
|
||||||
|
auto& h = ue_cc.dl_harqs[pid];
|
||||||
|
|
||||||
|
if (h.active and to_tx_dl_ack(h.last_tti_rx) == tti_rx) {
|
||||||
|
if (feedback_list.cc_list.size() <= ue_cc_idx) {
|
||||||
|
feedback_list.cc_list.resize(ue_cc_idx + 1);
|
||||||
|
}
|
||||||
|
auto& result = feedback_list.cc_list[ue_cc_idx];
|
||||||
|
result.enb_cc_idx = enb_cc_idx;
|
||||||
|
result.ack = ack_val[ue_cc_idx];
|
||||||
|
result.pid = pid;
|
||||||
|
|
||||||
|
if (result.pid >= 0 and (result.ack or h.nof_retxs + 1 >= ctxt.ue_cfg.maxharq_tx)) {
|
||||||
|
h.active = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ack_added = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ack_added;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ue_sim::update(const sf_output_res_t& sf_out)
|
||||||
|
{
|
||||||
|
update_dl_harqs(sf_out);
|
||||||
|
update_ul_harqs(sf_out);
|
||||||
|
|
||||||
|
return SRSLTE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ue_sim::update_dl_harqs(const sf_output_res_t& sf_out)
|
||||||
|
{
|
||||||
|
for (uint32_t cc = 0; cc < sf_out.cc_params.size(); ++cc) {
|
||||||
|
for (uint32_t i = 0; i < sf_out.dl_cc_result[cc].nof_data_elems; ++i) {
|
||||||
|
const auto& data = sf_out.dl_cc_result[cc].data[i];
|
||||||
|
if (data.dci.rnti != ctxt.rnti) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
auto& h = ctxt.cc_list[data.dci.ue_cc_idx].dl_harqs[data.dci.pid];
|
||||||
|
if (h.nof_txs == 0 or h.ndi != data.dci.tb[0].ndi) {
|
||||||
|
// It is newtx
|
||||||
|
h.active = true;
|
||||||
|
h.nof_retxs = 0;
|
||||||
|
h.ndi = data.dci.tb[0].ndi;
|
||||||
|
} else {
|
||||||
|
// it is retx
|
||||||
|
h.nof_retxs++;
|
||||||
|
}
|
||||||
|
h.last_tti_rx = sf_out.tti_rx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ue_sim::update_ul_harqs(const sf_output_res_t& sf_out)
|
||||||
|
{
|
||||||
|
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) {
|
||||||
|
const auto& phich = sf_out.ul_cc_result[cc].phich[i];
|
||||||
|
if (phich.rnti != ctxt.rnti) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
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()];
|
||||||
|
|
||||||
|
if (phich.phich == sched_interface::ul_sched_phich_t::ACK or h.nof_retxs + 1 >= ctxt.ue_cfg.maxharq_tx) {
|
||||||
|
h.active = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update UL harqs with PUSCH grants
|
||||||
|
for (uint32_t i = 0; i < sf_out.ul_cc_result[cc].nof_dci_elems; ++i) {
|
||||||
|
const auto& data = sf_out.ul_cc_result[cc].pusch[i];
|
||||||
|
if (data.dci.rnti != ctxt.rnti) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
auto& ue_cc_ctxt = ctxt.cc_list[data.dci.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()];
|
||||||
|
|
||||||
|
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;
|
||||||
|
} else {
|
||||||
|
h.nof_retxs++;
|
||||||
|
}
|
||||||
|
h.last_tti_rx = sf_out.tti_rx;
|
||||||
|
h.riv = data.dci.type2_alloc.riv;
|
||||||
|
h.nof_txs++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace srsenb
|
@ -0,0 +1,89 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2013-2020 Software Radio Systems Limited
|
||||||
|
*
|
||||||
|
* This file is part of srsLTE.
|
||||||
|
*
|
||||||
|
* srsLTE is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* srsLTE is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* A copy of the GNU Affero General Public License can be found in
|
||||||
|
* the LICENSE file in the top-level directory of this distribution
|
||||||
|
* and at http://www.gnu.org/licenses/.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SRSLTE_SCHED_SIM_UE_H
|
||||||
|
#define SRSLTE_SCHED_SIM_UE_H
|
||||||
|
|
||||||
|
#include "sched_common_test_suite.h"
|
||||||
|
#include "srslte/interfaces/sched_interface.h"
|
||||||
|
#include <bitset>
|
||||||
|
|
||||||
|
namespace srsenb {
|
||||||
|
|
||||||
|
struct ue_harq_ctxt_t {
|
||||||
|
bool active = false;
|
||||||
|
bool ndi = false;
|
||||||
|
uint32_t pid = 0;
|
||||||
|
uint32_t nof_txs = 0;
|
||||||
|
uint32_t nof_retxs = 0;
|
||||||
|
uint32_t riv = 0;
|
||||||
|
srslte::tti_point last_tti_rx;
|
||||||
|
};
|
||||||
|
struct ue_cc_ctxt_t {
|
||||||
|
std::array<ue_harq_ctxt_t, SRSLTE_FDD_NOF_HARQ> dl_harqs;
|
||||||
|
std::array<ue_harq_ctxt_t, SRSLTE_FDD_NOF_HARQ> 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<ue_cc_ctxt_t> 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<sched_cell_params_t> cell_params;
|
||||||
|
std::map<uint16_t, sim_ue_ctxt_t> ue_db;
|
||||||
|
};
|
||||||
|
struct pucch_feedback {
|
||||||
|
struct cc_data {
|
||||||
|
uint32_t enb_cc_idx = 0;
|
||||||
|
int cqi = -1;
|
||||||
|
int pid = -1;
|
||||||
|
bool ack = false;
|
||||||
|
};
|
||||||
|
std::vector<cc_data> cc_list;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ue_sim
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ue_sim() = default;
|
||||||
|
|
||||||
|
int update(const sf_output_res_t& sf_out);
|
||||||
|
|
||||||
|
bool enqueue_pending_acks(srslte::tti_point tti_rx,
|
||||||
|
pucch_feedback& feedback_list,
|
||||||
|
std::bitset<SRSLTE_MAX_CARRIERS> ack_val);
|
||||||
|
|
||||||
|
const sim_ue_ctxt_t& get_ctxt() const { return ctxt; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
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;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace srsenb
|
||||||
|
|
||||||
|
#endif // SRSLTE_SCHED_SIM_UE_H
|
@ -0,0 +1,178 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2013-2020 Software Radio Systems Limited
|
||||||
|
*
|
||||||
|
* This file is part of srsLTE.
|
||||||
|
*
|
||||||
|
* srsLTE is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* srsLTE is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* A copy of the GNU Affero General Public License can be found in
|
||||||
|
* the LICENSE file in the top-level directory of this distribution
|
||||||
|
* and at http://www.gnu.org/licenses/.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "sched_ue_ded_test_suite.h"
|
||||||
|
#include "srslte/common/test_common.h"
|
||||||
|
|
||||||
|
namespace srsenb {
|
||||||
|
|
||||||
|
using phich_t = sched_interface::ul_sched_phich_t;
|
||||||
|
using pusch_t = sched_interface::ul_sched_data_t;
|
||||||
|
|
||||||
|
const sched_interface::ue_cfg_t::cc_cfg_t* sim_ue_ctxt_t::get_cc_cfg(uint32_t enb_cc_idx) const
|
||||||
|
{
|
||||||
|
// TODO: verify SCELL Act was received
|
||||||
|
auto it =
|
||||||
|
std::find_if(ue_cfg.supported_cc_list.begin(),
|
||||||
|
ue_cfg.supported_cc_list.end(),
|
||||||
|
[enb_cc_idx](const sched_interface::ue_cfg_t::cc_cfg_t& cc) { return cc.enb_cc_idx == enb_cc_idx; });
|
||||||
|
return (it == ue_cfg.supported_cc_list.end()) ? nullptr : &(*it);
|
||||||
|
}
|
||||||
|
|
||||||
|
int sim_ue_ctxt_t::enb_to_ue_cc_idx(uint32_t enb_cc_idx) const
|
||||||
|
{
|
||||||
|
auto it =
|
||||||
|
std::find_if(ue_cfg.supported_cc_list.begin(),
|
||||||
|
ue_cfg.supported_cc_list.end(),
|
||||||
|
[enb_cc_idx](const sched_interface::ue_cfg_t::cc_cfg_t& cc) { return cc.enb_cc_idx == enb_cc_idx; });
|
||||||
|
return it == ue_cfg.supported_cc_list.end() ? -1 : std::distance(ue_cfg.supported_cc_list.begin(), it);
|
||||||
|
}
|
||||||
|
|
||||||
|
int test_pdsch_grant(const sim_ue_ctxt_t& ue_ctxt,
|
||||||
|
srslte::tti_point tti_rx,
|
||||||
|
uint32_t enb_cc_idx,
|
||||||
|
const sched_interface::dl_sched_data_t& pdsch)
|
||||||
|
{
|
||||||
|
auto* cc_cfg = ue_ctxt.get_cc_cfg(enb_cc_idx);
|
||||||
|
|
||||||
|
// TEST: Check if CC is configured and active
|
||||||
|
CONDERROR(cc_cfg == nullptr or not cc_cfg->active, "PDSCH allocation for disabled or unavailable cc\n");
|
||||||
|
CONDERROR(pdsch.dci.ue_cc_idx != std::distance(&ue_ctxt.ue_cfg.supported_cc_list.front(), cc_cfg),
|
||||||
|
"Inconsistent enb_cc_idx -> ue_cc_idx mapping\n");
|
||||||
|
|
||||||
|
// TEST: DCI is consistent with current UE DL harq state
|
||||||
|
auto& h = ue_ctxt.cc_list[pdsch.dci.ue_cc_idx].dl_harqs[pdsch.dci.pid];
|
||||||
|
uint32_t nof_retx = sched_utils::get_nof_retx(pdsch.dci.tb[0].rv); // 0..3
|
||||||
|
if (h.nof_txs == 0 or h.ndi != pdsch.dci.tb[0].ndi) {
|
||||||
|
// It is newtx
|
||||||
|
CONDERROR(nof_retx != 0, "Invalid rv index for new tx\n");
|
||||||
|
} else {
|
||||||
|
// it is retx
|
||||||
|
CONDERROR(sched_utils::get_rvidx(h.nof_retxs + 1) != (uint32_t)pdsch.dci.tb[0].rv, "Invalid rv index for retx\n");
|
||||||
|
CONDERROR(not h.active, "retx for inactive dl harq pid=%d\n", h.pid);
|
||||||
|
CONDERROR(to_tx_dl_ack(h.last_tti_rx) > tti_rx, "harq pid=%d reused too soon\n", h.pid);
|
||||||
|
CONDERROR(h.nof_retxs + 1 > ue_ctxt.ue_cfg.maxharq_tx,
|
||||||
|
"The number of retx=%d exceeded its max=%d\n",
|
||||||
|
h.nof_retxs + 1,
|
||||||
|
ue_ctxt.ue_cfg.maxharq_tx);
|
||||||
|
}
|
||||||
|
|
||||||
|
return SRSLTE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
for (uint32_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];
|
||||||
|
const auto* pusch_end = &sf_out.ul_cc_result[cc].pusch[sf_out.ul_cc_result[cc].nof_dci_elems];
|
||||||
|
|
||||||
|
// TEST: rnti must exist for all PHICH
|
||||||
|
CONDERROR(std::any_of(phich_begin,
|
||||||
|
phich_end,
|
||||||
|
[&enb_ctxt](const phich_t& phich) { return enb_ctxt.ue_db.count(phich.rnti) == 0; }),
|
||||||
|
"Scheduled PHICH does not have associated rnti\n");
|
||||||
|
|
||||||
|
// TEST: rnti must exist for all PUSCH
|
||||||
|
CONDERROR(std::any_of(pusch_begin,
|
||||||
|
pusch_end,
|
||||||
|
[&enb_ctxt](const pusch_t& pusch) { return enb_ctxt.ue_db.count(pusch.dci.rnti) == 0; }),
|
||||||
|
"Scheduled PUSCH does not have associated rnti.");
|
||||||
|
|
||||||
|
for (const auto& ue_pair : enb_ctxt.ue_db) {
|
||||||
|
const auto& ue = ue_pair.second;
|
||||||
|
uint16_t rnti = ue.rnti;
|
||||||
|
int ue_cc_idx = ue.enb_to_ue_cc_idx(cc);
|
||||||
|
|
||||||
|
// TEST: Check if CC is configured and active
|
||||||
|
CONDERROR(ue_cc_idx < 0 or not ue.ue_cfg.supported_cc_list[ue_cc_idx].active,
|
||||||
|
"PUSCH allocation for disabled or unavailable cc\n");
|
||||||
|
|
||||||
|
const phich_t* phich_ptr =
|
||||||
|
std::find_if(phich_begin, phich_end, [rnti](const phich_t& phich) { return phich.rnti == rnti; });
|
||||||
|
phich_ptr = phich_ptr == phich_end ? nullptr : phich_ptr;
|
||||||
|
const pusch_t* pusch_ptr =
|
||||||
|
std::find_if(pusch_begin, pusch_end, [rnti](const pusch_t& pusch) { return pusch.dci.rnti == rnti; });
|
||||||
|
pusch_ptr = pusch_ptr == pusch_end ? nullptr : pusch_ptr;
|
||||||
|
|
||||||
|
// TEST: Already active UL HARQs have to receive PHICH
|
||||||
|
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);
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pusch_ptr != nullptr) {
|
||||||
|
CONDERROR(pusch_ptr->dci.ue_cc_idx != (uint32_t)ue_cc_idx, "Inconsistent enb_cc_idx -> ue_cc_idx mapping\n");
|
||||||
|
|
||||||
|
// TEST: DCI is consistent with current UE UL harq state
|
||||||
|
uint32_t nof_retx = sched_utils::get_nof_retx(pusch_ptr->dci.tb.rv); // 0..3
|
||||||
|
|
||||||
|
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");
|
||||||
|
} else {
|
||||||
|
CONDERROR(not h.active, "retx for inactive UL harq pid=%d\n", h.pid);
|
||||||
|
if (pusch_ptr->needs_pdcch) {
|
||||||
|
// adaptive retx
|
||||||
|
} else {
|
||||||
|
// non-adaptive retx
|
||||||
|
CONDERROR(pusch_ptr->dci.type2_alloc.riv != h.riv, "Non-adaptive retx must keep the same riv\n");
|
||||||
|
}
|
||||||
|
if (pusch_ptr->tbs > 0) {
|
||||||
|
CONDERROR(sched_utils::get_rvidx(h.nof_retxs + 1) != (uint32_t)pusch_ptr->dci.tb.rv,
|
||||||
|
"Invalid rv index for retx\n");
|
||||||
|
}
|
||||||
|
CONDERROR(to_tx_ul(h.last_tti_rx) > sf_out.tti_rx, "UL harq pid=%d was reused too soon\n", h.pid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return SRSLTE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TESTASSERT(test_ul_sched_result(enb_ctxt, sf_out) == SRSLTE_SUCCESS);
|
||||||
|
|
||||||
|
return SRSLTE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace srsenb
|
@ -0,0 +1,70 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2013-2020 Software Radio Systems Limited
|
||||||
|
*
|
||||||
|
* This file is part of srsLTE.
|
||||||
|
*
|
||||||
|
* srsLTE is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* srsLTE is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* A copy of the GNU Affero General Public License can be found in
|
||||||
|
* the LICENSE file in the top-level directory of this distribution
|
||||||
|
* and at http://www.gnu.org/licenses/.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SRSLTE_SCHED_UE_DED_TEST_SUITE_H
|
||||||
|
#define SRSLTE_SCHED_UE_DED_TEST_SUITE_H
|
||||||
|
|
||||||
|
#include "sched_common_test_suite.h"
|
||||||
|
#include "sched_sim_ue.h"
|
||||||
|
|
||||||
|
namespace srsenb {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks DL grant content and whether it is consistent with the current UE context. Current checks:
|
||||||
|
* - The DCI rv matches the nof DL harq retxs observed from the UE perspective
|
||||||
|
* - The number of retxs per DL harq does not exceed its maximum set in the ue cfg
|
||||||
|
* - HARQ pids are not reused too early (ACK hasn't arrive to the eNB yet)
|
||||||
|
* @param ue_ctxt current simulation UE context
|
||||||
|
* @param tti_rx TTI when scheduling decision was made
|
||||||
|
* @param enb_cc_idx eNB carrier index
|
||||||
|
* @param pdsch PDSCH grant data
|
||||||
|
* @return error code
|
||||||
|
*/
|
||||||
|
int test_pdsch_grant(const sim_ue_ctxt_t& ue_ctxt,
|
||||||
|
srslte::tti_point tti_rx,
|
||||||
|
uint32_t enb_cc_idx,
|
||||||
|
const sched_interface::dl_sched_data_t& pdsch);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks PHICH & PUSCH grant content and whether it is consistent with the current UE HARQ state. Current checks:
|
||||||
|
* - All PHICH and PUSCH grants' rnti values are present in the eNB context
|
||||||
|
* - UEs only get PUSCH grants in active CCs
|
||||||
|
* - Active UE UL HARQs expect PHICH
|
||||||
|
* - Active UE UL HARQs expect PUSCH grants except if it is the last retx
|
||||||
|
* - The DCI rv matches the nof UL harq retxs observed from the UE perspective
|
||||||
|
* - The number of retxs per UL harq does not exceed its maximum value set in the ue cfg
|
||||||
|
* @param enb_ctxt current eNB state, including list of UEs
|
||||||
|
* @param sf_out result of a subframe sched result
|
||||||
|
* @return error code
|
||||||
|
*/
|
||||||
|
int test_ul_sched_result(const sim_enb_ctxt_t& enb_ctxt, const sf_output_res_t& sf_out);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Call all tests that depend on the UE internal state for all registered UEs in the eNB
|
||||||
|
* @param enb_ctxt current eNB state, including list of UEs
|
||||||
|
* @param sf_out result of a subframe sched result
|
||||||
|
* @return error code
|
||||||
|
*/
|
||||||
|
int test_all_ues(const sim_enb_ctxt_t& enb_ctxt, const sf_output_res_t& sf_out);
|
||||||
|
|
||||||
|
} // namespace srsenb
|
||||||
|
|
||||||
|
#endif // SRSLTE_SCHED_UE_DED_TEST_SUITE_H
|
Loading…
Reference in New Issue