Add SDR loop api
This commit is contained in:
parent
e7eacfd4b7
commit
619ca1fa18
5 changed files with 276 additions and 96 deletions
|
@ -53,7 +53,7 @@ typedef struct r_cfg {
|
|||
char const *test_data;
|
||||
list_t in_files;
|
||||
char const *in_filename;
|
||||
volatile sig_atomic_t break_async;
|
||||
volatile sig_atomic_t hop_now;
|
||||
volatile sig_atomic_t exit_async;
|
||||
volatile sig_atomic_t exit_code; ///< 0=no err, 1=params or cmd line err, 2=sdr device read error, 3=usb init error, 5=USB error (reset), other=other error
|
||||
int frequencies;
|
||||
|
|
|
@ -15,7 +15,27 @@
|
|||
#include <stdint.h>
|
||||
|
||||
typedef struct sdr_dev sdr_dev_t;
|
||||
typedef void (*sdr_read_cb_t)(unsigned char *buf, uint32_t len, void *ctx);
|
||||
|
||||
typedef enum sdr_event_flags {
|
||||
SDR_EV_EMPTY = 0,
|
||||
SDR_EV_DATA = 1 << 0,
|
||||
SDR_EV_RATE = 1 << 1,
|
||||
SDR_EV_CORR = 1 << 2,
|
||||
SDR_EV_FREQ = 1 << 3,
|
||||
SDR_EV_GAIN = 1 << 4,
|
||||
} sdr_event_flags_t;
|
||||
|
||||
typedef struct sdr_event {
|
||||
sdr_event_flags_t ev;
|
||||
uint32_t sample_rate;
|
||||
int freq_correction;
|
||||
uint32_t center_frequency;
|
||||
char const *gain_str;
|
||||
void *buf;
|
||||
int len;
|
||||
} sdr_event_t;
|
||||
|
||||
typedef void (*sdr_event_cb_t)(sdr_event_t *ev, void *ctx);
|
||||
|
||||
/** Find the closest matching device, optionally report status.
|
||||
|
||||
|
@ -139,7 +159,7 @@ int sdr_deactivate(sdr_dev_t *dev);
|
|||
*/
|
||||
int sdr_reset(sdr_dev_t *dev, int verbose);
|
||||
|
||||
int sdr_start(sdr_dev_t *dev, sdr_read_cb_t cb, void *ctx, uint32_t buf_num, uint32_t buf_len);
|
||||
int sdr_start(sdr_dev_t *dev, sdr_event_cb_t cb, void *ctx, uint32_t buf_num, uint32_t buf_len);
|
||||
int sdr_stop(sdr_dev_t *dev);
|
||||
|
||||
#endif /* INCLUDE_SDR_H_ */
|
||||
|
|
12
src/r_api.c
12
src/r_api.c
|
@ -94,22 +94,19 @@ void set_center_freq(r_cfg_t *cfg, uint32_t center_freq)
|
|||
cfg->frequencies = 1;
|
||||
cfg->frequency_index = 0;
|
||||
cfg->frequency[0] = center_freq;
|
||||
cfg->break_async = 1;
|
||||
sdr_stop(cfg->dev);
|
||||
sdr_set_center_freq(cfg->dev, center_freq, 0);
|
||||
}
|
||||
|
||||
void set_freq_correction(r_cfg_t *cfg, int freq_correction)
|
||||
{
|
||||
cfg->ppm_error = freq_correction;
|
||||
cfg->break_async = 1;
|
||||
sdr_stop(cfg->dev);
|
||||
sdr_set_freq_correction(cfg->dev, freq_correction, 0);
|
||||
}
|
||||
|
||||
void set_sample_rate(r_cfg_t *cfg, uint32_t sample_rate)
|
||||
{
|
||||
cfg->samp_rate = sample_rate;
|
||||
cfg->break_async = 1;
|
||||
sdr_stop(cfg->dev);
|
||||
sdr_set_sample_rate(cfg->dev, sample_rate, 0);
|
||||
}
|
||||
|
||||
void set_gain_str(struct r_cfg *cfg, char const *gain_str)
|
||||
|
@ -123,8 +120,7 @@ void set_gain_str(struct r_cfg *cfg, char const *gain_str)
|
|||
if (!cfg->gain_str)
|
||||
WARN_STRDUP("set_gain_str()");
|
||||
}
|
||||
cfg->break_async = 1;
|
||||
sdr_stop(cfg->dev);
|
||||
sdr_set_tuner_gain(cfg->dev, gain_str, 0);
|
||||
}
|
||||
|
||||
/* general */
|
||||
|
|
121
src/rtl_433.c
121
src/rtl_433.c
|
@ -297,10 +297,6 @@ static void sdr_callback(unsigned char *iq_buf, uint32_t len, void *ctx)
|
|||
char time_str[LOCAL_TIME_BUFLEN];
|
||||
unsigned long n_samples;
|
||||
|
||||
if (cfg->mgr) {
|
||||
mg_mgr_poll(cfg->mgr, 0);
|
||||
}
|
||||
|
||||
if ((cfg->bytes_to_read > 0) && (cfg->bytes_to_read <= len)) {
|
||||
len = cfg->bytes_to_read;
|
||||
cfg->exit_async = 1;
|
||||
|
@ -583,7 +579,7 @@ static void sdr_callback(unsigned char *iq_buf, uint32_t len, void *ctx)
|
|||
cfg->exit_async = 1;
|
||||
}
|
||||
else {
|
||||
cfg->break_async = 1;
|
||||
cfg->hop_now = 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -596,7 +592,7 @@ static void sdr_callback(unsigned char *iq_buf, uint32_t len, void *ctx)
|
|||
#ifndef _WIN32
|
||||
alarm(0); // cancel the watchdog timer
|
||||
#endif
|
||||
cfg->break_async = 1;
|
||||
cfg->hop_now = 1;
|
||||
}
|
||||
if (cfg->duration > 0 && rawtime >= cfg->stop_time) {
|
||||
#ifndef _WIN32
|
||||
|
@ -614,8 +610,13 @@ static void sdr_callback(unsigned char *iq_buf, uint32_t len, void *ctx)
|
|||
cfg->stats_now--;
|
||||
}
|
||||
|
||||
if (cfg->exit_async || cfg->break_async)
|
||||
sdr_stop(cfg->dev);
|
||||
if (cfg->hop_now && !cfg->exit_async) {
|
||||
cfg->hop_now = 0;
|
||||
time(&cfg->hop_start_time);
|
||||
cfg->frequency_index = (cfg->frequency_index + 1) % cfg->frequencies;
|
||||
cfg->center_frequency = cfg->frequency[cfg->frequency_index];
|
||||
sdr_set_center_freq(cfg->dev, cfg->center_frequency, 0);
|
||||
}
|
||||
}
|
||||
|
||||
static int hasopt(int test, int argc, char *argv[], char const *optstring)
|
||||
|
@ -1137,7 +1138,7 @@ sighandler(int signum)
|
|||
}
|
||||
else if (CTRL_BREAK_EVENT == signum) {
|
||||
fprintf(stderr, "CTRL-BREAK detected, hopping to next frequency (-f). Use CTRL-C to quit.\n");
|
||||
g_cfg.break_async = 1;
|
||||
g_cfg.hop_now = 1;
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
|
@ -1153,7 +1154,7 @@ static void sighandler(int signum)
|
|||
return;
|
||||
}
|
||||
else if (signum == SIGUSR1) {
|
||||
g_cfg.break_async = 1;
|
||||
g_cfg.hop_now = 1;
|
||||
return;
|
||||
}
|
||||
else if (signum == SIGALRM) {
|
||||
|
@ -1167,6 +1168,53 @@ static void sighandler(int signum)
|
|||
}
|
||||
#endif
|
||||
|
||||
static void sdr_handler(sdr_event_t *ev, void *ctx)
|
||||
{
|
||||
r_cfg_t *cfg = ctx;
|
||||
|
||||
data_t *data = NULL;
|
||||
if (ev->ev & SDR_EV_RATE) {
|
||||
data = data_append(data,
|
||||
"sample_rate", "", DATA_INT, ev->sample_rate,
|
||||
NULL);
|
||||
}
|
||||
if (ev->ev & SDR_EV_CORR) {
|
||||
data = data_append(data,
|
||||
"freq_correction", "", DATA_INT, ev->freq_correction,
|
||||
NULL);
|
||||
}
|
||||
if (ev->ev & SDR_EV_FREQ) {
|
||||
data = data_append(data,
|
||||
"center_frequency", "", DATA_INT, ev->center_frequency,
|
||||
"frequencies", "", DATA_COND, cfg->frequencies > 1, DATA_ARRAY, data_array(cfg->frequencies, DATA_INT, cfg->frequency),
|
||||
"hop_times", "", DATA_COND, cfg->frequencies > 1, DATA_ARRAY, data_array(cfg->hop_times, DATA_INT, cfg->hop_time),
|
||||
NULL);
|
||||
}
|
||||
if (ev->ev & SDR_EV_GAIN) {
|
||||
data = data_append(data,
|
||||
"gain", "", DATA_STRING, ev->gain_str,
|
||||
NULL);
|
||||
}
|
||||
if (data) {
|
||||
for (size_t i = 0; i < cfg->output_handler.len; ++i) { // list might contain NULLs
|
||||
data_output_print(cfg->output_handler.elems[i], data);
|
||||
}
|
||||
data_free(data);
|
||||
}
|
||||
|
||||
if (ev->ev == SDR_EV_DATA) {
|
||||
if (cfg->mgr) {
|
||||
mg_mgr_poll(cfg->mgr, 0);
|
||||
}
|
||||
|
||||
if (!cfg->exit_async)
|
||||
sdr_callback((unsigned char *)ev->buf, ev->len, ctx);
|
||||
}
|
||||
|
||||
if (cfg->exit_async)
|
||||
sdr_stop(cfg->dev);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
#ifndef _WIN32
|
||||
struct sigaction sigact;
|
||||
|
@ -1614,73 +1662,22 @@ int main(int argc, char **argv) {
|
|||
cfg->stop_time += cfg->duration;
|
||||
}
|
||||
|
||||
uint32_t samp_rate = cfg->samp_rate;
|
||||
char *gain_str = cfg->gain_str;
|
||||
int ppm_error = cfg->ppm_error;
|
||||
|
||||
cfg->center_frequency = cfg->frequency[cfg->frequency_index];
|
||||
r = sdr_set_center_freq(cfg->dev, cfg->center_frequency, 1); // always verbose
|
||||
|
||||
while (!cfg->exit_async) {
|
||||
time(&cfg->hop_start_time);
|
||||
data_t *data = NULL;
|
||||
if (samp_rate != cfg->samp_rate) {
|
||||
samp_rate = cfg->samp_rate;
|
||||
r = sdr_set_sample_rate(cfg->dev, cfg->samp_rate, 1); // always verbose
|
||||
|
||||
data = data_append(data,
|
||||
"sample_rate", "", DATA_INT, cfg->samp_rate,
|
||||
NULL);
|
||||
}
|
||||
if (ppm_error != cfg->ppm_error) {
|
||||
ppm_error = cfg->ppm_error;
|
||||
r = sdr_set_freq_correction(cfg->dev, cfg->ppm_error, 1); // always verbose
|
||||
|
||||
data = data_append(data,
|
||||
"freq_correction", "", DATA_INT, cfg->ppm_error,
|
||||
NULL);
|
||||
}
|
||||
if (cfg->center_frequency != cfg->frequency[cfg->frequency_index]) {
|
||||
cfg->center_frequency = cfg->frequency[cfg->frequency_index];
|
||||
r = sdr_set_center_freq(cfg->dev, cfg->center_frequency, 1); // always verbose
|
||||
|
||||
data = data_append(data,
|
||||
"center_frequency", "", DATA_INT, cfg->center_frequency,
|
||||
"frequencies", "", DATA_COND, cfg->frequencies > 1, DATA_ARRAY, data_array(cfg->frequencies, DATA_INT, cfg->frequency),
|
||||
"hop_times", "", DATA_COND, cfg->frequencies > 1, DATA_ARRAY, data_array(cfg->hop_times, DATA_INT, cfg->hop_time),
|
||||
NULL);
|
||||
}
|
||||
if (gain_str != cfg->gain_str) {
|
||||
gain_str = cfg->gain_str;
|
||||
r = sdr_set_tuner_gain(cfg->dev, cfg->gain_str, 1); // always verbose
|
||||
|
||||
data = data_append(data,
|
||||
"gain", "", DATA_STRING, cfg->gain_str,
|
||||
NULL);
|
||||
}
|
||||
if (data) {
|
||||
for (size_t i = 0; i < cfg->output_handler.len; ++i) { // list might contain NULLs
|
||||
data_output_print(cfg->output_handler.elems[i], data);
|
||||
}
|
||||
data_free(data);
|
||||
}
|
||||
|
||||
#ifndef _WIN32
|
||||
signal(SIGALRM, sighandler);
|
||||
alarm(3); // require callback to run every 3 second, abort otherwise
|
||||
#endif
|
||||
cfg->break_async = 0;
|
||||
r = sdr_start(cfg->dev, sdr_callback, (void *)cfg,
|
||||
r = sdr_start(cfg->dev, sdr_handler, (void *)cfg,
|
||||
DEFAULT_ASYNC_BUF_NUMBER, cfg->out_block_size);
|
||||
if (r < 0) {
|
||||
fprintf(stderr, "WARNING: async read failed (%i).\n", r);
|
||||
break;
|
||||
}
|
||||
#ifndef _WIN32
|
||||
alarm(0); // cancel the watchdog timer
|
||||
#endif
|
||||
cfg->frequency_index = (cfg->frequency_index + 1) % cfg->frequencies;
|
||||
}
|
||||
|
||||
if (cfg->report_stats > 0) {
|
||||
event_occurred_handler(cfg, create_report_data(cfg, cfg->report_stats));
|
||||
|
|
213
src/sdr.c
213
src/sdr.c
|
@ -21,7 +21,7 @@
|
|||
#include "optparse.h"
|
||||
#include "fatal.h"
|
||||
#ifdef RTLSDR
|
||||
#include "rtl-sdr.h"
|
||||
#include <rtl-sdr.h>
|
||||
#include <libusb.h> /* libusb_error_name(), libusb_strerror() */
|
||||
#endif
|
||||
#ifdef SOAPYSDR
|
||||
|
@ -78,17 +78,75 @@ struct sdr_dev {
|
|||
|
||||
#ifdef RTLSDR
|
||||
rtlsdr_dev_t *rtlsdr_dev;
|
||||
sdr_event_cb_t rtlsdr_cb;
|
||||
void *rtlsdr_cb_ctx;
|
||||
#endif
|
||||
|
||||
char *dev_info;
|
||||
|
||||
int running;
|
||||
int polling;
|
||||
void *buffer;
|
||||
size_t buffer_size;
|
||||
|
||||
int sample_size;
|
||||
|
||||
int apply_rate;
|
||||
int apply_freq;
|
||||
int apply_corr;
|
||||
int apply_gain;
|
||||
uint32_t sample_rate;
|
||||
int freq_correction;
|
||||
uint32_t center_frequency;
|
||||
char *gain_str;
|
||||
};
|
||||
|
||||
/* internal helpers */
|
||||
|
||||
static int apply_changes(sdr_dev_t *dev, sdr_event_cb_t cb, void *ctx)
|
||||
{
|
||||
int r = 0;
|
||||
sdr_event_flags_t flags = 0;
|
||||
if (dev->apply_rate) {
|
||||
r = sdr_set_sample_rate(dev, dev->sample_rate, 1); // always verbose
|
||||
dev->apply_rate = 0;
|
||||
flags |= SDR_EV_RATE;
|
||||
}
|
||||
|
||||
if (dev->apply_corr) {
|
||||
r = sdr_set_freq_correction(dev, dev->freq_correction, 1); // always verbose
|
||||
dev->apply_corr = 0;
|
||||
flags |= SDR_EV_CORR;
|
||||
}
|
||||
|
||||
if (dev->apply_freq) {
|
||||
r = sdr_set_center_freq(dev, dev->center_frequency, 1); // always verbose
|
||||
dev->apply_freq = 0;
|
||||
flags |= SDR_EV_FREQ;
|
||||
}
|
||||
|
||||
char *gain_str = dev->gain_str;
|
||||
dev->gain_str = NULL;
|
||||
if (dev->apply_gain) {
|
||||
r = sdr_set_tuner_gain(dev, gain_str, 1); // always verbose
|
||||
dev->apply_gain = 0;
|
||||
flags |= SDR_EV_GAIN;
|
||||
}
|
||||
if (flags) {
|
||||
sdr_event_t ev = {
|
||||
.ev = flags,
|
||||
.sample_rate = dev->sample_rate,
|
||||
.freq_correction = dev->freq_correction,
|
||||
.center_frequency = dev->center_frequency,
|
||||
.gain_str = gain_str,
|
||||
};
|
||||
if (cb)
|
||||
cb(&ev, ctx);
|
||||
free(gain_str);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
/* rtl_tcp helpers */
|
||||
|
||||
#pragma pack(push, 1)
|
||||
|
@ -208,7 +266,7 @@ static int rtltcp_close(SOCKET sock)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int rtltcp_read_loop(sdr_dev_t *dev, sdr_read_cb_t cb, void *ctx, uint32_t buf_num, uint32_t buf_len)
|
||||
static int rtltcp_read_loop(sdr_dev_t *dev, sdr_event_cb_t cb, void *ctx, uint32_t buf_num, uint32_t buf_len)
|
||||
{
|
||||
if (dev->buffer_size != buf_len) {
|
||||
free(dev->buffer);
|
||||
|
@ -243,8 +301,16 @@ static int rtltcp_read_loop(sdr_dev_t *dev, sdr_read_cb_t cb, void *ctx, uint32_
|
|||
dev->running = 0;
|
||||
}
|
||||
|
||||
sdr_event_t ev = {
|
||||
.ev = SDR_EV_DATA,
|
||||
.buf = buffer,
|
||||
.len = n_read,
|
||||
};
|
||||
dev->polling = 1;
|
||||
if (n_read > 0) // prevent a crash in callback
|
||||
cb((unsigned char *)buffer, n_read, ctx);
|
||||
cb(&ev, ctx);
|
||||
dev->polling = 0;
|
||||
apply_changes(dev, cb, ctx);
|
||||
|
||||
} while (dev->running);
|
||||
|
||||
|
@ -328,6 +394,7 @@ static int sdr_open_rtl(sdr_dev_t **out_dev, int *sample_size, char *dev_query,
|
|||
WARN_CALLOC("sdr_open_rtl()");
|
||||
return -1; // NOTE: returns error on alloc failure.
|
||||
}
|
||||
|
||||
for (uint32_t i = dev_query ? dev_index : 0;
|
||||
//cast quiets -Wsign-compare; if dev_index were < 0, would have returned -1 above
|
||||
i < (dev_query ? (unsigned)dev_index + 1 : device_count);
|
||||
|
@ -409,6 +476,51 @@ static int rtlsdr_find_tuner_gain(sdr_dev_t *dev, int centigain, int verbose)
|
|||
return centigain;
|
||||
}
|
||||
|
||||
static void rtlsdr_read_cb(unsigned char *iq_buf, uint32_t len, void *ctx)
|
||||
{
|
||||
sdr_dev_t *dev = ctx;
|
||||
sdr_event_t ev = {
|
||||
.ev = SDR_EV_DATA,
|
||||
.buf = iq_buf,
|
||||
.len = len,
|
||||
};
|
||||
if (len > 0) // prevent a crash in callback
|
||||
dev->rtlsdr_cb(&ev, dev->rtlsdr_cb_ctx);
|
||||
// FIXME: we actually need to copy the buffer to prevent it going away on cancel_async
|
||||
}
|
||||
|
||||
static int rtlsdr_read_loop(sdr_dev_t *dev, sdr_event_cb_t cb, void *ctx, uint32_t buf_num, uint32_t buf_len)
|
||||
{
|
||||
int r = 0;
|
||||
|
||||
dev->rtlsdr_cb = cb;
|
||||
dev->rtlsdr_cb_ctx = ctx;
|
||||
|
||||
dev->running = 1;
|
||||
do {
|
||||
dev->polling = 1;
|
||||
|
||||
r = rtlsdr_read_async(dev->rtlsdr_dev, rtlsdr_read_cb, dev, buf_num, buf_len);
|
||||
// rtlsdr_read_async() returns possible error codes from:
|
||||
// if (!dev) return -1;
|
||||
// if (RTLSDR_INACTIVE != dev->async_status) return -2;
|
||||
// r = libusb_submit_transfer(dev->xfer[i]);
|
||||
// r = libusb_handle_events_timeout_completed(dev->ctx, &tv,
|
||||
// r = libusb_cancel_transfer(dev->xfer[i]);
|
||||
// We can safely assume it's an libusb error.
|
||||
if (r < 0) {
|
||||
fprintf(stderr, "\n%s: %s!\n"
|
||||
"Check your RTL-SDR dongle, USB cables, and power supply.\n\n",
|
||||
libusb_error_name(r), libusb_strerror(r));
|
||||
}
|
||||
dev->polling = 0;
|
||||
apply_changes(dev, cb, ctx);
|
||||
|
||||
} while (dev->running);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* SoapySDR helpers */
|
||||
|
@ -784,7 +896,7 @@ static int sdr_open_soapy(sdr_dev_t **out_dev, int *sample_size, char *dev_query
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int soapysdr_read_loop(sdr_dev_t *dev, sdr_read_cb_t cb, void *ctx, uint32_t buf_num, uint32_t buf_len)
|
||||
static int soapysdr_read_loop(sdr_dev_t *dev, sdr_event_cb_t cb, void *ctx, uint32_t buf_num, uint32_t buf_len)
|
||||
{
|
||||
if (dev->buffer_size != buf_len) {
|
||||
free(dev->buffer);
|
||||
|
@ -842,8 +954,16 @@ static int soapysdr_read_loop(sdr_dev_t *dev, sdr_read_cb_t cb, void *ctx, uint3
|
|||
buffer[i] *= upscale;
|
||||
}
|
||||
|
||||
sdr_event_t ev = {
|
||||
.ev = SDR_EV_DATA,
|
||||
.buf = buffer,
|
||||
.len = n_read * 2 * dev->sample_size,
|
||||
};
|
||||
dev->polling = 1;
|
||||
if (n_read > 0) // prevent a crash in callback
|
||||
cb((unsigned char *)buffer, n_read * 2 * dev->sample_size, ctx);
|
||||
cb(&ev, ctx);
|
||||
dev->polling = 0;
|
||||
apply_changes(dev, cb, ctx);
|
||||
|
||||
} while (dev->running);
|
||||
|
||||
|
@ -913,6 +1033,16 @@ char const *sdr_get_dev_info(sdr_dev_t *dev)
|
|||
|
||||
int sdr_set_center_freq(sdr_dev_t *dev, uint32_t freq, int verbose)
|
||||
{
|
||||
if (dev->polling) {
|
||||
dev->center_frequency = freq;
|
||||
dev->apply_freq = 1;
|
||||
#ifdef RTLSDR
|
||||
if (dev->rtlsdr_dev)
|
||||
rtlsdr_cancel_async(dev->rtlsdr_dev);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
int r = -1;
|
||||
|
||||
if (dev->rtl_tcp) {
|
||||
|
@ -961,6 +1091,16 @@ uint32_t sdr_get_center_freq(sdr_dev_t *dev)
|
|||
|
||||
int sdr_set_freq_correction(sdr_dev_t *dev, int ppm, int verbose)
|
||||
{
|
||||
if (dev->polling) {
|
||||
dev->freq_correction = ppm;
|
||||
dev->apply_corr = 1;
|
||||
#ifdef RTLSDR
|
||||
if (dev->rtlsdr_dev)
|
||||
rtlsdr_cancel_async(dev->rtlsdr_dev);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
int r = -1;
|
||||
|
||||
if (dev->rtl_tcp)
|
||||
|
@ -987,6 +1127,17 @@ int sdr_set_freq_correction(sdr_dev_t *dev, int ppm, int verbose)
|
|||
|
||||
int sdr_set_auto_gain(sdr_dev_t *dev, int verbose)
|
||||
{
|
||||
if (dev->polling) {
|
||||
free(dev->gain_str);
|
||||
dev->gain_str = NULL; // auto gain
|
||||
dev->apply_gain = 1;
|
||||
#ifdef RTLSDR
|
||||
if (dev->rtlsdr_dev)
|
||||
rtlsdr_cancel_async(dev->rtlsdr_dev);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
int r = -1;
|
||||
|
||||
if (dev->rtl_tcp)
|
||||
|
@ -1013,6 +1164,24 @@ int sdr_set_auto_gain(sdr_dev_t *dev, int verbose)
|
|||
|
||||
int sdr_set_tuner_gain(sdr_dev_t *dev, char const *gain_str, int verbose)
|
||||
{
|
||||
if (dev->polling) {
|
||||
free(dev->gain_str);
|
||||
if (!gain_str) {
|
||||
dev->gain_str = NULL; // auto gain
|
||||
}
|
||||
else {
|
||||
dev->gain_str = strdup(gain_str);
|
||||
if (!dev->gain_str)
|
||||
WARN_STRDUP("set_gain_str()");
|
||||
}
|
||||
dev->apply_gain = 1;
|
||||
#ifdef RTLSDR
|
||||
if (dev->rtlsdr_dev)
|
||||
rtlsdr_cancel_async(dev->rtlsdr_dev);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
int r = -1;
|
||||
|
||||
if (!gain_str || !*gain_str) {
|
||||
|
@ -1090,6 +1259,16 @@ int sdr_set_antenna(sdr_dev_t *dev, char const *antenna_str, int verbose)
|
|||
|
||||
int sdr_set_sample_rate(sdr_dev_t *dev, uint32_t rate, int verbose)
|
||||
{
|
||||
if (dev->polling) {
|
||||
dev->sample_rate = rate;
|
||||
dev->apply_rate = 1;
|
||||
#ifdef RTLSDR
|
||||
if (dev->rtlsdr_dev)
|
||||
rtlsdr_cancel_async(dev->rtlsdr_dev);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
int r = -1;
|
||||
|
||||
if (dev->rtl_tcp) {
|
||||
|
@ -1224,7 +1403,7 @@ int sdr_reset(sdr_dev_t *dev, int verbose)
|
|||
return r;
|
||||
}
|
||||
|
||||
int sdr_start(sdr_dev_t *dev, sdr_read_cb_t cb, void *ctx, uint32_t buf_num, uint32_t buf_len)
|
||||
int sdr_start(sdr_dev_t *dev, sdr_event_cb_t cb, void *ctx, uint32_t buf_num, uint32_t buf_len)
|
||||
{
|
||||
if (dev->rtl_tcp)
|
||||
return rtltcp_read_loop(dev, cb, ctx, buf_num, buf_len);
|
||||
|
@ -1235,22 +1414,8 @@ int sdr_start(sdr_dev_t *dev, sdr_read_cb_t cb, void *ctx, uint32_t buf_num, uin
|
|||
#endif
|
||||
|
||||
#ifdef RTLSDR
|
||||
if (dev->rtlsdr_dev) {
|
||||
int r = rtlsdr_read_async(dev->rtlsdr_dev, cb, ctx, buf_num, buf_len);
|
||||
// rtlsdr_read_async() returns possible error codes from:
|
||||
// if (!dev) return -1;
|
||||
// if (RTLSDR_INACTIVE != dev->async_status) return -2;
|
||||
// r = libusb_submit_transfer(dev->xfer[i]);
|
||||
// r = libusb_handle_events_timeout_completed(dev->ctx, &tv,
|
||||
// r = libusb_cancel_transfer(dev->xfer[i]);
|
||||
// We can safely assume it's an libusb error.
|
||||
if (r < 0) {
|
||||
fprintf(stderr, "\n%s: %s!\n"
|
||||
"Check your RTL-SDR dongle, USB cables, and power supply.\n\n",
|
||||
libusb_error_name(r), libusb_strerror(r));
|
||||
}
|
||||
return r;
|
||||
}
|
||||
if (dev->rtlsdr_dev)
|
||||
return rtlsdr_read_loop(dev, cb, ctx, buf_num, buf_len);
|
||||
#endif
|
||||
|
||||
return -1;
|
||||
|
@ -1274,8 +1439,10 @@ int sdr_stop(sdr_dev_t *dev)
|
|||
#endif
|
||||
|
||||
#ifdef RTLSDR
|
||||
if (dev->rtlsdr_dev)
|
||||
if (dev->rtlsdr_dev) {
|
||||
dev->running = 0;
|
||||
return rtlsdr_cancel_async(dev->rtlsdr_dev);
|
||||
}
|
||||
#endif
|
||||
|
||||
return -1;
|
||||
|
|
Loading…
Add table
Reference in a new issue