int rf_rssi_scan(srslte_rf_t *rf, float *freqs, float *rssi, int nof_bands, double fs, int nsamp) { int i, j; int ret = -1; cf_t *buffer; double f; buffer = calloc(nsamp, sizeof(cf_t)); if (!buffer) { goto free_and_exit; } srslte_rf_set_rx_gain(rf, 20.0); srslte_rf_set_rx_srate(rf, fs); for (i=0;i<nof_bands;i++) { srslte_rf_stop_rx_stream(rf); f = (double) freqs[i]; srslte_rf_set_rx_freq(rf, f); srslte_rf_rx_wait_lo_locked(rf); usleep(10000); srslte_rf_start_rx_stream(rf, false); /* discard first samples */ for (j=0;j<2;j++) { if (srslte_rf_recv(rf, 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"); } } srslte_rf_stop_rx_stream(rf); ret = 0; free_and_exit: free(buffer); return ret; }
/* This thread listens for set_rx_gain commands to the USRP */ static void* thread_gain_fcn(void *h) { srslte_rf_t* rf = (srslte_rf_t*) h; while(1) { pthread_mutex_lock(&rf->mutex); while(rf->cur_rx_gain == rf->new_rx_gain) { pthread_cond_wait(&rf->cond, &rf->mutex); } if (rf->new_rx_gain != rf->cur_rx_gain) { rf->cur_rx_gain = rf->new_rx_gain; srslte_rf_set_rx_gain(h, rf->cur_rx_gain); } if (rf->tx_gain_same_rx) { srslte_rf_set_tx_gain(h, rf->cur_rx_gain+rf->tx_rx_gain_offset); } pthread_mutex_unlock(&rf->mutex); } return NULL; }
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) { 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; srslte_rf_t rf; 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); } printf("Opening RF device...\n"); if (srslte_rf_open(&rf, prog_args.rf_args)) { fprintf(stderr, "Error opening rf\n"); exit(-1); } if (prog_args.rf_gain > 0) { srslte_rf_set_rx_gain(&rf, prog_args.rf_gain); } else { printf("Starting AGC thread...\n"); if (srslte_rf_start_gain_thread(&rf, false)) { fprintf(stderr, "Error opening rf\n"); exit(-1); } srslte_rf_set_rx_gain(&rf, 50); } sigset_t sigset; sigemptyset(&sigset); sigaddset(&sigset, SIGINT); sigprocmask(SIG_UNBLOCK, &sigset, NULL); signal(SIGINT, sig_int_handler); srslte_rf_set_master_clock_rate(&rf, 30.72e6); /* set receiver frequency */ srslte_rf_set_rx_freq(&rf, (double) prog_args.rf_freq); srslte_rf_rx_wait_lo_locked(&rf); printf("Tunning receiver to %.3f MHz\n", (double ) prog_args.rf_freq/1000000); cell_detect_config.init_agc = (prog_args.rf_gain<0); uint32_t ntrial=0; do { ret = rf_search_and_decode_mib(&rf, &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) { srslte_rf_set_master_clock_rate(&rf, 4*srate); } else { srslte_rf_set_master_clock_rate(&rf, srate); } printf("Setting sampling rate %.2f MHz\n", (float) srate/1000000); float srate_rf = srslte_rf_set_rx_srate(&rf, (double) srate); if (srate_rf != 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 RF and flushing buffer...\n",0); srslte_rf_stop_rx_stream(&rf); srslte_rf_flush_buffer(&rf); if (srslte_ue_sync_init(&ue_sync, cell, srslte_rf_recv_wrapper, (void*) &rf)) { 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); } srslte_rf_start_rx_stream(&rf); 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 (srslte_rf_has_rssi(&rf)) { rx_gain_offset = 10*log10(rssi)-srslte_rf_get_rssi(&rf); } else { rx_gain_offset = srslte_rf_get_rx_gain(&rf); } } // 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); srslte_rf_close(&rf); printf("\nBye\n"); exit(0); }