/** This function is simply a wrapper to the ue_cell_search module for rf devices * Return 1 if the MIB is decoded, 0 if not or -1 on error. */ int rf_mib_decoder(srslte_rf_t *rf, uint32_t nof_rx_antennas,cell_search_cfg_t *config, srslte_cell_t *cell, float *cfo) { int ret = SRSLTE_ERROR; srslte_ue_mib_sync_t ue_mib; uint8_t bch_payload[SRSLTE_BCH_PAYLOAD_LEN]; if (srslte_ue_mib_sync_init_multi(&ue_mib, srslte_rf_recv_wrapper_cs, nof_rx_antennas, (void*) rf)) { fprintf(stderr, "Error initiating srslte_ue_mib_sync\n"); goto clean_exit; } if (srslte_ue_mib_sync_set_cell(&ue_mib, cell->id, cell->cp)) { fprintf(stderr, "Error initiating srslte_ue_mib_sync\n"); goto clean_exit; } int srate = srslte_sampling_freq_hz(SRSLTE_UE_MIB_NOF_PRB); INFO("Setting sampling frequency %.2f MHz for PSS search\n", (float) srate/1000000); srslte_rf_set_rx_srate(rf, (float) srate); INFO("Starting receiver...\n"); srslte_rf_start_rx_stream(rf, false); // Copy CFO estimate if provided and disable CP estimation during find if (cfo) { ue_mib.ue_sync.cfo_current_value = *cfo/15000; ue_mib.ue_sync.cfo_is_copied = true; ue_mib.ue_sync.cfo_correct_enable_find = true; srslte_sync_set_cfo_cp_enable(&ue_mib.ue_sync.sfind, false, 0); } /* Find and decode MIB */ ret = srslte_ue_mib_sync_decode(&ue_mib, config->max_frames_pbch, bch_payload, &cell->nof_ports, NULL); if (ret < 0) { fprintf(stderr, "Error decoding MIB\n"); goto clean_exit; } if (ret == 1) { srslte_pbch_mib_unpack(bch_payload, cell, NULL); } // Save CFO if (cfo) { *cfo = srslte_ue_sync_get_cfo(&ue_mib.ue_sync); } clean_exit: srslte_rf_stop_rx_stream(rf); srslte_ue_mib_sync_free(&ue_mib); return ret; }
/** This function is simply a wrapper to the ue_cell_search module for cuhd devices * Return 1 if the MIB is decoded, 0 if not or -1 on error. */ int cuhd_mib_decoder(void *uhd, cell_search_cfg_t *config, srslte_cell_t *cell) { int ret = SRSLTE_ERROR; srslte_ue_mib_sync_t ue_mib; uint8_t bch_payload[SRSLTE_BCH_PAYLOAD_LEN]; if (srslte_ue_mib_sync_init(&ue_mib, cell->id, cell->cp, cuhd_recv_wrapper_cs, uhd)) { fprintf(stderr, "Error initiating srslte_ue_mib_sync\n"); goto clean_exit; } if (config->init_agc > 0) { srslte_ue_sync_start_agc(&ue_mib.ue_sync, cuhd_set_rx_gain_th, config->init_agc); } int srate = srslte_sampling_freq_hz(SRSLTE_UE_MIB_NOF_PRB); INFO("Setting sampling frequency %.2f MHz for PSS search\n", (float) srate/1000000); cuhd_set_rx_srate(uhd, (float) srate); INFO("Starting receiver...\n", 0); cuhd_start_rx_stream(uhd); /* Find and decody MIB */ ret = srslte_ue_mib_sync_decode(&ue_mib, config->max_frames_pss, bch_payload, &cell->nof_ports, NULL); if (ret < 0) { fprintf(stderr, "Error decoding MIB\n"); goto clean_exit; } if (ret == 1) { srslte_pbch_mib_unpack(bch_payload, cell, NULL); } // Save AGC value if (config->init_agc > 0) { config->init_agc = srslte_agc_get_gain(&ue_mib.ue_sync.agc); } clean_exit: cuhd_stop_rx_stream(uhd); srslte_ue_mib_sync_free(&ue_mib); return 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 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) { parse_args(argc, argv); uint32_t flen = srslte_sampling_freq_hz(nof_prb)/1000; cf_t *rx_buffer = malloc(sizeof(cf_t)*flen*nof_frames); if (!rx_buffer) { perror("malloc"); exit(-1); } cf_t *tx_buffer = malloc(sizeof(cf_t)*(flen+time_adv_samples)); if (!tx_buffer) { perror("malloc"); exit(-1); } bzero(tx_buffer, sizeof(cf_t)*(flen+time_adv_samples)); cf_t *zeros = calloc(sizeof(cf_t),flen); if (!zeros) { perror("calloc"); exit(-1); } float time_adv_sec = (float) time_adv_samples/srslte_sampling_freq_hz(nof_prb); // Send through RF srslte_rf_t rf; printf("Opening RF device...\n"); if (srslte_rf_open(&rf, rf_args)) { fprintf(stderr, "Error opening rf\n"); exit(-1); } srslte_rf_set_master_clock_rate(&rf, 30.72e6); int srate = srslte_sampling_freq_hz(nof_prb); if (srate < 10e6) { srslte_rf_set_master_clock_rate(&rf, 4*srate); } else { srslte_rf_set_master_clock_rate(&rf, srate); } srslte_rf_set_rx_srate(&rf, (double) srate); srslte_rf_set_tx_srate(&rf, (double) srate); printf("Subframe len: %d samples\n", flen); printf("Time advance: %f us\n",time_adv_sec*1e6); printf("Set TX/RX rate: %.2f MHz\n", (float) srate / 1000000); printf("Set RX gain: %.1f dB\n", srslte_rf_set_rx_gain(&rf, rf_rx_gain)); printf("Set TX gain: %.1f dB\n", srslte_rf_set_tx_gain(&rf, srslte_rf_tx_gain)); printf("Set TX/RX freq: %.2f MHz\n", srslte_rf_set_rx_freq(&rf, rf_freq) / 1000000); srslte_rf_set_tx_freq(&rf, rf_freq); sleep(1); if (input_filename) { srslte_vec_load_file(input_filename, &tx_buffer[time_adv_samples], flen*sizeof(cf_t)); } else { for (int i=0;i<flen-time_adv_samples;i++) { tx_buffer[i+time_adv_samples] = 0.3*cexpf(_Complex_I*2*M_PI*tone_offset_hz*((float) i/(float) srate)); } srslte_vec_save_file("srslte_rf_txrx_tone", tx_buffer, flen*sizeof(cf_t)); } srslte_timestamp_t tstamp; srslte_rf_start_rx_stream(&rf); uint32_t nframe=0; while(nframe<nof_frames) { printf("Rx subframe %d\n", nframe); srslte_rf_recv_with_time(&rf, &rx_buffer[flen*nframe], flen, true, &tstamp.full_secs, &tstamp.frac_secs); nframe++; if (nframe==9) { srslte_timestamp_add(&tstamp, 0, 2e-3-time_adv_sec); srslte_rf_send_timed2(&rf, tx_buffer, flen+time_adv_samples, tstamp.full_secs, tstamp.frac_secs, true, true); printf("Transmitting Signal\n"); } } srslte_vec_save_file(output_filename, &rx_buffer[10*flen], flen*sizeof(cf_t)); free(tx_buffer); free(rx_buffer); printf("Done\n"); exit(0); }
int main(int argc, char **argv) { parse_args(argc, argv); srslte_prach_t *p = (srslte_prach_t*)malloc(sizeof(srslte_prach_t)); bool high_speed_flag = false; cf_t preamble[MAX_LEN]; memset(preamble, 0, sizeof(cf_t)*MAX_LEN); srslte_prach_init(p, srslte_symbol_sz(nof_prb), preamble_format, root_seq_idx, high_speed_flag, zero_corr_zone); uint32_t flen = srslte_sampling_freq_hz(nof_prb)/1000; printf("Generating PRACH\n"); bzero(preamble, flen*sizeof(cf_t)); srslte_prach_gen(p, seq_idx, frequency_offset, preamble); uint32_t prach_len = p->N_seq; srslte_vec_save_file("generated",preamble,prach_len*sizeof(cf_t)); cf_t *buffer = malloc(sizeof(cf_t)*flen*nof_frames); // Send through UHD void *uhd; printf("Opening UHD device...\n"); if (cuhd_open(uhd_args, &uhd)) { fprintf(stderr, "Error opening uhd\n"); exit(-1); } printf("Subframe len: %d samples\n", flen); printf("Set TX/RX rate: %.2f MHz\n", cuhd_set_rx_srate(uhd, srslte_sampling_freq_hz(nof_prb)) / 1000000); printf("Set RX gain: %.1f dB\n", cuhd_set_rx_gain(uhd, uhd_gain)); printf("Set TX gain: %.1f dB\n", cuhd_set_tx_gain(uhd, uhd_gain)); printf("Set TX/RX freq: %.2f MHz\n", cuhd_set_rx_freq(uhd, uhd_freq) / 1000000); cuhd_set_tx_srate(uhd, srslte_sampling_freq_hz(nof_prb)); cuhd_set_tx_freq_offset(uhd, uhd_freq, 8e6); sleep(1); cf_t *zeros = calloc(sizeof(cf_t),flen); FILE *f = NULL; if (output_filename) { f = fopen(output_filename, "w"); } srslte_timestamp_t tstamp; cuhd_start_rx_stream(uhd); uint32_t nframe=0; while(nframe<nof_frames) { printf("Rx subframe %d\n", nframe); cuhd_recv_with_time(uhd, &buffer[flen*nframe], flen, true, &tstamp.full_secs, &tstamp.frac_secs); nframe++; if (nframe==9 || nframe==8) { srslte_timestamp_add(&tstamp, 0, 2e-3); if (nframe==8) { cuhd_send_timed2(uhd, zeros, flen, tstamp.full_secs, tstamp.frac_secs, true, false); printf("Transmitting zeros\n"); } else { cuhd_send_timed2(uhd, preamble, flen, tstamp.full_secs, tstamp.frac_secs, true, true); printf("Transmitting PRACH\n"); } } } if (f) { fwrite(&buffer[10*flen], flen*sizeof(cf_t), 1, f); } if (f) { fclose(f); } srslte_prach_free(p); free(p); printf("Done\n"); exit(0); }
/* the gateway function */ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { if (nrhs != NOF_INPUTS) { help(); return; } uint32_t n_ul_rb = 0; if (mexutils_read_uint32_struct(UECFG, "NULRB", &n_ul_rb)) { mexErrMsgTxt("Field NULRB not found in UE config\n"); return; } int r = srslte_symbol_sz(n_ul_rb); if (r < 0) { mexErrMsgTxt("Invalid NULRB\n"); return; } uint32_t N_ifft_ul = (uint32_t) r; uint32_t sf_idx = 0; mexutils_read_uint32_struct(UECFG, "NSubframe", &sf_idx); uint32_t nframe = 0; mexutils_read_uint32_struct(UECFG, "NFrame", &nframe); uint32_t preamble_format = 0; mexutils_read_uint32_struct(PRACHCFG, "Format", &preamble_format); uint32_t root_seq_idx = 0; mexutils_read_uint32_struct(PRACHCFG, "SeqIdx", &root_seq_idx); uint32_t seq_idx = 0; mexutils_read_uint32_struct(PRACHCFG, "PreambleIdx", &seq_idx); uint32_t zero_corr_zone = 0; mexutils_read_uint32_struct(PRACHCFG, "CyclicShiftIdx", &zero_corr_zone); uint32_t high_speed_flag = 0; mexutils_read_uint32_struct(PRACHCFG, "HighSpeed", &high_speed_flag); uint32_t timing_offset = 0; mexutils_read_uint32_struct(PRACHCFG, "TimingOffset", &timing_offset); uint32_t frequency_offset = 0; mexutils_read_uint32_struct(PRACHCFG, "FreqOffset", &frequency_offset); srslte_prach_t prach; if (srslte_prach_init(&prach, N_ifft_ul, preamble_format, root_seq_idx, high_speed_flag, zero_corr_zone)) { mexErrMsgTxt("Error initiating PRACH\n"); return; } uint32_t nof_samples = srslte_sampling_freq_hz(n_ul_rb) * 0.001; cf_t *signal = srslte_vec_malloc(sizeof(cf_t) * nof_samples); if (!signal) { mexErrMsgTxt("malloc"); return; } bzero(signal, sizeof(cf_t) * nof_samples); if (srslte_prach_gen(&prach, seq_idx, frequency_offset, signal)) { mexErrMsgTxt("Error generating PRACH\n"); return; } srslte_vec_sc_prod_cfc(signal, 1.0/sqrtf(N_ifft_ul), signal, nof_samples); if (nlhs >= 0) { mexutils_write_cf(signal, &plhs[0], nof_samples, 1); } free(signal); srslte_prach_free(&prach); return; }