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; for (i = 0; i < SRSLTE_MAX_CODEWORDS; i++) { srslte_softbuffer_tx_free(softbuffers[i]); if (softbuffers[i]) { free(softbuffers[i]); } } srslte_pdsch_free(&pdsch); srslte_pdcch_free(&pdcch); srslte_regs_free(®s); srslte_pbch_free(&pbch); if(mbsfn_area_id > -1){ srslte_pmch_free(&pmch); } srslte_ofdm_tx_free(&ifft_mbsfn); for (i = 0; i < cell.nof_ports; i++) { srslte_ofdm_tx_free(&ifft[i]); } for (i = 0; i < SRSLTE_MAX_CODEWORDS; i++) { if (data[i]) { free(data[i]); } } for (i = 0; i < SRSLTE_MAX_PORTS; i++) { if (sf_buffer[i]) { free(sf_buffer[i]); } if (output_buffer[i]) { free(output_buffer[i]); } } if (output_file_name) { if (!null_file_sink) { srslte_filesink_free(&fsink); } } else { #ifndef DISABLE_RF srslte_rf_close(&rf); #endif } if (net_port > 0) { srslte_netsource_free(&net_source); sem_close(&net_sem); } }
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)); } }
void srslte_enb_dl_free(srslte_enb_dl_t *q) { if (q) { for (int i = 0; i < SRSLTE_MAX_PORTS; i++) { srslte_ofdm_tx_free(&q->ifft[i]); } srslte_ofdm_tx_free(&q->ifft_mbsfn); srslte_regs_free(&q->regs); srslte_pbch_free(&q->pbch); 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_refsignal_free(&q->csr_signal); srslte_refsignal_free(&q->mbsfnr_signal); for (int i=0;i<SRSLTE_MAX_PORTS;i++) { if (q->sf_symbols[i]) { free(q->sf_symbols[i]); } } bzero(q, sizeof(srslte_enb_dl_t)); } }
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); }
/** * Initializes REGs structure. * Sets all REG indices and initializes PCFICH, PHICH and PDCCH REGs * Returns 0 if OK, -1 on error */ int srslte_regs_init(srslte_regs_t *h, srslte_cell_t cell) { int ret = SRSLTE_ERROR_INVALID_INPUTS; uint32_t i, k; uint32_t j[4], jmax, prb; uint32_t n[4], vo; uint32_t max_ctrl_symbols; if (h != NULL && srslte_cell_isvalid(&cell)) { bzero(h, sizeof(srslte_regs_t)); ret = SRSLTE_ERROR; max_ctrl_symbols = cell.nof_prb<10?4:3; vo = cell.id % 3; h->cell = cell; h->max_ctrl_symbols = max_ctrl_symbols; h->cfi_initiated = false; h->phich_res = cell.phich_resources; h->phich_len = cell.phich_length; h->nof_regs = 0; for (i = 0; i < max_ctrl_symbols; i++) { n[i] = regs_num_x_symbol(i, h->cell.nof_ports, h->cell.cp); if (n[i] == -1) { goto clean_and_exit; } h->nof_regs += h->cell.nof_prb * n[i]; } INFO("Indexing %d REGs. CellId: %d, %d PRB, CP: %s\n", h->nof_regs, h->cell.id, h->cell.nof_prb, SRSLTE_CP_ISNORM(h->cell.cp)?"Normal":"Extended"); h->regs = malloc(sizeof(srslte_regs_reg_t) * h->nof_regs); if (!h->regs) { perror("malloc"); goto clean_and_exit; } /* Sort REGs according to PDCCH mapping, beggining from the lowest l index then k */ bzero(j, sizeof(int) * 4); k = i = prb = jmax = 0; while (k < h->nof_regs) { if (n[i] == 3 || (n[i] == 2 && jmax != 1)) { if (regs_reg_init(&h->regs[k], i, j[i], prb * SRSLTE_NRE, n[i], vo)) { fprintf(stderr, "Error initializing REGs\n"); goto clean_and_exit; } /*DEBUG("Available REG #%3d: l=%d, prb=%d, nreg=%d (k0=%d)\n", k, i, prb, j[i], h->regs[k].k0); */ j[i]++; k++; } i++; if (i == max_ctrl_symbols) { i = 0; jmax++; } if (jmax == 3) { prb++; bzero(j, sizeof(int) * 4); jmax = 0; } } if (regs_pcfich_init(h)) { fprintf(stderr, "Error initializing PCFICH REGs\n"); goto clean_and_exit; } if (regs_phich_init(h)) { fprintf(stderr, "Error initializing PHICH REGs\n"); goto clean_and_exit; } if (regs_pdcch_init(h)) { fprintf(stderr, "Error initializing PDCCH REGs\n"); goto clean_and_exit; } ret = SRSLTE_SUCCESS; } clean_and_exit: if (ret != SRSLTE_SUCCESS) { srslte_regs_free(h); } return ret; }
int srslte_enb_dl_set_cell(srslte_enb_dl_t *q, srslte_cell_t cell) { int ret = SRSLTE_ERROR_INVALID_INPUTS; if (q != NULL && srslte_cell_isvalid(&cell)) { if (q->cell.id != cell.id || q->cell.nof_prb == 0) { if (q->cell.nof_prb != 0) { srslte_regs_free(&q->regs); } q->cell = cell; if (srslte_regs_init(&q->regs, q->cell)) { ERROR("Error resizing REGs\n"); return SRSLTE_ERROR; } for (int i = 0; i < q->cell.nof_ports; i++) { if (srslte_ofdm_tx_set_prb(&q->ifft[i], q->cell.cp, q->cell.nof_prb)) { ERROR("Error re-planning iFFT (%d)\n", i); return SRSLTE_ERROR; } } if (srslte_ofdm_tx_set_prb(&q->ifft_mbsfn, SRSLTE_CP_EXT, q->cell.nof_prb)) { ERROR("Error re-planning ifft_mbsfn\n"); return SRSLTE_ERROR; } srslte_ofdm_set_non_mbsfn_region(&q->ifft_mbsfn, 2); if (srslte_pbch_set_cell(&q->pbch, q->cell)) { ERROR("Error creating PBCH object\n"); return SRSLTE_ERROR; } if (srslte_pcfich_set_cell(&q->pcfich, &q->regs, q->cell)) { ERROR("Error creating PCFICH object\n"); return SRSLTE_ERROR; } if (srslte_phich_set_cell(&q->phich, &q->regs, q->cell)) { ERROR("Error creating PHICH object\n"); return SRSLTE_ERROR; } if (srslte_pdcch_set_cell(&q->pdcch, &q->regs, q->cell)) { ERROR("Error creating PDCCH object\n"); return SRSLTE_ERROR; } if (srslte_pdsch_set_cell(&q->pdsch, q->cell)) { ERROR("Error creating PDSCH object\n"); return SRSLTE_ERROR; } if (srslte_pmch_set_cell(&q->pmch, q->cell)) { ERROR("Error creating PMCH object\n"); return SRSLTE_ERROR; } if (srslte_refsignal_cs_set_cell(&q->csr_signal, q->cell)) { ERROR("Error initializing CSR signal (%d)\n", ret); return SRSLTE_ERROR; } int mbsfn_area_id = 1; if (srslte_refsignal_mbsfn_set_cell(&q->mbsfnr_signal, q->cell, mbsfn_area_id)) { ERROR("Error initializing MBSFNR signal (%d)\n", ret); return SRSLTE_ERROR; } /* Generate PSS/SSS signals */ srslte_pss_generate(q->pss_signal, cell.id%3); srslte_sss_generate(q->sss_signal0, q->sss_signal5, cell.id); } ret = SRSLTE_SUCCESS; } else { ERROR("Invalid cell properties: Id=%d, Ports=%d, PRBs=%d\n", cell.id, cell.nof_ports, cell.nof_prb); } return ret; }
int main(int argc, char** argv) { srslte_chest_dl_res_t chest_dl_res; srslte_pdcch_t pdcch_tx, pdcch_rx; testcase_dci_t testcases[10]; srslte_regs_t regs; int i; int nof_re; cf_t *slot_symbols[SRSLTE_MAX_PORTS]; int nof_dcis; bzero(&testcases, sizeof(testcase_dci_t)*10); int ret = -1; parse_args(argc, argv); nof_re = SRSLTE_CP_NORM_NSYMB * cell.nof_prb * SRSLTE_NRE; if (test_dci_payload_size()) { exit(-1); } /* init memory */ srslte_chest_dl_res_init(&chest_dl_res, cell.nof_prb); srslte_chest_dl_res_set_identity(&chest_dl_res); for (i = 0; i < SRSLTE_MAX_PORTS; i++) { slot_symbols[i] = malloc(sizeof(cf_t) * nof_re); if (!slot_symbols[i]) { perror("malloc"); exit(-1); } bzero(slot_symbols[i], sizeof(cf_t) * nof_re); } if (srslte_regs_init(®s, cell)) { ERROR("Error initiating regs\n"); exit(-1); } if (srslte_pdcch_init_enb(&pdcch_tx, cell.nof_prb)) { ERROR("Error creating PDCCH object\n"); exit(-1); } if (srslte_pdcch_set_cell(&pdcch_tx, ®s, cell)) { ERROR("Error setting cell in PDCCH object\n"); exit(-1); } if (srslte_pdcch_init_ue(&pdcch_rx, cell.nof_prb, nof_rx_ant)) { ERROR("Error creating PDCCH object\n"); exit(-1); } if (srslte_pdcch_set_cell(&pdcch_rx, ®s, cell)) { ERROR("Error setting cell in PDCCH object\n"); exit(-1); } /* Resource allocate init */ nof_dcis = 0; srslte_dci_dl_t dci; ZERO_OBJECT(dci); dci.pid = 5; dci.tb[0].mcs_idx = 5; dci.tb[0].ndi = 0; dci.tb[0].rv = 1; dci.alloc_type = SRSLTE_RA_ALLOC_TYPE0; dci.type0_alloc.rbg_bitmask = 0x5; dci.cif_present = dci_cfg.cif_enabled; if (dci_cfg.cif_enabled) { dci.cif = (uint32_t)(random() & 0x7); } /* Format 1 Test case */ if (cell.nof_ports == 1) { testcases[nof_dcis].dci_format = SRSLTE_DCI_FORMAT1; if (dci_cfg.cif_enabled) { dci.cif = (uint32_t)(random() & 0x7); } testcases[nof_dcis].ra_dl_tx = dci; nof_dcis++; /* Format 1 Test case */ dci.tb[0].mcs_idx = 15; testcases[nof_dcis].dci_format = SRSLTE_DCI_FORMAT1; if (dci_cfg.cif_enabled) { dci.cif = (uint32_t)(random() & 0x7); } testcases[nof_dcis].ra_dl_tx = dci; nof_dcis++; } /* Tx Diversity Test case */ if (cell.nof_ports > 1) { dci.tb[1].mcs_idx = 13; dci.tb[1].rv = 3; dci.tb[1].ndi = true; testcases[nof_dcis].dci_format = SRSLTE_DCI_FORMAT2A; if (dci_cfg.cif_enabled) { dci.cif = (uint32_t)(random() & 0x7); } testcases[nof_dcis].ra_dl_tx = dci; nof_dcis++; } /* CDD Spatial Multiplexing Test case */ if (cell.nof_ports > 1) { dci.tb[1].mcs_idx = 28; dci.tb[1].rv = 1; dci.tb[1].ndi = false; testcases[nof_dcis].dci_format = SRSLTE_DCI_FORMAT2; if (dci_cfg.cif_enabled) { dci.cif = (uint32_t)(random() & 0x7); } testcases[nof_dcis].ra_dl_tx = dci; nof_dcis++; } srslte_dci_cfg_t dci_cfg; ZERO_OBJECT(dci_cfg); srslte_dl_sf_cfg_t dl_sf; ZERO_OBJECT(dl_sf); dl_sf.cfi = cfi; for (int s=0;s<10;s++) { dl_sf.tti = s; printf("Encoding %d DCIs for sf_idx=%d\n", nof_dcis, s); /* Execute Rx */ for (i=0;i<nof_dcis;i++) { testcases[i].ra_dl_tx.rnti = (uint16_t) (1234 + i); testcases[i].ra_dl_tx.format = testcases[i].dci_format; srslte_dci_msg_pack_pdsch(&cell, &dl_sf, &dci_cfg, &testcases[i].ra_dl_tx, &testcases[i].dci_tx); srslte_dci_location_set(&testcases[i].dci_location, 0, (uint32_t) i); testcases[i].dci_tx.format = testcases[i].dci_format; testcases[i].dci_tx.location = testcases[i].dci_location; // Enable just 1 TB per default if (testcases[i].dci_format < SRSLTE_DCI_FORMAT2) { for (int j=1;j<SRSLTE_MAX_CODEWORDS;j++) { SRSLTE_DCI_TB_DISABLE(testcases[i].ra_dl_tx.tb[j]); } } if (srslte_pdcch_encode(&pdcch_tx, &dl_sf, &testcases[i].dci_tx, slot_symbols)) { ERROR("Error encoding DCI message\n"); goto quit; } } /* Execute 'Rx' */ if (srslte_pdcch_extract_llr(&pdcch_rx, &dl_sf, &chest_dl_res, slot_symbols)) { ERROR("Error extracting LLRs\n"); goto quit; } /* Decode DCIs */ for (i=0;i<nof_dcis;i++) { testcases[i].dci_rx.format = testcases[i].dci_format; testcases[i].dci_rx.location = testcases[i].dci_location; if (srslte_pdcch_decode_msg(&pdcch_rx, &dl_sf, &dci_cfg, &testcases[i].dci_rx)) { ERROR("Error decoding DCI message\n"); goto quit; } if (srslte_dci_msg_unpack_pdsch(&cell, &dl_sf, &dci_cfg, &testcases[i].dci_rx, &testcases[i].ra_dl_rx)) { ERROR("Error unpacking DCI message\n"); goto quit; } if (testcases[i].dci_rx.rnti >= 1234 && testcases[i].dci_rx.rnti < 1234 + nof_dcis) { testcases[i].dci_rx.rnti -= 1234; } else { printf("Received invalid DCI CRC %d\n", testcases[i].dci_rx.rnti); goto quit; } } /* Compare Tx and Rx */ for (i = 0; i < nof_dcis; i++) { if (memcmp(testcases[i].dci_tx.payload, testcases[i].dci_rx.payload, testcases[i].dci_tx.nof_bits)) { printf("Error in DCI %d: Received data does not match\n", i); goto quit; } #if SRSLTE_DCI_HEXDEBUG // Ignore Hex str bzero(testcases[i].ra_dl_rx.hex_str, sizeof(testcases[i].ra_dl_rx.hex_str)); testcases[i].ra_dl_rx.nof_bits = 0; #endif // Ignore DCI location testcases[i].ra_dl_rx.location = testcases[i].ra_dl_tx.location; // Ignore cw_idx for (int j=0;j<SRSLTE_MAX_CODEWORDS;j++) { testcases[i].ra_dl_rx.tb[j].cw_idx = testcases[i].ra_dl_tx.tb[j].cw_idx; } if (memcmp(&testcases[i].ra_dl_tx, &testcases[i].ra_dl_rx, sizeof(srslte_dci_dl_t))) { uint8_t *x=(uint8_t*) &testcases[i].ra_dl_rx; uint8_t *y=(uint8_t*) &testcases[i].ra_dl_tx; for (int j=0;j<sizeof(srslte_dci_dl_t);j++) { if (x[j] != y[j]) { printf("error in byte %d, rx=%d, tx=%d\n", j, x[j], y[j]); } } printf("tx: "); srslte_vec_fprint_byte(stdout, (uint8_t*) &testcases[i].ra_dl_tx, sizeof(srslte_dci_dl_t)); printf("rx: "); srslte_vec_fprint_byte(stdout, (uint8_t*) &testcases[i].ra_dl_rx, sizeof(srslte_dci_dl_t)); printf("Error in RA %d: Received data does not match\n", i); printf(" Field | Tx | Rx \n"); printf("--------------+----------+----------\n"); if (testcases[i].ra_dl_tx.cif) { printf(" cif | %8d | %8d\n", testcases[i].ra_dl_tx.cif, testcases[i].ra_dl_rx.cif); } printf(" harq_process | %8d | %8d\n", testcases[i].ra_dl_tx.pid, testcases[i].ra_dl_rx.pid); printf(" mcs_idx | %8d | %8d\n", testcases[i].ra_dl_tx.tb[0].mcs_idx, testcases[i].ra_dl_rx.tb[0].mcs_idx); printf(" rv_idx | %8d | %8d\n", testcases[i].ra_dl_tx.tb[0].rv, testcases[i].ra_dl_rx.tb[0].rv); printf(" ndi | %8d | %8d\n", testcases[i].ra_dl_tx.tb[0].ndi, testcases[i].ra_dl_rx.tb[0].ndi); printf(" mcs_idx_1 | %8d | %8d\n", testcases[i].ra_dl_tx.tb[1].mcs_idx, testcases[i].ra_dl_rx.tb[1].mcs_idx); printf(" rv_idx_1 | %8d | %8d\n", testcases[i].ra_dl_tx.tb[1].rv, testcases[i].ra_dl_rx.tb[1].rv); printf(" ndi_1 | %8d | %8d\n", testcases[i].ra_dl_tx.tb[1].ndi, testcases[i].ra_dl_rx.tb[1].ndi); printf(" tb_cw_swap | %8d | %8d\n", testcases[i].ra_dl_tx.tb_cw_swap, testcases[i].ra_dl_rx.tb_cw_swap); printf(" sram_id | %8d | %8d\n", testcases[i].ra_dl_tx.sram_id, testcases[i].ra_dl_rx.sram_id); printf(" pinfo | %8d | %8d\n", testcases[i].ra_dl_tx.pinfo, testcases[i].ra_dl_rx.pinfo); printf(" pconf | %8d | %8d\n", testcases[i].ra_dl_tx.pconf, testcases[i].ra_dl_rx.pconf); printf(" power_offset | %8d | %8d\n", testcases[i].ra_dl_tx.power_offset, testcases[i].ra_dl_rx.power_offset); printf(" tpc_pucch | %8d | %8d\n", testcases[i].ra_dl_tx.tpc_pucch, testcases[i].ra_dl_rx.tpc_pucch); goto quit; } } } ret = 0; quit: srslte_pdcch_free(&pdcch_tx); srslte_pdcch_free(&pdcch_rx); srslte_chest_dl_res_free(&chest_dl_res); srslte_regs_free(®s); for (i = 0; i < SRSLTE_MAX_PORTS; i++) { free(slot_symbols[i]); } if (ret) { printf("Error\n"); } else { printf("Ok\n"); } srslte_dft_exit(); exit(ret); }
int srslte_ue_dl_set_cell(srslte_ue_dl_t* q, srslte_cell_t cell) { int ret = SRSLTE_ERROR_INVALID_INPUTS; if (q != NULL && srslte_cell_isvalid(&cell)) { q->pending_ul_dci_count = 0; if (q->cell.id != cell.id || q->cell.nof_prb == 0) { if (q->cell.nof_prb != 0) { for (int i = 0; i < MI_NOF_REGS; i++) { srslte_regs_free(&q->regs[i]); } } q->cell = cell; for (int i = 0; i < MI_NOF_REGS; i++) { if (srslte_regs_init_opts(&q->regs[i], q->cell, mi_reg_idx[i % 3], i > 2)) { ERROR("Error resizing REGs\n"); return SRSLTE_ERROR; } } for (int port = 0; port < q->nof_rx_antennas; port++) { if (srslte_ofdm_rx_set_prb(&q->fft[port], q->cell.cp, q->cell.nof_prb)) { ERROR("Error resizing FFT\n"); return SRSLTE_ERROR; } } // In TDD, initialize PDCCH and PHICH for the worst case: max ncces and phich groupds respectively uint32_t pdcch_init_reg = 0; uint32_t phich_init_reg = 0; if (q->cell.frame_type == SRSLTE_TDD) { pdcch_init_reg = 1; // mi=0 phich_init_reg = 2; // mi=2 } if (srslte_ofdm_rx_set_prb(&q->fft_mbsfn, SRSLTE_CP_EXT, q->cell.nof_prb)) { ERROR("Error resizing MBSFN FFT\n"); return SRSLTE_ERROR; } if (srslte_chest_dl_set_cell(&q->chest, q->cell)) { ERROR("Error resizing channel estimator\n"); return SRSLTE_ERROR; } if (srslte_pcfich_set_cell(&q->pcfich, &q->regs[0], q->cell)) { ERROR("Error resizing PCFICH object\n"); return SRSLTE_ERROR; } if (srslte_phich_set_cell(&q->phich, &q->regs[phich_init_reg], q->cell)) { ERROR("Error resizing PHICH object\n"); return SRSLTE_ERROR; } if (srslte_pdcch_set_cell(&q->pdcch, &q->regs[pdcch_init_reg], q->cell)) { ERROR("Error resizing PDCCH object\n"); return SRSLTE_ERROR; } if (srslte_pdsch_set_cell(&q->pdsch, q->cell)) { ERROR("Error resizing PDSCH object\n"); return SRSLTE_ERROR; } if (srslte_pmch_set_cell(&q->pmch, q->cell)) { ERROR("Error resizing PMCH object\n"); return SRSLTE_ERROR; } } if (q->pregen_rnti) { srslte_ue_dl_set_rnti(q, q->pregen_rnti); } ret = SRSLTE_SUCCESS; } else { ERROR("Invalid cell properties ue_dl: Id=%d, Ports=%d, PRBs=%d\n", q->cell.id, q->cell.nof_ports, q->cell.nof_prb); } return ret; }
int main(int argc, char **argv) { srslte_phich_t phich; srslte_regs_t regs; int i, j; cf_t *ce[SRSLTE_MAX_PORTS]; int nof_re; cf_t *slot_symbols[SRSLTE_MAX_PORTS]; uint8_t ack[50][SRSLTE_PHICH_NORM_NSEQUENCES], ack_rx; uint32_t nsf; float distance; int cid, max_cid; uint32_t ngroup, nseq, max_nseq; parse_args(argc,argv); max_nseq = SRSLTE_CP_ISNORM(cell.cp)?SRSLTE_PHICH_NORM_NSEQUENCES:SRSLTE_PHICH_EXT_NSEQUENCES; 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_phich_init(&phich, ®s, cell)) { fprintf(stderr, "Error creating PBCH object\n"); exit(-1); } for (nsf=0;nsf<10;nsf++) { srslte_phich_reset(&phich, slot_symbols); /* Transmit all PHICH groups and sequence numbers */ for (ngroup=0;ngroup<srslte_phich_ngroups(&phich);ngroup++) { for (nseq=0;nseq<max_nseq;nseq++) { ack[ngroup][nseq] = rand()%2; srslte_phich_encode(&phich, ack[ngroup][nseq], ngroup, nseq, nsf, slot_symbols); } } /* 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]; } } /* Receive all PHICH groups and sequence numbers */ for (ngroup=0;ngroup<srslte_phich_ngroups(&phich);ngroup++) { for (nseq=0;nseq<max_nseq;nseq++) { if (srslte_phich_decode(&phich, slot_symbols[0], ce, 0, ngroup, nseq, nsf, &ack_rx, &distance)<0) { printf("Error decoding ACK\n"); exit(-1); } INFO("%d/%d, ack_tx: %d, ack_rx: %d, ns: %d, distance: %f\n", ngroup, nseq, ack[ngroup][nseq], ack_rx, nsf, distance); if (ack[ngroup][nseq] != ack_rx) { printf("Invalid received ACK: %d!=%d\n", ack[ngroup][nseq], ack_rx); exit(-1); } if (distance < 1.5) { printf("Error\n"); exit(-1); } } } } srslte_phich_free(&phich); 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); }
int srslte_ue_dl_set_cell(srslte_ue_dl_t *q, srslte_cell_t cell) { int ret = SRSLTE_ERROR_INVALID_INPUTS; if (q != NULL && srslte_cell_isvalid(&cell)) { q->pkt_errors = 0; q->pkts_total = 0; q->pending_ul_dci_rnti = 0; q->sample_offset = 0; if (q->cell.id != cell.id || q->cell.nof_prb == 0) { if (q->cell.nof_prb != 0) { srslte_regs_free(&q->regs); } memcpy(&q->cell, &cell, sizeof(srslte_cell_t)); if (srslte_regs_init(&q->regs, q->cell)) { fprintf(stderr, "Error resizing REGs\n"); return SRSLTE_ERROR; } if (srslte_cfo_resize(&q->sfo_correct, q->cell.nof_prb*SRSLTE_NRE)) { fprintf(stderr, "Error resizing SFO correct\n"); return SRSLTE_ERROR; } srslte_cfo_set_tol(&q->sfo_correct, 1e-5f/q->fft[0].symbol_sz); for (int port = 0; port < q->nof_rx_antennas; port++) { if (srslte_ofdm_rx_set_prb(&q->fft[port], q->cell.cp, q->cell.nof_prb)) { fprintf(stderr, "Error resizing FFT\n"); return SRSLTE_ERROR; } } if (srslte_chest_dl_set_cell(&q->chest, q->cell)) { fprintf(stderr, "Error resizing channel estimator\n"); return SRSLTE_ERROR; } if (srslte_pcfich_set_cell(&q->pcfich, &q->regs, q->cell)) { fprintf(stderr, "Error resizing PCFICH object\n"); return SRSLTE_ERROR; } if (srslte_phich_set_cell(&q->phich, &q->regs, q->cell)) { fprintf(stderr, "Error resizing PHICH object\n"); return SRSLTE_ERROR; } if (srslte_pdcch_set_cell(&q->pdcch, &q->regs, q->cell)) { fprintf(stderr, "Error resizing PDCCH object\n"); return SRSLTE_ERROR; } if (srslte_pdsch_set_cell(&q->pdsch, q->cell)) { fprintf(stderr, "Error creating PDSCH object\n"); return SRSLTE_ERROR; } q->current_rnti = 0; } ret = SRSLTE_SUCCESS; } else { fprintf(stderr, "Invalid cell properties ue_dl: Id=%d, Ports=%d, PRBs=%d\n", cell.id, cell.nof_ports, cell.nof_prb); } return ret; }
/* 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; }