SCH does not terminate all codeblocks if one fail. Also, SCH does not decode blocks with CRC=OK

master
Xavier Arteaga 7 years ago
parent 8cabfa82cf
commit 2a69211f32

@ -42,6 +42,9 @@
typedef struct SRSLTE_API { typedef struct SRSLTE_API {
uint32_t max_cb; uint32_t max_cb;
int16_t **buffer_f; int16_t **buffer_f;
uint8_t **data;
bool *cb_crc;
bool tb_crc;
} srslte_softbuffer_rx_t; } srslte_softbuffer_rx_t;
typedef struct SRSLTE_API { typedef struct SRSLTE_API {

@ -47,32 +47,56 @@ int srslte_softbuffer_rx_init(srslte_softbuffer_rx_t *q, uint32_t nof_prb) {
int ret = SRSLTE_ERROR_INVALID_INPUTS; int ret = SRSLTE_ERROR_INVALID_INPUTS;
if (q != NULL) { if (q != NULL) {
ret = SRSLTE_ERROR;
bzero(q, sizeof(srslte_softbuffer_rx_t)); bzero(q, sizeof(srslte_softbuffer_rx_t));
ret = srslte_ra_tbs_from_idx(26, nof_prb); ret = srslte_ra_tbs_from_idx(26, nof_prb);
if (ret != SRSLTE_ERROR) { if (ret != SRSLTE_ERROR) {
q->max_cb = (uint32_t) ret / (SRSLTE_TCOD_MAX_LEN_CB - 24) + 1; 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); q->buffer_f = srslte_vec_malloc(sizeof(int16_t*) * q->max_cb);
if (!q->buffer_f) { if (!q->buffer_f) {
perror("malloc"); 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 // FIXME: Use HARQ buffer limitation based on UE category
for (uint32_t i=0;i<q->max_cb;i++) { for (uint32_t i=0;i<q->max_cb;i++) {
q->buffer_f[i] = srslte_vec_malloc(sizeof(int16_t) * SOFTBUFFER_SIZE); q->buffer_f[i] = srslte_vec_malloc(sizeof(int16_t) * SOFTBUFFER_SIZE);
if (!q->buffer_f[i]) { if (!q->buffer_f[i]) {
perror("malloc"); 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); //srslte_softbuffer_rx_reset(q);
ret = SRSLTE_SUCCESS; ret = SRSLTE_SUCCESS;
} }
} }
clean_exit:
if (ret != SRSLTE_SUCCESS) {
srslte_softbuffer_rx_free(q);
}
return ret; return ret;
} }
@ -86,6 +110,17 @@ void srslte_softbuffer_rx_free(srslte_softbuffer_rx_t *q) {
} }
free(q->buffer_f); free(q->buffer_f);
} }
if (q->data) {
for (uint32_t i=0;i<q->max_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)); 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);
}
} }

@ -336,14 +336,17 @@ bool decode_tb_cb(srslte_sch_t *q,
decoder_input[i] = NULL; decoder_input[i] = NULL;
} }
uint32_t remaining_cb = 0;
for (int i=0;i<nof_cb;i++) { for (int i=0;i<nof_cb;i++) {
cb_map[i] = false; /* Do not process blocks with CRC Ok */
cb_map[i] = softbuffer->cb_crc[i];
if (softbuffer->cb_crc[i] == false) {
remaining_cb ++;
}
} }
srslte_tdec_reset(&q->decoder, cb_len); srslte_tdec_reset(&q->decoder, cb_len);
uint32_t remaining_cb = nof_cb;
q->nof_iterations = 0; q->nof_iterations = 0;
while(remaining_cb>0) { while(remaining_cb>0) {
@ -401,7 +404,8 @@ bool decode_tb_cb(srslte_sch_t *q,
// CRC is OK // CRC is OK
if (!srslte_crc_checksum_byte(crc_ptr, q->cb_in, len_crc)) { 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); 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); cb_idx[i], remaining_cb, i, first_cb, nof_cb);
q->nof_iterations += q->max_iterations; q->nof_iterations += q->max_iterations;
q->nof_iterations /= (nof_cb-remaining_cb+1); srslte_tdec_reset_cb(&q->decoder, i);
return false; 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; q->nof_iterations /= nof_cb;
return true; return softbuffer->tb_crc;
} }
/** /**

Loading…
Cancel
Save