|
|
|
@ -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);
|
|
|
|
|
|
|
|
|
|