int srslte_ue_dl_decode_rnti_rv(srslte_ue_dl_t *q, cf_t *input, uint8_t *data, uint32_t sf_idx, uint16_t rnti, uint32_t rvidx) { srslte_dci_msg_t dci_msg; srslte_ra_dl_dci_t dci_unpacked; srslte_ra_dl_grant_t grant; int ret = SRSLTE_ERROR; if ((ret = srslte_ue_dl_decode_fft_estimate(q, input, sf_idx, &q->cfi)) < 0) { return ret; } if (srslte_pdcch_extract_llr(&q->pdcch, q->sf_symbols, q->ce, 0, sf_idx, q->cfi)) { fprintf(stderr, "Error extracting LLRs\n"); return SRSLTE_ERROR; } int found_dci = srslte_ue_dl_find_dl_dci(q, &dci_msg, q->cfi, sf_idx, rnti); if (found_dci == 1) { if (srslte_dci_msg_to_dl_grant(&dci_msg, rnti, q->cell.nof_prb, &dci_unpacked, &grant)) { fprintf(stderr, "Error unpacking DCI\n"); return SRSLTE_ERROR; } ret = srslte_ue_dl_decode_rnti_rv_packet(q, &grant, data, q->cfi, sf_idx, rnti, rvidx); } if (found_dci == 1 && ret == SRSLTE_SUCCESS) { return q->pdsch_cfg.grant.mcs.tbs; } else { return 0; } }
int srslte_ue_dl_find_and_decode(srslte_ue_dl_t* q, srslte_dl_sf_cfg_t* sf, srslte_ue_dl_cfg_t* cfg, srslte_pdsch_cfg_t* pdsch_cfg, uint8_t* data[SRSLTE_MAX_CODEWORDS], bool acks[SRSLTE_MAX_CODEWORDS]) { int ret = SRSLTE_ERROR; srslte_dci_dl_t dci_dl; srslte_pmch_cfg_t pmch_cfg; srslte_pdsch_res_t pdsch_res[SRSLTE_MAX_CODEWORDS]; // Use default values for PDSCH decoder ZERO_OBJECT(pmch_cfg); uint32_t mi_set_len; if (q->cell.frame_type == SRSLTE_TDD && !sf->tdd_config.configured) { mi_set_len = 3; } else { mi_set_len = 1; } // Blind search PHICH mi value ZERO_OBJECT(dci_dl); ret = 0; for (uint32_t i = 0; i < mi_set_len && !ret; i++) { if (mi_set_len == 1) { srslte_ue_dl_set_mi_auto(q); } else { srslte_ue_dl_set_mi_manual(q, i); } if ((ret = srslte_ue_dl_decode_fft_estimate(q, sf, cfg)) < 0) { return ret; } ret = srslte_ue_dl_find_dl_dci(q, sf, cfg, pdsch_cfg->rnti, &dci_dl); } if (ret == 1) { // Logging char str[512]; srslte_dci_dl_info(&dci_dl, str, 512); INFO("PDCCH: %s, snr=%.1f dB\n", str, q->chest_res.snr_db); // Force known MBSFN grant if (sf->sf_type == SRSLTE_SF_MBSFN) { dci_dl.rnti = SRSLTE_MRNTI; dci_dl.alloc_type = SRSLTE_RA_ALLOC_TYPE0; dci_dl.type0_alloc.rbg_bitmask = 0xffffffff; dci_dl.tb[0].rv = 0; dci_dl.tb[0].mcs_idx = 2; dci_dl.format = SRSLTE_DCI_FORMAT1; } // Convert DCI message to DL grant if (srslte_ue_dl_dci_to_pdsch_grant(q, sf, cfg, &dci_dl, &pdsch_cfg->grant)) { ERROR("Error unpacking DCI\n"); return SRSLTE_ERROR; } // Calculate RV if not provided in the grant and reset softbuffer for (int i = 0; i < SRSLTE_MAX_CODEWORDS; i++) { if (pdsch_cfg->grant.tb[i].enabled) { if (pdsch_cfg->grant.tb[i].rv < 0) { uint32_t sfn = sf->tti / 10; uint32_t k = (sfn / 2) % 4; pdsch_cfg->grant.tb[i].rv = ((uint32_t)ceilf((float)1.5 * k)) % 4; } srslte_softbuffer_rx_reset_tbs(pdsch_cfg->softbuffers.rx[i], (uint32_t)pdsch_cfg->grant.tb[i].tbs); } } bool decode_enable = false; for (uint32_t tb = 0; tb < SRSLTE_MAX_CODEWORDS; tb++) { if (pdsch_cfg->grant.tb[tb].enabled) { decode_enable = true; pdsch_res[tb].payload = data[tb]; pdsch_res[tb].crc = false; } } if (decode_enable) { if (sf->sf_type == SRSLTE_SF_NORM) { if (srslte_ue_dl_decode_pdsch(q, sf, pdsch_cfg, pdsch_res)) { ERROR("ERROR: Decoding PDSCH\n"); ret = -1; } } else { pmch_cfg.pdsch_cfg = *pdsch_cfg; if (srslte_ue_dl_decode_pmch(q, sf, &pmch_cfg, pdsch_res)) { ERROR("Decoding PMCH\n"); ret = -1; } } } for (uint32_t tb = 0; tb < SRSLTE_MAX_CODEWORDS; tb++) { if (pdsch_cfg->grant.tb[tb].enabled) { acks[tb] = pdsch_res[tb].crc; } } } return ret; }