diff --git a/lib/include/srslte/phy/fec/softbuffer.h b/lib/include/srslte/phy/fec/softbuffer.h index a47cc7b96..3949134d8 100644 --- a/lib/include/srslte/phy/fec/softbuffer.h +++ b/lib/include/srslte/phy/fec/softbuffer.h @@ -42,6 +42,9 @@ typedef struct SRSLTE_API { uint32_t max_cb; int16_t **buffer_f; + uint8_t **data; + bool *cb_crc; + bool tb_crc; } srslte_softbuffer_rx_t; typedef struct SRSLTE_API { diff --git a/lib/src/phy/fec/softbuffer.c b/lib/src/phy/fec/softbuffer.c index 8efa937cb..9ed526825 100644 --- a/lib/src/phy/fec/softbuffer.c +++ b/lib/src/phy/fec/softbuffer.c @@ -47,32 +47,56 @@ int srslte_softbuffer_rx_init(srslte_softbuffer_rx_t *q, uint32_t nof_prb) { int ret = SRSLTE_ERROR_INVALID_INPUTS; if (q != NULL) { - ret = SRSLTE_ERROR; - bzero(q, sizeof(srslte_softbuffer_rx_t)); ret = srslte_ra_tbs_from_idx(26, nof_prb); if (ret != SRSLTE_ERROR) { q->max_cb = (uint32_t) ret / (SRSLTE_TCOD_MAX_LEN_CB - 24) + 1; + ret = SRSLTE_ERROR; q->buffer_f = srslte_vec_malloc(sizeof(int16_t*) * q->max_cb); if (!q->buffer_f) { perror("malloc"); - return SRSLTE_ERROR; + goto clean_exit; } + q->data = srslte_vec_malloc(sizeof(uint8_t*) * q->max_cb); + if (!q->data) { + perror("malloc"); + goto clean_exit; + } + + q->cb_crc = srslte_vec_malloc(sizeof(bool) * q->max_cb); + if (!q->cb_crc) { + perror("malloc"); + goto clean_exit; + } + bzero(q->cb_crc, sizeof(bool) * q->max_cb); + // FIXME: Use HARQ buffer limitation based on UE category for (uint32_t i=0;imax_cb;i++) { q->buffer_f[i] = srslte_vec_malloc(sizeof(int16_t) * SOFTBUFFER_SIZE); if (!q->buffer_f[i]) { perror("malloc"); - return SRSLTE_ERROR; + goto clean_exit; + } + + q->data[i] = srslte_vec_malloc(sizeof(uint8_t) * 6144/8); + if (!q->data[i]) { + perror("malloc"); + goto clean_exit; } } //srslte_softbuffer_rx_reset(q); ret = SRSLTE_SUCCESS; } } + + clean_exit: + if (ret != SRSLTE_SUCCESS) { + srslte_softbuffer_rx_free(q); + } + return ret; } @@ -86,6 +110,17 @@ void srslte_softbuffer_rx_free(srslte_softbuffer_rx_t *q) { } free(q->buffer_f); } + if (q->data) { + for (uint32_t i=0;imax_cb;i++) { + if (q->data[i]) { + free(q->data[i]); + } + } + free(q->data); + } + if (q->cb_crc) { + free(q->cb_crc); + } bzero(q, sizeof(srslte_softbuffer_rx_t)); } } @@ -110,6 +145,9 @@ void srslte_softbuffer_rx_reset_cb(srslte_softbuffer_rx_t *q, uint32_t nof_cb) { } } } + if (q->cb_crc) { + bzero(q->cb_crc, sizeof(bool) * q->max_cb); + } } diff --git a/lib/src/phy/phch/sch.c b/lib/src/phy/phch/sch.c index e6b7d49b9..b679e00f9 100644 --- a/lib/src/phy/phch/sch.c +++ b/lib/src/phy/phch/sch.c @@ -336,14 +336,17 @@ bool decode_tb_cb(srslte_sch_t *q, decoder_input[i] = NULL; } + uint32_t remaining_cb = 0; for (int i=0;icb_crc[i]; + if (softbuffer->cb_crc[i] == false) { + remaining_cb ++; + } } srslte_tdec_reset(&q->decoder, cb_len); - uint32_t remaining_cb = nof_cb; - q->nof_iterations = 0; while(remaining_cb>0) { @@ -401,7 +404,8 @@ bool decode_tb_cb(srslte_sch_t *q, // CRC is OK if (!srslte_crc_checksum_byte(crc_ptr, q->cb_in, len_crc)) { - memcpy(&data[(cb_idx[i]*rlen)/8], q->cb_in, rlen/8 * sizeof(uint8_t)); + memcpy(softbuffer->data[cb_idx[i]], q->cb_in, rlen/8 * sizeof(uint8_t)); + softbuffer->cb_crc[cb_idx[i]] = true; q->nof_iterations += srslte_tdec_get_nof_iterations_cb(&q->decoder, i); @@ -418,15 +422,28 @@ bool decode_tb_cb(srslte_sch_t *q, cb_idx[i], remaining_cb, i, first_cb, nof_cb); q->nof_iterations += q->max_iterations; - q->nof_iterations /= (nof_cb-remaining_cb+1); - return false; + srslte_tdec_reset_cb(&q->decoder, i); + remaining_cb--; + decoder_input[i] = NULL; + cb_idx[i] = 0; } } } } + softbuffer->tb_crc = true; + for (int i = 0; i < nof_cb && softbuffer->tb_crc; i++) { + /* If one CB failed return false */ + softbuffer->tb_crc = softbuffer->cb_crc[i]; + } + if (softbuffer->tb_crc) { + for (int i = 0; i < nof_cb; i++) { + memcpy(&data[i * rlen / 8], softbuffer->data[i], rlen/8 * sizeof(uint8_t)); + } + } + q->nof_iterations /= nof_cb; - return true; + return softbuffer->tb_crc; } /**