bool HackRFSource::Start() { if (this->m_streamingState != Streaming) { this->m_streamingState = Streaming; int status = hackrf_start_rx(this->m_dev, _hackRF_rx_callback, (void *)this); HANDLE_ERROR("Failed to start RX streaming: %%s\n"); uint16_t frequencies[2]; frequencies[0] = this->m_scanStartFrequency; frequencies[1] = this->m_scanStopFrequency; status = hackrf_init_sweep(this->m_dev, frequencies, 1, // num_ranges this->m_scanNumBytes, this->m_scanStepWidth, // TUNE_STEP * FREQ_ONE_MHZ, this->m_scanOffset, // OFFSET, LINEAR); HANDLE_ERROR("Failed to set sweep parameters: %%s\n"); } return true; }
int main(int argc, char** argv) { int opt, i, result = 0; const char* path = NULL; const char* serial_number = NULL; int exit_code = EXIT_SUCCESS; struct timeval time_now; float time_diff; float sweep_rate; unsigned int lna_gain=16, vga_gain=20; uint32_t freq_min = 0; uint32_t freq_max = 6000; uint32_t requested_fft_bin_width; while( (opt = getopt(argc, argv, "a:f:p:l:g:d:n:N:w:1BIr:h?")) != EOF ) { result = HACKRF_SUCCESS; switch( opt ) { case 'd': serial_number = optarg; break; case 'a': amp = true; result = parse_u32(optarg, &_enable); break; case 'f': result = parse_u32_range(optarg, &freq_min, &freq_max); if(freq_min >= freq_max) { fprintf(stderr, "argument error: freq_max must be greater than freq_min.\n"); usage(); return EXIT_FAILURE; } if(FREQ_MAX_MHZ <freq_max) { fprintf(stderr, "argument error: freq_max may not be higher than %u.\n", FREQ_MAX_MHZ); usage(); return EXIT_FAILURE; } if(MAX_SWEEP_RANGES <= num_ranges) { fprintf(stderr, "argument error: specify a maximum of %u frequency ranges.\n", MAX_SWEEP_RANGES); usage(); return EXIT_FAILURE; } frequencies[2*num_ranges] = (uint16_t)freq_min; frequencies[2*num_ranges+1] = (uint16_t)freq_max; num_ranges++; break; case 'p': antenna = true; result = parse_u32(optarg, &antenna_enable); break; case 'l': result = parse_u32(optarg, &lna_gain); break; case 'g': result = parse_u32(optarg, &vga_gain); break; case 'n': result = parse_u32(optarg, &num_samples); break; case 'N': finite_mode = true; result = parse_u32(optarg, &num_sweeps); break; case 'w': result = parse_u32(optarg, &requested_fft_bin_width); fftSize = DEFAULT_SAMPLE_RATE_HZ / requested_fft_bin_width; break; case '1': one_shot = true; break; case 'B': binary_output = true; break; case 'I': ifft_output = true; break; case 'r': path = optarg; break; case 'h': case '?': usage(); return EXIT_SUCCESS; default: fprintf(stderr, "unknown argument '-%c %s'\n", opt, optarg); usage(); return EXIT_FAILURE; } if( result != HACKRF_SUCCESS ) { fprintf(stderr, "argument error: '-%c %s' %s (%d)\n", opt, optarg, hackrf_error_name(result), result); usage(); return EXIT_FAILURE; } } if (lna_gain % 8) fprintf(stderr, "warning: lna_gain (-l) must be a multiple of 8\n"); if (vga_gain % 2) fprintf(stderr, "warning: vga_gain (-g) must be a multiple of 2\n"); if (num_samples % SAMPLES_PER_BLOCK) { fprintf(stderr, "warning: num_samples (-n) must be a multiple of 8192\n"); return EXIT_FAILURE; } if (num_samples < SAMPLES_PER_BLOCK) { fprintf(stderr, "warning: num_samples (-n) must be at least 8192\n"); return EXIT_FAILURE; } if( amp ) { if( amp_enable > 1 ) { fprintf(stderr, "argument error: amp_enable shall be 0 or 1.\n"); usage(); return EXIT_FAILURE; } } if (antenna) { if (antenna_enable > 1) { fprintf(stderr, "argument error: antenna_enable shall be 0 or 1.\n"); usage(); return EXIT_FAILURE; } } if (0 == num_ranges) { frequencies[0] = (uint16_t)freq_min; frequencies[1] = (uint16_t)freq_max; num_ranges++; } if(binary_output && ifft_output) { fprintf(stderr, "argument error: binary output (-B) and IFFT output (-I) are mutually exclusive.\n"); return EXIT_FAILURE; } if(ifft_output && (1 < num_ranges)) { fprintf(stderr, "argument error: only one frequency range is supported in IFFT output (-I) mode.\n"); return EXIT_FAILURE; } if(4 > fftSize) { fprintf(stderr, "argument error: FFT bin width (-w) must be no more than one quarter the sample rate\n"); return EXIT_FAILURE; } if(8184 < fftSize) { fprintf(stderr, "argument error: FFT bin width (-w) too small, resulted in more than 8184 FFT bins\n"); return EXIT_FAILURE; } /* In interleaved mode, the FFT bin selection works best if the total * number of FFT bins is equal to an odd multiple of four. * (e.g. 4, 12, 20, 28, 36, . . .) */ while((fftSize + 4) % 8) { fftSize++; } fft_bin_width = (double)DEFAULT_SAMPLE_RATE_HZ / fftSize; fftwIn = (fftwf_complex*)fftwf_malloc(sizeof(fftwf_complex) * fftSize); fftwOut = (fftwf_complex*)fftwf_malloc(sizeof(fftwf_complex) * fftSize); fftwPlan = fftwf_plan_dft_1d(fftSize, fftwIn, fftwOut, FFTW_FORWARD, FFTW_MEASURE); pwr = (float*)fftwf_malloc(sizeof(float) * fftSize); window = (float*)fftwf_malloc(sizeof(float) * fftSize); for (i = 0; i < fftSize; i++) { window[i] = (float) (0.5f * (1.0f - cos(2 * M_PI * i / (fftSize - 1)))); } result = hackrf_init(); if( result != HACKRF_SUCCESS ) { fprintf(stderr, "hackrf_init() failed: %s (%d)\n", hackrf_error_name(result), result); usage(); return EXIT_FAILURE; } result = hackrf_open_by_serial(serial_number, &device); if( result != HACKRF_SUCCESS ) { fprintf(stderr, "hackrf_open() failed: %s (%d)\n", hackrf_error_name(result), result); usage(); return EXIT_FAILURE; } if((NULL == path) || (strcmp(path, "-") == 0)) { fd = stdout; } else { fd = fopen(path, "wb"); } if(NULL == fd) { fprintf(stderr, "Failed to open file: %s\n", path); return EXIT_FAILURE; } /* Change fd buffer to have bigger one to store or read data on/to HDD */ result = setvbuf(fd , NULL , _IOFBF , FD_BUFFER_SIZE); if( result != 0 ) { fprintf(stderr, "setvbuf() failed: %d\n", result); usage(); return EXIT_FAILURE; } #ifdef _MSC_VER SetConsoleCtrlHandler( (PHANDLER_ROUTINE) sighandler, TRUE ); #else signal(SIGINT, &sigint_callback_handler); signal(SIGILL, &sigint_callback_handler); signal(SIGFPE, &sigint_callback_handler); signal(SIGSEGV, &sigint_callback_handler); signal(SIGTERM, &sigint_callback_handler); signal(SIGABRT, &sigint_callback_handler); #endif fprintf(stderr, "call hackrf_sample_rate_set(%.03f MHz)\n", ((float)DEFAULT_SAMPLE_RATE_HZ/(float)FREQ_ONE_MHZ)); result = hackrf_set_sample_rate_manual(device, DEFAULT_SAMPLE_RATE_HZ, 1); if( result != HACKRF_SUCCESS ) { fprintf(stderr, "hackrf_sample_rate_set() failed: %s (%d)\n", hackrf_error_name(result), result); usage(); return EXIT_FAILURE; } fprintf(stderr, "call hackrf_baseband_filter_bandwidth_set(%.03f MHz)\n", ((float)DEFAULT_BASEBAND_FILTER_BANDWIDTH/(float)FREQ_ONE_MHZ)); result = hackrf_set_baseband_filter_bandwidth(device, DEFAULT_BASEBAND_FILTER_BANDWIDTH); if( result != HACKRF_SUCCESS ) { fprintf(stderr, "hackrf_baseband_filter_bandwidth_set() failed: %s (%d)\n", hackrf_error_name(result), result); usage(); return EXIT_FAILURE; } result = hackrf_set_vga_gain(device, vga_gain); result |= hackrf_set_lna_gain(device, lna_gain); /* * For each range, plan a whole number of tuning steps of a certain * bandwidth. Increase high end of range if necessary to accommodate a * whole number of steps, minimum 1. */ for(i = 0; i < num_ranges; i++) { step_count = 1 + (frequencies[2*i+1] - frequencies[2*i] - 1) / TUNE_STEP; frequencies[2*i+1] = (uint16_t) (frequencies[2*i] + step_count * TUNE_STEP); fprintf(stderr, "Sweeping from %u MHz to %u MHz\n", frequencies[2*i], frequencies[2*i+1]); } if(ifft_output) { ifftwIn = (fftwf_complex*)fftwf_malloc(sizeof(fftwf_complex) * fftSize * step_count); ifftwOut = (fftwf_complex*)fftwf_malloc(sizeof(fftwf_complex) * fftSize * step_count); ifftwPlan = fftwf_plan_dft_1d(fftSize * step_count, ifftwIn, ifftwOut, FFTW_BACKWARD, FFTW_MEASURE); } result |= hackrf_start_rx(device, rx_callback, NULL); if (result != HACKRF_SUCCESS) { fprintf(stderr, "hackrf_start_rx() failed: %s (%d)\n", hackrf_error_name(result), result); usage(); return EXIT_FAILURE; } result = hackrf_init_sweep(device, frequencies, num_ranges, num_samples * 2, TUNE_STEP * FREQ_ONE_MHZ, OFFSET, INTERLEAVED); if( result != HACKRF_SUCCESS ) { fprintf(stderr, "hackrf_init_sweep() failed: %s (%d)\n", hackrf_error_name(result), result); return EXIT_FAILURE; } if (amp) { fprintf(stderr, "call hackrf_set_amp_enable(%u)\n", amp_enable); result = hackrf_set_amp_enable(device, (uint8_t)amp_enable); if (result != HACKRF_SUCCESS) { fprintf(stderr, "hackrf_set_amp_enable() failed: %s (%d)\n", hackrf_error_name(result), result); usage(); return EXIT_FAILURE; } } if (antenna) { fprintf(stderr, "call hackrf_set_antenna_enable(%u)\n", antenna_enable); result = hackrf_set_antenna_enable(device, (uint8_t)antenna_enable); if (result != HACKRF_SUCCESS) { fprintf(stderr, "hackrf_set_antenna_enable() failed: %s (%d)\n", hackrf_error_name(result), result); usage(); return EXIT_FAILURE; } } gettimeofday(&t_start, NULL); fprintf(stderr, "Stop with Ctrl-C\n"); while((hackrf_is_streaming(device) == HACKRF_TRUE) && (do_exit == false)) { float time_difference; m_sleep(50); gettimeofday(&time_now, NULL); time_difference = TimevalDiff(&time_now, &t_start); sweep_rate = (float)sweep_count / time_difference; fprintf(stderr, "%" PRIu64 " total sweeps completed, %.2f sweeps/second\n", sweep_count, sweep_rate); if (byte_count == 0) { exit_code = EXIT_FAILURE; fprintf(stderr, "\nCouldn't transfer any data for one second.\n"); break; } byte_count = 0; } result = hackrf_is_streaming(device); if (do_exit) { fprintf(stderr, "\nExiting...\n"); } else { fprintf(stderr, "\nExiting... hackrf_is_streaming() result: %s (%d)\n", hackrf_error_name(result), result); } gettimeofday(&time_now, NULL); time_diff = TimevalDiff(&time_now, &t_start); fprintf(stderr, "Total sweeps: %" PRIu64 " in %.5f seconds (%.2f sweeps/second)\n", sweep_count, time_diff, sweep_rate); if(device != NULL) { result = hackrf_stop_rx(device); if(result != HACKRF_SUCCESS) { fprintf(stderr, "hackrf_stop_rx() failed: %s (%d)\n", hackrf_error_name(result), result); } else { fprintf(stderr, "hackrf_stop_rx() done\n"); } result = hackrf_close(device); if(result != HACKRF_SUCCESS) { fprintf(stderr, "hackrf_close() failed: %s (%d)\n", hackrf_error_name(result), result); } else { fprintf(stderr, "hackrf_close() done\n"); } hackrf_exit(); fprintf(stderr, "hackrf_exit() done\n"); } if(fd != NULL) { fclose(fd); fd = NULL; fprintf(stderr, "fclose(fd) done\n"); } fftwf_free(fftwIn); fftwf_free(fftwOut); fftwf_free(pwr); fftwf_free(window); fftwf_free(ifftwIn); fftwf_free(ifftwOut); fprintf(stderr, "exit\n"); return exit_code; }