void srslte_ue_dl_free(srslte_ue_dl_t *q) { if (q) { for (int port = 0; port < SRSLTE_MAX_PORTS; port++) { srslte_ofdm_rx_free(&q->fft[port]); } srslte_ofdm_rx_free(&q->fft_mbsfn); srslte_chest_dl_free(&q->chest); srslte_regs_free(&q->regs); srslte_pcfich_free(&q->pcfich); srslte_phich_free(&q->phich); srslte_pdcch_free(&q->pdcch); srslte_pdsch_free(&q->pdsch); srslte_pmch_free(&q->pmch); srslte_cfo_free(&q->sfo_correct); for (int i = 0; i < SRSLTE_MAX_TB; i++) { srslte_softbuffer_rx_free(q->softbuffers[i]); if (q->softbuffers[i]) { free(q->softbuffers[i]); } } for (int j = 0; j < SRSLTE_MAX_PORTS; j++) { if (q->sf_symbols_m[j]) { free(q->sf_symbols_m[j]); } for (uint32_t i=0;i<SRSLTE_MAX_PORTS;i++) { if (q->ce_m[i][j]) { free(q->ce_m[i][j]); } } } bzero(q, sizeof(srslte_ue_dl_t)); } }
void srslte_ue_dl_free(srslte_ue_dl_t* q) { if (q) { for (int port = 0; port < SRSLTE_MAX_PORTS; port++) { srslte_ofdm_rx_free(&q->fft[port]); } srslte_ofdm_rx_free(&q->fft_mbsfn); srslte_chest_dl_free(&q->chest); srslte_chest_dl_res_free(&q->chest_res); for (int i = 0; i < MI_NOF_REGS; i++) { srslte_regs_free(&q->regs[i]); } srslte_pcfich_free(&q->pcfich); srslte_phich_free(&q->phich); srslte_pdcch_free(&q->pdcch); srslte_pdsch_free(&q->pdsch); srslte_pmch_free(&q->pmch); for (int j = 0; j < SRSLTE_MAX_PORTS; j++) { if (q->sf_symbols[j]) { free(q->sf_symbols[j]); } } bzero(q, sizeof(srslte_ue_dl_t)); } }
void base_free() { int i; srslte_filesource_free(&fsrc); free(input_buffer); free(fft_buffer); srslte_filesource_free(&fsrc); for (i=0;i<cell.nof_ports;i++) { free(ce[i]); } srslte_chest_dl_free(&chest); srslte_ofdm_rx_free(&fft); srslte_pbch_free(&pbch); }
void srslte_ue_mib_free(srslte_ue_mib_t * q) { if (q->sf_symbols) { free(q->sf_symbols); } for (int i=0;i<SRSLTE_MAX_PORTS;i++) { if (q->ce[i]) { free(q->ce[i]); } } srslte_sync_free(&q->sfind); srslte_chest_dl_free(&q->chest); srslte_pbch_free(&q->pbch); srslte_ofdm_rx_free(&q->fft); bzero(q, sizeof(srslte_ue_mib_t)); }
void base_free() { int i; srslte_filesource_free(&fsrc); free(input_buffer); free(fft_buffer); srslte_filesource_free(&fsrc); for (i=0;i<SRSLTE_MAX_PORTS;i++) { free(ce[i]); } srslte_chest_dl_free(&chest); srslte_ofdm_rx_free(&fft); srslte_pdcch_free(&pdcch); srslte_regs_free(®s); }
void srslte_ue_dl_free(srslte_ue_dl_t *q) { if (q) { srslte_ofdm_rx_free(&q->fft); srslte_chest_dl_free(&q->chest); srslte_regs_free(&q->regs); srslte_pcfich_free(&q->pcfich); srslte_phich_free(&q->phich); srslte_pdcch_free(&q->pdcch); srslte_pdsch_free(&q->pdsch); srslte_softbuffer_rx_free(&q->softbuffer); if (q->sf_symbols) { free(q->sf_symbols); } for (uint32_t i=0;i<q->cell.nof_ports;i++) { if (q->ce[i]) { free(q->ce[i]); } } bzero(q, sizeof(srslte_ue_dl_t)); } }
/* the gateway function */ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { int i; srslte_cell_t cell; srslte_ofdm_t ofdm_rx; srslte_pdsch_t pdsch; srslte_chest_dl_t chest; cf_t *input_fft; srslte_pdsch_cfg_t cfg; srslte_softbuffer_rx_t softbuffer; uint32_t rnti32; uint32_t cfi; if (nrhs < NOF_INPUTS) { help(); return; } srslte_verbose = SRSLTE_VERBOSE_DEBUG; bzero(&cfg, sizeof(srslte_pdsch_cfg_t)); if (mexutils_read_cell(ENBCFG, &cell)) { help(); return; } if (mexutils_read_uint32_struct(PDSCHCFG, "RNTI", &rnti32)) { mexErrMsgTxt("Field RNTI not found in pdsch config\n"); return; } if (mexutils_read_uint32_struct(ENBCFG, "CFI", &cfi)) { help(); return; } if (mexutils_read_uint32_struct(ENBCFG, "NSubframe", &cfg.sf_idx)) { help(); return; } if (srslte_ofdm_rx_init(&ofdm_rx, cell.cp, cell.nof_prb)) { fprintf(stderr, "Error initializing FFT\n"); return; } if (srslte_pdsch_init(&pdsch, cell)) { mexErrMsgTxt("Error initiating PDSCH\n"); return; } srslte_pdsch_set_rnti(&pdsch, (uint16_t) (rnti32 & 0xffff)); if (srslte_softbuffer_rx_init(&softbuffer, cell.nof_prb)) { mexErrMsgTxt("Error initiating soft buffer\n"); return; } if (srslte_chest_dl_init(&chest, cell)) { mexErrMsgTxt("Error initializing equalizer\n"); return; } srslte_ra_dl_grant_t grant; grant.mcs.tbs = mxGetScalar(TBS); if (grant.mcs.tbs == 0) { mexErrMsgTxt("Error trblklen is zero\n"); return; } if (srslte_cbsegm(&cfg.cb_segm, grant.mcs.tbs)) { mexErrMsgTxt("Error computing CB segmentation\n"); return; } if (mexutils_read_uint32_struct(PDSCHCFG, "RV", &cfg.rv)) { mexErrMsgTxt("Field RV not found in pdsch config\n"); return; } uint32_t max_iterations = 5; mexutils_read_uint32_struct(PDSCHCFG, "NTurboDecIts", &max_iterations); char *mod_str = mexutils_get_char_struct(PDSCHCFG, "Modulation"); if (!strcmp(mod_str, "QPSK")) { grant.mcs.mod = SRSLTE_MOD_QPSK; } else if (!strcmp(mod_str, "16QAM")) { grant.mcs.mod = SRSLTE_MOD_16QAM; } else if (!strcmp(mod_str, "64QAM")) { grant.mcs.mod = SRSLTE_MOD_64QAM; } else { mexErrMsgTxt("Unknown modulation\n"); return; } mxFree(mod_str); mxArray *p; p = mxGetField(PDSCHCFG, 0, "PRBSet"); if (!p) { mexErrMsgTxt("Error field PRBSet not found\n"); return; } float *prbset_f; uint64_t *prbset; if (mxGetClassID(p) == mxDOUBLE_CLASS) { grant.nof_prb = mexutils_read_f(p, &prbset_f); prbset = malloc(sizeof(uint64_t)*grant.nof_prb); for (i=0;i<grant.nof_prb;i++) { prbset[i] = (uint64_t) prbset_f[i]; } } else { grant.nof_prb = mexutils_read_uint64(p, &prbset); } for (i=0;i<cell.nof_prb;i++) { grant.prb_idx[0][i] = false; for (int j=0;j<grant.nof_prb && !grant.prb_idx[0][i];j++) { if ((int) prbset[j] == i) { grant.prb_idx[0][i] = true; } } grant.prb_idx[1][i] = grant.prb_idx[0][i]; } free(prbset); /* Configure rest of pdsch_cfg parameters */ grant.Qm = srslte_mod_bits_x_symbol(grant.mcs.mod); if (srslte_pdsch_cfg(&cfg, cell, &grant, cfi, cfg.sf_idx, cfg.rv)) { fprintf(stderr, "Error configuring PDSCH\n"); exit(-1); } /** Allocate input buffers */ int nof_retx=1; if (mexutils_isCell(INPUT)) { nof_retx = mexutils_getLength(INPUT); } 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)); } uint8_t *data_bytes = srslte_vec_malloc(sizeof(uint8_t) * grant.mcs.tbs/8); if (!data_bytes) { return; } srslte_sch_set_max_noi(&pdsch.dl_sch, max_iterations); input_fft = NULL; int r=-1; for (int rvIdx=0;rvIdx<nof_retx && r != 0;rvIdx++) { mxArray *tmp = (mxArray*) INPUT; if (mexutils_isCell(INPUT)) { tmp = mexutils_getCellArray(INPUT, rvIdx); if (nof_retx > 1) { cfg.rv = rv_seq[rvIdx%4]; } } // Read input signal cf_t *input_signal = NULL; int insignal_len = mexutils_read_cf(tmp, &input_signal); if (insignal_len < 0) { mexErrMsgTxt("Error reading input signal\n"); return; } if (insignal_len == SRSLTE_SF_LEN_RE(cell.nof_prb, cell.cp)) { input_fft = input_signal; } else { input_fft = srslte_vec_malloc(SRSLTE_SF_LEN_RE(cell.nof_prb, cell.cp) * sizeof(cf_t)); srslte_ofdm_rx_sf(&ofdm_rx, input_signal, input_fft); free(input_signal); } if (nrhs > NOF_INPUTS) { cf_t *cearray = NULL; mexutils_read_cf(prhs[NOF_INPUTS], &cearray); cf_t *cearray_ptr = 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_ptr; cearray_ptr++; } } if (cearray) free(cearray); } else { srslte_chest_dl_estimate(&chest, input_fft, ce, cfg.sf_idx); } float noise_power; if (nrhs > NOF_INPUTS + 1) { noise_power = mxGetScalar(prhs[NOF_INPUTS+1]); } else if (nrhs > NOF_INPUTS) { noise_power = 0; } else { noise_power = srslte_chest_dl_get_noise_estimate(&chest); } r = srslte_pdsch_decode(&pdsch, &cfg, &softbuffer, input_fft, ce, noise_power, data_bytes); } uint8_t *data = malloc(grant.mcs.tbs); srslte_bit_unpack_vector(data_bytes, data, grant.mcs.tbs); if (nlhs >= 1) { plhs[0] = mxCreateLogicalScalar(r == 0); } if (nlhs >= 2) { mexutils_write_uint8(data, &plhs[1], grant.mcs.tbs, 1); } if (nlhs >= 3) { mexutils_write_cf(pdsch.symbols[0], &plhs[2], cfg.nbits.nof_re, 1); } if (nlhs >= 4) { mexutils_write_cf(pdsch.d, &plhs[3], cfg.nbits.nof_re, 1); } if (nlhs >= 5) { mexutils_write_s(pdsch.e, &plhs[4], cfg.nbits.nof_bits, 1); } srslte_softbuffer_rx_free(&softbuffer); srslte_chest_dl_free(&chest); srslte_pdsch_free(&pdsch); srslte_ofdm_rx_free(&ofdm_rx); for (i=0;i<cell.nof_ports;i++) { free(ce[i]); } free(data_bytes); free(data); if (input_fft) { free(input_fft); } return; }
/* the gateway function */ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { int i; srslte_cell_t cell; srslte_chest_dl_t chest; srslte_precoding_t cheq; cf_t *input_signal = NULL, *output_signal[SRSLTE_MAX_LAYERS]; cf_t *output_signal2 = NULL; cf_t *ce[SRSLTE_MAX_PORTS]; double *outr0=NULL, *outi0=NULL; double *outr1=NULL, *outi1=NULL; double *outr2=NULL, *outi2=NULL; if (!mxIsDouble(CELLID) && mxGetN(CELLID) != 1 && !mxIsDouble(PORTS) && mxGetN(PORTS) != 1 && mxGetM(CELLID) != 1) { help(); return; } cell.id = (uint32_t) *((double*) mxGetPr(CELLID)); cell.nof_prb = mxGetM(INPUT)/SRSLTE_NRE; cell.nof_ports = (uint32_t) *((double*) mxGetPr(PORTS)); if ((mxGetN(INPUT)%14) == 0) { cell.cp = SRSLTE_CP_NORM; } else if ((mxGetN(INPUT)%12)!=0) { cell.cp = SRSLTE_CP_EXT; } else { mexErrMsgTxt("Invalid number of symbols\n"); help(); return; } if (srslte_chest_dl_init(&chest, cell)) { mexErrMsgTxt("Error initiating channel estimator\n"); return; } int nsubframes; if (cell.cp == SRSLTE_CP_NORM) { nsubframes = mxGetN(INPUT)/14; } else { nsubframes = mxGetN(INPUT)/12; } uint32_t sf_idx=0; if (nsubframes == 1) { if (nrhs != NOF_INPUTS+1) { mexErrMsgTxt("Received 1 subframe. Need to provide subframe index.\n"); help(); return; } sf_idx = (uint32_t) *((double*) mxGetPr(SFIDX)); } if (nrhs > 5) { uint32_t filter_len = 0; float *filter; double *f; filter_len = mxGetNumberOfElements(FREQ_FILTER); filter = malloc(sizeof(float) * filter_len); f = (double*) mxGetPr(FREQ_FILTER); for (i=0;i<filter_len;i++) { filter[i] = (float) f[i]; } srslte_chest_dl_set_filter_freq(&chest, filter, filter_len); filter_len = mxGetNumberOfElements(TIME_FILTER); filter = malloc(sizeof(float) * filter_len); f = (double*) mxGetPr(TIME_FILTER); for (i=0;i<filter_len;i++) { filter[i] = (float) f[i]; } srslte_chest_dl_set_filter_time(&chest, filter, filter_len); } double *inr=(double *)mxGetPr(INPUT); double *ini=(double *)mxGetPi(INPUT); /** Allocate input buffers */ int nof_re = 2*SRSLTE_CP_NSYMB(cell.cp)*cell.nof_prb*SRSLTE_NRE; for (i=0;i<SRSLTE_MAX_PORTS;i++) { ce[i] = srslte_vec_malloc(nof_re * sizeof(cf_t)); } input_signal = srslte_vec_malloc(nof_re * sizeof(cf_t)); for (i=0;i<SRSLTE_MAX_PORTS;i++) { output_signal[i] = srslte_vec_malloc(nof_re * sizeof(cf_t)); } output_signal2 = srslte_vec_malloc(nof_re * sizeof(cf_t)); srslte_precoding_init(&cheq, nof_re); /* Create output values */ if (nlhs >= 1) { plhs[0] = mxCreateDoubleMatrix(nof_re * nsubframes, cell.nof_ports, mxCOMPLEX); outr0 = mxGetPr(plhs[0]); outi0 = mxGetPi(plhs[0]); } if (nlhs >= 2) { plhs[1] = mxCreateDoubleMatrix(SRSLTE_REFSIGNAL_MAX_NUM_SF(cell.nof_prb)*nsubframes, cell.nof_ports, mxCOMPLEX); outr1 = mxGetPr(plhs[1]); outi1 = mxGetPi(plhs[1]); } if (nlhs >= 3) { plhs[2] = mxCreateDoubleMatrix(nof_re * nsubframes, 1, mxCOMPLEX); outr2 = mxGetPr(plhs[2]); outi2 = mxGetPi(plhs[2]); } for (int sf=0;sf<nsubframes;sf++) { /* Convert input to C complex type */ for (i=0;i<nof_re;i++) { __real__ input_signal[i] = (float) *inr; if (ini) { __imag__ input_signal[i] = (float) *ini; } inr++; ini++; } if (nsubframes != 1) { sf_idx = sf%10; } if (srslte_chest_dl_estimate(&chest, input_signal, ce, sf_idx)) { mexErrMsgTxt("Error running channel estimator\n"); return; } if (cell.nof_ports == 1) { srslte_predecoding_single(input_signal, ce[0], output_signal2, nof_re, srslte_chest_dl_get_noise_estimate(&chest)); } else { srslte_predecoding_diversity(&cheq, input_signal, ce, output_signal, cell.nof_ports, nof_re, srslte_chest_dl_get_noise_estimate(&chest)); srslte_layerdemap_diversity(output_signal, output_signal2, cell.nof_ports, nof_re/cell.nof_ports); } if (nlhs >= 1) { for (int j=0;j<cell.nof_ports;j++) { for (i=0;i<nof_re;i++) { *outr0 = (double) crealf(ce[j][i]); if (outi0) { *outi0 = (double) cimagf(ce[j][i]); } outr0++; outi0++; } } } if (nlhs >= 2) { for (int j=0;j<cell.nof_ports;j++) { for (i=0;i<SRSLTE_REFSIGNAL_NUM_SF(cell.nof_prb,j);i++) { *outr1 = (double) crealf(chest.pilot_estimates_average[j][i]); if (outi1) { *outi1 = (double) cimagf(chest.pilot_estimates_average[j][i]); } outr1++; outi1++; } } } if (nlhs >= 3) { for (i=0;i<nof_re;i++) { *outr2 = (double) crealf(output_signal2[i]); if (outi2) { *outi2 = (double) cimagf(output_signal2[i]); } outr2++; outi2++; } } } if (nlhs >= 4) { plhs[3] = mxCreateDoubleScalar(srslte_chest_dl_get_noise_estimate(&chest)); } if (nlhs >= 5) { plhs[4] = mxCreateDoubleScalar(srslte_chest_dl_get_rsrp(&chest)); } srslte_chest_dl_free(&chest); srslte_precoding_free(&cheq); return; }
/* the gateway function */ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { int i; srslte_cell_t cell; srslte_pdsch_t pdsch; srslte_chest_dl_t chest; srslte_ofdm_t fft; cf_t *input_fft, *input_signal; int nof_re; srslte_pdsch_cfg_t cfg; srslte_softbuffer_rx_t softbuffer; uint32_t rnti32; uint32_t cfi; if (nrhs < NOF_INPUTS) { help(); return; } bzero(&cfg, sizeof(srslte_pdsch_cfg_t)); if (mexutils_read_cell(ENBCFG, &cell)) { help(); return; } if (mexutils_read_uint32_struct(PDSCHCFG, "RNTI", &rnti32)) { mexErrMsgTxt("Field RNTI not found in pdsch config\n"); return; } if (mexutils_read_uint32_struct(ENBCFG, "CFI", &cfi)) { help(); return; } if (mexutils_read_uint32_struct(ENBCFG, "NSubframe", &cfg.sf_idx)) { help(); return; } if (srslte_pdsch_init(&pdsch, cell)) { mexErrMsgTxt("Error initiating PDSCH\n"); return; } srslte_pdsch_set_rnti(&pdsch, (uint16_t) (rnti32 & 0xffff)); if (srslte_softbuffer_rx_init(&softbuffer, cell)) { mexErrMsgTxt("Error initiating soft buffer\n"); 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; } nof_re = 2 * SRSLTE_CP_NORM_NSYMB * cell.nof_prb * SRSLTE_NRE; cfg.grant.mcs.tbs = mxGetScalar(TBS); if (cfg.grant.mcs.tbs == 0) { mexErrMsgTxt("Error trblklen is zero\n"); return; } if (srslte_cbsegm(&cfg.cb_segm, cfg.grant.mcs.tbs)) { mexErrMsgTxt("Error computing CB segmentation\n"); return; } if (mexutils_read_uint32_struct(PDSCHCFG, "RV", &cfg.rv)) { mexErrMsgTxt("Field RV not found in pdsch config\n"); return; } char *mod_str = mexutils_get_char_struct(PDSCHCFG, "Modulation"); if (!strcmp(mod_str, "QPSK")) { cfg.grant.mcs.mod = SRSLTE_MOD_QPSK; } else if (!strcmp(mod_str, "16QAM")) { cfg.grant.mcs.mod = SRSLTE_MOD_16QAM; } else if (!strcmp(mod_str, "64QAM")) { cfg.grant.mcs.mod = SRSLTE_MOD_64QAM; } else { mexErrMsgTxt("Unknown modulation\n"); return; } mxFree(mod_str); float *prbset; mxArray *p; p = mxGetField(PDSCHCFG, 0, "PRBSet"); if (!p) { mexErrMsgTxt("Error field PRBSet not found\n"); return; } // Only localized PRB supported cfg.grant.nof_prb = mexutils_read_f(p, &prbset); for (i=0;i<cell.nof_prb;i++) { cfg.grant.prb_idx[0][i] = false; for (int j=0;j<cfg.grant.nof_prb && !cfg.grant.prb_idx[0][i];j++) { if ((int) prbset[j] == i) { cfg.grant.prb_idx[0][i] = true; } } } memcpy(&cfg.grant.prb_idx[1], &cfg.grant.prb_idx[0], SRSLTE_MAX_PRB*sizeof(bool)); free(prbset); srslte_dl_dci_to_grant_nof_re(&cfg.grant, cell, cfg.sf_idx, cell.nof_prb<10?(cfi+1):cfi); // Fill rest of grant structure cfg.grant.lstart = cell.nof_prb<10?(cfi+1):cfi; cfg.grant.nof_symb = 2*SRSLTE_CP_NSYMB(cell.cp)-cfg.grant.lstart; cfg.grant.Qm = srslte_mod_bits_x_symbol(cfg.grant.mcs.mod); cfg.grant.nof_bits = cfg.grant.nof_re * cfg.grant.Qm; /** 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)); 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 = NULL; nof_re = mexutils_read_cf(prhs[NOF_INPUTS], &cearray); cf_t *cearray_ptr = cearray; for (i=0;i<cell.nof_ports;i++) { for (int j=0;j<nof_re/cell.nof_ports;j++) { ce[i][j] = *cearray; cearray++; } } if (cearray_ptr) free(cearray_ptr); } else { srslte_chest_dl_estimate(&chest, input_fft, ce, cfg.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); } uint8_t *data = malloc(sizeof(uint8_t) * cfg.grant.mcs.tbs); if (!data) { return; } int r = srslte_pdsch_decode(&pdsch, &cfg, &softbuffer, input_fft, ce, noise_power, data); if (nlhs >= 1) { plhs[0] = mxCreateLogicalScalar(r == 0); } if (nlhs >= 2) { mexutils_write_uint8(data, &plhs[1], cfg.grant.mcs.tbs, 1); } if (nlhs >= 3) { mexutils_write_cf(pdsch.symbols[0], &plhs[2], cfg.grant.nof_re, 1); } if (nlhs >= 4) { mexutils_write_cf(pdsch.d, &plhs[3], cfg.grant.nof_re, 1); } if (nlhs >= 5) { mexutils_write_f(pdsch.e, &plhs[4], cfg.grant.nof_bits, 1); } srslte_chest_dl_free(&chest); srslte_ofdm_rx_free(&fft); srslte_pdsch_free(&pdsch); for (i=0;i<cell.nof_ports;i++) { free(ce[i]); } free(data); free(input_signal); free(input_fft); return; }
/* the gateway function */ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { int i; srslte_cell_t cell; srslte_phich_t phich; srslte_chest_dl_t chest; srslte_ofdm_t ofdm_rx; 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(&ofdm_rx, 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_phich_init(&phich, ®s, cell)) { mexErrMsgTxt("Error creating PHICH object\n"); return; } // Read input signal input_signal = NULL; int insignal_len = mexutils_read_cf(INPUT, &input_signal); if (insignal_len < 0) { mexErrMsgTxt("Error reading input signal\n"); return; } if (insignal_len == SRSLTE_SF_LEN_RE(cell.nof_prb, cell.cp)) { input_fft = input_signal; } else { input_fft = srslte_vec_malloc(SRSLTE_SF_LEN_RE(cell.nof_prb, cell.cp) * sizeof(cf_t)); srslte_ofdm_rx_sf(&ofdm_rx, input_signal, input_fft); free(input_signal); } 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)); } if (nrhs > NOF_INPUTS) { cf_t *cearray = NULL; mexutils_read_cf(prhs[NOF_INPUTS], &cearray); cf_t *cearray_ptr = 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_ptr; cearray_ptr++; } } if (cearray) { free(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 if (nrhs > NOF_INPUTS) { noise_power = 0; } else { noise_power = srslte_chest_dl_get_noise_estimate(&chest); } // Read hires values float *hires = NULL; int nhires = mexutils_read_f(HIRES, &hires); if (nhires != 2) { mexErrMsgTxt("Expecting 2 values for hires parameter\n"); return; } uint32_t ngroup = (uint32_t) hires[0]; uint32_t nseq = (uint32_t) hires[1]; uint8_t ack; float corr_res; int n = srslte_phich_decode(&phich, input_fft, ce, noise_power, ngroup, nseq, sf_idx, &ack, &corr_res); if (nlhs >= 1) { if (n < 0) { plhs[0] = mxCreateDoubleScalar(-1); } else { plhs[0] = mxCreateDoubleScalar(ack); } } if (nlhs >= 2) { mexutils_write_cf(phich.z, &plhs[1], 1, SRSLTE_PHICH_NBITS); } srslte_chest_dl_free(&chest); srslte_ofdm_rx_free(&ofdm_rx); srslte_phich_free(&phich); srslte_regs_free(®s); for (i=0;i<cell.nof_ports;i++) { free(ce[i]); } free(input_fft); return; }
/* 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; }