int find_cell(void *uhd, ue_celldetect_t *s, cf_t *buffer, ue_celldetect_result_t found_cell[3]) { int n; INFO("Setting sampling frequency 960 KHz for PSS search\n", 0); cuhd_set_rx_srate(uhd, 960000.0); INFO("Starting receiver...\n", 0); cuhd_start_rx_stream(uhd); uint32_t nof_scanned_cells = 0; uint32_t flen = 4800; int nof_detected_cells = 0; do { if (cuhd_recv(uhd, buffer, flen, 1)<0) { fprintf(stderr, "Error receiving from USRP\n"); return LIBLTE_ERROR; } n = ue_celldetect_scan(s, buffer, flen, &found_cell[nof_scanned_cells]); switch(n) { case CS_FRAME_UNALIGNED: printf("Realigning frame\n"); if (cuhd_recv(uhd, buffer, flen/2, 1)<0) { fprintf(stderr, "Error receiving from USRP\n"); return LIBLTE_ERROR; } return LIBLTE_ERROR; case CS_CELL_DETECTED: nof_detected_cells++; if (found_cell[nof_scanned_cells].peak > 0) { printf("\n\tCELL ID: %d, CP: %s, Peak: %.2f, Mode: %d/%d\n", found_cell[nof_scanned_cells].cell_id, lte_cp_string(found_cell[nof_scanned_cells].cp), found_cell[nof_scanned_cells].peak, found_cell[nof_scanned_cells].mode, s->nof_frames_detected); } nof_scanned_cells++; break; case CS_CELL_NOT_DETECTED: nof_scanned_cells++; break; case LIBLTE_ERROR: case LIBLTE_ERROR_INVALID_INPUTS: fprintf(stderr, "Error calling cellsearch_scan()\n"); return LIBLTE_ERROR; } } while(nof_scanned_cells < 3); INFO("Stopping receiver...\n", 0); cuhd_stop_rx_stream(uhd); cuhd_flush_buffer(uhd); return nof_detected_cells; }
int decode_pbch(void *uhd, cf_t *buffer, ue_celldetect_result_t *found_cell, uint32_t nof_frames_total, pbch_mib_t *mib) { ue_mib_t uemib; int n; bzero(mib, sizeof(pbch_mib_t)); uint32_t nof_frames = 0; uint32_t flen = MIB_FRAME_SIZE; if (ue_mib_init(&uemib, found_cell->cell_id, found_cell->cp)) { fprintf(stderr, "Error initiating PBCH decoder\n"); return LIBLTE_ERROR; } INFO("Setting sampling frequency 1.92 MHz for PBCH decoding\n", 0); cuhd_set_rx_srate(uhd, 1920000.0); INFO("Starting receiver...\n", 0); cuhd_start_rx_stream(uhd); do { if (cuhd_recv(uhd, buffer, flen, 1)<0) { fprintf(stderr, "Error receiving from USRP\n"); return LIBLTE_ERROR; } INFO("Calling ue_mib_decode() %d/%d\n", nof_frames, nof_frames_total); n = ue_mib_decode(&uemib, buffer, flen, mib); if (n == LIBLTE_ERROR || n == LIBLTE_ERROR_INVALID_INPUTS) { fprintf(stderr, "Error calling ue_mib_decode()\n"); return LIBLTE_ERROR; } if (n == MIB_FRAME_UNALIGNED) { printf("Realigning frame\n"); if (cuhd_recv(uhd, buffer, flen/2, 1)<0) { fprintf(stderr, "Error receiving from USRP\n"); return LIBLTE_ERROR; } } nof_frames++; } while (n != MIB_FOUND && nof_frames < 2*nof_frames_total); if (n == MIB_FOUND) { printf("\n\nMIB decoded in %d ms (%d half frames)\n", nof_frames*5, nof_frames); pbch_mib_fprint(stdout, mib, found_cell->cell_id); } else { printf("\nCould not decode MIB\n"); } cuhd_stop_rx_stream(uhd); cuhd_flush_buffer(uhd); ue_mib_free(&uemib); return LIBLTE_SUCCESS; }
void input_init() { printf("Opening UHD device...\n"); if (cuhd_open(uhd_args, &uhd)) { fprintf(stderr, "Error opening uhd\n"); exit(-1); } cuhd_set_rx_gain(uhd, uhd_gain); /* set uhd_freq */ cuhd_set_rx_freq(uhd, (double) uhd_freq); cuhd_rx_wait_lo_locked(uhd); DEBUG("Set uhd_freq to %.3f MHz\n", (double ) uhd_freq/1000000); DEBUG("Starting receiver...\n", 0); cuhd_start_rx_stream(uhd); }
/** 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 cuhd_rssi_scan(void *uhd, float *freqs, float *rssi, int nof_bands, double fs, int nsamp) { int i, j; int ret = -1; _Complex float *buffer; double f; buffer = calloc(nsamp, sizeof(_Complex float)); if (!buffer) { goto free_and_exit; } cuhd_set_rx_gain(uhd, 20.0); cuhd_set_rx_srate(uhd, fs); for (i=0;i<nof_bands;i++) { cuhd_stop_rx_stream(uhd); f = (double) freqs[i]; cuhd_set_rx_freq(uhd, f); cuhd_rx_wait_lo_locked(uhd); usleep(10000); cuhd_start_rx_stream(uhd); /* discard first samples */ for (j=0;j<2;j++) { if (cuhd_recv(uhd, buffer, nsamp, 1) != nsamp) { goto free_and_exit; } } rssi[i] = srslte_vec_avg_power_cf(buffer, nsamp); printf("[%3d]: Freq %4.1f Mhz - RSSI: %3.2f dBm\r", i, f/1000000, 10*log10f(rssi[i]) + 30); fflush(stdout); if (SRSLTE_VERBOSE_ISINFO()) { printf("\n"); } } cuhd_stop_rx_stream(uhd); ret = 0; free_and_exit: free(buffer); 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) { cf_t *buffer; int frame_cnt, n; void *uhd; srslte_pss_synch_t pss; srslte_cfo_t cfocorr, cfocorr64; srslte_sss_synch_t sss; int32_t flen; int peak_idx, last_peak; float peak_value; float mean_peak; uint32_t nof_det, nof_nodet, nof_nopeak, nof_nopeakdet; cf_t ce[SRSLTE_PSS_LEN]; parse_args(argc, argv); if (N_id_2_sync == -1) { N_id_2_sync = cell_id%3; } uint32_t N_id_2 = cell_id%3; uint32_t N_id_1 = cell_id/3; #ifndef DISABLE_GRAPHICS if (!disable_plots) init_plots(); #endif float srate = 15000.0*fft_size; flen = srate*5/1000; printf("Opening UHD device...\n"); if (cuhd_open(uhd_args, &uhd)) { fprintf(stderr, "Error opening uhd\n"); exit(-1); } if (srate < 10e6) { cuhd_set_master_clock_rate(uhd, 4*srate); } else { cuhd_set_master_clock_rate(uhd, srate); } printf("Set RX rate: %.2f MHz\n", cuhd_set_rx_srate(uhd, srate) / 1000000); printf("Set RX gain: %.1f dB\n", cuhd_set_rx_gain(uhd, uhd_gain)); printf("Set RX freq: %.2f MHz\n", cuhd_set_rx_freq(uhd, uhd_freq) / 1000000); cuhd_rx_wait_lo_locked(uhd); buffer = malloc(sizeof(cf_t) * flen * 2); if (!buffer) { perror("malloc"); exit(-1); } if (srslte_pss_synch_init_fft(&pss, flen, fft_size)) { fprintf(stderr, "Error initiating PSS\n"); exit(-1); } if (srslte_pss_synch_set_N_id_2(&pss, N_id_2_sync)) { fprintf(stderr, "Error setting N_id_2=%d\n",N_id_2_sync); exit(-1); } srslte_cfo_init(&cfocorr, flen); srslte_cfo_init(&cfocorr64, flen); if (srslte_sss_synch_init(&sss, fft_size)) { fprintf(stderr, "Error initializing SSS object\n"); return SRSLTE_ERROR; } srslte_sss_synch_set_N_id_2(&sss, N_id_2); printf("N_id_2: %d\n", N_id_2); cuhd_start_rx_stream(uhd); printf("Frame length %d samples\n", flen); printf("PSS detection threshold: %.2f\n", threshold); nof_det = nof_nodet = nof_nopeak = nof_nopeakdet = 0; frame_cnt = 0; last_peak = 0; mean_peak = 0; int peak_offset = 0; float cfo; float mean_cfo = 0; uint32_t m0, m1; uint32_t sss_error1 = 0, sss_error2 = 0, sss_error3 = 0; uint32_t cp_is_norm = 0; srslte_sync_t ssync; bzero(&ssync, sizeof(srslte_sync_t)); ssync.fft_size = fft_size; while(frame_cnt < nof_frames || nof_frames == -1) { n = cuhd_recv(uhd, buffer, flen - peak_offset, 1); if (n < 0) { fprintf(stderr, "Error receiving samples\n"); exit(-1); } peak_idx = srslte_pss_synch_find_pss(&pss, buffer, &peak_value); if (peak_idx < 0) { fprintf(stderr, "Error finding PSS peak\n"); exit(-1); } mean_peak = SRSLTE_VEC_CMA(peak_value, mean_peak, frame_cnt); if (peak_value >= threshold) { nof_det++; if (peak_idx >= fft_size) { // Estimate CFO cfo = srslte_pss_synch_cfo_compute(&pss, &buffer[peak_idx-fft_size]); mean_cfo = SRSLTE_VEC_CMA(cfo, mean_cfo, frame_cnt); // Correct CFO srslte_cfo_correct(&cfocorr, buffer, buffer, -mean_cfo / fft_size); // Estimate channel if (srslte_pss_synch_chest(&pss, &buffer[peak_idx-fft_size], ce)) { fprintf(stderr, "Error computing channel estimation\n"); exit(-1); } // Find SSS int sss_idx = peak_idx-2*fft_size-(SRSLTE_CP_ISNORM(cp)?SRSLTE_CP_LEN(fft_size, SRSLTE_CP_NORM_LEN):SRSLTE_CP_LEN(fft_size, SRSLTE_CP_EXT_LEN)); if (sss_idx >= 0 && sss_idx < flen-fft_size) { srslte_sss_synch_m0m1_partial(&sss, &buffer[sss_idx], 3, NULL, &m0, &m0_value, &m1, &m1_value); if (srslte_sss_synch_N_id_1(&sss, m0, m1) != N_id_1) { sss_error2++; } INFO("Partial N_id_1: %d\n", srslte_sss_synch_N_id_1(&sss, m0, m1)); srslte_sss_synch_m0m1_diff(&sss, &buffer[sss_idx], &m0, &m0_value, &m1, &m1_value); if (srslte_sss_synch_N_id_1(&sss, m0, m1) != N_id_1) { sss_error3++; } INFO("Diff N_id_1: %d\n", srslte_sss_synch_N_id_1(&sss, m0, m1)); srslte_sss_synch_m0m1_partial(&sss, &buffer[sss_idx], 1, NULL, &m0, &m0_value, &m1, &m1_value); if (srslte_sss_synch_N_id_1(&sss, m0, m1) != N_id_1) { sss_error1++; } INFO("Full N_id_1: %d\n", srslte_sss_synch_N_id_1(&sss, m0, m1)); } // Estimate CP if (peak_idx > 2*(fft_size + SRSLTE_CP_LEN_EXT(fft_size))) { srslte_cp_t cp = srslte_sync_detect_cp(&ssync, buffer, peak_idx); if (SRSLTE_CP_ISNORM(cp)) { cp_is_norm++; } } } else { INFO("No space for CFO computation. Frame starts at \n",peak_idx); } if(srslte_sss_synch_subframe(m0,m1) == 0) { #ifndef DISABLE_GRAPHICS if (!disable_plots) do_plots_sss(sss.corr_output_m0, sss.corr_output_m1); #endif } } else { nof_nodet++; } if (frame_cnt > 100) { if (abs(last_peak-peak_idx) > 4) { if (peak_value >= threshold) { nof_nopeakdet++; } nof_nopeak++; } } frame_cnt++; printf("[%5d]: Pos: %5d, PSR: %4.1f (~%4.1f) Pdet: %4.2f, " "FA: %4.2f, CFO: %+4.1f KHz SSSmiss: %4.2f/%4.2f/%4.2f CPNorm: %.0f%%\r", frame_cnt, peak_idx, peak_value, mean_peak, (float) nof_det/frame_cnt, (float) nof_nopeakdet/frame_cnt, mean_cfo*15, (float) sss_error1/nof_det,(float) sss_error2/nof_det,(float) sss_error3/nof_det, (float) cp_is_norm/nof_det * 100); if (SRSLTE_VERBOSE_ISINFO()) { printf("\n"); } #ifndef DISABLE_GRAPHICS if (!disable_plots) do_plots(pss.conv_output_avg, pss.conv_output_avg[peak_idx], pss.fft_size+pss.frame_size-1, ce); #endif last_peak = peak_idx; } srslte_pss_synch_free(&pss); free(buffer); cuhd_close(uhd); printf("Ok\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); }
int main(int argc, char **argv) { int frame_cnt, valid_frames; int freq; int cell_id; sync_t sfind, strack; float max_peak_to_avg; float sfo; int find_idx, track_idx, last_found; enum sync_state state; int n; filesink_t fs; if (argc < 3) { usage(argv[0]); exit(-1); } parse_args(argc,argv); if (base_init(FLEN)) { fprintf(stderr, "Error initializing memory\n"); exit(-1); } if (sync_init(&sfind, FLEN)) { fprintf(stderr, "Error initiating PSS/SSS\n"); exit(-1); } sync_pss_det_peak_to_avg(&sfind); if (sync_init(&strack, track_len)) { fprintf(stderr, "Error initiating PSS/SSS\n"); exit(-1); } sync_pss_det_peak_to_avg(&strack); nof_bands = lte_band_get_fd_band(band, channels, earfcn_start, earfcn_end, MAX_EARFCN); printf("RSSI scan: %d freqs in band %d, RSSI threshold %.2f dBm\n", nof_bands, band, rssi_threshold); n = rssi_scan(); if (n == -1) { exit(-1); } printf("\nDone. Starting PSS search on %d channels\n", n); usleep(500000); INFO("Setting sampling frequency %.2f MHz\n", (float) SAMP_FREQ/MHZ); cuhd_set_rx_srate(uhd, SAMP_FREQ); cuhd_set_rx_gain(uhd, uhd_gain); print_to_matlab(); filesink_init(&fs, "test.dat", COMPLEX_FLOAT_BIN); freq=0; state = INIT; find_idx = 0; max_peak_to_avg = 0; last_found = 0; frame_cnt = 0; while(freq<nof_bands) { /* scan only bands above rssi_threshold */ if (!IS_SIGNAL(freq)) { INFO("[%3d/%d]: Skipping EARFCN %d %.2f MHz RSSI %.2f dB\n", freq, nof_bands, channels[freq].id, channels[freq].fd,10*log10f(rssi[freq]) + 30); freq++; } else { if (state == TRACK || state == FIND) { cuhd_recv(uhd, &input_buffer[FLEN], FLEN, 1); } switch(state) { case INIT: DEBUG("Stopping receiver...\n",0); cuhd_stop_rx_stream(uhd); /* set freq */ cuhd_set_rx_freq(uhd, (double) channels[freq].fd * MHZ); cuhd_rx_wait_lo_locked(uhd); DEBUG("Set freq to %.3f MHz\n", (double) channels[freq].fd); DEBUG("Starting receiver...\n",0); cuhd_start_rx_stream(uhd); /* init variables */ frame_cnt = 0; max_peak_to_avg = -99; cell_id = -1; /* receive first frame */ cuhd_recv(uhd, input_buffer, FLEN, 1); /* set find_threshold and go to FIND state */ sync_set_threshold(&sfind, find_threshold); sync_force_N_id_2(&sfind, -1); state = FIND; break; case FIND: /* find peak in all frame */ find_idx = sync_run(&sfind, &input_buffer[FLEN]); DEBUG("[%3d/%d]: PAR=%.2f\n", freq, nof_bands, sync_get_peak_to_avg(&sfind)); if (find_idx != -1) { /* if found peak, go to track and set lower threshold */ frame_cnt = -1; last_found = 0; sync_set_threshold(&strack, track_threshold); sync_force_N_id_2(&strack, sync_get_N_id_2(&sfind)); state = TRACK; INFO("[%3d/%d]: EARFCN %d Freq. %.2f MHz PSS found PAR %.2f dB\n", freq, nof_bands, channels[freq].id, channels[freq].fd, 10*log10f(sync_get_peak_to_avg(&sfind))); } else { if (frame_cnt >= nof_frames_find) { state = INIT; printf("[%3d/%d]: EARFCN %d Freq. %.2f MHz No PSS found\r", freq, nof_bands, channels[freq].id, channels[freq].fd, frame_cnt - last_found); if (VERBOSE_ISINFO()) { printf("\n"); } freq++; } } break; case TRACK: INFO("Tracking PSS find_idx %d offset %d\n", find_idx, find_idx + track_len); filesink_write(&fs, &input_buffer[FLEN+find_idx+track_len], track_len); track_idx = sync_run(&strack, &input_buffer[FLEN + find_idx - track_len]); p2a_v[frame_cnt] = sync_get_peak_to_avg(&strack); /* save cell id for the best peak-to-avg */ if (p2a_v[frame_cnt] > max_peak_to_avg) { max_peak_to_avg = p2a_v[frame_cnt]; cell_id = sync_get_cell_id(&strack); } if (track_idx != -1) { cfo_v[frame_cnt] = sync_get_cfo(&strack); last_found = frame_cnt; find_idx += track_idx - track_len; idx_v[frame_cnt] = find_idx; } else { idx_v[frame_cnt] = -1; cfo_v[frame_cnt] = 0.0; } /* if we missed to many PSS it is not a cell, next freq */ if (frame_cnt - last_found > max_track_lost) { INFO("\n[%3d/%d]: EARFCN %d Freq. %.2f MHz %d frames lost\n", freq, nof_bands, channels[freq].id, channels[freq].fd, frame_cnt - last_found); state = INIT; freq++; } else if (frame_cnt >= nof_frames_track) { state = DONE; } break; case DONE: cfo[freq] = mean_valid(idx_v, cfo_v, frame_cnt); p2a[freq] = mean_valid(idx_v, p2a_v, frame_cnt); valid_frames = preprocess_idx(idx_v, idx_valid, t, frame_cnt); sfo = sfo_estimate_period(idx_valid, t, valid_frames, FLEN_PERIOD); printf("\n[%3d/%d]: FOUND EARFCN %d Freq. %.2f MHz. " "PAR %2.2f dB, CFO=%+.2f KHz, SFO=%+2.3f KHz, CELL_ID=%3d\n", freq, nof_bands, channels[freq].id, channels[freq].fd, 10*log10f(p2a[freq]), cfo[freq] * 15, sfo / 1000, cell_id); state = INIT; freq++; break; } if (state == TRACK || (state == FIND && frame_cnt)) { memcpy(input_buffer, &input_buffer[FLEN], FLEN * sizeof(cf_t)); } frame_cnt++; } } print_to_matlab(); sync_free(&sfind); base_free(); printf("\n\nDone\n"); exit(0); }
/** This function is simply a wrapper to the ue_cell_search module for cuhd devices */ int cuhd_cell_search(void *uhd, cell_search_cfg_t *config, int force_N_id_2, srslte_cell_t *cell) { int ret = SRSLTE_ERROR; srslte_ue_cellsearch_t cs; srslte_ue_cellsearch_result_t found_cells[3]; bzero(found_cells, 3*sizeof(srslte_ue_cellsearch_result_t)); if (srslte_ue_cellsearch_init(&cs, cuhd_recv_wrapper_cs, uhd)) { fprintf(stderr, "Error initiating UE cell detect\n"); return SRSLTE_ERROR; } if (config->max_frames_pss) { srslte_ue_cellsearch_set_nof_frames_to_scan(&cs, config->max_frames_pss); } if (config->threshold) { srslte_ue_cellsearch_set_threshold(&cs, config->threshold); } if (config->init_agc > 0) { srslte_ue_sync_start_agc(&cs.ue_sync, cuhd_set_rx_gain_th, config->init_agc); } INFO("Setting sampling frequency %.2f MHz for PSS search\n", SRSLTE_CS_SAMP_FREQ/1000000); cuhd_set_rx_srate(uhd, SRSLTE_CS_SAMP_FREQ); INFO("Starting receiver...\n", 0); cuhd_start_rx_stream(uhd); /* Find a cell in the given N_id_2 or go through the 3 of them to find the strongest */ uint32_t max_peak_cell = 0; if (force_N_id_2 >= 0) { ret = srslte_ue_cellsearch_scan_N_id_2(&cs, force_N_id_2, &found_cells[force_N_id_2]); max_peak_cell = force_N_id_2; } else { ret = srslte_ue_cellsearch_scan(&cs, found_cells, &max_peak_cell); } if (ret < 0) { fprintf(stderr, "Error searching cell\n"); return SRSLTE_ERROR; } else if (ret == 0) { fprintf(stderr, "Could not find any cell in this frequency\n"); return SRSLTE_SUCCESS; } for (int i=0;i<3;i++) { if (i == max_peak_cell) { printf("*"); } else { printf(" "); } printf("Found Cell_id: %3d CP: %s, DetectRatio=%2.0f%% PSR=%.2f, Power=%.1f dBm\n", found_cells[i].cell_id, srslte_cp_string(found_cells[i].cp), found_cells[i].mode*100, found_cells[i].psr, 20*log10(found_cells[i].peak*1000)); } // Save result if (cell) { cell->id = found_cells[max_peak_cell].cell_id; cell->cp = found_cells[max_peak_cell].cp; } // Save AGC value for MIB decoding if (config->init_agc > 0) { config->init_agc = srslte_agc_get_gain(&cs.ue_sync.agc); } cuhd_stop_rx_stream(uhd); srslte_ue_cellsearch_free(&cs); return ret; }
/* Setup USRP or input file */ int iodev_init(iodev_t *q, iodev_cfg_t *config, lte_cell_t *cell, pbch_mib_t *mib) { if (config->input_file_name) { mib->phich_resources = R_1; mib->phich_length = PHICH_NORM; cell->id = config->cell_id_file; cell->cp = CPNORM; cell->nof_ports = config->nof_ports_file; cell->nof_prb = config->nof_prb_file; if (filesource_init(&q->fsrc, config->input_file_name, COMPLEX_FLOAT_BIN)) { return LIBLTE_ERROR; } q->mode = FILESOURCE; int symbol_sz = lte_symbol_sz(cell->nof_prb); if (symbol_sz > 0) { q->sf_len = SF_LEN(symbol_sz); } else { fprintf(stderr, "Invalid number of PRB %d\n", cell->nof_prb); return LIBLTE_ERROR; } q->input_buffer_file = vec_malloc(q->sf_len * sizeof(cf_t)); if (!q->input_buffer_file) { perror("malloc"); return LIBLTE_ERROR; } q->sf_idx = 9; } else { #ifndef DISABLE_UHD printf("Opening UHD device...\n"); if (cuhd_open(config->uhd_args, &q->uhd)) { fprintf(stderr, "Error opening uhd\n"); return LIBLTE_ERROR; } cuhd_set_rx_gain(q->uhd, config->uhd_gain); /* set receiver frequency */ cuhd_set_rx_freq(q->uhd, (double) config->uhd_freq); cuhd_rx_wait_lo_locked(q->uhd); DEBUG("Set uhd_freq to %.3f MHz\n", (double ) config->uhd_freq); int n; ue_celldetect_t cd; ue_celldetect_result_t found_cells[3]; cf_t *buffer = vec_malloc(sizeof(cf_t) * 96000); if (!buffer) { perror("malloc"); return LIBLTE_ERROR; } if (ue_celldetect_init(&cd)) { fprintf(stderr, "Error initiating UE cell detect\n"); exit(-1); } n = find_cell(q->uhd, &cd, buffer, found_cells); if (n < 0) { fprintf(stderr, "Error searching cell\n"); exit(-1); } int max_peak_cell = 0; float max_peak_value = -1.0; if (n > 0) { for (int i=0;i<3;i++) { if (found_cells[i].peak > max_peak_value) { max_peak_value = found_cells[i].peak; max_peak_cell = i; } } if (decode_pbch(q->uhd, buffer, &found_cells[max_peak_cell], 400, mib)) { fprintf(stderr, "Could not decode PBCH from CELL ID %d\n", found_cells[max_peak_cell].cell_id); return LIBLTE_ERROR; } } else { fprintf(stderr, "Could not find any cell in this frequency\n"); return LIBLTE_ERROR; } free(buffer); cell->cp = found_cells[max_peak_cell].cp; cell->id = found_cells[max_peak_cell].cell_id; cell->nof_prb = mib->nof_prb; cell->nof_ports = mib->nof_ports; /* set sampling frequency */ int srate = lte_sampling_freq_hz(cell->nof_prb); if (srate != -1) { cuhd_set_rx_srate(q->uhd, (double) srate); } else { fprintf(stderr, "Invalid number of PRB %d\n", cell->nof_prb); return LIBLTE_ERROR; } DEBUG("Starting receiver...\n", 0); cuhd_start_rx_stream(q->uhd); if (ue_sync_init(&q->sframe, *cell, cuhd_recv_wrapper, q->uhd)) { fprintf(stderr, "Error initiating ue_sync\n"); return LIBLTE_ERROR; } /* Decodes the SSS signal during the tracking phase. Extra overhead, but makes sure we are in the correct subframe */ ue_sync_decode_sss_on_track(&q->sframe, true); // Here, the subframe length and input buffer is managed by ue_sync q->mode = UHD; #else printf("Error UHD not available. Select an input file\n"); return LIBLTE_ERROR; #endif } memcpy(&q->config, config, sizeof(iodev_cfg_t)); return LIBLTE_SUCCESS; }