void srslte_vec_fprint_hex(FILE *stream, uint8_t *x, uint32_t len) { uint32_t i, nbytes; uint8_t byte; nbytes = len/8; fprintf(stream, "[", len); for (i=0;i<nbytes;i++) { byte = (uint8_t) srslte_bit_pack(&x, 8); fprintf(stream, "%02x ", byte); } if (len%8) { byte = (uint8_t) srslte_bit_pack(&x, len%8); fprintf(stream, "%02x ", byte); } fprintf(stream, "];\n"); }
int srslte_uci_encode_cqi_pucch_from_table(srslte_uci_cqi_pucch_t *q, uint8_t *cqi_data, uint32_t cqi_len, uint8_t b_bits[SRSLTE_UCI_CQI_CODED_PUCCH_B]) { if (cqi_len <= SRSLTE_UCI_MAX_CQI_LEN_PUCCH) { bzero(&cqi_data[cqi_len], SRSLTE_UCI_MAX_CQI_LEN_PUCCH - cqi_len); uint8_t *ptr = cqi_data; uint32_t packed = srslte_bit_pack(&ptr, SRSLTE_UCI_MAX_CQI_LEN_PUCCH); memcpy(b_bits, q->cqi_table[packed], SRSLTE_UCI_CQI_CODED_PUCCH_B); return SRSLTE_SUCCESS; } else { return SRSLTE_ERROR_INVALID_INPUTS; } }
/* Encode UCI CQI/PMI for payloads equal or lower to 11 bits (Sec 5.2.2.6.4) */ int encode_cqi_short(srslte_uci_cqi_pusch_t *q, uint8_t *data, uint32_t nof_bits, uint8_t *q_bits, uint32_t Q) { if (nof_bits <= 11 && nof_bits > 0 && q != NULL && data != NULL && q_bits != NULL) { uint8_t *ptr = data; uint32_t w = srslte_bit_pack(&ptr, nof_bits); for (int i=0;i<Q;i++) { q_bits[i] = q->cqi_table[nof_bits-1][w*32+(i%32)]; } return SRSLTE_SUCCESS; } else { return SRSLTE_ERROR_INVALID_INPUTS; } }
/* Encode a transport block according to 36.212 5.3.2 * */ static int encode_tb(srslte_sch_t *q, srslte_softbuffer_tx_t *soft_buffer, srslte_cbsegm_t *cb_segm, uint32_t Qm, uint32_t rv, uint32_t nof_e_bits, uint8_t *data, uint8_t *e_bits) { uint8_t parity[24]; uint8_t *p_parity = parity; uint32_t par; uint32_t i; uint32_t cb_len, rp, wp, rlen, F, n_e; int ret = SRSLTE_ERROR_INVALID_INPUTS; if (q != NULL && e_bits != NULL && cb_segm != NULL && soft_buffer != NULL) { uint32_t Gp = nof_e_bits / Qm; uint32_t gamma = Gp; if (cb_segm->C > 0) { gamma = Gp%cb_segm->C; } if (data) { /* Compute transport block CRC */ par = srslte_crc_checksum(&q->crc_tb, data, cb_segm->tbs); /* parity bits will be appended later */ srslte_bit_pack(par, &p_parity, 24); if (SRSLTE_VERBOSE_ISDEBUG()) { DEBUG("DATA: ", 0); srslte_vec_fprint_b(stdout, data, cb_segm->tbs); DEBUG("PARITY: ", 0); srslte_vec_fprint_b(stdout, parity, 24); } } wp = 0; rp = 0; for (i = 0; i < cb_segm->C; i++) { /* Get read lengths */ if (i < cb_segm->C2) { cb_len = cb_segm->K2; } else { cb_len = cb_segm->K1; } if (cb_segm->C > 1) { rlen = cb_len - 24; } else { rlen = cb_len; } if (i == 0) { F = cb_segm->F; } else { F = 0; } if (i <= cb_segm->C - gamma - 1) { n_e = Qm * (Gp/cb_segm->C); } else { n_e = Qm * ((uint32_t) ceilf((float) Gp/cb_segm->C)); } INFO("CB#%d: cb_len: %d, rlen: %d, wp: %d, rp: %d, F: %d, E: %d\n", i, cb_len, rlen - F, wp, rp, F, n_e); if (data) { /* Copy data to another buffer, making space for the Codeblock CRC */ if (i < cb_segm->C - 1) { // Copy data memcpy(&q->cb_in[F], &data[rp], (rlen - F) * sizeof(uint8_t)); } else { INFO("Last CB, appending parity: %d from %d and 24 to %d\n", rlen - F - 24, rp, rlen - 24); /* Append Transport Block parity bits to the last CB */ memcpy(&q->cb_in[F], &data[rp], (rlen - 24 - F) * sizeof(uint8_t)); memcpy(&q->cb_in[rlen - 24], parity, 24 * sizeof(uint8_t)); } /* Filler bits are treated like zeros for the CB CRC calculation */ for (int j = 0; j < F; j++) { q->cb_in[j] = 0; } /* Attach Codeblock CRC */ if (cb_segm->C > 1) { srslte_crc_attach(&q->crc_cb, q->cb_in, rlen); } /* Set the filler bits to <NULL> */ for (int j = 0; j < F; j++) { q->cb_in[j] = SRSLTE_TX_NULL; } if (SRSLTE_VERBOSE_ISDEBUG()) { DEBUG("CB#%d: ", i); srslte_vec_fprint_b(stdout, q->cb_in, cb_len); } /* Turbo Encoding */ srslte_tcod_encode(&q->encoder, q->cb_in, (uint8_t*) q->cb_out, cb_len); } /* Rate matching */ if (srslte_rm_turbo_tx(soft_buffer->buffer_b[i], soft_buffer->buff_size, (uint8_t*) q->cb_out, 3 * cb_len + 12, &e_bits[wp], n_e, rv)) { fprintf(stderr, "Error in rate matching\n"); return SRSLTE_ERROR; } /* Set read/write pointers */ rp += (rlen - F); wp += n_e; } INFO("END CB#%d: wp: %d, rp: %d\n", i, wp, rp); ret = SRSLTE_SUCCESS; } return ret; }
int main(int argc, char **argv) { srslte_dci_msg_t msg; srslte_ra_dl_dci_t ra_dl; int len, rlen; int nof_prb; int nwords; int i; uint8_t *y; if (argc < 3) { usage(argv[0]); exit(-1); } nof_prb = atoi(argv[1]); len = atoi(argv[2]); nwords = (len - 1) / 32 + 1; if (argc < 3 + nwords) { usage(argv[0]); exit(-1); } y = msg.data; rlen = 0; uint32_t x; for (i = 0; i < nwords; i++) { x = strtoul(argv[i + 3], NULL, 16); if (len - rlen < 32) { srslte_bit_pack(x, &y, len - rlen); } else { srslte_bit_pack(x, &y, 32); } } printf("DCI message len %d:\n", len); for (i = 0; i < len; i++) { printf("%d, ", msg.data[i]); } printf("\n"); srslte_dci_msg_type_t dci_type; msg.nof_bits = len; if (srslte_dci_msg_get_type(&msg, &dci_type, nof_prb, SRSLTE_SIRNTI)) { fprintf(stderr, "Can't obtain DCI message type\n"); exit(-1); } printf("\n"); printf("Message type:"); srslte_dci_msg_type_fprint(stdout, dci_type); switch (dci_type.type) { case SRSLTE_DCI_MSG_TYPE_PDSCH_SCHED: bzero(&ra_dl, sizeof(srslte_ra_dl_dci_t)); srslte_dci_msg_unpack_pdsch(&msg, &ra_dl, nof_prb, false); srslte_ra_pdsch_fprint(stdout, &ra_dl, nof_prb); break; default: printf("Error expected PDSCH\n"); exit(-1); } printf("\n"); }