void base_init() { int i; /* Select transmission mode */ if (srslte_str2mimotype(mimo_type_str, &pdsch_cfg.mimo_type)) { ERROR("Wrong transmission mode! Allowed modes: single, diversity, cdd and multiplex"); exit(-1); } /* Configure cell and PDSCH in function of the transmission mode */ switch(pdsch_cfg.mimo_type) { case SRSLTE_MIMO_TYPE_SINGLE_ANTENNA: cell.nof_ports = 1; break; case SRSLTE_MIMO_TYPE_TX_DIVERSITY: cell.nof_ports = 2; break; case SRSLTE_MIMO_TYPE_CDD: cell.nof_ports = 2; break; case SRSLTE_MIMO_TYPE_SPATIAL_MULTIPLEX: cell.nof_ports = 2; break; default: ERROR("Transmission mode not implemented."); exit(-1); } /* Allocate memory */ for(i = 0; i < SRSLTE_MAX_CODEWORDS; i++) { data[i] = srslte_vec_malloc(sizeof(uint8_t) * SOFTBUFFER_SIZE); if (!data[i]) { perror("malloc"); exit(-1); } bzero(data[i], sizeof(uint8_t) * SOFTBUFFER_SIZE); } data_mbms = srslte_vec_malloc(sizeof(uint8_t) * SOFTBUFFER_SIZE); /* init memory */ for (i = 0; i < SRSLTE_MAX_PORTS; i++) { sf_buffer[i] = srslte_vec_malloc(sizeof(cf_t) * sf_n_re); if (!sf_buffer[i]) { perror("malloc"); exit(-1); } } for (i = 0; i < SRSLTE_MAX_PORTS; i++) { output_buffer[i] = srslte_vec_malloc(sizeof(cf_t) * sf_n_samples); if (!output_buffer[i]) { perror("malloc"); exit(-1); } bzero(output_buffer[i], sizeof(cf_t) * sf_n_samples); } /* open file or USRP */ if (output_file_name) { if (strcmp(output_file_name, "NULL")) { if (srslte_filesink_init(&fsink, output_file_name, SRSLTE_COMPLEX_FLOAT_BIN)) { fprintf(stderr, "Error opening file %s\n", output_file_name); exit(-1); } null_file_sink = false; } else { null_file_sink = true; } } else { #ifndef DISABLE_RF printf("Opening RF device...\n"); if (srslte_rf_open_multi(&rf, rf_args, cell.nof_ports)) { fprintf(stderr, "Error opening rf\n"); exit(-1); } #else printf("Error RF not available. Select an output file\n"); exit(-1); #endif } if (net_port > 0) { if (srslte_netsource_init(&net_source, "127.0.0.1", net_port, SRSLTE_NETSOURCE_UDP)) { fprintf(stderr, "Error creating input UDP socket at port %d\n", net_port); exit(-1); } if (null_file_sink) { if (srslte_netsink_init(&net_sink, "127.0.0.1", net_port+1, SRSLTE_NETSINK_TCP)) { fprintf(stderr, "Error sink\n"); exit(-1); } } if (sem_init(&net_sem, 0, 1)) { perror("sem_init"); exit(-1); } } /* create ifft object */ for (i = 0; i < cell.nof_ports; i++) { if (srslte_ofdm_tx_init(&ifft[i], SRSLTE_CP_NORM, sf_buffer[i], output_buffer[i], cell.nof_prb)) { fprintf(stderr, "Error creating iFFT object\n"); exit(-1); } srslte_ofdm_set_normalize(&ifft[i], true); } if (srslte_ofdm_tx_init_mbsfn(&ifft_mbsfn, SRSLTE_CP_EXT, sf_buffer[0], output_buffer[0], cell.nof_prb)) { fprintf(stderr, "Error creating iFFT object\n"); exit(-1); } srslte_ofdm_set_non_mbsfn_region(&ifft_mbsfn, 2); srslte_ofdm_set_normalize(&ifft_mbsfn, true); if (srslte_pbch_init(&pbch)) { fprintf(stderr, "Error creating PBCH object\n"); exit(-1); } if (srslte_pbch_set_cell(&pbch, cell)) { fprintf(stderr, "Error creating PBCH object\n"); exit(-1); } if (srslte_regs_init(®s, cell)) { fprintf(stderr, "Error initiating regs\n"); exit(-1); } if (srslte_pcfich_init(&pcfich, 1)) { fprintf(stderr, "Error creating PBCH object\n"); exit(-1); } if (srslte_pcfich_set_cell(&pcfich, ®s, cell)) { fprintf(stderr, "Error creating PBCH object\n"); exit(-1); } if (srslte_pdcch_init_enb(&pdcch, cell.nof_prb)) { fprintf(stderr, "Error creating PDCCH object\n"); exit(-1); } if (srslte_pdcch_set_cell(&pdcch, ®s, cell)) { fprintf(stderr, "Error creating PDCCH object\n"); exit(-1); } if (srslte_pdsch_init_enb(&pdsch, cell.nof_prb)) { fprintf(stderr, "Error creating PDSCH object\n"); exit(-1); } if (srslte_pdsch_set_cell(&pdsch, cell)) { fprintf(stderr, "Error creating PDSCH object\n"); exit(-1); } srslte_pdsch_set_rnti(&pdsch, UE_CRNTI); if(mbsfn_area_id > -1){ if (srslte_pmch_init(&pmch, cell.nof_prb)) { fprintf(stderr, "Error creating PMCH object\n"); } srslte_pmch_set_area_id(&pmch, mbsfn_area_id); } for (i = 0; i < SRSLTE_MAX_CODEWORDS; i++) { softbuffers[i] = calloc(sizeof(srslte_softbuffer_tx_t), 1); if (!softbuffers[i]) { fprintf(stderr, "Error allocating soft buffer\n"); exit(-1); } if (srslte_softbuffer_tx_init(softbuffers[i], cell.nof_prb)) { fprintf(stderr, "Error initiating soft buffer\n"); exit(-1); } } }
int srslte_enb_dl_init(srslte_enb_dl_t *q, cf_t *out_buffer[SRSLTE_MAX_PORTS], uint32_t max_prb) { int ret = SRSLTE_ERROR_INVALID_INPUTS; if (q != NULL) { ret = SRSLTE_ERROR; bzero(q, sizeof(srslte_enb_dl_t)); for (int i=0;i<SRSLTE_MAX_PORTS;i++) { q->sf_symbols[i] = srslte_vec_malloc(SRSLTE_SF_LEN_RE(max_prb, SRSLTE_CP_NORM) * sizeof(cf_t)); if (!q->sf_symbols[i]) { perror("malloc"); goto clean_exit; } } for (int i = 0; i < SRSLTE_MAX_PORTS; i++) { if (srslte_ofdm_tx_init(&q->ifft[i], SRSLTE_CP_NORM, q->sf_symbols[i], out_buffer[i], max_prb)) { ERROR("Error initiating FFT (%d)\n", i); goto clean_exit; } } if (srslte_ofdm_tx_init_mbsfn(&q->ifft_mbsfn, SRSLTE_CP_EXT, q->sf_symbols[0], out_buffer[0], max_prb)) { ERROR("Error initiating FFT \n"); goto clean_exit; } if (srslte_pbch_init(&q->pbch)) { ERROR("Error creating PBCH object\n"); goto clean_exit; } if (srslte_pcfich_init(&q->pcfich, 0)) { ERROR("Error creating PCFICH object\n"); goto clean_exit; } if (srslte_phich_init(&q->phich, 0)) { ERROR("Error creating PHICH object\n"); goto clean_exit; } int mbsfn_area_id = 1; if (srslte_pmch_init(&q->pmch, max_prb, 1)) { ERROR("Error creating PMCH object\n"); } srslte_pmch_set_area_id(&q->pmch, mbsfn_area_id); if (srslte_pdcch_init_enb(&q->pdcch, max_prb)) { ERROR("Error creating PDCCH object\n"); goto clean_exit; } if (srslte_pdsch_init_enb(&q->pdsch, max_prb)) { ERROR("Error creating PDSCH object\n"); goto clean_exit; } if (srslte_refsignal_cs_init(&q->csr_signal, max_prb)) { ERROR("Error initializing CSR signal (%d)\n", ret); goto clean_exit; } if (srslte_refsignal_mbsfn_init(&q->mbsfnr_signal, max_prb)) { ERROR("Error initializing CSR signal (%d)\n", ret); goto clean_exit; } ret = SRSLTE_SUCCESS; } else { ERROR("Invalid parameters\n"); } clean_exit: if (ret == SRSLTE_ERROR) { srslte_enb_dl_free(q); } 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); }