Пример #1
0
void retune(rtlsdr_dev_t *d, int freq)
{
	uint8_t dump[BUFFER_DUMP];
	int f, n_read;
	f = (int)rtlsdr_get_center_freq(d);
	if (f == freq) {
		return;}
	rtlsdr_set_center_freq(d, (uint32_t)freq);
	/* wait for settling and flush buffer */
	usleep(5000);
	rtlsdr_read_sync(d, &dump, BUFFER_DUMP, &n_read);
	if (n_read != BUFFER_DUMP) {
		fprintf(stderr, "Error: bad retune.\n");}
}
Пример #2
0
void scanner(void)
{
	int i, j, j2, f, n_read, offset, bin_e, bin_len, buf_len, ds, ds_p;
	int32_t w;
	struct tuning_state *ts;
	bin_e = tunes[0].bin_e;
	bin_len = 1 << bin_e;
	buf_len = tunes[0].buf_len;
	for (i=0; i<tune_count; i++) {
		if (do_exit >= 2)
			{return;}
		ts = &tunes[i];
		f = (int)rtlsdr_get_center_freq(dev);
		if (f != ts->freq) {
			retune(dev, ts->freq);}
		rtlsdr_read_sync(dev, ts->buf8, buf_len, &n_read);
		if (n_read != buf_len) {
			fprintf(stderr, "Error: dropped samples.\n");}
		/* rms */
		if (bin_len == 1) {
			rms_power(ts);
			continue;
		}
		/* prep for fft */
		for (j=0; j<buf_len; j++) {
			fft_buf[j] = (int16_t)ts->buf8[j] - 127;
		}
		ds = ts->downsample;
		ds_p = ts->downsample_passes;
		if (boxcar && ds > 1) {
			j=2, j2=0;
			while (j < buf_len) {
				fft_buf[j2]   += fft_buf[j];
				fft_buf[j2+1] += fft_buf[j+1];
				fft_buf[j] = 0;
				fft_buf[j+1] = 0;
				j += 2;
				if (j % (ds*2) == 0) {
					j2 += 2;}
			}
		} else if (ds_p) {  /* recursive */
			for (j=0; j < ds_p; j++) {
				downsample_iq(fft_buf, buf_len >> j);
			}
			/* droop compensation */
			if (comp_fir_size == 9 && ds_p <= CIC_TABLE_MAX) {
				generic_fir(fft_buf, buf_len >> j, cic_9_tables[ds_p]);
				generic_fir(fft_buf+1, (buf_len >> j)-1, cic_9_tables[ds_p]);
			}
		}
		remove_dc(fft_buf, buf_len / ds);
		remove_dc(fft_buf+1, (buf_len / ds) - 1);
		/* window function and fft */
		for (offset=0; offset<(buf_len/ds); offset+=(2*bin_len)) {
			// todo, let rect skip this
			for (j=0; j<bin_len; j++) {
				w =  (int32_t)fft_buf[offset+j*2];
				w *= (int32_t)(window_coefs[j]);
				//w /= (int32_t)(ds);
				fft_buf[offset+j*2]   = (int16_t)w;
				w =  (int32_t)fft_buf[offset+j*2+1];
				w *= (int32_t)(window_coefs[j]);
				//w /= (int32_t)(ds);
				fft_buf[offset+j*2+1] = (int16_t)w;
			}
			fix_fft(fft_buf+offset, bin_e);
			if (!peak_hold) {
				for (j=0; j<bin_len; j++) {
					ts->avg[j] += real_conj(fft_buf[offset+j*2], fft_buf[offset+j*2+1]);
				}
			} else {
				for (j=0; j<bin_len; j++) {
					ts->avg[j] = MAX(real_conj(fft_buf[offset+j*2], fft_buf[offset+j*2+1]), ts->avg[j]);
				}
			}
			ts->samples += ds;
		}
	}
Пример #3
0
int main(int argc, char **argv) {
#ifndef _WIN32
    struct sigaction sigact;
#endif
    char *out_filename = NULL;
    char *in_filename = NULL;
    FILE *in_file;
    int n_read;
    int r = 0, opt;
    int i, gain = 0;
    int sync_mode = 0;
    int ppm_error = 0;
    struct dm_state* demod;
    uint32_t dev_index = 0;
    int frequency_current = 0;
    uint32_t out_block_size = DEFAULT_BUF_LENGTH;
    int device_count;
    char vendor[256], product[256], serial[256];
    int have_opt_R = 0;

    setbuf(stdout, NULL);
    setbuf(stderr, NULL);

    demod = malloc(sizeof (struct dm_state));
    memset(demod, 0, sizeof (struct dm_state));

    /* initialize tables */
    baseband_init();

	r_device devices[] = {
#define DECL(name) name,
			DEVICES
#undef DECL
			};

    num_r_devices = sizeof(devices)/sizeof(*devices);

    demod->level_limit = DEFAULT_LEVEL_LIMIT;

    while ((opt = getopt(argc, argv, "x:z:p:DtaAqm:r:l:d:f:g:s:b:n:SR:F:C:T:UW")) != -1) {
        switch (opt) {
            case 'd':
                dev_index = atoi(optarg);
                break;
            case 'f':
                if (frequencies < MAX_PROTOCOLS) frequency[frequencies++] = (uint32_t) atof(optarg);
                else fprintf(stderr, "Max number of frequencies reached %d\n", MAX_PROTOCOLS);
                break;
            case 'g':
                gain = (int) (atof(optarg) * 10); /* tenths of a dB */
                break;
            case 'p':
                ppm_error = atoi(optarg);
                break;
            case 's':
                samp_rate = (uint32_t) atof(optarg);
                break;
            case 'b':
                out_block_size = (uint32_t) atof(optarg);
                break;
            case 'l':
                demod->level_limit = (uint32_t) atof(optarg);
                break;
            case 'n':
                bytes_to_read = (uint32_t) atof(optarg) * 2;
                break;
            case 'a':
                demod->analyze = 1;
                break;
            case 'A':
                demod->analyze_pulses = 1;
                break;
            case 'r':
                in_filename = optarg;
                break;
            case 't':
                demod->signal_grabber = 1;
                break;
            case 'm':
                demod->debug_mode = atoi(optarg);
                break;
            case 'S':
                sync_mode = 1;
                break;
            case 'D':
                debug_output++;
                break;
            case 'z':
                override_short = atoi(optarg);
                break;
            case 'x':
                override_long = atoi(optarg);
                break;
            case 'R':
                if (!have_opt_R) {
                    for (i = 0; i < num_r_devices; i++) {
                        devices[i].disabled = 1;
                    }
                    have_opt_R = 1;
                }

                i = atoi(optarg);
                if (i > num_r_devices) {
                    fprintf(stderr, "Remote device number specified larger than number of devices\n\n");
                    usage(devices);
                }

                devices[i - 1].disabled = 0;
                break;
 	    case 'q':
	        quiet_mode = 1;
		break;
	    case 'F':
		if (strcmp(optarg, "json") == 0) {
            add_json_output();
		} else if (strcmp(optarg, "csv") == 0) {
            add_csv_output(determine_csv_fields(devices, num_r_devices));
		} else if (strcmp(optarg, "kv") == 0) {
            add_kv_output();
		} else {
                    fprintf(stderr, "Invalid output format %s\n", optarg);
                    usage(devices);
		}
		break;
        case 'C':
        if (strcmp(optarg, "native") == 0) {
            conversion_mode = CONVERT_NATIVE;
        } else if (strcmp(optarg, "si") == 0) {
            conversion_mode = CONVERT_SI;
        } else if (strcmp(optarg, "customary") == 0) {
            conversion_mode = CONVERT_CUSTOMARY;
        } else {
                    fprintf(stderr, "Invalid conversion mode %s\n", optarg);
                    usage(devices);
        }
        break;
        case 'U':
        #if !defined(__MINGW32__)
          utc_mode = setenv("TZ", "UTC", 1);
          if(utc_mode != 0) fprintf(stderr, "Unable to set TZ to UTC; error code: %d\n", utc_mode);
        #endif
        break;
            case 'W':
            overwrite_mode = 1;
        break;
        case 'T':
          time(&stop_time);
          duration = atoi(optarg);
          if (duration < 1) {
            fprintf(stderr, "Duration '%s' was not positive integer; will continue indefinitely\n", optarg);
          } else {
            stop_time += duration;
          }
          break;
            default:
                usage(devices);
                break;
        }
    }

    if (argc <= optind - 1) {
        usage(devices);
    } else {
        out_filename = argv[optind];
    }

    if (!output_handler) {
        add_kv_output();
    }

    for (i = 0; i < num_r_devices; i++) {
        if (!devices[i].disabled) {
            register_protocol(demod, &devices[i]);
            if(devices[i].modulation >= FSK_DEMOD_MIN_VAL) {
              demod->enable_FM_demod = 1;
            }
        }
    }

    if (out_block_size < MINIMAL_BUF_LENGTH ||
            out_block_size > MAXIMAL_BUF_LENGTH) {
        fprintf(stderr,
                "Output block size wrong value, falling back to default\n");
        fprintf(stderr,
                "Minimal length: %u\n", MINIMAL_BUF_LENGTH);
        fprintf(stderr,
                "Maximal length: %u\n", MAXIMAL_BUF_LENGTH);
        out_block_size = DEFAULT_BUF_LENGTH;
    }

    if (!in_filename) {
	device_count = rtlsdr_get_device_count();
	if (!device_count) {
	    fprintf(stderr, "No supported devices found.\n");
	    if (!in_filename)
		exit(1);
	}

	if (!quiet_mode) {
	    fprintf(stderr, "Found %d device(s):\n", device_count);
	    for (i = 0; i < device_count; i++) {
		rtlsdr_get_device_usb_strings(i, vendor, product, serial);
		fprintf(stderr, "  %d:  %s, %s, SN: %s\n", i, vendor, product, serial);
	    }
	    fprintf(stderr, "\n");

	    fprintf(stderr, "Using device %d: %s\n",
		    dev_index, rtlsdr_get_device_name(dev_index));
	}

	r = rtlsdr_open(&dev, dev_index);
	if (r < 0) {
	    fprintf(stderr, "Failed to open rtlsdr device #%d.\n", dev_index);
	    exit(1);
	}
#ifndef _WIN32
	sigact.sa_handler = sighandler;
	sigemptyset(&sigact.sa_mask);
	sigact.sa_flags = 0;
	sigaction(SIGINT, &sigact, NULL);
	sigaction(SIGTERM, &sigact, NULL);
	sigaction(SIGQUIT, &sigact, NULL);
	sigaction(SIGPIPE, &sigact, NULL);
#else
	SetConsoleCtrlHandler((PHANDLER_ROUTINE) sighandler, TRUE);
#endif
	/* Set the sample rate */
	r = rtlsdr_set_sample_rate(dev, samp_rate);
	if (r < 0)
	    fprintf(stderr, "WARNING: Failed to set sample rate.\n");
	else
	    fprintf(stderr, "Sample rate set to %d.\n", rtlsdr_get_sample_rate(dev)); // Unfortunately, doesn't return real rate

	fprintf(stderr, "Bit detection level set to %d.\n", demod->level_limit);

	if (0 == gain) {
	    /* Enable automatic gain */
	    r = rtlsdr_set_tuner_gain_mode(dev, 0);
	    if (r < 0)
		fprintf(stderr, "WARNING: Failed to enable automatic gain.\n");
	    else
		fprintf(stderr, "Tuner gain set to Auto.\n");
	} else {
	    /* Enable manual gain */
	    r = rtlsdr_set_tuner_gain_mode(dev, 1);
	    if (r < 0)
		fprintf(stderr, "WARNING: Failed to enable manual gain.\n");

	    /* Set the tuner gain */
	    r = rtlsdr_set_tuner_gain(dev, gain);
	    if (r < 0)
		fprintf(stderr, "WARNING: Failed to set tuner gain.\n");
	    else
		fprintf(stderr, "Tuner gain set to %f dB.\n", gain / 10.0);
	}

	r = rtlsdr_set_freq_correction(dev, ppm_error);

    }

	if (out_filename) {
		if (strcmp(out_filename, "-") == 0) { /* Write samples to stdout */
			demod->out_file = stdout;
#ifdef _WIN32
			_setmode(_fileno(stdin), _O_BINARY);
#endif
		} else {
		        if (access(out_filename, F_OK) == 0 && !overwrite_mode) {
			    fprintf(stderr, "Output file %s already exists, exiting\n", out_filename);
			    goto out;
			}
			demod->out_file = fopen(out_filename, "wb");
			if (!demod->out_file) {
				fprintf(stderr, "Failed to open %s\n", out_filename);
				goto out;
			}
		}
	}

    if (demod->signal_grabber)
        demod->sg_buf = malloc(SIGNAL_GRABBER_BUFFER);

    if (in_filename) {
        int i = 0;
        unsigned char test_mode_buf[DEFAULT_BUF_LENGTH];
        float test_mode_float_buf[DEFAULT_BUF_LENGTH];
	if (strcmp(in_filename, "-") == 0) { /* read samples from stdin */
	    in_file = stdin;
	    in_filename = "<stdin>";
	} else {
	    in_file = fopen(in_filename, "rb");
	    if (!in_file) {
		fprintf(stderr, "Opening file: %s failed!\n", in_filename);
		goto out;
	    }
	}
	fprintf(stderr, "Test mode active. Reading samples from file: %s\n", in_filename);	// Essential information (not quiet)
	if (!quiet_mode) {
	    fprintf(stderr, "Input format: %s\n", (demod->debug_mode == 3) ? "cf32" : "uint8");
	}
	sample_file_pos = 0.0;

        int n_read, cf32_tmp;
        do {
	    if (demod->debug_mode == 3) {
		n_read = fread(test_mode_float_buf, sizeof(float), 131072, in_file);
		for(int n = 0; n < n_read; n++) {
		    cf32_tmp = test_mode_float_buf[n]*127 + 127;
			if (cf32_tmp < 0)
			    cf32_tmp = 0;
			else if (cf32_tmp > 255)
			    cf32_tmp = 255;
			test_mode_buf[n] = (uint8_t)cf32_tmp;
		}
            } else {
                n_read = fread(test_mode_buf, 1, 131072, in_file);
            }
            if (n_read == 0) break;	// rtlsdr_callback() will Segmentation Fault with len=0
            rtlsdr_callback(test_mode_buf, n_read, demod);
            i++;
	    sample_file_pos = (float)i * n_read / samp_rate;
        } while (n_read != 0);

        // Call a last time with cleared samples to ensure EOP detection
        memset(test_mode_buf, 128, DEFAULT_BUF_LENGTH);     // 128 is 0 in unsigned data
        rtlsdr_callback(test_mode_buf, 131072, demod);      // Why the magic value 131072?

        //Always classify a signal at the end of the file
        classify_signal();
	if (!quiet_mode) {
	    fprintf(stderr, "Test mode file issued %d packets\n", i);
	}
        exit(0);
    }

    /* Reset endpoint before we start reading from it (mandatory) */
    r = rtlsdr_reset_buffer(dev);
    if (r < 0)
        fprintf(stderr, "WARNING: Failed to reset buffers.\n");

    if (sync_mode) {
        if (!demod->out_file) {
            fprintf(stderr, "Specify an output file for sync mode.\n");
            exit(0);
        }

	fprintf(stderr, "Reading samples in sync mode...\n");
	uint8_t *buffer = malloc(out_block_size * sizeof (uint8_t));

      time_t timestamp;
        while (!do_exit) {
            r = rtlsdr_read_sync(dev, buffer, out_block_size, &n_read);
            if (r < 0) {
                fprintf(stderr, "WARNING: sync read failed.\n");
                break;
            }

            if ((bytes_to_read > 0) && (bytes_to_read < (uint32_t) n_read)) {
                n_read = bytes_to_read;
                do_exit = 1;
            }

            if (fwrite(buffer, 1, n_read, demod->out_file) != (size_t) n_read) {
                fprintf(stderr, "Short write, samples lost, exiting!\n");
                break;
            }

            if ((uint32_t) n_read < out_block_size) {
                fprintf(stderr, "Short read, samples lost, exiting!\n");
                break;
            }

        if (duration > 0) {
          time(&timestamp);
          if (timestamp >= stop_time) {
            do_exit = 1;
            fprintf(stderr, "Time expired, exiting!\n");
          }
        }

            if (bytes_to_read > 0)
                bytes_to_read -= n_read;
        }

	free(buffer);
    } else {
        if (frequencies == 0) {
            frequency[0] = DEFAULT_FREQUENCY;
            frequencies = 1;
        } else {
            time(&rawtime_old);
        }
	if (!quiet_mode) {
	    fprintf(stderr, "Reading samples in async mode...\n");
	}
        while (!do_exit) {
            /* Set the frequency */
            r = rtlsdr_set_center_freq(dev, frequency[frequency_current]);
            if (r < 0)
                fprintf(stderr, "WARNING: Failed to set center freq.\n");
            else
                fprintf(stderr, "Tuned to %u Hz.\n", rtlsdr_get_center_freq(dev));
            r = rtlsdr_read_async(dev, rtlsdr_callback, (void *) demod,
                    DEFAULT_ASYNC_BUF_NUMBER, out_block_size);
            do_exit_async = 0;
            frequency_current++;
            if (frequency_current > frequencies - 1) frequency_current = 0;
        }
    }

    if (do_exit)
        fprintf(stderr, "\nUser cancel, exiting...\n");
    else
        fprintf(stderr, "\nLibrary error %d, exiting...\n", r);

    if (demod->out_file && (demod->out_file != stdout))
        fclose(demod->out_file);

    for (i = 0; i < demod->r_dev_num; i++)
        free(demod->r_devs[i]);

    if (demod->signal_grabber)
        free(demod->sg_buf);

    free(demod);

    rtlsdr_close(dev);
out:
    for (output_handler_t *output = output_handler; output; output = output->next) {
        if (output->aux_free) {
            output->aux_free(output->aux);
        }
    }
    return r >= 0 ? r : -r;
}
Пример #4
0
int32_t	dabStick::getVFOFrequency	(void) {
	if (!open || !libraryLoaded)
	   return defaultFrequency ();
	return (int32_t)rtlsdr_get_center_freq (device) - vfoOffset;
}
Пример #5
0
uint32_t rtl_get_center_freq(rtl r)
{
    return rtlsdr_get_center_freq(r->device);
}
Пример #6
0
int main(int argc, char* argv[])
{
    int rv;
    async_started = 0;
    quit_please = 0;
    buffers_received = 0;

    signal(SIGINT, sighandler);

    printf("Opening output file...\n");
    outf = fopen("rtlsdr_out.bin", "w");
    if(outf == NULL) {
        printf("Error opening output file: %d.\nExiting.\n", errno);
        return 1;
    }

    rv = rtlsdr_get_device_count();

    if(rv == 0) {
        printf("No RTL-SDR devices found, exiting.\n");
        return 2;
    }

    printf("Found %d device(s).\n", rv);

    printf("Opening the first, '%s'...\n", rtlsdr_get_device_name(0));
    rv = rtlsdr_open(&rtlsdr, 0);
    if(rv != 0) {
        printf("Error opening device: %d\nExiting.\n", rv);
        return 3;
    }

    printf("Setting frequency to 315MHz...\n");
    rv = rtlsdr_set_center_freq(rtlsdr, 315000000);
    if(rv != 0) {
        printf("Error setting frequency: %d\nExiting.\n", rv);
        return 4;
    }
    printf("Frequency set to %uHz.\n", rtlsdr_get_center_freq(rtlsdr));

    printf("Setting gain mode to automatic.\n");
    rv = rtlsdr_set_tuner_gain_mode(rtlsdr, 0);
    if(rv != 0) {
        printf("Error setting gain mode: %d\nExiting.\n", rv);
        return 5;
    }
    printf("Gain currently set to %d.\n", rtlsdr_get_tuner_gain(rtlsdr));

    printf("Setting sample rate to 240kHz...\n");
    rv = rtlsdr_set_sample_rate(rtlsdr, 240000);
    if(rv != 0) {
        printf("Error setting sample rate: %d\nExiting.\n", rv);
        return 6;
    }
    printf("Sample rate set to %u.\n", rtlsdr_get_sample_rate(rtlsdr));

    printf("Setting AGC on...\n");
    rv = rtlsdr_set_agc_mode(rtlsdr, 1);
    if(rv != 0) {
        printf("Error setting AGC: %d\nExiting.\n", rv);
        return 7;
    }
    
    
    printf("Clearing buffer and streaming data...\n");
    rv = rtlsdr_reset_buffer(rtlsdr);
    if(rv != 0) {
        printf("Error clearing buffer: %d\nExiting.\n", rv);
        return 8;
    }

    async_started = 1;

    rv = rtlsdr_read_async(rtlsdr, read_callback, NULL, 0, 0);
    if(rv != 0) {
        printf("Error setting up async streaming: %d\nExiting.\n", rv);
        return 9;
    }

    rtlsdr_cancel_async(rtlsdr);
    rtlsdr_close(rtlsdr);
    return 0;

}
Пример #7
0
uint CRtlSdr::getFrequency() {
    if (!power)
        return 0;
    return rtlsdr_get_center_freq(dongle.dev);
}