int srslte_ue_dl_decode_estimate(srslte_ue_dl_t *q, uint32_t sf_idx, uint32_t *cfi) { float cfi_corr; if (q && cfi && sf_idx < SRSLTE_NSUBFRAMES_X_FRAME) { /* Get channel estimates for each port */ srslte_chest_dl_estimate(&q->chest, q->sf_symbols, q->ce, sf_idx); /* First decode PCFICH and obtain CFI */ if (srslte_pcfich_decode(&q->pcfich, q->sf_symbols, q->ce, srslte_chest_dl_get_noise_estimate(&q->chest), sf_idx, cfi, &cfi_corr)<0) { fprintf(stderr, "Error decoding PCFICH\n"); return SRSLTE_ERROR; } INFO("Decoded CFI=%d with correlation %.2f, sf_idx=%d\n", *cfi, cfi_corr, sf_idx); if (srslte_regs_set_cfi(&q->regs, *cfi)) { fprintf(stderr, "Error setting CFI\n"); return SRSLTE_ERROR; } return SRSLTE_SUCCESS; } else { return SRSLTE_ERROR_INVALID_INPUTS; } }
static int estimate_pdcch_pcfich(srslte_ue_dl_t* q, srslte_dl_sf_cfg_t* sf, srslte_ue_dl_cfg_t* cfg) { if (q) { float cfi_corr = 0; set_mi_value(q, sf, cfg); /* Get channel estimates for each port */ srslte_chest_dl_estimate_cfg(&q->chest, sf, &cfg->chest_cfg, q->sf_symbols, &q->chest_res); /* First decode PCFICH and obtain CFI */ if (srslte_pcfich_decode(&q->pcfich, sf, &q->chest_res, q->sf_symbols, &cfi_corr) < 0) { ERROR("Error decoding PCFICH\n"); return SRSLTE_ERROR; } if (q->cell.frame_type == SRSLTE_TDD && ((sf->tti % 10) == 1 || (sf->tti % 10) == 6) && sf->cfi == 3) { sf->cfi = 2; INFO("Received CFI=3 in subframe 1 or 6 and TDD. Setting to 2\n"); } if (srslte_pdcch_extract_llr(&q->pdcch, sf, &q->chest_res, q->sf_symbols)) { ERROR("Extracting PDCCH LLR\n"); return false; } INFO("Decoded CFI=%d with correlation %.2f, sf_idx=%d\n", sf->cfi, cfi_corr, sf->tti % 10); return SRSLTE_SUCCESS; } else { return SRSLTE_ERROR_INVALID_INPUTS; } }
int main(int argc, char **argv) { uint32_t cfi; float cfi_corr; int n; if (argc < 3) { usage(argv[0]); exit(-1); } parse_args(argc,argv); if (base_init()) { fprintf(stderr, "Error initializing receiver\n"); exit(-1); } n = srslte_filesource_read(&fsrc, input_buffer, flen); srslte_ofdm_rx_sf(&fft, input_buffer, fft_buffer); if (fmatlab) { fprintf(fmatlab, "infft="); srslte_vec_fprint_c(fmatlab, input_buffer, flen); fprintf(fmatlab, ";\n"); fprintf(fmatlab, "outfft="); srslte_vec_sc_prod_cfc(fft_buffer, 1000.0, fft_buffer, SRSLTE_CP_NSYMB(cell.cp) * cell.nof_prb * SRSLTE_NRE); srslte_vec_fprint_c(fmatlab, fft_buffer, SRSLTE_CP_NSYMB(cell.cp) * cell.nof_prb * SRSLTE_NRE); fprintf(fmatlab, ";\n"); srslte_vec_sc_prod_cfc(fft_buffer, 0.001, fft_buffer, SRSLTE_CP_NSYMB(cell.cp) * cell.nof_prb * SRSLTE_NRE); } /* Get channel estimates for each port */ srslte_chest_dl_estimate(&chest, fft_buffer, ce, 0); INFO("Decoding PCFICH\n", 0); n = srslte_pcfich_decode(&pcfich, fft_buffer, ce, srslte_chest_dl_get_noise_estimate(&chest), 0, &cfi, &cfi_corr); printf("cfi: %d, distance: %f\n", cfi, cfi_corr); base_free(); if (n < 0) { fprintf(stderr, "Error decoding PCFICH\n"); exit(-1); } else if (n == 0) { printf("Could not decode PCFICH\n"); exit(-1); } else { if (cfi_corr > 2.8 && cfi == 1) { exit(0); } else { exit(-1); } } }
int main(int argc, char **argv) { srslte_pcfich_t pcfich; srslte_regs_t regs; int i, j; cf_t *ce[SRSLTE_MAX_PORTS]; int nof_re; cf_t *slot_symbols[SRSLTE_MAX_PORTS]; uint32_t cfi, cfi_rx, nsf; int cid, max_cid; float corr_res; parse_args(argc,argv); nof_re = SRSLTE_CP_NORM_NSYMB * cell.nof_prb * SRSLTE_NRE; /* init memory */ for (i=0;i<SRSLTE_MAX_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; } slot_symbols[i] = malloc(sizeof(cf_t) * nof_re); if (!slot_symbols[i]) { perror("malloc"); exit(-1); } } if (cell.id == 1000) { cid = 0; max_cid = 503; } else { cid = cell.id; max_cid = cell.id; } while(cid <= max_cid) { cell.id = cid; printf("Testing CellID=%d...\n", cid); if (srslte_regs_init(®s, cell)) { fprintf(stderr, "Error initiating regs\n"); exit(-1); } if (srslte_pcfich_init(&pcfich, ®s, cell)) { fprintf(stderr, "Error creating PBCH object\n"); exit(-1); } for (nsf=0;nsf<10;nsf++) { for (cfi=1;cfi<4;cfi++) { srslte_pcfich_encode(&pcfich, cfi, slot_symbols, nsf); /* combine outputs */ for (i=1;i<cell.nof_ports;i++) { for (j=0;j<nof_re;j++) { slot_symbols[0][j] += slot_symbols[i][j]; } } if (srslte_pcfich_decode(&pcfich, slot_symbols[0], ce, 0, nsf, &cfi_rx, &corr_res)<0) { exit(-1); } INFO("cfi_tx: %d, cfi_rx: %d, ns: %d, distance: %f\n", cfi, cfi_rx, nsf, corr_res); } } srslte_pcfich_free(&pcfich); srslte_regs_free(®s); cid++; } for (i=0;i<SRSLTE_MAX_PORTS;i++) { free(ce[i]); free(slot_symbols[i]); } printf("OK\n"); exit(0); }
/* the gateway function */ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { int i; srslte_cell_t cell; srslte_pcfich_t pcfich; srslte_chest_dl_t chest; srslte_ofdm_t fft; srslte_regs_t regs; uint32_t sf_idx; cf_t *input_fft, *input_signal; if (nrhs != NOF_INPUTS) { help(); return; } if (mexutils_read_cell(ENBCFG, &cell)) { help(); return; } if (mexutils_read_uint32_struct(ENBCFG, "NSubframe", &sf_idx)) { help(); return; } if (srslte_chest_dl_init(&chest, cell)) { mexErrMsgTxt("Error initializing equalizer\n"); return; } if (srslte_ofdm_rx_init(&fft, cell.cp, cell.nof_prb)) { mexErrMsgTxt("Error initializing FFT\n"); return; } if (srslte_regs_init(®s, cell)) { mexErrMsgTxt("Error initiating regs\n"); return; } if (srslte_pcfich_init(&pcfich, ®s, cell)) { mexErrMsgTxt("Error creating PBCH object\n"); return; } /** Allocate input buffers */ if (mexutils_read_cf(INPUT, &input_signal) < 0) { mexErrMsgTxt("Error reading input signal\n"); return; } input_fft = srslte_vec_malloc(SRSLTE_SF_LEN_RE(cell.nof_prb, cell.cp) * sizeof(cf_t)); // Set Channel estimates to 1.0 (ignore fading) cf_t *ce[SRSLTE_MAX_PORTS]; for (i=0;i<cell.nof_ports;i++) { ce[i] = srslte_vec_malloc(SRSLTE_SF_LEN_RE(cell.nof_prb, cell.cp) * sizeof(cf_t)); } srslte_ofdm_rx_sf(&fft, input_signal, input_fft); if (nrhs > NOF_INPUTS) { cf_t *cearray; mexutils_read_cf(prhs[NOF_INPUTS], &cearray); for (i=0;i<cell.nof_ports;i++) { for (int j=0;j<SRSLTE_SF_LEN_RE(cell.nof_prb, cell.cp);j++) { ce[i][j] = *cearray; cearray++; } } } else { srslte_chest_dl_estimate(&chest, input_fft, ce, sf_idx); } float noise_power; if (nrhs > NOF_INPUTS + 1) { noise_power = mxGetScalar(prhs[NOF_INPUTS+1]); } else { noise_power = srslte_chest_dl_get_noise_estimate(&chest); } uint32_t cfi; float corr_res; int n = srslte_pcfich_decode(&pcfich, input_fft, ce, noise_power, sf_idx, &cfi, &corr_res); if (nlhs >= 1) { if (n < 0) { plhs[0] = mxCreateDoubleScalar(-1); } else { plhs[0] = mxCreateDoubleScalar(cfi); } } if (nlhs >= 2) { mexutils_write_cf(pcfich.d, &plhs[1], 16, 1); } if (nlhs >= 3) { mexutils_write_cf(pcfich.symbols[0], &plhs[2], 16, 1); } srslte_chest_dl_free(&chest); srslte_ofdm_rx_free(&fft); srslte_pcfich_free(&pcfich); srslte_regs_free(®s); for (i=0;i<cell.nof_ports;i++) { free(ce[i]); } free(input_signal); free(input_fft); return; }