int srslte_conv_fft_cc_init(srslte_conv_fft_cc_t *q, uint32_t input_len, uint32_t filter_len) { q->input_len = input_len; q->filter_len = filter_len; q->output_len = input_len+filter_len; q->input_fft = srslte_vec_malloc(sizeof(cf_t)*q->output_len); q->filter_fft = srslte_vec_malloc(sizeof(cf_t)*q->output_len); q->output_fft = srslte_vec_malloc(sizeof(cf_t)*q->output_len); if (!q->input_fft || !q->filter_fft || !q->output_fft) { return SRSLTE_ERROR; } if (srslte_dft_plan(&q->input_plan,q->output_len,SRSLTE_DFT_FORWARD,SRSLTE_DFT_COMPLEX)) { fprintf(stderr, "Error initiating input plan\n"); return SRSLTE_ERROR; } if (srslte_dft_plan(&q->filter_plan,q->output_len,SRSLTE_DFT_FORWARD,SRSLTE_DFT_COMPLEX)) { fprintf(stderr, "Error initiating filter plan\n"); return SRSLTE_ERROR; } if (srslte_dft_plan(&q->output_plan,q->output_len,SRSLTE_DFT_BACKWARD,SRSLTE_DFT_COMPLEX)) { fprintf(stderr, "Error initiating output plan\n"); return SRSLTE_ERROR; } srslte_dft_plan_set_norm(&q->input_plan, true); srslte_dft_plan_set_norm(&q->filter_plan, true); srslte_dft_plan_set_norm(&q->output_plan, false); return SRSLTE_SUCCESS; }
int srslte_softbuffer_tx_init(srslte_softbuffer_tx_t *q, uint32_t nof_prb) { int ret = SRSLTE_ERROR_INVALID_INPUTS; if (q != NULL) { ret = SRSLTE_ERROR; bzero(q, sizeof(srslte_softbuffer_tx_t)); ret = srslte_ra_tbs_from_idx(26, nof_prb); if (ret != SRSLTE_ERROR) { q->max_cb = (uint32_t) ret / (SRSLTE_TCOD_MAX_LEN_CB - 24) + 1; q->buffer_b = srslte_vec_malloc(sizeof(uint8_t*) * q->max_cb); if (!q->buffer_b) { perror("malloc"); return SRSLTE_ERROR; } // FIXME: Use HARQ buffer limitation based on UE category for (uint32_t i=0;i<q->max_cb;i++) { q->buffer_b[i] = srslte_vec_malloc(sizeof(float) * SOFTBUFFER_SIZE); if (!q->buffer_b[i]) { perror("malloc"); return SRSLTE_ERROR; } } srslte_softbuffer_tx_reset(q); ret = SRSLTE_SUCCESS; } } return ret; }
int srslte_interp_linear_init(srslte_interp_lin_t *q, uint32_t vector_len, uint32_t M) { int ret = SRSLTE_ERROR_INVALID_INPUTS; if (q) { bzero(q, sizeof(srslte_interp_lin_t)); ret = SRSLTE_SUCCESS; q->diff_vec = srslte_vec_malloc(vector_len * sizeof(cf_t)); if (!q->diff_vec) { perror("malloc"); return SRSLTE_ERROR; } q->diff_vec2 = srslte_vec_malloc(M * vector_len * sizeof(cf_t)); if (!q->diff_vec2) { perror("malloc"); free(q->diff_vec); return SRSLTE_ERROR; } q->ramp = srslte_vec_malloc(M * sizeof(float)); if (!q->ramp) { perror("malloc"); free(q->ramp); free(q->diff_vec); return SRSLTE_ERROR; } for (int i=0;i<M;i++) { q->ramp[i] = (float) i; } q->vector_len = vector_len; q->M = M; } return ret; }
int srslte_softbuffer_rx_init(srslte_softbuffer_rx_t *q, uint32_t nof_prb) { int ret = SRSLTE_ERROR_INVALID_INPUTS; if (q != NULL) { bzero(q, sizeof(srslte_softbuffer_rx_t)); ret = srslte_ra_tbs_from_idx(26, nof_prb); if (ret != SRSLTE_ERROR) { q->max_cb = (uint32_t) ret / (SRSLTE_TCOD_MAX_LEN_CB - 24) + 1; ret = SRSLTE_ERROR; q->buffer_f = srslte_vec_malloc(sizeof(int16_t*) * q->max_cb); if (!q->buffer_f) { perror("malloc"); goto clean_exit; } q->data = srslte_vec_malloc(sizeof(uint8_t*) * q->max_cb); if (!q->data) { perror("malloc"); goto clean_exit; } q->cb_crc = srslte_vec_malloc(sizeof(bool) * q->max_cb); if (!q->cb_crc) { perror("malloc"); goto clean_exit; } bzero(q->cb_crc, sizeof(bool) * q->max_cb); // FIXME: Use HARQ buffer limitation based on UE category for (uint32_t i=0;i<q->max_cb;i++) { q->buffer_f[i] = srslte_vec_malloc(sizeof(int16_t) * SOFTBUFFER_SIZE); if (!q->buffer_f[i]) { perror("malloc"); goto clean_exit; } q->data[i] = srslte_vec_malloc(sizeof(uint8_t) * 6144/8); if (!q->data[i]) { perror("malloc"); goto clean_exit; } } //srslte_softbuffer_rx_reset(q); ret = SRSLTE_SUCCESS; } } clean_exit: if (ret != SRSLTE_SUCCESS) { srslte_softbuffer_rx_free(q); } return ret; }
int srslte_ue_mib_init(srslte_ue_mib_t * q, srslte_cell_t cell) { int ret = SRSLTE_ERROR_INVALID_INPUTS; if (q != NULL && cell.nof_ports <= SRSLTE_MAX_PORTS) { ret = SRSLTE_ERROR; bzero(q, sizeof(srslte_ue_mib_t)); if (srslte_pbch_init(&q->pbch, cell)) { fprintf(stderr, "Error initiating PBCH\n"); goto clean_exit; } if (cell.nof_ports == 0) { cell.nof_ports = SRSLTE_MAX_PORTS; } q->sf_symbols = srslte_vec_malloc(SRSLTE_SF_LEN_RE(cell.nof_prb, cell.cp) * sizeof(cf_t)); if (!q->sf_symbols) { perror("malloc"); goto clean_exit; } for (int i=0;i<cell.nof_ports;i++) { q->ce[i] = srslte_vec_malloc(SRSLTE_SF_LEN_RE(cell.nof_prb, cell.cp) * sizeof(cf_t)); if (!q->ce[i]) { perror("malloc"); goto clean_exit; } } if (srslte_ofdm_rx_init(&q->fft, cell.cp, cell.nof_prb)) { fprintf(stderr, "Error initializing FFT\n"); goto clean_exit; } if (srslte_chest_dl_init(&q->chest, cell)) { fprintf(stderr, "Error initializing reference signal\n"); goto clean_exit; } srslte_ue_mib_reset(q); ret = SRSLTE_SUCCESS; } clean_exit: if (ret == SRSLTE_ERROR) { srslte_ue_mib_free(q); } return ret; }
int srslte_ue_mib_init(srslte_ue_mib_t * q, cf_t *in_buffer[SRSLTE_MAX_PORTS], uint32_t max_prb) { int ret = SRSLTE_ERROR_INVALID_INPUTS; if (q != NULL) { ret = SRSLTE_ERROR; bzero(q, sizeof(srslte_ue_mib_t)); if (srslte_pbch_init(&q->pbch)) { fprintf(stderr, "Error initiating PBCH\n"); goto clean_exit; } q->sf_symbols = srslte_vec_malloc(SRSLTE_SF_LEN_RE(max_prb, SRSLTE_CP_NORM) * sizeof(cf_t)); if (!q->sf_symbols) { perror("malloc"); goto clean_exit; } for (int i=0;i<SRSLTE_MAX_PORTS;i++) { q->ce[i] = srslte_vec_malloc(SRSLTE_SF_LEN_RE(max_prb, SRSLTE_CP_NORM) * sizeof(cf_t)); if (!q->ce[i]) { perror("malloc"); goto clean_exit; } } if (srslte_ofdm_rx_init(&q->fft, SRSLTE_CP_NORM, in_buffer[0], q->sf_symbols, max_prb)) { fprintf(stderr, "Error initializing FFT\n"); goto clean_exit; } if (srslte_chest_dl_init(&q->chest, max_prb)) { fprintf(stderr, "Error initializing reference signal\n"); goto clean_exit; } srslte_ue_mib_reset(q); ret = SRSLTE_SUCCESS; } clean_exit: if (ret == SRSLTE_ERROR) { srslte_ue_mib_free(q); } return ret; }
int srslte_sch_init(srslte_sch_t *q) { int ret = SRSLTE_ERROR_INVALID_INPUTS; if (q) { bzero(q, sizeof(srslte_sch_t)); if (srslte_crc_init(&q->crc_tb, SRSLTE_LTE_CRC24A, 24)) { fprintf(stderr, "Error initiating CRC\n"); goto clean; } if (srslte_crc_init(&q->crc_cb, SRSLTE_LTE_CRC24B, 24)) { fprintf(stderr, "Error initiating CRC\n"); goto clean; } if (srslte_tcod_init(&q->encoder, SRSLTE_TCOD_MAX_LEN_CB)) { fprintf(stderr, "Error initiating Turbo Coder\n"); goto clean; } if (srslte_tdec_init(&q->decoder, SRSLTE_TCOD_MAX_LEN_CB)) { fprintf(stderr, "Error initiating Turbo Decoder\n"); goto clean; } // Allocate floats for reception (LLRs) q->cb_in = srslte_vec_malloc(sizeof(uint8_t) * SRSLTE_TCOD_MAX_LEN_CB); if (!q->cb_in) { goto clean; } q->cb_temp = srslte_vec_malloc(sizeof(uint8_t) * SRSLTE_TCOD_MAX_LEN_CB); if (!q->cb_temp) { goto clean; } q->cb_out = srslte_vec_malloc(sizeof(float) * (3 * SRSLTE_TCOD_MAX_LEN_CB + 12)); if (!q->cb_out) { goto clean; } if (srslte_uci_cqi_init(&q->uci_cqi)) { goto clean; } ret = SRSLTE_SUCCESS; } clean: if (ret == SRSLTE_ERROR) { srslte_sch_free(q); } return ret; }
/* Inititalizes constituent decoder object */ int map_gen_init(map_gen_t * h, int max_long_cb) { bzero(h, sizeof(map_gen_t)); h->alpha = srslte_vec_malloc(sizeof(int16_t) * (max_long_cb + SRSLTE_TCOD_TOTALTAIL + 1) * NUMSTATES); if (!h->alpha) { perror("srslte_vec_malloc"); return -1; } h->branch = srslte_vec_malloc(sizeof(int16_t) * (max_long_cb + SRSLTE_TCOD_TOTALTAIL + 1) * NUMSTATES); if (!h->branch) { perror("srslte_vec_malloc"); return -1; } h->max_long_cb = max_long_cb; return 0; }
int srslte_ofdm_init_(srslte_ofdm_t *q, srslte_cp_t cp, int symbol_sz, int nof_prb, srslte_dft_dir_t dir) { if (srslte_dft_plan_c(&q->fft_plan, symbol_sz, dir)) { fprintf(stderr, "Error: Creating DFT plan\n"); return -1; } q->tmp = srslte_vec_malloc((uint32_t) symbol_sz * sizeof(cf_t)); if (!q->tmp) { perror("malloc"); return -1; } srslte_dft_plan_set_mirror(&q->fft_plan, true); srslte_dft_plan_set_dc(&q->fft_plan, true); q->symbol_sz = (uint32_t) symbol_sz; q->nof_symbols = SRSLTE_CP_NSYMB(cp); q->cp = cp; q->freq_shift = false; q->shift_buffer = NULL; q->nof_re = nof_prb * SRSLTE_NRE; q->nof_guards = ((symbol_sz - q->nof_re) / 2); q->slot_sz = SRSLTE_SLOT_LEN(symbol_sz); DEBUG("Init %s symbol_sz=%d, nof_symbols=%d, cp=%s, nof_re=%d, nof_guards=%d\n", dir==SRSLTE_DFT_FORWARD?"FFT":"iFFT", q->symbol_sz, q->nof_symbols, q->cp==SRSLTE_CP_NORM?"Normal":"Extended", q->nof_re, q->nof_guards); return SRSLTE_SUCCESS; }
int srslte_ue_cellsearch_init_multi(srslte_ue_cellsearch_t * q, uint32_t max_frames, int (recv_callback)(void*, cf_t*[SRSLTE_MAX_PORTS], uint32_t,srslte_timestamp_t*), uint32_t nof_rx_antennas, void *stream_handler) { int ret = SRSLTE_ERROR_INVALID_INPUTS; if (q != NULL && nof_rx_antennas > 0) { ret = SRSLTE_ERROR; srslte_cell_t cell; bzero(q, sizeof(srslte_ue_cellsearch_t)); bzero(&cell, sizeof(srslte_cell_t)); cell.id = SRSLTE_CELL_ID_UNKNOWN; cell.nof_prb = SRSLTE_CS_NOF_PRB; if (srslte_ue_sync_init_multi(&q->ue_sync, cell.nof_prb, true, recv_callback, nof_rx_antennas, stream_handler)) { fprintf(stderr, "Error initiating ue_sync\n"); goto clean_exit; } if (srslte_ue_sync_set_cell(&q->ue_sync, cell)) { fprintf(stderr, "Error setting cell in ue_sync\n"); goto clean_exit; } for (int i=0;i<nof_rx_antennas;i++) { q->sf_buffer[i] = srslte_vec_malloc(3*sizeof(cf_t)*SRSLTE_SF_LEN_PRB(100)); } q->nof_rx_antennas = nof_rx_antennas; q->candidates = calloc(sizeof(srslte_ue_cellsearch_result_t), max_frames); if (!q->candidates) { perror("malloc"); goto clean_exit; } q->mode_ntimes = calloc(sizeof(uint32_t), max_frames); if (!q->mode_ntimes) { perror("malloc"); goto clean_exit; } q->mode_counted = calloc(sizeof(uint8_t), max_frames); if (!q->mode_counted) { perror("malloc"); goto clean_exit; } q->max_frames = max_frames; q->nof_valid_frames = max_frames; ret = SRSLTE_SUCCESS; } clean_exit: if (ret == SRSLTE_ERROR) { srslte_ue_cellsearch_free(q); } return ret; }
void cqi_pusch_pregen(srslte_uci_cqi_pusch_t *q) { uint8_t word[11]; for (int i=0;i<11;i++) { uint32_t nwords = (1<<(i+1)); q->cqi_table[i] = srslte_vec_malloc(sizeof(uint8_t)*nwords*32); q->cqi_table_s[i] = srslte_vec_malloc(sizeof(int16_t) * nwords * 32); for (uint32_t w=0;w<nwords;w++) { uint8_t *ptr = word; srslte_bit_unpack(w, &ptr, i+1); encode_cqi_pusch_block(word, i + 1, &q->cqi_table[i][32 * w]); for (int j=0;j<32;j++) { q->cqi_table_s[i][32*w+j] = 2*q->cqi_table[i][32*w+j]-1; } } } }
void srslte_uci_cqi_pucch_init(srslte_uci_cqi_pucch_t *q) { uint8_t word[16]; uint32_t nwords = 1 << SRSLTE_UCI_MAX_CQI_LEN_PUCCH; q->cqi_table = srslte_vec_malloc(nwords * sizeof(int8_t *)); q->cqi_table_s = srslte_vec_malloc(nwords * sizeof(int16_t *)); for (uint32_t w = 0; w < nwords; w++) { q->cqi_table[w] = srslte_vec_malloc(SRSLTE_UCI_CQI_CODED_PUCCH_B * sizeof(int8_t)); q->cqi_table_s[w] = srslte_vec_malloc(SRSLTE_UCI_CQI_CODED_PUCCH_B * sizeof(int16_t)); uint8_t *ptr = word; srslte_bit_unpack(w, &ptr, SRSLTE_UCI_MAX_CQI_LEN_PUCCH); srslte_uci_encode_cqi_pucch(word, SRSLTE_UCI_MAX_CQI_LEN_PUCCH, q->cqi_table[w]); for (int j = 0; j < SRSLTE_UCI_CQI_CODED_PUCCH_B; j++) { q->cqi_table_s[w][j] = (int16_t)(2 * q->cqi_table[w][j] - 1); } } }
int main(int argc, char **argv) { struct timeval t[3]; int ret; int decimate = 1; srslte_cell_t cell; int64_t sf_cnt; srslte_ue_mib_t ue_mib; #ifndef DISABLE_RF srslte_rf_t rf; #endif uint32_t nof_trials = 0; uint8_t bch_payload[SRSLTE_BCH_PAYLOAD_LEN]; int sfn_offset; float cfo = 0; srslte_debug_handle_crash(argc, argv); parse_args(&prog_args, argc, argv); #ifndef DISABLE_GRAPHICS if(prog_args.mbsfn_area_id > -1) { enable_mbsfn_plot = true; } #endif for (int i = 0; i< SRSLTE_MAX_CODEWORDS; i++) { data[i] = srslte_vec_malloc(sizeof(uint8_t)*1500*8); if (!data[i]) { ERROR("Allocating data"); go_exit = true; } } uint8_t mch_table[10]; bzero(&mch_table[0], sizeof(uint8_t)*10); if(prog_args.mbsfn_area_id < -1) { generate_mcch_table(mch_table, prog_args.mbsfn_sf_mask); } if(prog_args.cpu_affinity > -1) { cpu_set_t cpuset; pthread_t thread; thread = pthread_self(); for(int i = 0; i < 8;i++){ if(((prog_args.cpu_affinity >> i) & 0x01) == 1){ printf("Setting pdsch_ue with affinity to core %d\n", i); CPU_SET((size_t) i , &cpuset); } if(pthread_setaffinity_np(thread, sizeof(cpu_set_t), &cpuset)){ fprintf(stderr, "Error setting main thread affinity to %d \n", prog_args.cpu_affinity); exit(-1); } } }
void srslte_modem_table_bytes(srslte_modem_table_t* q) { uint8_t mask_qpsk[4] = {0xc0, 0x30, 0xc, 0x3}; uint8_t mask_16qam[2] = {0xf0, 0xf}; switch(q->nbits_x_symbol) { case 1: q->symbol_table_bpsk = srslte_vec_malloc(sizeof(bpsk_packed_t)*256); for (uint32_t i=0;i<256;i++) { for (int j=0;j<8;j++) { q->symbol_table_bpsk[i].symbol[j] = q->symbol_table[(i&(1<<(7-j)))>>(7-j)]; } } q->byte_tables_init = true; break; case 2: q->symbol_table_qpsk = srslte_vec_malloc(sizeof(qpsk_packed_t)*256); for (uint32_t i=0;i<256;i++) { for (int j=0;j<4;j++) { q->symbol_table_qpsk[i].symbol[j] = q->symbol_table[(i&mask_qpsk[j])>>(6-j*2)]; } } q->byte_tables_init = true; break; case 4: q->symbol_table_16qam = srslte_vec_malloc(sizeof(qam16_packed_t)*256); for (uint32_t i=0;i<256;i++) { for (int j=0;j<2;j++) { q->symbol_table_16qam[i].symbol[j] = q->symbol_table[(i&mask_16qam[j])>>(4-j*4)]; } } q->byte_tables_init = true; break; case 6: q->byte_tables_init = true; break; } }
int srslte_pdsch_enable_csi(srslte_pdsch_t *q, bool enable) { if (enable) { for (int i = 0; i < SRSLTE_MAX_CODEWORDS; i++) { if (!q->csi[i]) { q->csi[i] = srslte_vec_malloc(sizeof(float) * q->max_re); if (!q->csi[i]) { return SRSLTE_ERROR; } } } } q->csi_enabled = enable; return SRSLTE_SUCCESS; }
int srslte_interp_linear_vector_init(srslte_interp_linsrslte_vec_t *q, uint32_t vector_len) { int ret = SRSLTE_ERROR_INVALID_INPUTS; if (q) { bzero(q, sizeof(srslte_interp_linsrslte_vec_t)); ret = SRSLTE_SUCCESS; q->diff_vec = srslte_vec_malloc(vector_len * sizeof(cf_t)); if (!q->diff_vec) { perror("malloc"); return SRSLTE_ERROR; } q->vector_len = vector_len; } return ret; }
int srslte_agc_init_acc(srslte_agc_t *q, srslte_agc_mode_t mode, uint32_t nof_frames) { bzero(q, sizeof(srslte_agc_t)); q->mode = mode; q->nof_frames = nof_frames; if (nof_frames > 0) { q->y_tmp = srslte_vec_malloc(sizeof(float) * nof_frames); if (!q->y_tmp) { return SRSLTE_ERROR; } } else { q->y_tmp = NULL; } q->target = SRSLTE_AGC_DEFAULT_TARGET; srslte_agc_reset(q); return SRSLTE_SUCCESS; }
int srslte_ue_sync_init_file(srslte_ue_sync_t *q, uint32_t nof_prb, char *file_name, int offset_time, float offset_freq) { int ret = SRSLTE_ERROR_INVALID_INPUTS; if (q != NULL && file_name != NULL && srslte_nofprb_isvalid(nof_prb)) { ret = SRSLTE_ERROR; bzero(q, sizeof(srslte_ue_sync_t)); q->file_mode = true; q->sf_len = SRSLTE_SF_LEN(srslte_symbol_sz(nof_prb)); q->file_cfo = -offset_freq; q->correct_cfo = true; q->fft_size = srslte_symbol_sz(nof_prb); if (srslte_cfo_init(&q->file_cfo_correct, 2*q->sf_len)) { fprintf(stderr, "Error initiating CFO\n"); goto clean_exit; } if (srslte_filesource_init(&q->file_source, file_name, SRSLTE_COMPLEX_FLOAT_BIN)) { fprintf(stderr, "Error opening file %s\n", file_name); goto clean_exit; } q->input_buffer = srslte_vec_malloc(2 * q->sf_len * sizeof(cf_t)); if (!q->input_buffer) { perror("malloc"); goto clean_exit; } INFO("Offseting input file by %d samples and %.1f kHz\n", offset_time, offset_freq/1000); srslte_filesource_read(&q->file_source, dummy_offset_buffer, offset_time); srslte_ue_sync_reset(q); ret = SRSLTE_SUCCESS; } clean_exit: if (ret == SRSLTE_ERROR) { srslte_ue_sync_free(q); } return ret; }
/* the gateway function */ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { srslte_viterbi_t viterbi; float *input_llr; uint8_t *output_data; int nof_bits; if (nrhs < NOF_INPUTS) { help(); return; } // Read input symbols nof_bits = mexutils_read_f(INPUT, &input_llr); output_data = srslte_vec_malloc(nof_bits * sizeof(uint8_t)); uint32_t poly[3] = { 0x6D, 0x4F, 0x57 }; if (srslte_viterbi_init(&viterbi, SRSLTE_VITERBI_37, poly, nof_bits/3, true)) { return; } if (nrhs >= 2) { float gain_quant = mxGetScalar(prhs[1]); srslte_viterbi_set_gain_quant(&viterbi, gain_quant); } srslte_viterbi_decode_f(&viterbi, input_llr, output_data, nof_bits/3); if (nlhs >= 1) { mexutils_write_uint8(output_data, &plhs[0], nof_bits/3, 1); } if (nlhs >= 2) { mexutils_write_uint8(viterbi.symbols_uc, &plhs[1], nof_bits/3, 1); } srslte_viterbi_free(&viterbi); free(input_llr); free(output_data); return; }
int srslte_ue_mib_sync_init_multi(srslte_ue_mib_sync_t *q, int (recv_callback)(void*, cf_t*[SRSLTE_MAX_PORTS], uint32_t, srslte_timestamp_t*), uint32_t nof_rx_antennas, void *stream_handler) { for (int i=0;i<nof_rx_antennas;i++) { q->sf_buffer[i] = srslte_vec_malloc(3*sizeof(cf_t)*SRSLTE_SF_LEN_PRB(SRSLTE_UE_MIB_NOF_PRB)); } q->nof_rx_antennas = nof_rx_antennas; if (srslte_ue_mib_init(&q->ue_mib, q->sf_buffer, SRSLTE_UE_MIB_NOF_PRB)) { fprintf(stderr, "Error initiating ue_mib\n"); return SRSLTE_ERROR; } if (srslte_ue_sync_init_multi(&q->ue_sync, SRSLTE_UE_MIB_NOF_PRB, false, recv_callback, nof_rx_antennas, stream_handler)) { fprintf(stderr, "Error initiating ue_sync\n"); srslte_ue_mib_free(&q->ue_mib); return SRSLTE_ERROR; } srslte_ue_sync_decode_sss_on_track(&q->ue_sync, true); return SRSLTE_SUCCESS; }
/* Shifts the signal after the iFFT or before the FFT. * Freq_shift is relative to inter-carrier spacing. * Caution: This function shall not be called during run-time */ int srslte_ofdm_set_freq_shift(srslte_ofdm_t *q, float freq_shift) { q->shift_buffer = srslte_vec_malloc(sizeof(cf_t) * SRSLTE_SF_LEN(q->symbol_sz)); if (!q->shift_buffer) { perror("malloc"); return -1; } cf_t *ptr = q->shift_buffer; for (uint32_t n=0;n<2;n++) { for (uint32_t i=0;i<q->nof_symbols;i++) { uint32_t cplen = SRSLTE_CP_ISNORM(q->cp)?SRSLTE_CP_LEN_NORM(i, q->symbol_sz):SRSLTE_CP_LEN_EXT(q->symbol_sz); for (uint32_t t=0;t<q->symbol_sz+cplen;t++) { ptr[t] = cexpf(I*2*M_PI*((float) t-(float)cplen)*freq_shift/q->symbol_sz); } ptr += q->symbol_sz+cplen; } } /* Disable DC carrier addition */ srslte_dft_plan_set_dc(&q->fft_plan, false); q->freq_shift = true; return SRSLTE_SUCCESS; }
int srslte_pmch_init_multi(srslte_pmch_t *q, uint32_t max_prb, uint32_t nof_rx_antennas) { int ret = SRSLTE_ERROR_INVALID_INPUTS; if (q != NULL && nof_rx_antennas <= SRSLTE_MAX_PORTS) { bzero(q, sizeof(srslte_pmch_t)); ret = SRSLTE_ERROR; q->cell.nof_prb = max_prb; q->cell.nof_ports = 1; q->max_re = max_prb * MAX_PMCH_RE; q->nof_rx_antennas = nof_rx_antennas; INFO("Init PMCH: %d PRBs, max_symbols: %d\n", max_prb, q->max_re); for (int i = 0; i < 4; i++) { if (srslte_modem_table_lte(&q->mod[i], modulations[i])) { goto clean; } srslte_modem_table_bytes(&q->mod[i]); } srslte_sch_init(&q->dl_sch); // Allocate int16_t for reception (LLRs) q->e = srslte_vec_malloc(sizeof(int16_t) * q->max_re * srslte_mod_bits_x_symbol(SRSLTE_MOD_64QAM)); if (!q->e) { goto clean; } q->d = srslte_vec_malloc(sizeof(cf_t) * q->max_re); if (!q->d) { goto clean; } for (int i = 0; i < SRSLTE_MAX_PORTS; i++) { q->x[i] = srslte_vec_malloc(sizeof(cf_t) * q->max_re); if (!q->x[i]) { goto clean; } for (int j=0;j<q->nof_rx_antennas;j++) { q->ce[i][j] = srslte_vec_malloc(sizeof(cf_t) * q->max_re); if (!q->ce[i][j]) { goto clean; } } } for (int j=0;j<q->nof_rx_antennas;j++) { q->symbols[j] = srslte_vec_malloc(sizeof(cf_t) * q->max_re); if (!q->symbols[j]) { goto clean; } } q->seqs = calloc(SRSLTE_MAX_MBSFN_AREA_IDS, sizeof(srslte_pmch_seq_t*)); if (!q->seqs) { perror("calloc"); goto clean; } ret = SRSLTE_SUCCESS; } clean: if (ret == SRSLTE_ERROR) { srslte_pmch_free(q); } return ret; }
/* Initializes the turbo decoder object */ int srslte_tdec_sse_init(srslte_tdec_sse_t * h, uint32_t max_long_cb) { int ret = -1; bzero(h, sizeof(srslte_tdec_sse_t)); uint32_t len = max_long_cb + SRSLTE_TCOD_TOTALTAIL; h->max_long_cb = max_long_cb; h->app1 = srslte_vec_malloc(sizeof(int16_t) * len); if (!h->app1) { perror("srslte_vec_malloc"); goto clean_and_exit; } h->app2 = srslte_vec_malloc(sizeof(int16_t) * len); if (!h->app2) { perror("srslte_vec_malloc"); goto clean_and_exit; } h->ext1 = srslte_vec_malloc(sizeof(int16_t) * len); if (!h->ext1) { perror("srslte_vec_malloc"); goto clean_and_exit; } h->ext2 = srslte_vec_malloc(sizeof(int16_t) * len); if (!h->ext2) { perror("srslte_vec_malloc"); goto clean_and_exit; } h->syst = srslte_vec_malloc(sizeof(int16_t) * len); if (!h->syst) { perror("srslte_vec_malloc"); goto clean_and_exit; } h->parity0 = srslte_vec_malloc(sizeof(int16_t) * len); if (!h->parity0) { perror("srslte_vec_malloc"); goto clean_and_exit; } h->parity1 = srslte_vec_malloc(sizeof(int16_t) * len); if (!h->parity1) { perror("srslte_vec_malloc"); goto clean_and_exit; } if (map_gen_init(&h->dec, h->max_long_cb)) { goto clean_and_exit; } for (int i=0;i<SRSLTE_NOF_TC_CB_SIZES;i++) { if (srslte_tc_interl_init(&h->interleaver[i], srslte_cbsegm_cbsize(i)) < 0) { goto clean_and_exit; } srslte_tc_interl_LTE_gen(&h->interleaver[i], srslte_cbsegm_cbsize(i)); } h->current_cbidx = -1; ret = 0; clean_and_exit:if (ret == -1) { srslte_tdec_sse_free(h); } return ret; }
/* Initializes the PSS synchronization object. * * It correlates a signal of frame_size samples with the PSS sequence in the frequency * domain. The PSS sequence is transformed using fft_size samples. */ int srslte_pss_synch_init_fft_offset(srslte_pss_synch_t *q, uint32_t frame_size, uint32_t fft_size, int offset) { int ret = SRSLTE_ERROR_INVALID_INPUTS; if (q != NULL) { uint32_t N_id_2; uint32_t buffer_size; bzero(q, sizeof(srslte_pss_synch_t)); q->N_id_2 = 10; q->fft_size = fft_size; q->frame_size = frame_size; q->ema_alpha = 0.1; buffer_size = fft_size + frame_size + 1; if (srslte_dft_plan(&q->dftp_input, fft_size, SRSLTE_DFT_FORWARD, SRSLTE_DFT_COMPLEX)) { fprintf(stderr, "Error creating DFT plan \n"); goto clean_and_exit; } srslte_dft_plan_set_mirror(&q->dftp_input, true); srslte_dft_plan_set_dc(&q->dftp_input, true); srslte_dft_plan_set_norm(&q->dftp_input, true); q->tmp_input = srslte_vec_malloc(buffer_size * sizeof(cf_t)); if (!q->tmp_input) { fprintf(stderr, "Error allocating memory\n"); goto clean_and_exit; } bzero(&q->tmp_input[q->frame_size], q->fft_size * sizeof(cf_t)); q->conv_output = srslte_vec_malloc(buffer_size * sizeof(cf_t)); if (!q->conv_output) { fprintf(stderr, "Error allocating memory\n"); goto clean_and_exit; } bzero(q->conv_output, sizeof(cf_t) * buffer_size); q->conv_output_avg = srslte_vec_malloc(buffer_size * sizeof(float)); if (!q->conv_output_avg) { fprintf(stderr, "Error allocating memory\n"); goto clean_and_exit; } bzero(q->conv_output_avg, sizeof(float) * buffer_size); #ifdef SRSLTE_PSS_ACCUMULATE_ABS q->conv_output_abs = srslte_vec_malloc(buffer_size * sizeof(float)); if (!q->conv_output_abs) { fprintf(stderr, "Error allocating memory\n"); goto clean_and_exit; } bzero(q->conv_output_abs, sizeof(float) * buffer_size); #endif for (N_id_2=0;N_id_2<3;N_id_2++) { q->pss_signal_time[N_id_2] = srslte_vec_malloc(buffer_size * sizeof(cf_t)); if (!q->pss_signal_time[N_id_2]) { fprintf(stderr, "Error allocating memory\n"); goto clean_and_exit; } /* The PSS is translated into the time domain for each N_id_2 */ if (srslte_pss_synch_init_N_id_2(q->pss_signal_freq[N_id_2], q->pss_signal_time[N_id_2], N_id_2, fft_size, offset)) { fprintf(stderr, "Error initiating PSS detector for N_id_2=%d fft_size=%d\n", N_id_2, fft_size); goto clean_and_exit; } bzero(&q->pss_signal_time[N_id_2][q->fft_size], q->frame_size * sizeof(cf_t)); } #ifdef CONVOLUTION_FFT if (srslte_conv_fft_cc_init(&q->conv_fft, frame_size, fft_size)) { fprintf(stderr, "Error initiating convolution FFT\n"); goto clean_and_exit; } #endif srslte_pss_synch_reset(q); ret = SRSLTE_SUCCESS; } clean_and_exit: if (ret == SRSLTE_ERROR) { srslte_pss_synch_free(q); } return ret; }
int main(int argc, char **argv) { srslte_pucch_t pucch; srslte_pucch_cfg_t pucch_cfg; srslte_refsignal_ul_t dmrs; uint8_t bits[SRSLTE_PUCCH_MAX_BITS]; uint8_t pucch2_bits[2]; cf_t *sf_symbols = NULL; cf_t pucch_dmrs[2*SRSLTE_NRE*3]; int ret = -1; parse_args(argc,argv); if (srslte_pucch_init(&pucch, cell)) { fprintf(stderr, "Error creating PDSCH object\n"); goto quit; } if (srslte_refsignal_ul_init(&dmrs, cell)) { fprintf(stderr, "Error creating PDSCH object\n"); goto quit; } bzero(&pucch_cfg, sizeof(srslte_pucch_cfg_t)); for (int i=0;i<SRSLTE_PUCCH_MAX_BITS;i++) { bits[i] = i%2; } for (int i=0;i<2;i++) { pucch2_bits[i] = i%2; } if (srslte_pucch_set_crnti(&pucch, 11)) { fprintf(stderr, "Error setting C-RNTI\n"); goto quit; } sf_symbols = srslte_vec_malloc(sizeof(cf_t) * SRSLTE_SF_LEN_RE(cell.nof_prb, cell.cp)); if (!sf_symbols) { goto quit; } srslte_pucch_format_t format; for (format=0;format<=SRSLTE_PUCCH_FORMAT_2B;format++) { for (uint32_t d=1;d<=3;d++) { for (uint32_t ncs=0;ncs<8;ncs+=d) { for (uint32_t n_pucch=1;n_pucch<130;n_pucch+=50) { struct timeval t[3]; pucch_cfg.delta_pucch_shift = d; bool group_hopping_en = false; pucch_cfg.N_cs = ncs; pucch_cfg.n_rb_2 = 0; gettimeofday(&t[1], NULL); if (!srslte_pucch_set_cfg(&pucch, &pucch_cfg, group_hopping_en)) { fprintf(stderr, "Error setting PUCCH config\n"); goto quit; } if (srslte_pucch_encode(&pucch, format, n_pucch, subframe, bits, sf_symbols)) { fprintf(stderr, "Error encoding PUCCH\n"); goto quit; } srslte_refsignal_dmrs_pusch_cfg_t pusch_cfg; pusch_cfg.group_hopping_en = group_hopping_en; pusch_cfg.sequence_hopping_en = false; srslte_refsignal_ul_set_cfg(&dmrs, &pusch_cfg, &pucch_cfg, NULL); if (srslte_refsignal_dmrs_pucch_gen(&dmrs, format, n_pucch, subframe, pucch2_bits, pucch_dmrs)) { fprintf(stderr, "Error encoding PUCCH\n"); goto quit; } if (srslte_refsignal_dmrs_pucch_put(&dmrs, format, n_pucch, pucch_dmrs, sf_symbols)) { fprintf(stderr, "Error encoding PUCCH\n"); goto quit; } gettimeofday(&t[2], NULL); get_time_interval(t); INFO("format %d, n_pucch: %d, ncs: %d, d: %d, t_exec=%d us\n", format, n_pucch, ncs, d, t[0].tv_usec); } } } } ret = 0; quit: srslte_pucch_free(&pucch); srslte_refsignal_ul_free(&dmrs); if (sf_symbols) { free(sf_symbols); } if (ret) { printf("Error\n"); } else { printf("Ok\n"); } exit(ret); }
int main(int argc, char **argv) { int ret; cf_t *sf_buffer; prog_args_t prog_args; srslte_cell_t cell; int64_t sf_cnt; srslte_ue_sync_t ue_sync; srslte_ue_mib_t ue_mib; void *uhd; srslte_ue_dl_t ue_dl; srslte_ofdm_t fft; srslte_chest_dl_t chest; uint32_t nframes=0; uint32_t nof_trials = 0; uint32_t sfn = 0; // system frame number int n; uint8_t bch_payload[SRSLTE_BCH_PAYLOAD_LEN]; uint32_t sfn_offset; float rssi_utra=0,rssi=0, rsrp=0, rsrq=0, snr=0; cf_t *ce[SRSLTE_MAX_PORTS]; if (parse_args(&prog_args, argc, argv)) { exit(-1); } if (prog_args.uhd_gain > 0) { printf("Opening UHD device...\n"); if (cuhd_open(prog_args.uhd_args, &uhd)) { fprintf(stderr, "Error opening uhd\n"); exit(-1); } cuhd_set_rx_gain(uhd, prog_args.uhd_gain); } else { printf("Opening UHD device with threaded RX Gain control ...\n"); if (cuhd_open_th(prog_args.uhd_args, &uhd, false)) { fprintf(stderr, "Error opening uhd\n"); exit(-1); } cuhd_set_rx_gain(uhd, 50); } sigset_t sigset; sigemptyset(&sigset); sigaddset(&sigset, SIGINT); sigprocmask(SIG_UNBLOCK, &sigset, NULL); signal(SIGINT, sig_int_handler); cuhd_set_master_clock_rate(uhd, 30.72e6); /* set receiver frequency */ cuhd_set_rx_freq(uhd, (double) prog_args.uhd_freq); cuhd_rx_wait_lo_locked(uhd); printf("Tunning receiver to %.3f MHz\n", (double ) prog_args.uhd_freq/1000000); uint32_t ntrial=0; do { ret = cuhd_search_and_decode_mib(uhd, &cell_detect_config, prog_args.force_N_id_2, &cell); if (ret < 0) { fprintf(stderr, "Error searching for cell\n"); exit(-1); } else if (ret == 0 && !go_exit) { printf("Cell not found after %d trials. Trying again (Press Ctrl+C to exit)\n", ntrial++); } } while (ret == 0 && !go_exit); if (go_exit) { exit(0); } /* set sampling frequency */ int srate = srslte_sampling_freq_hz(cell.nof_prb); if (srate != -1) { if (srate < 10e6) { cuhd_set_master_clock_rate(uhd, 4*srate); } else { cuhd_set_master_clock_rate(uhd, srate); } printf("Setting sampling rate %.2f MHz\n", (float) srate/1000000); float srate_uhd = cuhd_set_rx_srate(uhd, (double) srate); if (srate_uhd != srate) { fprintf(stderr, "Could not set sampling rate\n"); exit(-1); } } else { fprintf(stderr, "Invalid number of PRB %d\n", cell.nof_prb); exit(-1); } INFO("Stopping UHD and flushing buffer...\n",0); cuhd_stop_rx_stream(uhd); cuhd_flush_buffer(uhd); if (srslte_ue_sync_init(&ue_sync, cell, cuhd_recv_wrapper, uhd)) { fprintf(stderr, "Error initiating ue_sync\n"); return -1; } if (srslte_ue_dl_init(&ue_dl, cell)) { fprintf(stderr, "Error initiating UE downlink processing module\n"); return -1; } if (srslte_ue_mib_init(&ue_mib, cell)) { fprintf(stderr, "Error initaiting UE MIB decoder\n"); return -1; } /* Configure downlink receiver for the SI-RNTI since will be the only one we'll use */ srslte_ue_dl_set_rnti(&ue_dl, SRSLTE_SIRNTI); /* Initialize subframe counter */ sf_cnt = 0; if (srslte_ofdm_rx_init(&fft, cell.cp, cell.nof_prb)) { fprintf(stderr, "Error initiating FFT\n"); return -1; } if (srslte_chest_dl_init(&chest, cell)) { fprintf(stderr, "Error initiating channel estimator\n"); return -1; } int sf_re = SRSLTE_SF_LEN_RE(cell.nof_prb, cell.cp); cf_t *sf_symbols = srslte_vec_malloc(sf_re * sizeof(cf_t)); for (int i=0;i<SRSLTE_MAX_PORTS;i++) { ce[i] = srslte_vec_malloc(sizeof(cf_t) * sf_re); } cuhd_start_rx_stream(uhd); float rx_gain_offset = 0; /* Main loop */ while ((sf_cnt < prog_args.nof_subframes || prog_args.nof_subframes == -1) && !go_exit) { ret = srslte_ue_sync_get_buffer(&ue_sync, &sf_buffer); if (ret < 0) { fprintf(stderr, "Error calling srslte_ue_sync_work()\n"); } /* srslte_ue_sync_get_buffer returns 1 if successfully read 1 aligned subframe */ if (ret == 1) { switch (state) { case DECODE_MIB: if (srslte_ue_sync_get_sfidx(&ue_sync) == 0) { srslte_pbch_decode_reset(&ue_mib.pbch); n = srslte_ue_mib_decode(&ue_mib, sf_buffer, bch_payload, NULL, &sfn_offset); if (n < 0) { fprintf(stderr, "Error decoding UE MIB\n"); return -1; } else if (n == SRSLTE_UE_MIB_FOUND) { srslte_pbch_mib_unpack(bch_payload, &cell, &sfn); printf("Decoded MIB. SFN: %d, offset: %d\n", sfn, sfn_offset); sfn = (sfn + sfn_offset)%1024; state = DECODE_SIB; } } break; case DECODE_SIB: /* We are looking for SI Blocks, search only in appropiate places */ if ((srslte_ue_sync_get_sfidx(&ue_sync) == 5 && (sfn%2)==0)) { n = srslte_ue_dl_decode_rnti_rv(&ue_dl, sf_buffer, data, srslte_ue_sync_get_sfidx(&ue_sync), SRSLTE_SIRNTI, ((int) ceilf((float)3*(((sfn)/2)%4)/2))%4); if (n < 0) { fprintf(stderr, "Error decoding UE DL\n");fflush(stdout); return -1; } else if (n == 0) { printf("CFO: %+6.4f KHz, SFO: %+6.4f Khz, NOI: %.2f, PDCCH-Det: %.3f\r", srslte_ue_sync_get_cfo(&ue_sync)/1000, srslte_ue_sync_get_sfo(&ue_sync)/1000, srslte_sch_average_noi(&ue_dl.pdsch.dl_sch), (float) ue_dl.nof_detected/nof_trials); nof_trials++; } else { printf("Decoded SIB1. Payload: "); srslte_vec_fprint_byte(stdout, data, n/8);; state = MEASURE; } } break; case MEASURE: if (srslte_ue_sync_get_sfidx(&ue_sync) == 5) { /* Run FFT for all subframe data */ srslte_ofdm_rx_sf(&fft, sf_buffer, sf_symbols); srslte_chest_dl_estimate(&chest, sf_symbols, ce, srslte_ue_sync_get_sfidx(&ue_sync)); rssi = SRSLTE_VEC_EMA(srslte_vec_avg_power_cf(sf_buffer,SRSLTE_SF_LEN(srslte_symbol_sz(cell.nof_prb))),rssi,0.05); rssi_utra = SRSLTE_VEC_EMA(srslte_chest_dl_get_rssi(&chest),rssi_utra,0.05); rsrq = SRSLTE_VEC_EMA(srslte_chest_dl_get_rsrq(&chest),rsrq,0.05); rsrp = SRSLTE_VEC_EMA(srslte_chest_dl_get_rsrp(&chest),rsrp,0.05); snr = SRSLTE_VEC_EMA(srslte_chest_dl_get_snr(&chest),snr,0.05); nframes++; } if ((nframes%100) == 0 || rx_gain_offset == 0) { if (cuhd_has_rssi(uhd)) { rx_gain_offset = 10*log10(rssi)-cuhd_get_rssi(uhd); } else { rx_gain_offset = cuhd_get_rx_gain(uhd); } } // Plot and Printf if ((nframes%10) == 0) { printf("CFO: %+8.4f KHz, SFO: %+8.4f Khz, RSSI: %5.1f dBm, RSSI/ref-symbol: %+5.1f dBm, " "RSRP: %+5.1f dBm, RSRQ: %5.1f dB, SNR: %5.1f dB\r", srslte_ue_sync_get_cfo(&ue_sync)/1000, srslte_ue_sync_get_sfo(&ue_sync)/1000, 10*log10(rssi*1000) - rx_gain_offset, 10*log10(rssi_utra*1000)- rx_gain_offset, 10*log10(rsrp*1000) - rx_gain_offset, 10*log10(rsrq), 10*log10(snr)); if (srslte_verbose != SRSLTE_VERBOSE_NONE) { printf("\n"); } } break; } if (srslte_ue_sync_get_sfidx(&ue_sync) == 9) { sfn++; if (sfn == 1024) { sfn = 0; } } } else if (ret == 0) { printf("Finding PSS... Peak: %8.1f, FrameCnt: %d, State: %d\r", srslte_sync_get_peak_value(&ue_sync.sfind), ue_sync.frame_total_cnt, ue_sync.state); } sf_cnt++; } // Main loop srslte_ue_sync_free(&ue_sync); cuhd_close(uhd); printf("\nBye\n"); exit(0); }
int srslte_sync_init(srslte_sync_t *q, uint32_t frame_size, uint32_t max_offset, uint32_t fft_size) { int ret = SRSLTE_ERROR_INVALID_INPUTS; if (q != NULL && frame_size <= 307200 && fft_size_isvalid(fft_size)) { ret = SRSLTE_ERROR; bzero(q, sizeof(srslte_sync_t)); q->detect_cp = true; q->mean_peak_value = 0.0; q->sss_en = true; q->mean_cfo = 0; q->N_id_2 = 1000; q->N_id_1 = 1000; q->cfo_i = 0; q->find_cfo_i = false; q->find_cfo_i_initiated = false; q->cfo_ema_alpha = CFO_EMA_ALPHA; q->fft_size = fft_size; q->frame_size = frame_size; q->max_offset = max_offset; q->sss_alg = SSS_PARTIAL_3; q->enable_cfo_corr = true; for (int i=0;i<2;i++) { q->cfo_i_corr[i] = srslte_vec_malloc(sizeof(cf_t)*q->frame_size); if (!q->cfo_i_corr[i]) { perror("malloc"); goto clean_exit; } } srslte_sync_set_cp(q, SRSLTE_CP_NORM); if (srslte_pss_synch_init_fft(&q->pss, max_offset, fft_size)) { fprintf(stderr, "Error initializing PSS object\n"); goto clean_exit; } if (srslte_sss_synch_init(&q->sss, fft_size)) { fprintf(stderr, "Error initializing SSS object\n"); goto clean_exit; } if (srslte_cfo_init(&q->cfocorr, frame_size)) { fprintf(stderr, "Error initiating CFO\n"); goto clean_exit; } if (srslte_cp_synch_init(&q->cp_synch, fft_size)) { fprintf(stderr, "Error initiating CFO\n"); goto clean_exit; } DEBUG("SYNC init with frame_size=%d, max_offset=%d and fft_size=%d\n", frame_size, max_offset, fft_size); ret = SRSLTE_SUCCESS; } else { fprintf(stderr, "Invalid parameters frame_size: %d, fft_size: %d\n", frame_size, fft_size); } clean_exit: if (ret == SRSLTE_ERROR) { srslte_sync_free(q); } return ret; }
int main(int argc, char **argv) { int i; srslte_modem_table_t mod; uint8_t *input, *input_bytes, *output; cf_t *symbols, *symbols_bytes; float *llr, *llr2; parse_args(argc, argv); /* initialize objects */ if (srslte_modem_table_lte(&mod, modulation)) { fprintf(stderr, "Error initializing modem table\n"); exit(-1); } srslte_modem_table_bytes(&mod); /* check that num_bits is multiple of num_bits x symbol */ if (num_bits % mod.nbits_x_symbol) { fprintf(stderr, "Error num_bits must be multiple of %d\n", mod.nbits_x_symbol); exit(-1); } /* allocate buffers */ input = srslte_vec_malloc(sizeof(uint8_t) * num_bits); if (!input) { perror("malloc"); exit(-1); } input_bytes = srslte_vec_malloc(sizeof(uint8_t) * num_bits/8); if (!input_bytes) { perror("malloc"); exit(-1); } output = srslte_vec_malloc(sizeof(uint8_t) * num_bits); if (!output) { perror("malloc"); exit(-1); } symbols = srslte_vec_malloc(sizeof(cf_t) * num_bits / mod.nbits_x_symbol); if (!symbols) { perror("malloc"); exit(-1); } symbols_bytes = srslte_vec_malloc(sizeof(cf_t) * num_bits / mod.nbits_x_symbol); if (!symbols_bytes) { perror("malloc"); exit(-1); } llr = srslte_vec_malloc(sizeof(float) * num_bits); if (!llr) { perror("malloc"); exit(-1); } llr2 = srslte_vec_malloc(sizeof(float) * num_bits); if (!llr2) { perror("malloc"); exit(-1); } /* generate random data */ for (i=0;i<num_bits;i++) { input[i] = rand()%2; } /* modulate */ struct timeval t[3]; gettimeofday(&t[1], NULL); int ntrials = 100; for (int i=0;i<ntrials;i++) { srslte_mod_modulate(&mod, input, symbols, num_bits); } gettimeofday(&t[2], NULL); get_time_interval(t); printf("Bit: %d us\n", t[0].tv_usec); /* Test packed implementation */ srslte_bit_pack_vector(input, input_bytes, num_bits); gettimeofday(&t[1], NULL); for (int i=0;i<ntrials;i++) { srslte_mod_modulate_bytes(&mod, input_bytes, symbols_bytes, num_bits); } gettimeofday(&t[2], NULL); get_time_interval(t); printf("Byte: %d us\n", t[0].tv_usec); for (int i=0;i<num_bits/mod.nbits_x_symbol;i++) { if (symbols[i] != symbols_bytes[i]) { printf("error in symbol %d\n", i); exit(-1); } } printf("Symbols OK\n"); /* demodulate */ gettimeofday(&x, NULL); srslte_demod_soft_demodulate(modulation, symbols, llr, num_bits / mod.nbits_x_symbol); gettimeofday(&y, NULL); printf("\nElapsed time [ns]: %d\n", (int) y.tv_usec - (int) x.tv_usec); for (i=0;i<num_bits;i++) { output[i] = llr[i]>=0 ? 1 : 0; } /* check errors */ for (i=0;i<num_bits;i++) { if (input[i] != output[i]) { fprintf(stderr, "Error in bit %d\n", i); exit(-1); } } free(llr); free(symbols); free(symbols_bytes); free(output); free(input); free(input_bytes); srslte_modem_table_free(&mod); printf("Ok\n"); exit(0); }
int srslte_chest_ul_init(srslte_chest_ul_t *q, uint32_t max_prb) { int ret = SRSLTE_ERROR_INVALID_INPUTS; if (q != NULL) { bzero(q, sizeof(srslte_chest_ul_t)); ret = srslte_refsignal_ul_init(&q->dmrs_signal, max_prb); if (ret != SRSLTE_SUCCESS) { fprintf(stderr, "Error initializing CSR signal (%d)\n",ret); goto clean_exit; } q->tmp_noise = srslte_vec_malloc(sizeof(cf_t) * MAX_REFS_SF); if (!q->tmp_noise) { perror("malloc"); goto clean_exit; } q->pilot_estimates = srslte_vec_malloc(sizeof(cf_t) * MAX_REFS_SF); if (!q->pilot_estimates) { perror("malloc"); goto clean_exit; } for (int i=0;i<4;i++) { q->pilot_estimates_tmp[i] = srslte_vec_malloc(sizeof(cf_t) * MAX_REFS_SF); if (!q->pilot_estimates_tmp[i]) { perror("malloc"); goto clean_exit; } } q->pilot_recv_signal = srslte_vec_malloc(sizeof(cf_t) * (MAX_REFS_SF+1)); if (!q->pilot_recv_signal) { perror("malloc"); goto clean_exit; } q->pilot_known_signal = srslte_vec_malloc(sizeof(cf_t) * (MAX_REFS_SF+1)); if (!q->pilot_known_signal) { perror("malloc"); goto clean_exit; } if (srslte_interp_linear_vector_init(&q->srslte_interp_linvec, MAX_REFS_SYM)) { fprintf(stderr, "Error initializing vector interpolator\n"); goto clean_exit; } q->smooth_filter_len = 3; srslte_chest_ul_set_smooth_filter3_coeff(q, 0.3333); q->dmrs_signal_configured = false; if (srslte_refsignal_dmrs_pusch_pregen_init(&q->dmrs_signal, &q->dmrs_pregen, max_prb)) { fprintf(stderr, "Error allocating memory for pregenerated signals\n"); goto clean_exit; } } ret = SRSLTE_SUCCESS; clean_exit: if (ret != SRSLTE_SUCCESS) { srslte_chest_ul_free(q); } return ret; }
/* Initializes the PSS synchronization object. * * It correlates a signal of frame_size samples with the PSS sequence in the frequency * domain. The PSS sequence is transformed using fft_size samples. */ int srslte_pss_init_fft_offset_decim(srslte_pss_t *q, uint32_t max_frame_size, uint32_t max_fft_size, int offset, int decimate) { int ret = SRSLTE_ERROR_INVALID_INPUTS; if (q != NULL) { ret = SRSLTE_ERROR; uint32_t N_id_2; uint32_t buffer_size; bzero(q, sizeof(srslte_pss_t)); q->N_id_2 = 10; q->ema_alpha = 0.2; q->max_fft_size = max_fft_size; q->max_frame_size = max_frame_size; q->decimate = decimate; uint32_t fft_size = max_fft_size/q->decimate; uint32_t frame_size = max_frame_size/q->decimate; q->fft_size = fft_size; q->frame_size = frame_size; buffer_size = fft_size + frame_size + 1; q->filter_pss_enable = false; q->chest_on_filter = false; if(q->decimate > 1) { int filter_order = 3; srslte_filt_decim_cc_init(&q->filter,q->decimate,filter_order); q->filter.filter_output = srslte_vec_malloc((buffer_size) * sizeof(cf_t)); q->filter.downsampled_input = srslte_vec_malloc((buffer_size + filter_order) * sizeof(cf_t)); printf("decimation for the PSS search is %d \n",q->decimate); } if (srslte_dft_plan(&q->dftp_input, fft_size, SRSLTE_DFT_FORWARD, SRSLTE_DFT_COMPLEX)) { ERROR("Error creating DFT plan \n"); goto clean_and_exit; } srslte_dft_plan_set_mirror(&q->dftp_input, true); srslte_dft_plan_set_dc(&q->dftp_input, true); srslte_dft_plan_set_norm(&q->dftp_input, false); if (srslte_dft_plan(&q->idftp_input, fft_size, SRSLTE_DFT_BACKWARD, SRSLTE_DFT_COMPLEX)) { ERROR("Error creating DFT plan \n"); goto clean_and_exit; } srslte_dft_plan_set_mirror(&q->idftp_input, true); srslte_dft_plan_set_dc(&q->idftp_input, true); srslte_dft_plan_set_norm(&q->idftp_input, false); bzero(q->tmp_fft2, sizeof(cf_t)*SRSLTE_SYMBOL_SZ_MAX); q->tmp_input = srslte_vec_malloc((buffer_size + frame_size*(q->decimate - 1)) * sizeof(cf_t)); if (!q->tmp_input) { ERROR("Error allocating memory\n"); goto clean_and_exit; } bzero(&q->tmp_input[q->frame_size], q->fft_size * sizeof(cf_t)); q->conv_output = srslte_vec_malloc(buffer_size * sizeof(cf_t)); if (!q->conv_output) { ERROR("Error allocating memory\n"); goto clean_and_exit; } bzero(q->conv_output, sizeof(cf_t) * buffer_size); q->conv_output_avg = srslte_vec_malloc(buffer_size * sizeof(float)); if (!q->conv_output_avg) { ERROR("Error allocating memory\n"); goto clean_and_exit; } bzero(q->conv_output_avg, sizeof(float) * buffer_size); #ifdef SRSLTE_PSS_ACCUMULATE_ABS q->conv_output_abs = srslte_vec_malloc(buffer_size * sizeof(float)); if (!q->conv_output_abs) { ERROR("Error allocating memory\n"); goto clean_and_exit; } bzero(q->conv_output_abs, sizeof(float) * buffer_size); #endif for (N_id_2=0;N_id_2<3;N_id_2++) { q->pss_signal_time[N_id_2] = srslte_vec_malloc(buffer_size * sizeof(cf_t)); if (!q->pss_signal_time[N_id_2]) { ERROR("Error allocating memory\n"); goto clean_and_exit; } /* The PSS is translated into the time domain for each N_id_2 */ if (srslte_pss_init_N_id_2(q->pss_signal_freq[N_id_2], q->pss_signal_time[N_id_2], N_id_2, fft_size, offset)) { ERROR("Error initiating PSS detector for N_id_2=%d fft_size=%d\n", N_id_2, fft_size); goto clean_and_exit; } bzero(&q->pss_signal_time[N_id_2][q->fft_size], q->frame_size * sizeof(cf_t)); } #ifdef CONVOLUTION_FFT if (srslte_conv_fft_cc_init(&q->conv_fft, frame_size, fft_size)) { ERROR("Error initiating convolution FFT\n"); goto clean_and_exit; } for(N_id_2=0; N_id_2<3; N_id_2++) { q->pss_signal_freq_full[N_id_2] = srslte_vec_malloc(buffer_size * sizeof(cf_t)); srslte_dft_run_c(&q->conv_fft.filter_plan, q->pss_signal_time[N_id_2], q->pss_signal_freq_full[N_id_2]); } #endif srslte_pss_reset(q); ret = SRSLTE_SUCCESS; } clean_and_exit: if (ret == SRSLTE_ERROR) { srslte_pss_free(q); } return ret; }