void srslte_enb_dl_gen_signal(srslte_enb_dl_t* q) { // TODO: PAPR control float norm_factor = 0.05f / sqrt(q->cell.nof_prb); if (q->dl_sf.sf_type == SRSLTE_SF_MBSFN) { srslte_ofdm_tx_sf(&q->ifft_mbsfn); srslte_vec_sc_prod_cfc( q->ifft_mbsfn.out_buffer, norm_factor, q->ifft_mbsfn.out_buffer, (uint32_t)SRSLTE_SF_LEN_PRB(q->cell.nof_prb)); } else { for (int i = 0; i < q->cell.nof_ports; i++) { srslte_ofdm_tx_sf(&q->ifft[i]); srslte_vec_sc_prod_cfc( q->ifft[i].out_buffer, norm_factor, q->ifft[i].out_buffer, (uint32_t)SRSLTE_SF_LEN_PRB(q->cell.nof_prb)); } } }
int main(int argc, char **argv) { int sf_idx=0, N_id_2=0; cf_t pss_signal[SRSLTE_PSS_LEN]; float sss_signal0[SRSLTE_SSS_LEN]; // for subframe 0 float sss_signal5[SRSLTE_SSS_LEN]; // for subframe 5 int i; #ifdef DISABLE_UHD if (argc < 3) { usage(argv[0]); exit(-1); } #endif parse_args(argc, argv); N_id_2 = cell.id % 3; sf_n_re = 2 * SRSLTE_CP_NORM_NSYMB * cell.nof_prb * SRSLTE_NRE; sf_n_samples = 2 * SRSLTE_SLOT_LEN(srslte_symbol_sz(cell.nof_prb)); cell.phich_length = SRSLTE_PHICH_NORM; cell.phich_resources = SRSLTE_PHICH_R_1; /* this *must* be called after setting slot_len_* */ base_init(); /* Generate PSS/SSS signals */ srslte_pss_generate(pss_signal, N_id_2); srslte_sss_generate(sss_signal0, sss_signal5, cell.id); printf("Set TX rate: %.2f MHz\n", cuhd_set_tx_srate(uhd, srslte_sampling_freq_hz(cell.nof_prb)) / 1000000); printf("Set TX gain: %.1f dB\n", cuhd_set_tx_gain(uhd, uhd_gain)); printf("Set TX freq: %.2f MHz\n", cuhd_set_tx_freq(uhd, uhd_freq) / 1000000); uint32_t nbits; srslte_modem_table_t modulator; srslte_modem_table_init(&modulator); srslte_modem_table_lte(&modulator, modulation); srslte_tcod_t turbocoder; srslte_tcod_init(&turbocoder, SRSLTE_TCOD_MAX_LEN_CB); srslte_dft_precoding_t dft_precod; srslte_dft_precoding_init(&dft_precod, 12); nbits = srslte_cbsegm_cbindex(sf_n_samples/8/srslte_mod_bits_x_symbol(modulation)/3 - 12); uint32_t ncoded_bits = sf_n_samples/8/srslte_mod_bits_x_symbol(modulation); uint8_t *data = malloc(sizeof(uint8_t)*nbits); uint8_t *data_enc = malloc(sizeof(uint8_t)*ncoded_bits); cf_t *symbols = malloc(sizeof(cf_t)*sf_n_samples); bzero(data_enc, sizeof(uint8_t)*ncoded_bits); while (1) { for (sf_idx = 0; sf_idx < SRSLTE_NSUBFRAMES_X_FRAME; sf_idx++) { bzero(sf_buffer, sizeof(cf_t) * sf_n_re); #ifdef kk if (sf_idx == 0 || sf_idx == 5) { srslte_pss_put_slot(pss_signal, sf_buffer, cell.nof_prb, SRSLTE_CP_NORM); srslte_sss_put_slot(sf_idx ? sss_signal5 : sss_signal0, sf_buffer, cell.nof_prb, SRSLTE_CP_NORM); /* Transform to OFDM symbols */ srslte_ofdm_tx_sf(&ifft, sf_buffer, output_buffer); float norm_factor = (float) sqrtf(cell.nof_prb)/15; srslte_vec_sc_prod_cfc(output_buffer, uhd_amp*norm_factor, output_buffer, SRSLTE_SF_LEN_PRB(cell.nof_prb)); } else { #endif /* Generate random data */ for (i=0;i<nbits;i++) { data[i] = rand()%2; } srslte_tcod_encode(&turbocoder, data, data_enc, nbits); srslte_mod_modulate(&modulator, data_enc, symbols, ncoded_bits); srslte_interp_linear_offset_cabs(symbols, output_buffer, 8, sf_n_samples/8, 0, 0); // } /* send to usrp */ srslte_vec_sc_prod_cfc(output_buffer, uhd_amp, output_buffer, sf_n_samples); cuhd_send(uhd, output_buffer, sf_n_samples, true); } } base_free(); printf("Done\n"); exit(0); }
int main(int argc, char **argv) { uint32_t i, j, k; int ret = -1; struct timeval t[3]; srslte_softbuffer_tx_t *softbuffers_tx[SRSLTE_MAX_CODEWORDS]; int M=1; parse_args(argc,argv); /* Initialise to zeros */ bzero(&pmch_tx, sizeof(srslte_pmch_t)); bzero(&pmch_rx, sizeof(srslte_pmch_t)); bzero(&pmch_cfg, sizeof(srslte_pdsch_cfg_t)); bzero(ce, sizeof(cf_t*)*SRSLTE_MAX_PORTS); bzero(tx_slot_symbols, sizeof(cf_t*)*SRSLTE_MAX_PORTS); bzero(rx_slot_symbols, sizeof(cf_t*)*SRSLTE_MAX_PORTS); cell.nof_ports = 1; srslte_ra_dl_dci_t dci; bzero(&dci, sizeof(srslte_ra_dl_dci_t)); dci.type0_alloc.rbg_bitmask = 0xffffffff; /* If transport block 0 is enabled */ grant.tb_en[0] = true; grant.tb_en[1] = false; grant.mcs[0].idx = mcs_idx; grant.nof_prb = cell.nof_prb; grant.sf_type = SRSLTE_SF_MBSFN; srslte_dl_fill_ra_mcs(&grant.mcs[0], cell.nof_prb); grant.Qm[0] = srslte_mod_bits_x_symbol(grant.mcs[0].mod); for(int i = 0; i < 2; i++){ for(int j = 0; j < grant.nof_prb; j++){ grant.prb_idx[i][j] = true; } } /* init memory */ for (i=0;i<SRSLTE_MAX_PORTS;i++) { for (j = 0; j < SRSLTE_MAX_PORTS; j++) { ce[i][j] = srslte_vec_malloc(sizeof(cf_t) * NOF_CE_SYMBOLS); if (!ce[i][j]) { perror("srslte_vec_malloc"); goto quit; } for (k = 0; k < NOF_CE_SYMBOLS; k++) { ce[i][j][k] = (i == j) ? 1.0f : 0.0f; } } rx_slot_symbols[i] = srslte_vec_malloc(sizeof(cf_t) * SRSLTE_SF_LEN_RE(cell.nof_prb, cell.cp)); if (!rx_slot_symbols[i]) { perror("srslte_vec_malloc"); goto quit; } } for (i = 0; i < SRSLTE_MAX_CODEWORDS; i++) { softbuffers_tx[i] = calloc(sizeof(srslte_softbuffer_tx_t), 1); if (!softbuffers_tx[i]) { fprintf(stderr, "Error allocating TX soft buffer\n"); } if (srslte_softbuffer_tx_init(softbuffers_tx[i], cell.nof_prb)) { fprintf(stderr, "Error initiating TX soft buffer\n"); goto quit; } } for (i = 0; i < cell.nof_ports; i++) { tx_slot_symbols[i] = calloc(SRSLTE_SF_LEN_RE(cell.nof_prb, cell.cp), sizeof(cf_t)); if (!tx_slot_symbols[i]) { perror("srslte_vec_malloc"); goto quit; } } for (int i = 0; i < SRSLTE_MAX_CODEWORDS; i++) { if (grant.tb_en[i]) { data_tx[i] = srslte_vec_malloc(sizeof(uint8_t) * grant.mcs[i].tbs); if (!data_tx[i]) { perror("srslte_vec_malloc"); goto quit; } bzero(data_tx[i], sizeof(uint8_t) * grant.mcs[i].tbs); data_rx[i] = srslte_vec_malloc(sizeof(uint8_t) * grant.mcs[i].tbs); if (!data_rx[i]) { perror("srslte_vec_malloc"); goto quit; } bzero(data_rx[i], sizeof(uint8_t) * grant.mcs[i].tbs); } } for (i = 0; i < SRSLTE_MAX_CODEWORDS; i++) { softbuffers_rx[i] = calloc(sizeof(srslte_softbuffer_rx_t), 1); if (!softbuffers_rx[i]) { fprintf(stderr, "Error allocating RX soft buffer\n"); goto quit; } if (srslte_softbuffer_rx_init(softbuffers_rx[i], cell.nof_prb)) { fprintf(stderr, "Error initiating RX soft buffer\n"); goto quit; } } #ifdef DO_OFDM for (i = 0; i < cell.nof_ports; i++) { tx_sf_symbols[i] = srslte_vec_malloc(sizeof(cf_t) * SRSLTE_SF_LEN_PRB(cell.nof_prb)); if (srslte_ofdm_tx_init_mbsfn(&ifft_mbsfn[i], SRSLTE_CP_EXT, tx_slot_symbols[i], tx_sf_symbols[i], cell.nof_prb)) { fprintf(stderr, "Error creating iFFT object\n"); exit(-1); } srslte_ofdm_set_non_mbsfn_region(&ifft_mbsfn[i], non_mbsfn_region); srslte_ofdm_set_normalize(&ifft_mbsfn[i], true); } for (i = 0; i < nof_rx_antennas; i++) { rx_sf_symbols[i] = srslte_vec_malloc(sizeof(cf_t) * SRSLTE_SF_LEN_PRB(cell.nof_prb)); if (srslte_ofdm_rx_init_mbsfn(&fft_mbsfn[i], SRSLTE_CP_EXT, rx_sf_symbols[i], rx_slot_symbols[i], cell.nof_prb)) { fprintf(stderr, "Error creating iFFT object\n"); exit(-1); } srslte_ofdm_set_non_mbsfn_region(&fft_mbsfn[i], non_mbsfn_region); srslte_ofdm_set_normalize(&fft_mbsfn[i], true); } #endif /* DO_OFDM */ /* Configure PDSCH */ if (srslte_pmch_cfg(&pmch_cfg, cell, &grant, cfi, subframe)) { fprintf(stderr, "Error configuring PMCH\n"); exit(-1); } if (srslte_pmch_cfg(&pmch_cfg, cell, &grant, cfi, subframe)) { fprintf(stderr, "Error configuring PMCH\n"); exit(-1); } INFO(" Global:\n"); INFO(" nof_prb=%d\n", cell.nof_prb); INFO(" nof_ports=%d\n", cell.nof_ports); INFO(" id=%d\n", cell.id); INFO(" cp=%s\n", srslte_cp_string(cell.cp)); INFO(" phich_length=%d\n", (int) cell.phich_length); INFO(" phich_resources=%d\n", (int) cell.phich_resources); INFO(" nof_prb=%d\n", pmch_cfg.grant.nof_prb); INFO(" sf_idx=%d\n", pmch_cfg.sf_idx); INFO(" mimo_type=%s\n", srslte_mimotype2str(pmch_cfg.mimo_type)); INFO(" nof_layers=%d\n", pmch_cfg.nof_layers); INFO(" nof_tb=%d\n", SRSLTE_RA_DL_GRANT_NOF_TB(&pmch_cfg.grant)); INFO(" Qm=%d\n", pmch_cfg.grant.Qm[0]); INFO(" mcs.idx=0x%X\n", pmch_cfg.grant.mcs[0].idx); INFO(" mcs.tbs=%d\n", pmch_cfg.grant.mcs[0].tbs); INFO(" mcs.mod=%s\n", srslte_mod_string(pmch_cfg.grant.mcs[0].mod)); INFO(" rv=%d\n", pmch_cfg.rv[0]); INFO(" lstart=%d\n", pmch_cfg.nbits[0].lstart); INFO(" nof_bits=%d\n", pmch_cfg.nbits[0].nof_bits); INFO(" nof_re=%d\n", pmch_cfg.nbits[0].nof_re); INFO(" nof_symb=%d\n", pmch_cfg.nbits[0].nof_symb); if (srslte_pmch_init(&pmch_tx, cell.nof_prb)) { fprintf(stderr, "Error creating PMCH object\n"); } srslte_pmch_set_area_id(&pmch_tx, mbsfn_area_id); if (srslte_pmch_init(&pmch_rx, cell.nof_prb)) { fprintf(stderr, "Error creating PMCH object\n"); } srslte_pmch_set_area_id(&pmch_rx, mbsfn_area_id); for (int tb = 0; tb < SRSLTE_MAX_CODEWORDS; tb++) { if (grant.tb_en[tb]) { for (int byte = 0; byte < grant.mcs[tb].tbs / 8; byte++) { data_tx[tb][byte] = (uint8_t) (rand() % 256); } } } if (srslte_pmch_encode(&pmch_tx, &pmch_cfg, softbuffers_tx[0], data_tx[0], mbsfn_area_id, tx_slot_symbols)) { fprintf(stderr, "Error encoding PDSCH\n"); exit(-1); } gettimeofday(&t[2], NULL); get_time_interval(t); printf("ENCODED in %.2f (PHY bitrate=%.2f Mbps. Processing bitrate=%.2f Mbps)\n", (float) t[0].tv_usec/M, (float) (grant.mcs[0].tbs + grant.mcs[1].tbs)/1000.0f, (float) (grant.mcs[0].tbs + grant.mcs[1].tbs)*M/t[0].tv_usec); #ifdef DO_OFDM for (i = 0; i < cell.nof_ports; i++) { /* For each Tx antenna modulate OFDM */ srslte_ofdm_tx_sf(&ifft_mbsfn[i]); } /* combine outputs */ for (j = 0; j < nof_rx_antennas; j++) { for (k = 0; k < NOF_CE_SYMBOLS; k++) { rx_sf_symbols[j][k] = 0.0f; for (i = 0; i < cell.nof_ports; i++) { rx_sf_symbols[j][k] += tx_sf_symbols[i][k] * ce[i][j][k]; } } } #else /* combine outputs */ for (j = 0; j < nof_rx_antennas; j++) { for (k = 0; k < SRSLTE_SF_LEN_RE(cell.nof_prb, cell.cp); k++) { rx_slot_symbols[j][k] = 0.0f; for (i = 0; i < cell.nof_ports; i++) { rx_slot_symbols[j][k] += tx_slot_symbols[i][k] * ce[i][j][k]; } } } #endif int r=0; gettimeofday(&t[1], NULL); #ifdef DO_OFDM /* For each Rx antenna demodulate OFDM */ for (i = 0; i < nof_rx_antennas; i++) { srslte_ofdm_rx_sf(&fft_mbsfn[i]); } #endif for (i = 0; i < SRSLTE_MAX_CODEWORDS; i++) { if (grant.tb_en[i]) { srslte_softbuffer_rx_reset_tbs(softbuffers_rx[i], (uint32_t) grant.mcs[i].tbs); } } r = srslte_pmch_decode(&pmch_rx, &pmch_cfg, softbuffers_rx[0],rx_slot_symbols[0], ce[0],0,mbsfn_area_id, data_rx[0]); gettimeofday(&t[2], NULL); get_time_interval(t); printf("DECODED %s in %.2f (PHY bitrate=%.2f Mbps. Processing bitrate=%.2f Mbps)\n", r?"Error":"OK", (float) t[0].tv_usec/M, (float) (grant.mcs[0].tbs + grant.mcs[1].tbs)/1000.0f, (float) (grant.mcs[0].tbs + grant.mcs[1].tbs)*M/t[0].tv_usec); /* If there is an error in PDSCH decode */ if (r) { ret = -1; goto quit; } /* Check Tx and Rx bytes */ for (int tb = 0; tb < SRSLTE_MAX_CODEWORDS; tb++) { if (grant.tb_en[tb]) { for (int byte = 0; byte < grant.mcs[tb].tbs / 8; byte++) { if (data_tx[tb][byte] != data_rx[tb][byte]) { ERROR("Found BYTE error in TB %d (%02X != %02X), quiting...", tb, data_tx[tb][byte], data_rx[tb][byte]); ret = SRSLTE_ERROR; goto quit; } } } } ret = SRSLTE_SUCCESS; quit: srslte_pmch_free(&pmch_tx); srslte_pmch_free(&pmch_rx); for (i = 0; i < SRSLTE_MAX_CODEWORDS; i++) { srslte_softbuffer_tx_free(softbuffers_tx[i]); if (softbuffers_tx[i]) { free(softbuffers_tx[i]); } srslte_softbuffer_rx_free(softbuffers_rx[i]); if (softbuffers_rx[i]) { free(softbuffers_rx[i]); } if (data_tx[i]) { free(data_tx[i]); } if (data_rx[i]) { free(data_rx[i]); } } for (i=0;i<SRSLTE_MAX_PORTS;i++) { for (j = 0; j < SRSLTE_MAX_PORTS; j++) { if (ce[i][j]) { free(ce[i][j]); } } if (tx_slot_symbols[i]) { free(tx_slot_symbols[i]); } if (rx_slot_symbols[i]) { free(rx_slot_symbols[i]); } } if (ret) { printf("Error\n"); } else { printf("Ok\n"); } exit(ret); }