int srslte_ue_dl_decode_mbsfn(srslte_ue_dl_t * q, uint8_t *data, uint32_t tti) { srslte_ra_dl_grant_t grant; int ret = SRSLTE_ERROR; uint32_t cfi; uint32_t sf_idx = tti%10; if ((ret = srslte_ue_dl_decode_fft_estimate_mbsfn(q, sf_idx, &cfi, SRSLTE_SF_MBSFN)) < 0) { return ret; } float noise_estimate = srslte_chest_dl_get_noise_estimate(&q->chest); // Uncoment next line to do ZF by default in pdsch_ue example //float noise_estimate = 0; grant.sf_type = SRSLTE_SF_MBSFN; grant.mcs[0].idx = 2; grant.tb_en[0] = true; grant.tb_en[1] = false; grant.nof_prb = q->pmch.cell.nof_prb; srslte_dl_fill_ra_mcs(&grant.mcs[0], grant.nof_prb); srslte_softbuffer_rx_reset_tbs(q->softbuffers[0], (uint32_t) grant.mcs[0].tbs); for(int j = 0; j < 2; j++){ for(int f = 0; f < grant.nof_prb; f++){ grant.prb_idx[j][f] = true; } } grant.Qm[0] = srslte_mod_bits_x_symbol(grant.mcs[0].mod); // redundancy version is set to 0 for the PMCH if (srslte_ue_dl_cfg_grant(q, &grant, cfi, sf_idx, SRSLTE_PMCH_RV, SRSLTE_MIMO_TYPE_SINGLE_ANTENNA)) { return SRSLTE_ERROR; } if (q->pmch_cfg.grant.mcs[0].mod > 0 && q->pmch_cfg.grant.mcs[0].tbs >= 0) { ret = srslte_pmch_decode_multi(&q->pmch, &q->pmch_cfg, q->softbuffers[0], q->sf_symbols_m, q->ce_m, noise_estimate, q->current_mbsfn_area_id, data); if (ret == SRSLTE_ERROR) { q->pmch_pkt_errors++; } else if (ret == SRSLTE_ERROR_INVALID_INPUTS) { fprintf(stderr, "Error calling srslte_pmch_decode()\n"); } } q->pmch_pkts_total++; if (ret == SRSLTE_SUCCESS) { return q->pmch_cfg.grant.mcs[0].tbs; } else { return 0; } }
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 srslte_ue_dl_decode_rnti(srslte_ue_dl_t *q, uint8_t *data[SRSLTE_MAX_CODEWORDS], uint32_t tm, uint32_t tti, uint16_t rnti, bool acks[SRSLTE_MAX_CODEWORDS]) { srslte_mimo_type_t mimo_type; srslte_dci_msg_t dci_msg; srslte_ra_dl_dci_t dci_unpacked; srslte_ra_dl_grant_t grant; int ret = SRSLTE_ERROR; uint32_t cfi; uint32_t sf_idx = tti%10; if ((ret = srslte_ue_dl_decode_fft_estimate_mbsfn(q, sf_idx, &cfi, SRSLTE_SF_NORM)) < 0) { return ret; } float noise_estimate = srslte_chest_dl_get_noise_estimate(&q->chest); // Uncoment next line to do ZF by default in pdsch_ue example //float noise_estimate = 0; if (srslte_pdcch_extract_llr_multi(&q->pdcch, q->sf_symbols_m, q->ce_m, noise_estimate, sf_idx, cfi)) { fprintf(stderr, "Error extracting LLRs\n"); return SRSLTE_ERROR; } int found_dci = srslte_ue_dl_find_dl_dci(q, tm, cfi, sf_idx, rnti, &dci_msg); if (found_dci == 1) { if (srslte_dci_msg_to_dl_grant(&dci_msg, rnti, q->cell.nof_prb, q->cell.nof_ports, &dci_unpacked, &grant)) { fprintf(stderr, "Error unpacking DCI\n"); return SRSLTE_ERROR; } /* ===== These lines of code are supposed to be MAC functionality === */ int rvidx[SRSLTE_MAX_CODEWORDS] = {1}; if (dci_unpacked.rv_idx < 0) { uint32_t sfn = tti / 10; uint32_t k = (sfn / 2) % 4; for (int i = 0; i < SRSLTE_MAX_CODEWORDS; i++) { if (grant.tb_en[i]) { rvidx[i] = ((uint32_t) ceilf((float) 1.5 * k)) % 4; srslte_softbuffer_rx_reset_tbs(q->softbuffers[i], (uint32_t) grant.mcs[i].tbs); } } } else { for (int i = 0; i < SRSLTE_MAX_CODEWORDS; i++) { if (grant.tb_en[i]) { switch (i) { case 0: rvidx[i] = (uint32_t) dci_unpacked.rv_idx; break; case 1: rvidx[i] = (uint32_t) dci_unpacked.rv_idx_1; break; default: ERROR("Wrong number of transport blocks"); return SRSLTE_ERROR; } srslte_softbuffer_rx_reset_tbs(q->softbuffers[i], (uint32_t) grant.mcs[i].tbs); } } } switch(dci_msg.format) { case SRSLTE_DCI_FORMAT1: case SRSLTE_DCI_FORMAT1A: case SRSLTE_DCI_FORMAT1C: if (q->cell.nof_ports == 1) { mimo_type = SRSLTE_MIMO_TYPE_SINGLE_ANTENNA; } else { mimo_type = SRSLTE_MIMO_TYPE_TX_DIVERSITY; } break; case SRSLTE_DCI_FORMAT2: if (SRSLTE_RA_DL_GRANT_NOF_TB(&grant) == 1 && dci_unpacked.pinfo == 0) { mimo_type = SRSLTE_MIMO_TYPE_TX_DIVERSITY; } else { mimo_type = SRSLTE_MIMO_TYPE_SPATIAL_MULTIPLEX; } break; case SRSLTE_DCI_FORMAT2A: if (SRSLTE_RA_DL_GRANT_NOF_TB(&grant) == 1 && dci_unpacked.pinfo == 0) { mimo_type = SRSLTE_MIMO_TYPE_TX_DIVERSITY; } else { mimo_type = SRSLTE_MIMO_TYPE_CDD; } break; /* Not implemented formats */ case SRSLTE_DCI_FORMAT0: case SRSLTE_DCI_FORMAT1B: case SRSLTE_DCI_FORMAT1D: case SRSLTE_DCI_FORMAT2B: default: ERROR("Transmission mode not supported."); return SRSLTE_ERROR; } if (srslte_ue_dl_cfg_grant(q, &grant, cfi, sf_idx, rvidx, mimo_type)) { ERROR("Configuing PDSCH"); return SRSLTE_ERROR; } /* ===== End of MAC functionality ========== */ q->nof_detected++; if (q->pdsch_cfg.grant.mcs[0].mod > 0 && q->pdsch_cfg.grant.mcs[0].tbs >= 0) { ret = srslte_pdsch_decode(&q->pdsch, &q->pdsch_cfg, q->softbuffers, q->sf_symbols_m, q->ce_m, noise_estimate, rnti, data, acks); for (int tb = 0; tb < SRSLTE_MAX_TB; tb++) { if (grant.tb_en[tb]) { if (!acks[tb]) { q->pdsch_pkt_errors++; } q->pdsch_pkts_total++; } } if (ret == SRSLTE_ERROR) { } else if (ret == SRSLTE_ERROR_INVALID_INPUTS) { fprintf(stderr, "Error calling srslte_pdsch_decode()\n"); } /* If we are in TM4 (Closed-Loop MIMO), compute condition number */ } /* printf("Saving signal...\n"); srslte_vec_save_file("input", input, sizeof(cf_t)*SRSLTE_SF_LEN_PRB(q->cell.nof_prb)); srslte_ue_dl_save_signal(q, &q->softbuffer, sf_idx, rvidx, rnti, cfi); //exit(-1); */ } if (found_dci == 1 && ret == SRSLTE_SUCCESS) { return q->pdsch_cfg.grant.mcs[0].tbs; } else { return 0; } }