diff --git a/lib/include/srslte/interfaces/ue_interfaces.h b/lib/include/srslte/interfaces/ue_interfaces.h index c15a09804..03edd0b88 100644 --- a/lib/include/srslte/interfaces/ue_interfaces.h +++ b/lib/include/srslte/interfaces/ue_interfaces.h @@ -303,11 +303,11 @@ public: } mac_grant_t; typedef struct { - bool decode_enabled; + bool decode_enabled[SRSLTE_MAX_TB]; int rv[SRSLTE_MAX_TB]; uint16_t rnti; bool generate_ack; - bool default_ack; + bool default_ack[SRSLTE_MAX_TB]; // If non-null, called after tb_decoded_ok to determine if ack needs to be sent bool (*generate_ack_callback)(void*); void *generate_ack_callback_arg; diff --git a/lib/src/phy/phch/pdsch.c b/lib/src/phy/phch/pdsch.c index 0908793db..16f72a37e 100644 --- a/lib/src/phy/phch/pdsch.c +++ b/lib/src/phy/phch/pdsch.c @@ -613,7 +613,7 @@ static int srslte_pdsch_codeword_decode(srslte_pdsch_t *q, srslte_pdsch_cfg_t *c ret = SRSLTE_SUCCESS; } } else { - ERROR("Detected NULL pointer"); + ERROR("Detected NULL pointer in TB%d &softbuffer=%p &data=%p &ack=%p", codeword_idx, softbuffer, (void*)data, ack); } return ret; @@ -689,7 +689,8 @@ int srslte_pdsch_decode(srslte_pdsch_t *q, // Codeword decoding for (uint32_t tb = 0; tb < SRSLTE_MAX_CODEWORDS; tb ++) { - if (cfg->grant.tb_en[tb]) { + /* Decode only if transport block is enabled and the default ACK is not true */ + if (cfg->grant.tb_en[tb] && !acks[tb]) { int ret = srslte_pdsch_codeword_decode(q, cfg, softbuffers[tb], rnti, data[tb], tb, &acks[tb]); /* Check if there has been any execution error */ diff --git a/lib/src/phy/phch/test/pdsch_test.c b/lib/src/phy/phch/test/pdsch_test.c index c5b55b48d..0c98079b9 100644 --- a/lib/src/phy/phch/test/pdsch_test.c +++ b/lib/src/phy/phch/test/pdsch_test.c @@ -460,6 +460,10 @@ int main(int argc, char **argv) { srslte_softbuffer_rx_reset_tbs(softbuffers_rx[i], (uint32_t) grant.mcs[i].tbs); } } + + /* Set ACKs to zero, otherwise will not decode if there are positive ACKs*/ + bzero(acks, sizeof(acks)); + r = srslte_pdsch_decode(&pdsch_rx, &pdsch_cfg, softbuffers_rx, rx_slot_symbols, ce, 0, rnti, data_rx, acks); } gettimeofday(&t[2], NULL); diff --git a/srsue/hdr/mac/dl_harq.h b/srsue/hdr/mac/dl_harq.h index e897ac76f..7c6dbac1e 100644 --- a/srsue/hdr/mac/dl_harq.h +++ b/srsue/hdr/mac/dl_harq.h @@ -168,12 +168,14 @@ private: void new_grant_dl(Tgrant grant, Taction *action) { /* Fill action structure */ bzero(action, sizeof(Taction)); - action->default_ack = false; action->generate_ack = true; - action->decode_enabled = false; + action->rnti = grant.rnti; /* For each subprocess... */ for (uint32_t tb = 0; tb < SRSLTE_MAX_TB; tb++) { + action->default_ack[tb] = false; + action->decode_enabled[tb] = false; + action->phy_grant.dl.tb_en[tb] = grant.tb_en[tb]; if (grant.tb_en[tb]) { subproc[tb].new_grant_dl(grant, action); } @@ -258,20 +260,19 @@ private: cur_grant.n_bytes[tid]); action->payload_ptr[tid] = payload_buffer_ptr; if (!action->payload_ptr) { - action->decode_enabled = false; + action->decode_enabled[tid] = false; Error("Can't get a buffer for TBS=%d\n", cur_grant.n_bytes[tid]); return; } - action->decode_enabled = true; + action->decode_enabled[tid]= true; action->rv[tid] = cur_grant.rv[tid]; - action->rnti = cur_grant.rnti; action->softbuffers[tid] = &softbuffer; memcpy(&action->phy_grant, &cur_grant.phy_grant, sizeof(Tphygrant)); n_retx++; } else { + action->default_ack[tid] = true; Warning("DL PID %d: Received duplicate TB. Discarting and retransmitting ACK\n", pid); - action->phy_grant.dl.tb_en[tid] = false; } if (pid == HARQ_BCCH_PID || harq_entity->timers_db->get(TIME_ALIGNMENT)->is_expired()) { diff --git a/srsue/src/mac/mac.cc b/srsue/src/mac/mac.cc index f28e43553..5c0a00b4a 100644 --- a/srsue/src/mac/mac.cc +++ b/srsue/src/mac/mac.cc @@ -268,7 +268,7 @@ void mac::new_grant_dl(mac_interface_phy::mac_grant_t grant, mac_interface_phy:: memcpy(&action->phy_grant, &grant.phy_grant, sizeof(srslte_phy_grant_t)); action->generate_ack = false; - action->decode_enabled = true; + action->decode_enabled[0] = true; srslte_softbuffer_rx_reset_cb(&pch_softbuffer, 1); action->payload_ptr[0] = pch_payload_buffer; action->softbuffers[0] = &pch_softbuffer; @@ -276,7 +276,7 @@ void mac::new_grant_dl(mac_interface_phy::mac_grant_t grant, mac_interface_phy:: action->rv[0] = grant.rv[0]; if (grant.n_bytes[0] > pch_payload_buffer_sz) { Error("Received grant for PCH (%d bytes) exceeds buffer (%d bytes)\n", grant.n_bytes[0], pch_payload_buffer_sz); - action->decode_enabled = false; + action->decode_enabled[0] = false; } } else { // If PDCCH for C-RNTI and RA procedure in Contention Resolution, notify it diff --git a/srsue/src/mac/proc_ra.cc b/srsue/src/mac/proc_ra.cc index 28a2b47e3..3c5adacd9 100644 --- a/srsue/src/mac/proc_ra.cc +++ b/srsue/src/mac/proc_ra.cc @@ -275,8 +275,9 @@ void ra_proc::new_grant_dl(mac_interface_phy::mac_grant_t grant, mac_interface_p { if (grant.n_bytes[0] < MAX_RAR_PDU_LEN) { rDebug("DL grant found RA-RNTI=%d\n", ra_rnti); - action->decode_enabled = true; - action->default_ack = false; + action->decode_enabled[0] = true; + action->decode_enabled[1] = false; + action->default_ack[0] = false; action->generate_ack = false; action->payload_ptr[0] = rar_pdu_buffer; action->rnti = grant.rnti; @@ -290,7 +291,8 @@ void ra_proc::new_grant_dl(mac_interface_phy::mac_grant_t grant, mac_interface_p } } else { rError("Received RAR grant exceeds buffer length (%d>%d)\n", grant.n_bytes[0], MAX_RAR_PDU_LEN); - action->decode_enabled = false; + action->decode_enabled[0] = false; + action->decode_enabled[1] = false; state = RESPONSE_ERROR; } } diff --git a/srsue/src/phy/phch_worker.cc b/srsue/src/phy/phch_worker.cc index 0290c0745..2f99c2699 100644 --- a/srsue/src/phy/phch_worker.cc +++ b/srsue/src/phy/phch_worker.cc @@ -230,18 +230,18 @@ void phch_worker::work_imp() /* Set DL ACKs to default */ for (uint32_t tb = 0; tb < SRSLTE_MAX_CODEWORDS; tb++) { - dl_ack[tb] = dl_action.default_ack; + dl_ack[tb] = dl_action.default_ack[tb]; } /* Decode PDSCH if instructed to do so */ - if (dl_action.decode_enabled) { + if (dl_action.decode_enabled[0] || dl_action.decode_enabled[1]) { decode_pdsch(&dl_action.phy_grant.dl, dl_action.payload_ptr, dl_action.softbuffers, dl_action.rv, dl_action.rnti, dl_mac_grant.pid, dl_ack); } - if (dl_action.generate_ack_callback && dl_action.decode_enabled) { + if (dl_action.generate_ack_callback) { for (uint32_t tb = 0; tb < SRSLTE_MAX_TB; tb++) { - if (dl_mac_grant.tb_en[tb]) { + if (dl_action.decode_enabled[tb]) { phy->mac->tb_decoded(dl_ack[tb], tb, dl_mac_grant.rnti_type, dl_mac_grant.pid); dl_ack[tb] = dl_action.generate_ack_callback(dl_action.generate_ack_callback_arg); Debug("Calling generate ACK callback for TB %d returned=%d\n", tb, dl_ack[tb]); @@ -332,12 +332,12 @@ void phch_worker::work_imp() phy->worker_end(tx_tti, signal_ready, signal_buffer[0], SRSLTE_SF_LEN_PRB(cell.nof_prb), tx_time); - if (dl_action.decode_enabled && !dl_action.generate_ack_callback) { - if (dl_mac_grant.rnti_type == SRSLTE_RNTI_PCH) { + if (!dl_action.generate_ack_callback) { + if (dl_mac_grant.rnti_type == SRSLTE_RNTI_PCH && dl_action.decode_enabled[0]) { phy->mac->pch_decoded_ok(dl_mac_grant.n_bytes[0]); } else { for (uint32_t tb = 0; tb < SRSLTE_MAX_TB; tb++) { - if (dl_mac_grant.tb_en[tb]) { + if (dl_action.decode_enabled[tb]) { phy->mac->tb_decoded(dl_ack[tb], tb, dl_mac_grant.rnti_type, dl_mac_grant.pid); } } diff --git a/srsue/test/phy/ue_itf_test_prach.cc b/srsue/test/phy/ue_itf_test_prach.cc index 42e04c495..810278c7c 100644 --- a/srsue/test/phy/ue_itf_test_prach.cc +++ b/srsue/test/phy/ue_itf_test_prach.cc @@ -277,8 +277,8 @@ public: } void new_grant_dl(mac_grant_t grant, tb_action_dl_t *action) { - action->decode_enabled = true; - action->default_ack = false; + action->decode_enabled[0] = true; + action->default_ack[0] = false; if (grant.rnti == 2) { action->generate_ack = false; } else { diff --git a/srsue/test/phy/ue_itf_test_sib1.cc b/srsue/test/phy/ue_itf_test_sib1.cc index 90f8b5b43..23f8566be 100644 --- a/srsue/test/phy/ue_itf_test_sib1.cc +++ b/srsue/test/phy/ue_itf_test_sib1.cc @@ -116,8 +116,8 @@ public: total_dci++; - action->decode_enabled = true; - action->default_ack = false; + action->decode_enabled[0] = true; + action->default_ack[0] = false; action->generate_ack = false; for (uint32_t tb = 0; tb < SRSLTE_MAX_TB; tb++) { action->payload_ptr[tb] = payload[tb];