int srslte_ue_dl_decode_rnti_rv_packet(srslte_ue_dl_t *q, srslte_dci_msg_t *dci_msg, uint8_t *data, uint32_t cfi, uint32_t sf_idx, uint16_t rnti, uint32_t rvidx) { int ret = SRSLTE_ERROR; q->nof_detected++; /* Setup PDSCH configuration for this CFI, SFIDX and RVIDX */ if (srslte_ue_dl_cfg_grant(q, dci_msg, cfi, sf_idx, rnti, rvidx)) { return SRSLTE_ERROR; } if (q->pdsch_cfg.rv == 0) { srslte_softbuffer_rx_reset(&q->softbuffer); } #ifdef PDSCH_DO_ZF float noise_estimate = 0; #else float noise_estimate = srslte_chest_dl_get_noise_estimate(&q->chest); #endif if (q->pdsch_cfg.grant.mcs.mod > 0 && q->pdsch_cfg.grant.mcs.tbs >= 0) { ret = srslte_pdsch_decode_rnti(&q->pdsch, &q->pdsch_cfg, &q->softbuffer, q->sf_symbols, q->ce, noise_estimate, rnti, data); if (ret == SRSLTE_ERROR) { q->pkt_errors++; } else if (ret == SRSLTE_ERROR_INVALID_INPUTS) { fprintf(stderr, "Error calling srslte_pdsch_decode()\n"); } else if (ret == SRSLTE_SUCCESS) { if (SRSLTE_VERBOSE_ISDEBUG()) { INFO("Decoded Message: ", 0); srslte_vec_fprint_hex(stdout, data, q->pdsch_cfg.grant.mcs.tbs); } } q->pkts_total++; } return ret; }
int main(int argc, char **argv) { srslte_pbch_t pbch; uint8_t bch_payload_tx[SRSLTE_BCH_PAYLOAD_LEN], bch_payload_rx[SRSLTE_BCH_PAYLOAD_LEN]; int i, j; cf_t *ce[SRSLTE_MAX_PORTS]; int nof_re; cf_t *slot1_symbols[SRSLTE_MAX_PORTS]; uint32_t nof_rx_ports; parse_args(argc,argv); nof_re = SRSLTE_SLOT_LEN_RE(cell.nof_prb, SRSLTE_CP_NORM); /* init memory */ for (i=0;i<cell.nof_ports;i++) { ce[i] = malloc(sizeof(cf_t) * nof_re); if (!ce[i]) { perror("malloc"); exit(-1); } for (j=0;j<nof_re;j++) { ce[i][j] = 1; } slot1_symbols[i] = malloc(sizeof(cf_t) * nof_re); if (!slot1_symbols[i]) { perror("malloc"); exit(-1); } } if (srslte_pbch_init(&pbch, cell)) { fprintf(stderr, "Error creating PBCH object\n"); exit(-1); } srand(time(NULL)); for (i=0;i<SRSLTE_BCH_PAYLOAD_LEN;i++) { bch_payload_tx[i] = rand()%2; } srslte_pbch_encode(&pbch, bch_payload_tx, slot1_symbols, 0); /* combine outputs */ for (i=1;i<cell.nof_ports;i++) { for (j=0;j<nof_re;j++) { slot1_symbols[0][j] += slot1_symbols[i][j]; } } srslte_pbch_decode_reset(&pbch); if (1 != srslte_pbch_decode(&pbch, slot1_symbols[0], ce, 0, bch_payload_rx, &nof_rx_ports, NULL)) { printf("Error decoding\n"); exit(-1); } srslte_pbch_free(&pbch); for (i=0;i<cell.nof_ports;i++) { free(ce[i]); free(slot1_symbols[i]); } printf("Tx ports: %d - Rx ports: %d\n", cell.nof_ports, nof_rx_ports); printf("Tx payload: "); srslte_vec_fprint_hex(stdout, bch_payload_tx, SRSLTE_BCH_PAYLOAD_LEN); printf("Rx payload: "); srslte_vec_fprint_hex(stdout, bch_payload_rx, SRSLTE_BCH_PAYLOAD_LEN); if (nof_rx_ports == cell.nof_ports && !memcmp(bch_payload_rx, bch_payload_tx, sizeof(uint8_t) * SRSLTE_BCH_PAYLOAD_LEN)) { printf("OK\n"); exit(0); } else { printf("Error\n"); exit(-1); } }
/* 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[3] = {0, 0, 0}; 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_byte(&q->crc_tb, data, cb_segm->tbs); /* parity bits will be appended later */ parity[0] = (par&(0xff<<16))>>16; parity[1] = (par&(0xff<<8))>>8; parity[2] = par&0xff; if (SRSLTE_VERBOSE_ISDEBUG()) { DEBUG("DATA: ", 0); srslte_vec_fprint_byte(stdout, data, cb_segm->tbs/8); DEBUG("PARITY: ", 0); srslte_vec_fprint_byte(stdout, parity, 3); } } 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/8], &data[rp/8], (rlen - F) * sizeof(uint8_t)/8); } 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/8], &data[rp/8], (rlen - 24 - F) * sizeof(uint8_t)/8); memcpy(&q->cb_in[(rlen - 24)/8], parity, 3 * sizeof(uint8_t)); } /* Filler bits are treated like zeros for the CB CRC calculation */ for (int j = 0; j < F/8; j++) { q->cb_in[j] = 0; } /* Attach Codeblock CRC */ if (cb_segm->C > 1) { srslte_crc_attach_byte(&q->crc_cb, q->cb_in, rlen); } /* pack bits to temporal buffer for encoding */ srslte_bit_unpack_vector(q->cb_in, q->cb_temp, cb_len); /* Set the filler bits to <NULL> */ for (int j = 0; j < F; j++) { q->cb_temp[j] = SRSLTE_TX_NULL; } if (SRSLTE_VERBOSE_ISDEBUG()) { DEBUG("CB#%d: ", i); srslte_vec_fprint_hex(stdout, q->cb_temp, cb_len); } /* Turbo Encoding */ srslte_tcod_encode(&q->encoder, q->cb_temp, (uint8_t*) q->cb_out, cb_len); if (SRSLTE_VERBOSE_ISDEBUG()) { DEBUG("CB#%d encoded: ", i); srslte_vec_fprint_b(stdout, q->cb_out, 3*cb_len+12); } } /* 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; }
int main(int argc, char **argv) { uint8_t bch_payload[SRSLTE_BCH_PAYLOAD_LEN]; int n; uint32_t nof_tx_ports, sfn_offset; cf_t *ce_slot1[SRSLTE_MAX_PORTS]; if (argc < 3) { usage(argv[0]); exit(-1); } parse_args(argc,argv); if (base_init()) { fprintf(stderr, "Error initializing receiver\n"); exit(-1); } int frame_cnt = 0; int nof_decoded_mibs = 0; int nread = 0; do { nread = srslte_filesource_read(&fsrc, input_buffer, FLEN); if (nread > 0) { // process 1st subframe only srslte_ofdm_rx_sf(&fft, input_buffer, fft_buffer); /* Get channel estimates for each port */ srslte_chest_dl_estimate(&chest, fft_buffer, ce, 0); INFO("Decoding PBCH\n", 0); for (int i=0;i<SRSLTE_MAX_PORTS;i++) { ce_slot1[i] = &ce[i][SRSLTE_SLOT_LEN_RE(cell.nof_prb, cell.cp)]; } srslte_pbch_decode_reset(&pbch); n = srslte_pbch_decode(&pbch, &fft_buffer[SRSLTE_SLOT_LEN_RE(cell.nof_prb, cell.cp)], ce_slot1, srslte_chest_dl_get_noise_estimate(&chest), bch_payload, &nof_tx_ports, &sfn_offset); if (n == 1) { nof_decoded_mibs++; } else if (n < 0) { fprintf(stderr, "Error decoding PBCH\n"); exit(-1); } frame_cnt++; } else if (nread < 0) { fprintf(stderr, "Error reading from file\n"); exit(-1); } } while(nread > 0 && frame_cnt < nof_frames); base_free(); if (frame_cnt == 1) { if (n == 0) { printf("Could not decode PBCH\n"); exit(-1); } else { printf("MIB decoded OK. Nof ports: %d. SFN offset: %d Payload: ", nof_tx_ports, sfn_offset); srslte_vec_fprint_hex(stdout, bch_payload, SRSLTE_BCH_PAYLOAD_LEN); if (nof_tx_ports == 2 && sfn_offset == 0 && !memcmp(bch_payload, bch_payload_file, SRSLTE_BCH_PAYLOAD_LEN)) { printf("This is the signal.1.92M.dat file\n"); exit(0); } else { printf("This is an unknown file\n"); exit(-1); } } } else { printf("Decoded %d/%d MIBs\n", nof_decoded_mibs, frame_cnt); } }