From be0c6ebd203196930357b9e13733a6347dcb2a51 Mon Sep 17 00:00:00 2001 From: Xavier Arteaga Date: Mon, 28 Aug 2017 13:07:44 +0200 Subject: [PATCH] Added multiple codeword architecture to MAC layer --- lib/include/srslte/interfaces/ue_interfaces.h | 22 +- srsue/hdr/mac/dl_harq.h | 379 ++++++++++-------- srsue/hdr/mac/mac.h | 2 +- srsue/hdr/mac/ul_harq.h | 26 +- srsue/hdr/phy/phch_worker.h | 14 +- srsue/src/mac/mac.cc | 15 +- srsue/src/mac/proc_ra.cc | 12 +- srsue/src/phy/phch_worker.cc | 131 +++--- srsue/test/phy/ue_itf_test_prach.cc | 76 ++-- srsue/test/phy/ue_itf_test_sib1.cc | 29 +- 10 files changed, 392 insertions(+), 314 deletions(-) diff --git a/lib/include/srslte/interfaces/ue_interfaces.h b/lib/include/srslte/interfaces/ue_interfaces.h index 81ed67b74..879118021 100644 --- a/lib/include/srslte/interfaces/ue_interfaces.h +++ b/lib/include/srslte/interfaces/ue_interfaces.h @@ -277,10 +277,10 @@ public: uint32_t pid; uint32_t tti; uint32_t last_tti; - bool ndi; - bool last_ndi; - uint32_t n_bytes; - int rv; + bool ndi[SRSLTE_MAX_CODEWORDS]; + bool last_ndi[SRSLTE_MAX_CODEWORDS]; + uint32_t n_bytes[SRSLTE_MAX_CODEWORDS]; + int rv[SRSLTE_MAX_CODEWORDS]; uint16_t rnti; bool is_from_rar; bool is_sps_release; @@ -291,28 +291,28 @@ public: typedef struct { bool decode_enabled; - int rv; + int rv[SRSLTE_MAX_TB]; uint16_t rnti; bool generate_ack; bool default_ack; // 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; - uint8_t *payload_ptr; - srslte_softbuffer_rx_t *softbuffer; + uint8_t *payload_ptr[SRSLTE_MAX_TB]; + srslte_softbuffer_rx_t *softbuffers[SRSLTE_MAX_TB]; srslte_phy_grant_t phy_grant; } tb_action_dl_t; typedef struct { bool tx_enabled; bool expect_ack; - uint32_t rv; + uint32_t rv[SRSLTE_MAX_TB]; uint16_t rnti; uint32_t current_tx_nb; int32_t tti_offset; // relative offset between grant and UL tx/HARQ rx - srslte_softbuffer_tx_t *softbuffer; + srslte_softbuffer_tx_t *softbuffers; srslte_phy_grant_t phy_grant; - uint8_t *payload_ptr; + uint8_t *payload_ptr[SRSLTE_MAX_TB]; } tb_action_ul_t; /* Indicate reception of UL grant. @@ -329,7 +329,7 @@ public: virtual void new_grant_dl(mac_grant_t grant, tb_action_dl_t *action) = 0; /* Indicate successfull decoding of PDSCH TB. */ - virtual void tb_decoded(bool ack, srslte_rnti_type_t rnti_type, uint32_t harq_pid) = 0; + virtual void tb_decoded(bool ack, uint32_t tb_idx, srslte_rnti_type_t rnti_type, uint32_t harq_pid) = 0; /* Indicate successfull decoding of BCH TB through PBCH */ virtual void bch_decoded_ok(uint8_t *payload, uint32_t len) = 0; diff --git a/srsue/hdr/mac/dl_harq.h b/srsue/hdr/mac/dl_harq.h index 809ecd151..4f6df9b51 100644 --- a/srsue/hdr/mac/dl_harq.h +++ b/srsue/hdr/mac/dl_harq.h @@ -84,20 +84,20 @@ public: harq_pid = grant.pid%N; } if (grant.rnti_type == SRSLTE_RNTI_TEMP && last_temporal_crnti != grant.rnti) { - grant.ndi = true; + grant.ndi[0] = true; Info("Set NDI=1 for Temp-RNTI DL grant\n"); last_temporal_crnti = grant.rnti; } if (grant.rnti_type == SRSLTE_RNTI_USER && proc[harq_pid].is_sps()) { - grant.ndi = true; + grant.ndi[0] = true; Info("Set NDI=1 for C-RNTI DL grant\n"); } proc[harq_pid].new_grant_dl(grant, action); } else { /* This is for SPS scheduling */ uint32_t harq_pid = get_harq_sps_pid(grant.tti)%N; - if (grant.ndi) { - grant.ndi = false; + if (grant.ndi[0]) { + grant.ndi[0] = false; proc[harq_pid].new_grant_dl(grant, action); } else { if (grant.is_sps_release) { @@ -117,12 +117,12 @@ public: } - void tb_decoded(bool ack, srslte_rnti_type_t rnti_type, uint32_t harq_pid) + void tb_decoded(bool ack, uint32_t tb_idx, srslte_rnti_type_t rnti_type, uint32_t harq_pid) { if (rnti_type == SRSLTE_RNTI_SI) { - proc[N].tb_decoded(ack); + proc[N].tb_decoded(ack, 0); } else { - proc[harq_pid%N].tb_decoded(ack); + proc[harq_pid%N].tb_decoded(ack, tb_idx); } } @@ -137,200 +137,239 @@ public: void start_pcap(srslte::mac_pcap* pcap_) { pcap = pcap_; } - int get_current_tbs(uint32_t harq_pid) { return proc[harq_pid%N].get_current_tbs(); } + int get_current_tbs(uint32_t harq_pid, uint32_t tb_idx) { return proc[harq_pid%N].get_current_tbs(tb_idx); } void set_si_window_start(int si_window_start_) { si_window_start = si_window_start_; } float get_average_retx() { return average_retx; } -private: +private: class dl_harq_process { public: - dl_harq_process() - { - is_initiated = false; - ack = false; - bzero(&cur_grant, sizeof(Tgrant)); + dl_harq_process() : subproc(SRSLTE_MAX_TB) { + } - bool init(uint32_t pid_, dl_harq_entity *parent) - { - if (srslte_softbuffer_rx_init(&softbuffer, 110)) { - Error("Error initiating soft buffer\n"); - return false; - } else { - pid = pid_; - is_initiated = true; - harq_entity = parent; - log_h = harq_entity->log_h; - return true; + bool init(uint32_t pid_, dl_harq_entity *parent) { + bool ret = true; + + for (uint32_t tb = 0; tb < SRSLTE_MAX_TB; tb++) { + ret &= subproc[tb].init(pid_, parent, tb); } + return ret; } - void reset() - { - ack = false; - payload_buffer_ptr = NULL; - bzero(&cur_grant, sizeof(Tgrant)); - if (is_initiated) { - srslte_softbuffer_rx_reset(&softbuffer); + void reset(void) { + for (uint32_t tb = 0; tb < SRSLTE_MAX_TB; tb++) { + subproc[tb].reset(); } } - - void new_grant_dl(Tgrant grant, Taction *action) - { - // Compute RV for BCCH when not specified in PDCCH format - if (pid == HARQ_BCCH_PID && grant.rv == -1) { - uint32_t k; - if ((grant.tti/10)%2 == 0 && grant.tti%10 == 5) { // This is SIB1, k is different - k = (grant.tti/20)%4; - grant.rv = ((uint32_t) ceilf((float)1.5*k))%4; - } else if (grant.rv == -1) { - k = (grant.tti-harq_entity->si_window_start)%4; - grant.rv = ((uint32_t) ceilf((float)1.5*k))%4; - } - } - calc_is_new_transmission(grant); - if (is_new_transmission) { - ack = false; - srslte_softbuffer_rx_reset_tbs(&softbuffer, cur_grant.n_bytes*8); - n_retx = 0; + + void new_grant_dl(Tgrant grant, Taction *action) { + for (uint32_t tb = 0; tb < grant.phy_grant.dl.nof_tb; tb++) { + subproc[tb].new_grant_dl(grant, action); } - - // Save grant - grant.last_ndi = cur_grant.ndi; - grant.last_tti = cur_grant.tti; - memcpy(&cur_grant, &grant, sizeof(Tgrant)); - - // Fill action structure - bzero(action, sizeof(Taction)); - action->default_ack = ack; - action->generate_ack = true; - action->decode_enabled = false; - - // If data has not yet been successfully decoded - if (ack == false) { - - // Instruct the PHY To combine the received data and attempt to decode it - payload_buffer_ptr = harq_entity->demux_unit->request_buffer(pid, cur_grant.n_bytes); - action->payload_ptr = payload_buffer_ptr; - if (!action->payload_ptr) { - action->decode_enabled = false; - Error("Can't get a buffer for TBS=%d\n", cur_grant.n_bytes); - return; - } - action->decode_enabled = true; - action->rv = cur_grant.rv; - action->rnti = cur_grant.rnti; - action->softbuffer = &softbuffer; - memcpy(&action->phy_grant, &cur_grant.phy_grant, sizeof(Tphygrant)); - n_retx++; - - } else { - Warning("DL PID %d: Received duplicate TB. Discarting and retransmitting ACK\n", pid); + } + + int get_current_tbs(uint32_t tb_idx) { return subproc[tb_idx].get_current_tbs(); } + + bool is_sps() { return false; } + + void tb_decoded(bool ack_, uint32_t tb_idx) { + subproc[tb_idx].tb_decoded(ack_); + } + + private: + class dl_tb_process { + public: + dl_tb_process(void) { + is_initiated = false; + ack = false; + bzero(&cur_grant, sizeof(Tgrant)); } - - if (pid == HARQ_BCCH_PID || harq_entity->timers_db->get(TIME_ALIGNMENT)->is_expired()) { - // Do not generate ACK - Debug("Not generating ACK\n"); - action->generate_ack = false; - } else { - if (cur_grant.rnti_type == SRSLTE_RNTI_TEMP && ack == false) { - // Postpone ACK after contention resolution is resolved - action->generate_ack_callback = harq_entity->generate_ack_callback; - action->generate_ack_callback_arg = harq_entity->demux_unit; - Debug("ACK pending contention resolution\n"); + + bool init(uint32_t pid_, dl_harq_entity *parent, uint32_t tb_idx) { + tid = tb_idx; + if (srslte_softbuffer_rx_init(&softbuffer, 110)) { + Error("Error initiating soft buffer\n"); + return false; } else { - Debug("Generating ACK\n"); + pid = pid_; + is_initiated = true; + harq_entity = parent; + log_h = harq_entity->log_h; + return true; } } - } - - void tb_decoded(bool ack_) - { - ack = ack_; - if (ack == true) { - if (pid == HARQ_BCCH_PID) { - if (harq_entity->pcap) { - harq_entity->pcap->write_dl_sirnti(payload_buffer_ptr, cur_grant.n_bytes, ack, cur_grant.tti); + + void reset(void) { + ack = false; + payload_buffer_ptr = NULL; + bzero(&cur_grant, sizeof(Tgrant)); + if (is_initiated) { + srslte_softbuffer_rx_reset(&softbuffer); + } + } + + void new_grant_dl(Tgrant grant, Taction *action) { + // Compute RV for BCCH when not specified in PDCCH format + if (pid == HARQ_BCCH_PID && grant.rv[tid] == -1) { + uint32_t k; + if ((grant.tti / 10) % 2 == 0 && grant.tti % 10 == 5) { // This is SIB1, k is different + k = (grant.tti / 20) % 4; + grant.rv[tid] = ((uint32_t) ceilf((float) 1.5 * k)) % 4; + } else if (grant.rv[tid] == -1) { + k = (grant.tti - harq_entity->si_window_start) % 4; + grant.rv[tid] = ((uint32_t) ceilf((float) 1.5 * k)) % 4; } - Debug("Delivering PDU=%d bytes to Dissassemble and Demux unit (BCCH)\n", cur_grant.n_bytes); - harq_entity->demux_unit->push_pdu(pid, payload_buffer_ptr, cur_grant.n_bytes, cur_grant.tti); - } else { - if (harq_entity->pcap) { - harq_entity->pcap->write_dl_crnti(payload_buffer_ptr, cur_grant.n_bytes, cur_grant.rnti, ack, cur_grant.tti); + } + calc_is_new_transmission(grant); + if (is_new_transmission) { + ack = false; + srslte_softbuffer_rx_reset_tbs(&softbuffer, cur_grant.n_bytes[tid] * 8); + n_retx = 0; + } + + // Save grant + grant.last_ndi[tid] = cur_grant.ndi[tid]; + grant.last_tti = cur_grant.tti; + memcpy(&cur_grant, &grant, sizeof(Tgrant)); + + // Fill action structure + bzero(action, sizeof(Taction)); + action->default_ack = ack; + action->generate_ack = true; + action->decode_enabled = false; + + // If data has not yet been successfully decoded + if (!ack) { + + // Instruct the PHY To combine the received data and attempt to decode it + payload_buffer_ptr = harq_entity->demux_unit->request_buffer(pid * SRSLTE_MAX_TB + tid, + cur_grant.n_bytes[tid]); + action->payload_ptr[tid] = payload_buffer_ptr; + if (!action->payload_ptr) { + action->decode_enabled = false; + Error("Can't get a buffer for TBS=%d\n", cur_grant.n_bytes[tid]); + return; } - if (ack) { - if (cur_grant.rnti_type == SRSLTE_RNTI_TEMP) { - Debug("Delivering PDU=%d bytes to Dissassemble and Demux unit (Temporal C-RNTI)\n", cur_grant.n_bytes); - harq_entity->demux_unit->push_pdu_temp_crnti(payload_buffer_ptr, cur_grant.n_bytes); - } else { - Debug("Delivering PDU=%d bytes to Dissassemble and Demux unit\n", cur_grant.n_bytes); - harq_entity->demux_unit->push_pdu(pid, payload_buffer_ptr, cur_grant.n_bytes, cur_grant.tti); - - // Compute average number of retransmissions per packet - harq_entity->average_retx = SRSLTE_VEC_CMA((float) n_retx, harq_entity->average_retx, harq_entity->nof_pkts++); - } + action->decode_enabled = 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 { + Warning("DL PID %d: Received duplicate TB. Discarting and retransmitting ACK\n", pid); + } + + if (pid == HARQ_BCCH_PID || harq_entity->timers_db->get(TIME_ALIGNMENT)->is_expired()) { + // Do not generate ACK + Debug("Not generating ACK\n"); + action->generate_ack = false; + } else { + if (cur_grant.rnti_type == SRSLTE_RNTI_TEMP && !ack) { + // Postpone ACK after contention resolution is resolved + action->generate_ack_callback = harq_entity->generate_ack_callback; + action->generate_ack_callback_arg = harq_entity->demux_unit; + Debug("ACK pending contention resolution\n"); + } else { + Debug("Generating ACK\n"); } } - } else { - harq_entity->demux_unit->deallocate(payload_buffer_ptr); - } - - Info("DL %d: %s tbs=%d, rv=%d, ack=%s, ndi=%d (%d), tti=%d (%d)\n", - pid, is_new_transmission?"newTX":"reTX ", - cur_grant.n_bytes, cur_grant.rv, ack?"OK":"KO", - cur_grant.ndi, cur_grant.last_ndi, cur_grant.tti, cur_grant.last_tti); - - if (ack && pid == HARQ_BCCH_PID) { - reset(); } - } - bool is_sps() { return false; } - int get_current_tbs() { return cur_grant.n_bytes*8; } - - private: - bool calc_is_new_transmission(Tgrant grant) - { - bool is_new_tb = true; - if ((srslte_tti_interval(grant.tti, cur_grant.tti) <= 8 && (grant.n_bytes == cur_grant.n_bytes)) || - pid == HARQ_BCCH_PID) - { - is_new_tb = false; + void tb_decoded(bool ack_) { + ack = ack_; + if (ack) { + if (pid == HARQ_BCCH_PID) { + if (harq_entity->pcap) { + harq_entity->pcap->write_dl_sirnti(payload_buffer_ptr, cur_grant.n_bytes[tid], ack, cur_grant.tti); + } + Debug("Delivering PDU=%d bytes to Dissassemble and Demux unit (BCCH)\n", cur_grant.n_bytes[tid]); + harq_entity->demux_unit->push_pdu(pid * SRSLTE_MAX_TB + tid, payload_buffer_ptr, cur_grant.n_bytes[tid], + cur_grant.tti); + } else { + if (harq_entity->pcap) { + harq_entity->pcap->write_dl_crnti(payload_buffer_ptr, cur_grant.n_bytes[tid], cur_grant.rnti, ack, + cur_grant.tti); + } + if (ack) { + if (cur_grant.rnti_type == SRSLTE_RNTI_TEMP) { + Debug("Delivering PDU=%d bytes to Dissassemble and Demux unit (Temporal C-RNTI)\n", + cur_grant.n_bytes[tid]); + harq_entity->demux_unit->push_pdu_temp_crnti(payload_buffer_ptr, cur_grant.n_bytes[tid]); + } else { + Debug("Delivering PDU=%d bytes to Dissassemble and Demux unit\n", cur_grant.n_bytes[tid]); + harq_entity->demux_unit->push_pdu(pid * SRSLTE_MAX_TB + tid, payload_buffer_ptr, cur_grant.n_bytes[tid], + cur_grant.tti); + + // Compute average number of retransmissions per packet + harq_entity->average_retx = SRSLTE_VEC_CMA((float) n_retx, harq_entity->average_retx, + harq_entity->nof_pkts++); + } + } + } + } else { + harq_entity->demux_unit->deallocate(payload_buffer_ptr); + } + + Info("DL %d (TB %d): %s tbs=%d, rv=%d, ack=%s, ndi=%d (%d), tti=%d (%d)\n", + pid, tid, is_new_transmission ? "newTX" : "reTX ", + cur_grant.n_bytes[tid], cur_grant.rv[tid], ack ? "OK" : "KO", + cur_grant.ndi[tid], cur_grant.last_ndi, cur_grant.tti, cur_grant.last_tti); + + if (ack && pid == HARQ_BCCH_PID) { + reset(); + } } - - if ((grant.ndi != cur_grant.ndi && !is_new_tb) || // NDI toggled for same TB - is_new_tb || // is new TB - (pid == HARQ_BCCH_PID && grant.rv == 0)) // Broadcast PID and 1st TX (RV=0) - { - is_new_transmission = true; - Debug("Set HARQ for new transmission\n"); - } else { - is_new_transmission = false; - Debug("Set HARQ for retransmission\n"); + + int get_current_tbs(void) { return cur_grant.n_bytes[tid] * 8; } + + private: + bool calc_is_new_transmission(Tgrant grant) { + bool is_new_tb = true; + if ((srslte_tti_interval(grant.tti, cur_grant.tti) <= 8 && (grant.n_bytes[tid] == cur_grant.n_bytes[tid])) || + pid == HARQ_BCCH_PID) { + is_new_tb = false; + } + + if ((grant.ndi[tid] != cur_grant.ndi[tid] && !is_new_tb) || // NDI toggled for same TB + is_new_tb || // is new TB + (pid == HARQ_BCCH_PID && grant.rv[tid] == 0)) // Broadcast PID and 1st TX (RV=0) + { + is_new_transmission = true; + Debug("Set HARQ for new transmission\n"); + } else { + is_new_transmission = false; + Debug("Set HARQ for retransmission\n"); + } + + return is_new_transmission; } - return is_new_transmission; - } + bool is_initiated; + dl_harq_entity *harq_entity; + srslte::log *log_h; - bool is_initiated; - dl_harq_entity *harq_entity; - srslte::log *log_h; - - bool is_new_transmission; - - uint32_t pid; - uint8_t *payload_buffer_ptr; - bool ack; - - uint32_t n_retx; - - Tgrant cur_grant; - srslte_softbuffer_rx_t softbuffer; + bool is_new_transmission; + + uint32_t pid; /* HARQ Proccess ID */ + uint32_t tid; /* Transport block ID */ + uint8_t *payload_buffer_ptr; + bool ack; + + uint32_t n_retx; + + Tgrant cur_grant; + srslte_softbuffer_rx_t softbuffer; + }; + + /* Transport blocks */ + std::vector subproc; }; - // Private members of dl_harq_entity static bool generate_ack_callback(void *arg) diff --git a/srsue/hdr/mac/mac.h b/srsue/hdr/mac/mac.h index 660f7fbba..f2785e288 100644 --- a/srsue/hdr/mac/mac.h +++ b/srsue/hdr/mac/mac.h @@ -65,7 +65,7 @@ public: void new_grant_ul_ack(mac_grant_t grant, bool ack, tb_action_ul_t *action); void harq_recv(uint32_t tti, bool ack, tb_action_ul_t *action); void new_grant_dl(mac_grant_t grant, tb_action_dl_t *action); - void tb_decoded(bool ack, srslte_rnti_type_t rnti_type, uint32_t harq_pid); + void tb_decoded(bool ack, uint32_t tb_idx, srslte_rnti_type_t rnti_type, uint32_t harq_pid); void bch_decoded_ok(uint8_t *payload, uint32_t len); void pch_decoded_ok(uint32_t len); void tti_clock(uint32_t tti); diff --git a/srsue/hdr/mac/ul_harq.h b/srsue/hdr/mac/ul_harq.h index 2ef1ed2b6..13ec0b9b3 100644 --- a/srsue/hdr/mac/ul_harq.h +++ b/srsue/hdr/mac/ul_harq.h @@ -113,12 +113,12 @@ public: grant.rnti_type == SRSLTE_RNTI_RAR) { if (grant.rnti_type == SRSLTE_RNTI_USER && proc[pidof(grant.tti)].is_sps()) { - grant.ndi = true; + grant.ndi[0] = true; } run_tti(grant.tti, &grant, action); } else if (grant.rnti_type == SRSLTE_RNTI_SPS) { - if (grant.ndi) { - grant.ndi = proc[pidof(grant.tti)].get_ndi(); + if (grant.ndi[0]) { + grant.ndi[0] = proc[pidof(grant.tti)].get_ndi(); run_tti(grant.tti, &grant, action); } else { Info("Not implemented\n"); @@ -208,7 +208,7 @@ private: // Receive and route HARQ feedbacks if (grant) { - if ((!(grant->rnti_type == SRSLTE_RNTI_TEMP) && grant->ndi != get_ndi()) || + if ((!(grant->rnti_type == SRSLTE_RNTI_TEMP) && grant->ndi[0] != get_ndi()) || (grant->rnti_type == SRSLTE_RNTI_USER && !has_grant()) || grant->is_from_rar) { @@ -216,8 +216,8 @@ private: // Uplink grant in a RAR if (grant->is_from_rar) { - Debug("Getting Msg3 buffer payload, grant size=%d bytes\n", grant->n_bytes); - pdu_ptr = harq_entity->mux_unit->msg3_get(payload_buffer, grant->n_bytes); + Debug("Getting Msg3 buffer payload, grant size=%d bytes\n", grant->n_bytes[0]); + pdu_ptr = harq_entity->mux_unit->msg3_get(payload_buffer, grant->n_bytes[0]); if (pdu_ptr) { generate_new_tx(tti_tx, true, grant, action); } else { @@ -227,7 +227,7 @@ private: // Normal UL grant } else { // Request a MAC PDU from the Multiplexing & Assemble Unit - pdu_ptr = harq_entity->mux_unit->pdu_get(payload_buffer, grant->n_bytes, tti_tx, pid); + pdu_ptr = harq_entity->mux_unit->pdu_get(payload_buffer, grant->n_bytes[0], tti_tx, pid); if (pdu_ptr) { generate_new_tx(tti_tx, false, grant, action); } else { @@ -258,7 +258,7 @@ private: if (grant->is_from_rar) { grant->rnti = harq_entity->rntis->temp_rnti; } - harq_entity->pcap->write_ul_crnti(pdu_ptr, grant->n_bytes, grant->rnti, get_nof_retx(), tti_tx); + harq_entity->pcap->write_ul_crnti(pdu_ptr, grant->n_bytes[0], grant->rnti, get_nof_retx(), tti_tx); } } @@ -285,7 +285,7 @@ private: bool is_sps() { return false; } uint32_t last_tx_tti() { return tti_last_tx; } uint32_t get_nof_retx() { return current_tx_nb; } - int get_current_tbs() { return cur_grant.n_bytes*8; } + int get_current_tbs() { return cur_grant.n_bytes[0]*8; } private: Tgrant cur_grant; @@ -321,7 +321,7 @@ private: if (grant) { // HARQ entity requests an adaptive transmission if (grant->rv) { - current_irv = irv_of_rv[grant->rv%4]; + current_irv = irv_of_rv[grant->rv[0]%4]; } memcpy(&cur_grant, grant, sizeof(Tgrant)); harq_feedback = false; @@ -370,10 +370,10 @@ private: current_tx_nb++; action->expect_ack = true; action->rnti = is_msg3?harq_entity->rntis->temp_rnti:cur_grant.rnti; - action->rv = cur_grant.rv>0?cur_grant.rv:get_rv(); - action->softbuffer = &softbuffer; + action->rv[0] = cur_grant.rv[0]>0?cur_grant.rv[0]:get_rv(); + action->softbuffers = &softbuffer; action->tx_enabled = true; - action->payload_ptr = pdu_ptr; + action->payload_ptr[0] = pdu_ptr; memcpy(&action->phy_grant, &cur_grant.phy_grant, sizeof(Tphygrant)); current_irv = (current_irv+1)%4; diff --git a/srsue/hdr/phy/phch_worker.h b/srsue/hdr/phy/phch_worker.h index ed1d7af26..a47008629 100644 --- a/srsue/hdr/phy/phch_worker.h +++ b/srsue/hdr/phy/phch_worker.h @@ -78,18 +78,20 @@ private: bool decode_pdcch_dl(mac_interface_phy::mac_grant_t *grant); bool decode_phich(bool *ack); - bool decode_pdsch(srslte_ra_dl_grant_t *grant, + int decode_pdsch(srslte_ra_dl_grant_t *grant, uint8_t *payload, srslte_softbuffer_rx_t *softbuffer, int rv, uint16_t rnti, - uint32_t pid); + uint32_t pid, + bool acks[SRSLTE_MAX_CODEWORDS]); - bool decode_pdsch_multi(srslte_ra_dl_grant_t *grant, + int decode_pdsch_multi(srslte_ra_dl_grant_t *grant, uint8_t *payload[SRSLTE_MAX_CODEWORDS], - srslte_softbuffer_rx_t softbuffers[SRSLTE_MAX_CODEWORDS], + srslte_softbuffer_rx_t *softbuffers[SRSLTE_MAX_CODEWORDS], int rv[SRSLTE_MAX_CODEWORDS], uint16_t rnti, - uint32_t pid); + uint32_t pid, + bool acks[SRSLTE_MAX_CODEWORDS]); /* ... for UL */ void encode_pusch(srslte_ra_ul_grant_t *grant, uint8_t *payload, uint32_t current_tx_nb, srslte_softbuffer_tx_t *softbuffer, @@ -100,7 +102,7 @@ private: void set_uci_sr(); void set_uci_periodic_cqi(); void set_uci_aperiodic_cqi(); - void set_uci_ack(bool ack); + void set_uci_ack(bool ack[SRSLTE_MAX_CODEWORDS], uint32_t nof_tb); bool srs_is_ready_to_send(); float set_power(float tx_power); void setup_tx_gain(); diff --git a/srsue/src/mac/mac.cc b/srsue/src/mac/mac.cc index e1426780e..1bc335bb1 100644 --- a/srsue/src/mac/mac.cc +++ b/srsue/src/mac/mac.cc @@ -44,7 +44,7 @@ namespace srsue { mac::mac() : ttisync(10240), timers_db((uint32_t) NOF_MAC_TIMERS), mux_unit(MAC_NOF_HARQ_PROC), - demux_unit(MAC_NOF_HARQ_PROC), + demux_unit(SRSLTE_MAX_TB*MAC_NOF_HARQ_PROC), pdu_process_thread(&demux_unit) { started = false; @@ -255,17 +255,17 @@ void mac::pch_decoded_ok(uint32_t len) } } -void mac::tb_decoded(bool ack, srslte_rnti_type_t rnti_type, uint32_t harq_pid) +void mac::tb_decoded(bool ack, uint32_t tb_idx, srslte_rnti_type_t rnti_type, uint32_t harq_pid) { if (rnti_type == SRSLTE_RNTI_RAR) { if (ack) { ra_procedure.tb_decoded_ok(); } } else { - dl_harq.tb_decoded(ack, rnti_type, harq_pid); + dl_harq.tb_decoded(ack, tb_idx, rnti_type, harq_pid); if (ack) { pdu_process_thread.notify(); - metrics.rx_brate += dl_harq.get_current_tbs(harq_pid); + metrics.rx_brate += dl_harq.get_current_tbs(harq_pid, tb_idx); } else { metrics.rx_errors++; } @@ -282,12 +282,9 @@ 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; - srslte_softbuffer_rx_reset_cb(&pch_softbuffer, 1); - action->payload_ptr = pch_payload_buffer; - action->softbuffer = &pch_softbuffer; action->rnti = grant.rnti; - action->rv = grant.rv; - if (grant.n_bytes > pch_payload_buffer_sz) { + 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, pch_payload_buffer_sz); action->decode_enabled = false; } diff --git a/srsue/src/mac/proc_ra.cc b/srsue/src/mac/proc_ra.cc index 73b51d61c..213042018 100644 --- a/srsue/src/mac/proc_ra.cc +++ b/srsue/src/mac/proc_ra.cc @@ -269,19 +269,19 @@ void ra_proc::step_pdcch_setup() { void ra_proc::new_grant_dl(mac_interface_phy::mac_grant_t grant, mac_interface_phy::tb_action_dl_t* action) { - if (grant.n_bytes < MAX_RAR_PDU_LEN) { + 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->generate_ack = false; - action->payload_ptr = rar_pdu_buffer; + action->payload_ptr[0] = rar_pdu_buffer; action->rnti = grant.rnti; memcpy(&action->phy_grant, &grant.phy_grant, sizeof(srslte_phy_grant_t)); - action->rv = grant.rv; - action->softbuffer = &softbuffer_rar; - rar_grant_nbytes = grant.n_bytes; + action->rv[0] = grant.rv[0]; + action->softbuffers[0] = &softbuffer_rar; + rar_grant_nbytes = grant.n_bytes[0]; rar_grant_tti = grant.tti; - if (action->rv == 0) { + if (action->rv[0] == 0) { srslte_softbuffer_rx_reset(&softbuffer_rar); } } else { diff --git a/srsue/src/phy/phch_worker.cc b/srsue/src/phy/phch_worker.cc index 6dabbbf01..78c5b2f71 100644 --- a/srsue/src/phy/phch_worker.cc +++ b/srsue/src/phy/phch_worker.cc @@ -178,8 +178,8 @@ void phch_worker::work_imp() reset_uci(); bool dl_grant_available = false; - bool ul_grant_available = false; - bool dl_ack = false; + bool ul_grant_available = false; + bool dl_ack[SRSLTE_MAX_CODEWORDS] = {false}; mac_interface_phy::mac_grant_t dl_mac_grant; mac_interface_phy::tb_action_dl_t dl_action; @@ -200,22 +200,28 @@ void phch_worker::work_imp() if(dl_grant_available) { /* Send grant to MAC and get action for this TB */ phy->mac->new_grant_dl(dl_mac_grant, &dl_action); - + + /* Set DL ACKs to default */ + for (uint32_t tb = 0; tb < SRSLTE_MAX_CODEWORDS; tb++) { + dl_ack[tb] = dl_action.default_ack; + } + /* Decode PDSCH if instructed to do so */ - dl_ack = dl_action.default_ack; if (dl_action.decode_enabled) { - dl_ack = decode_pdsch(&dl_action.phy_grant.dl, dl_action.payload_ptr, - dl_action.softbuffer, dl_action.rv, dl_action.rnti, - dl_mac_grant.pid); + decode_pdsch_multi(&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) { - phy->mac->tb_decoded(dl_ack, dl_mac_grant.rnti_type, dl_mac_grant.pid); - dl_ack = dl_action.generate_ack_callback(dl_action.generate_ack_callback_arg); - Debug("Calling generate ACK callback returned=%d\n", dl_ack); + for (uint32_t tb = 0; tb < SRSLTE_MAX_CODEWORDS; 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); + } } - Debug("dl_ack=%d, generate_ack=%d\n", dl_ack, dl_action.generate_ack); + Debug("dl_ack={%d, %d}, generate_ack=%d\n", dl_ack[0], dl_ack[1], dl_action.generate_ack); if (dl_action.generate_ack) { - set_uci_ack(dl_ack); + set_uci_ack(dl_ack, dl_mac_grant.phy_grant.dl.nof_tb); } } } @@ -258,8 +264,8 @@ void phch_worker::work_imp() /* Transmit PUSCH, PUCCH or SRS */ bool signal_ready = false; if (ul_action.tx_enabled) { - encode_pusch(&ul_action.phy_grant.ul, ul_action.payload_ptr, ul_action.current_tx_nb, - ul_action.softbuffer, ul_action.rv, ul_action.rnti, ul_mac_grant.is_from_rar); + encode_pusch(&ul_action.phy_grant.ul, ul_action.payload_ptr[0], ul_action.current_tx_nb, + &ul_action.softbuffers[0], ul_action.rv[0], ul_action.rnti, ul_mac_grant.is_from_rar); signal_ready = true; if (ul_action.expect_ack) { phy->set_pending_ack(tti + 8, ue_ul.pusch_cfg.grant.n_prb_tilde[0], ul_action.phy_grant.ul.ncs_dmrs); @@ -279,9 +285,11 @@ void phch_worker::work_imp() if (dl_action.decode_enabled && !dl_action.generate_ack_callback) { if (dl_mac_grant.rnti_type == SRSLTE_RNTI_PCH) { - phy->mac->pch_decoded_ok(dl_mac_grant.n_bytes); + phy->mac->pch_decoded_ok(dl_mac_grant.n_bytes[0]); } else { - phy->mac->tb_decoded(dl_ack, dl_mac_grant.rnti_type, dl_mac_grant.pid); + for (uint32_t tb = 0; tb < dl_mac_grant.phy_grant.dl.nof_tb; tb++) { + phy->mac->tb_decoded(dl_ack[tb], tb, dl_mac_grant.rnti_type, dl_mac_grant.pid); + } } } @@ -380,13 +388,16 @@ bool phch_worker::decode_pdcch_dl(srsue::mac_interface_phy::mac_grant_t* grant) } /* Fill MAC grant structure */ - grant->ndi = dci_unpacked.ndi; + grant->ndi[0] = dci_unpacked.ndi; + grant->ndi[1] = dci_unpacked.ndi_1; grant->pid = dci_unpacked.harq_process; - grant->n_bytes = grant->phy_grant.dl.mcs[0].tbs/8; - grant->tti = tti; - grant->rv = dci_unpacked.rv_idx; - grant->rnti = dl_rnti; - grant->rnti_type = type; + grant->n_bytes[0] = grant->phy_grant.dl.mcs[0].tbs / (uint32_t) 8; + grant->n_bytes[1] = grant->phy_grant.dl.mcs[1].tbs / (uint32_t) 8; + grant->tti = tti; + grant->rv[0] = dci_unpacked.rv_idx; + grant->rv[1] = dci_unpacked.rv_idx_1; + grant->rnti = dl_rnti; + grant->rnti_type = type; grant->last_tti = 0; last_dl_pdcch_ncce = srslte_ue_dl_get_ncce(&ue_dl); @@ -405,23 +416,27 @@ bool phch_worker::decode_pdcch_dl(srsue::mac_interface_phy::mac_grant_t* grant) } } -bool phch_worker::decode_pdsch(srslte_ra_dl_grant_t *grant, uint8_t *payload, +int phch_worker::decode_pdsch(srslte_ra_dl_grant_t *grant, uint8_t *payload, srslte_softbuffer_rx_t *softbuffer, int rv, - uint16_t rnti, uint32_t harq_pid) { - int _rv [SRSLTE_MAX_CODEWORDS] = {1}; + uint16_t rnti, uint32_t harq_pid, bool acks[SRSLTE_MAX_CODEWORDS]) { + int _rv [SRSLTE_MAX_TB] = {1}; + srslte_softbuffer_rx_t *softbuffers[SRSLTE_MAX_TB] = {NULL}; + _rv[0] = rv; + softbuffers[0] = softbuffer; - return decode_pdsch_multi(grant, &payload, softbuffer, _rv, rnti, harq_pid); + return decode_pdsch_multi(grant, &payload, softbuffers, _rv, rnti, harq_pid, acks); } -bool phch_worker::decode_pdsch_multi(srslte_ra_dl_grant_t *grant, uint8_t *payload[SRSLTE_MAX_CODEWORDS], - srslte_softbuffer_rx_t softbuffers[SRSLTE_MAX_CODEWORDS], +int phch_worker::decode_pdsch_multi(srslte_ra_dl_grant_t *grant, uint8_t *payload[SRSLTE_MAX_CODEWORDS], + srslte_softbuffer_rx_t *softbuffers[SRSLTE_MAX_CODEWORDS], int rv[SRSLTE_MAX_CODEWORDS], - uint16_t rnti, uint32_t harq_pid) { + uint16_t rnti, uint32_t harq_pid, bool acks[SRSLTE_MAX_CODEWORDS]) { char timestr[64]; bool valid_config = true; timestr[0]='\0'; srslte_mimo_type_t mimo_type = SRSLTE_MIMO_TYPE_SINGLE_ANTENNA; + int ret = SRSLTE_SUCCESS; for (uint32_t tb = 0; tb < grant->nof_tb; tb++) { if (rv[tb] < 0 || rv[tb] > 3) { @@ -497,38 +512,39 @@ bool phch_worker::decode_pdsch_multi(srslte_ra_dl_grant_t *grant, uint8_t *paylo struct timeval t[3]; gettimeofday(&t[1], NULL); #endif - - bool ack = srslte_pdsch_decode_multi(&ue_dl.pdsch, &ue_dl.pdsch_cfg, softbuffers, ue_dl.sf_symbols_m, - ue_dl.ce_m, noise_estimate, rnti, payload) == 0; + ret = srslte_pdsch_decode_multi(&ue_dl.pdsch, &ue_dl.pdsch_cfg, softbuffers, ue_dl.sf_symbols_m, + ue_dl.ce_m, noise_estimate, rnti, payload, acks); + if (ret) { + Error("Decoding PDSCH"); + } #ifdef LOG_EXECTIME gettimeofday(&t[2], NULL); get_time_interval(t); snprintf(timestr, 64, ", dec_time=%4d us", (int) t[0].tv_usec); #endif - - Info("PDSCH: l_crb=%2d, harq=%d, tbs=%d, mcs=%d, rv=%d, crc=%s, snr=%.1f dB, n_iter=%d%s\n", - grant->nof_prb, harq_pid, - grant->mcs[0].tbs/8, grant->mcs[0].idx, rv, - ack?"OK":"KO", - 10*log10(srslte_chest_dl_get_snr(&ue_dl.chest)), - srslte_pdsch_last_noi(&ue_dl.pdsch), - timestr); + + Info("PDSCH: l_crb=%2d, harq=%d, nof_tb=%d, tbs={%d, %d}, mcs={%d, %d}, rv={%d, %d}, crc={%s, %s}, snr=%.1f dB, n_iter=%d%s\n", + grant->nof_prb, harq_pid, + grant->nof_tb, grant->mcs[0].tbs / 8, grant->mcs[1].tbs / 8, grant->mcs[0].idx, grant->mcs[1].idx, + rv[0], rv[1], acks[0] ? "OK" : "KO", acks[1] ? "OK" : "KO", + 10 * log10(srslte_chest_dl_get_snr(&ue_dl.chest)), + srslte_pdsch_last_noi(&ue_dl.pdsch), + timestr); //printf("tti=%d, cfo=%f\n", tti, cfo*15000); //srslte_vec_save_file("pdsch", signal_buffer, sizeof(cf_t)*SRSLTE_SF_LEN_PRB(cell.nof_prb)); // Store metrics dl_metrics.mcs = grant->mcs[0].idx; - - return ack; } else { Warning("Received grant for TBS=0\n"); } } else { - Error("Error configuring DL grant\n"); + Error("Error configuring DL grant\n"); + ret = SRSLTE_ERROR; } } - return true; + return ret; } bool phch_worker::decode_phich(bool *ack) @@ -625,12 +641,12 @@ bool phch_worker::decode_pdcch_ul(mac_interface_phy::mac_grant_t* grant) } if (ret) { - grant->ndi = dci_unpacked.ndi; + grant->ndi[0] = dci_unpacked.ndi; grant->pid = 0; // This is computed by MAC from TTI - grant->n_bytes = grant->phy_grant.ul.mcs.tbs/8; + grant->n_bytes[0] = grant->phy_grant.ul.mcs.tbs / (uint32_t) 8; grant->tti = tti; grant->rnti = ul_rnti; - grant->rv = dci_unpacked.rv_idx; + grant->rv[0] = dci_unpacked.rv_idx; if (SRSLTE_VERBOSE_ISINFO()) { srslte_ra_pusch_fprint(stdout, &dci_unpacked, cell.nof_prb); } @@ -646,11 +662,22 @@ void phch_worker::reset_uci() bzero(&uci_data, sizeof(srslte_uci_data_t)); } -void phch_worker::set_uci_ack(bool ack) -{ - uci_data.uci_ack = ack?1:0; - uci_data.uci_ack_len = 1; -} + void phch_worker::set_uci_ack(bool ack[SRSLTE_MAX_CODEWORDS], uint32_t nof_tb) { + if (nof_tb > 0) { + uci_data.uci_ack = (uint8_t) ((ack[0]) ? 1 : 0); + } + + if (nof_tb > 1) { + uci_data.uci_ack_2 = (uint8_t) ((ack[1]) ? 1 : 0); + } + + if (nof_tb > 2) { + Error("Number of transport blocks is not supported"); + } + + uci_data.uci_ack_len = nof_tb; + + } void phch_worker::set_uci_sr() { diff --git a/srsue/test/phy/ue_itf_test_prach.cc b/srsue/test/phy/ue_itf_test_prach.cc index 30d3e9f3d..c2d78470d 100644 --- a/srsue/test/phy/ue_itf_test_prach.cc +++ b/srsue/test/phy/ue_itf_test_prach.cc @@ -158,8 +158,8 @@ int rar_unpack(uint8_t *buffer, rar_msg_t *msg) srsue::phy my_phy; bool bch_decoded = false; -uint8_t payload[10240]; -uint8_t payload_bits[10240]; +uint8_t payload[SRSLTE_MAX_TB][10240]; +uint8_t payload_bits[SRSLTE_MAX_TB][10240]; const uint8_t conn_request_msg[] = {0x20, 0x06, 0x1F, 0x5C, 0x2C, 0x04, 0xB2, 0xAC, 0xF6, 0x00, 0x00, 0x00}; enum mac_state {RA, RAR, CONNREQUEST, CONNSETUP} state = RA; @@ -168,7 +168,7 @@ uint32_t preamble_idx = 0; rar_msg_t rar_msg; uint32_t nof_rtx_connsetup = 0; -uint32_t rv_value[4] = {0, 2, 3, 1}; +uint32_t rv_value[4] = {0, 2, 3, 1}; void config_phy() { srsue::phy_interface_rrc::phy_cfg_t config; @@ -194,8 +194,8 @@ void config_phy() { my_phy.configure_prach_params(); } -srslte_softbuffer_rx_t softbuffer_rx; -srslte_softbuffer_tx_t softbuffer_tx; +srslte_softbuffer_rx_t softbuffers_rx[SRSLTE_MAX_TB]; +srslte_softbuffer_tx_t softbuffers_tx[SRSLTE_MAX_TB]; uint16_t temp_c_rnti; @@ -218,7 +218,7 @@ public: bool rar_rnti_set; - void pch_decoded_ok(uint32_t len) {} + void pch_decoded_ok(uint32_t len) {} void tti_clock(uint32_t tti) { @@ -233,19 +233,21 @@ public: void new_grant_ul(mac_grant_t grant, tb_action_ul_t *action) { printf("New grant UL\n"); - memcpy(payload, conn_request_msg, grant.n_bytes*sizeof(uint8_t)); + for (uint32_t tb = 0; tb < SRSLTE_MAX_TB; tb ++) { + memcpy(payload[tb], conn_request_msg, grant.n_bytes[tb]*sizeof(uint8_t)); + action->rv[tb] = rv_value[nof_rtx_connsetup%4]; + action->payload_ptr[tb] = payload[tb]; + if (action->rv[tb] == 0) { + srslte_softbuffer_tx_reset(&softbuffers_tx[tb]); + } + } action->current_tx_nb = nof_rtx_connsetup; - action->rv = rv_value[nof_rtx_connsetup%4]; - action->softbuffer = &softbuffer_tx; + action->softbuffers = softbuffers_tx; action->rnti = temp_c_rnti; action->expect_ack = (nof_rtx_connsetup < 5)?true:false; - action->payload_ptr = payload; memcpy(&action->phy_grant, &grant.phy_grant, sizeof(srslte_phy_grant_t)); memcpy(&last_grant, &grant, sizeof(mac_grant_t)); action->tx_enabled = true; - if (action->rv == 0) { - srslte_softbuffer_tx_reset(&softbuffer_tx); - } my_phy.pdcch_dl_search(SRSLTE_RNTI_USER, temp_c_rnti); } @@ -258,17 +260,20 @@ public: if (!ack) { nof_rtx_connsetup++; action->current_tx_nb = nof_rtx_connsetup; - action->rv = rv_value[nof_rtx_connsetup%4]; - action->softbuffer = &softbuffer_tx; + action->softbuffers = softbuffers_tx; action->rnti = temp_c_rnti; action->expect_ack = true; memcpy(&action->phy_grant, &last_grant.phy_grant, sizeof(srslte_phy_grant_t)); - action->tx_enabled = true; - if (action->rv == 0) { - srslte_softbuffer_tx_reset(&softbuffer_tx); + action->tx_enabled = true; + for (uint32_t tb = 0; tb < SRSLTE_MAX_TB; tb ++) { + action->rv[tb] = rv_value[nof_rtx_connsetup%4]; + if (action->rv[tb] == 0) { + srslte_softbuffer_tx_reset(&softbuffers_tx[tb]); + } + printf("Retransmission %d (TB %d), rv=%d\n", nof_rtx_connsetup, tb, action->rv[tb]); + } - printf("Retransmission %d, rv=%d\n", nof_rtx_connsetup, action->rv); - } + } } void new_grant_dl(mac_grant_t grant, tb_action_dl_t *action) { @@ -279,24 +284,25 @@ public: } else { action->generate_ack = true; } - action->payload_ptr = payload; - action->rnti = grant.rnti; + action->rnti = grant.rnti; memcpy(&action->phy_grant, &grant.phy_grant, sizeof(srslte_phy_grant_t)); memcpy(&last_grant, &grant, sizeof(mac_grant_t)); - action->rv = grant.rv; - action->softbuffer = &softbuffer_rx; - - if (action->rv == 0) { - srslte_softbuffer_rx_reset(&softbuffer_rx); + for (uint32_t tb = 0; tb < SRSLTE_MAX_TB; tb ++) { + action->softbuffers[tb] = &softbuffers_rx[tb]; + action->rv[tb] = grant.rv[tb]; + action->payload_ptr[tb] = payload[tb]; + if (action->rv[tb] == 0) { + srslte_softbuffer_rx_reset(&softbuffers_rx[tb]); + } } } - void tb_decoded(bool ack, srslte_rnti_type_t rnti_type, uint32_t harq_pid) { + void tb_decoded(bool ack, uint32_t tb_idx, srslte_rnti_type_t rnti_type, uint32_t harq_pid) { if (ack) { if (rnti_type == SRSLTE_RNTI_RAR) { my_phy.pdcch_dl_search_reset(); - srslte_bit_unpack_vector(payload, payload_bits, last_grant.n_bytes*8); - rar_unpack(payload_bits, &rar_msg); + srslte_bit_unpack_vector(payload[tb_idx], payload_bits[tb_idx], last_grant.n_bytes[tb_idx]*8); + rar_unpack(payload_bits[tb_idx], &rar_msg); if (rar_msg.RAPID == preamble_idx) { printf("Received RAR at TTI: %d\n", last_grant.tti); @@ -304,7 +310,7 @@ public: temp_c_rnti = rar_msg.temp_c_rnti; - if (last_grant.n_bytes*8 > 20 + SRSLTE_RAR_GRANT_LEN) { + if (last_grant.n_bytes[0]*8 > 20 + SRSLTE_RAR_GRANT_LEN) { uint8_t rar_grant[SRSLTE_RAR_GRANT_LEN]; memcpy(rar_grant, &payload_bits[20], sizeof(uint8_t)*SRSLTE_RAR_GRANT_LEN); my_phy.set_rar_grant(last_grant.tti, rar_grant); @@ -323,9 +329,11 @@ public: printf("BCH decoded\n"); bch_decoded = true; srslte_cell_t cell; - my_phy.get_current_cell(&cell); - srslte_softbuffer_rx_init(&softbuffer_rx, cell.nof_prb); - srslte_softbuffer_tx_init(&softbuffer_tx, cell.nof_prb); + my_phy.get_current_cell(&cell); + for (uint32_t tb = 0; tb < SRSLTE_MAX_TB; tb++) { + srslte_softbuffer_rx_init(&softbuffers_rx[tb], cell.nof_prb); + srslte_softbuffer_tx_init(&softbuffers_tx[tb], cell.nof_prb); + } } private: diff --git a/srsue/test/phy/ue_itf_test_sib1.cc b/srsue/test/phy/ue_itf_test_sib1.cc index 803c5ff11..be3cb18e8 100644 --- a/srsue/test/phy/ue_itf_test_sib1.cc +++ b/srsue/test/phy/ue_itf_test_sib1.cc @@ -87,8 +87,8 @@ bool bch_decoded = false; uint32_t total_pkts=0; uint32_t total_dci=0; uint32_t total_oks=0; -uint8_t payload[1024]; -srslte_softbuffer_rx_t softbuffer; +uint8_t payload[SRSLTE_MAX_TB][1024]; +srslte_softbuffer_rx_t softbuffers[SRSLTE_MAX_TB]; class rrc_dummy : public srsue::rrc_interface_phy { @@ -118,20 +118,23 @@ public: action->decode_enabled = true; action->default_ack = false; - action->generate_ack = false; - action->payload_ptr = payload; - memcpy(&action->phy_grant, &grant.phy_grant, sizeof(srslte_phy_grant_t)); - action->rv = ((uint32_t) ceilf((float)3*((my_phy.tti_to_SFN(grant.tti)/2)%4)/2))%4; - action->softbuffer = &softbuffer; - action->rnti = grant.rnti; - if (action->rv == 0) { - srslte_softbuffer_rx_reset(&softbuffer); + action->generate_ack = false; + for (uint32_t tb = 0; tb < SRSLTE_MAX_TB; tb++) { + action->payload_ptr[tb] = payload[tb]; + action->rv[tb] = ((uint32_t) ceilf((float) 3 * ((my_phy.tti_to_SFN(grant.tti) / 2) % 4) / 2)) % 4; + if (action->rv == 0) { + srslte_softbuffer_rx_reset(&softbuffers[tb]); + } + action->softbuffers[0] = &softbuffers[tb]; } + memcpy(&action->phy_grant, &grant.phy_grant, sizeof(srslte_phy_grant_t)); + + action->rnti = grant.rnti; } - void tb_decoded(bool ack, srslte_rnti_type_t rnti, uint32_t harq_pid) { + void tb_decoded(bool ack, uint32_t tb_idx, srslte_rnti_type_t rnti_type, uint32_t harq_pid) { if (ack) { total_oks++; } @@ -144,7 +147,9 @@ public: bch_decoded = true; srslte_cell_t cell; my_phy.get_current_cell(&cell); - srslte_softbuffer_rx_init(&softbuffer, cell.nof_prb); + for (uint32_t tb = 0; tb < SRSLTE_MAX_TB; tb++) { + srslte_softbuffer_rx_init(&softbuffers[tb], cell.nof_prb); + } } void tti_clock(uint32_t tti) {