diff --git a/include/rtl-sdr.h b/include/rtl-sdr.h index 547022d..4a1c570 100644 --- a/include/rtl-sdr.h +++ b/include/rtl-sdr.h @@ -32,7 +32,7 @@ RTLSDR_API uint32_t rtlsdr_get_device_count(void); RTLSDR_API const char* rtlsdr_get_device_name(uint32_t index); -RTLSDR_API rtlsdr_dev_t* rtlsdr_open(uint32_t index); +RTLSDR_API int rtlsdr_open(rtlsdr_dev_t **dev, uint32_t index); RTLSDR_API int rtlsdr_close(rtlsdr_dev_t *dev); @@ -61,9 +61,9 @@ RTLSDR_API int rtlsdr_reset_buffer(rtlsdr_dev_t *dev); RTLSDR_API int rtlsdr_read_sync(rtlsdr_dev_t *dev, void *buf, int len, int *n_read); -typedef void(*rtlsdr_async_read_cb_t)(const char *buf, uint32_t len, void *context); +typedef void(*rtlsdr_async_read_cb_t)(const char *buf, uint32_t len, void *ctx); -RTLSDR_API int rtlsdr_wait_async(rtlsdr_dev_t *dev, rtlsdr_async_read_cb_t cb, void *context); +RTLSDR_API int rtlsdr_wait_async(rtlsdr_dev_t *dev, rtlsdr_async_read_cb_t cb, void *ctx); RTLSDR_API int rtlsdr_cancel_async(rtlsdr_dev_t *dev); diff --git a/src/main.c b/src/main.c index 017ad6b..1ca1a17 100644 --- a/src/main.c +++ b/src/main.c @@ -98,9 +98,9 @@ int main(int argc, char **argv) printf("Found %d device(s).\n", device_count); - dev = rtlsdr_open(dev_index); - if (NULL == dev) { - fprintf(stderr, "Failed to open rtlsdr device #%d.\n", dev_index); + r = rtlsdr_open(&dev, dev_index); + if (r < 0) { + fprintf(stderr, "Failed to open rtlsdr device #%d.\n", dev_index); exit(1); } diff --git a/src/rtl-sdr.c b/src/rtl-sdr.c index bf01bb3..ad01c70 100644 --- a/src/rtl-sdr.c +++ b/src/rtl-sdr.c @@ -122,19 +122,17 @@ static rtlsdr_device_t devices[] = { #define BUF_LENGTH (16 * 16384) typedef struct rtlsdr_dev { + libusb_context *ctx; struct libusb_device_handle *devh; struct libusb_transfer *xfer[BUF_COUNT]; unsigned char *xfer_buf[BUF_COUNT]; rtlsdr_async_read_cb_t cb; - void *context; + void *cb_ctx; int run_async; rtlsdr_tuner_t *tuner; int rate; /* Hz */ } rtlsdr_dev_t; -static int opened_devices = 0; -static int libusb_inited = 0; - #define CRYSTAL_FREQ 28800000 #define MAX_SAMP_RATE 3200000 @@ -538,8 +536,7 @@ uint32_t rtlsdr_get_device_count(void) struct libusb_device_descriptor dd; ssize_t cnt; - if (!libusb_inited) - libusb_init(NULL); + libusb_init(NULL); cnt = libusb_get_device_list(NULL, &list); @@ -552,8 +549,7 @@ uint32_t rtlsdr_get_device_count(void) libusb_free_device_list(list, 0); - if (!libusb_inited) - libusb_exit(NULL); + libusb_exit(NULL); return device_count; } @@ -567,8 +563,7 @@ const char *rtlsdr_get_device_name(uint32_t index) uint32_t device_count = 0; ssize_t cnt; - if (!libusb_inited) - libusb_init(NULL); + libusb_init(NULL); cnt = libusb_get_device_list(NULL, &list); @@ -587,8 +582,7 @@ const char *rtlsdr_get_device_name(uint32_t index) libusb_free_device_list(list, 0); - if (!libusb_inited) - libusb_exit(NULL); + libusb_exit(NULL); if (device) return device->name; @@ -596,12 +590,12 @@ const char *rtlsdr_get_device_name(uint32_t index) return ""; } -rtlsdr_dev_t *rtlsdr_open(uint32_t index) +int rtlsdr_open(rtlsdr_dev_t **out_dev, uint32_t index) { int r; int i; libusb_device **list; - rtlsdr_dev_t * dev = NULL; + rtlsdr_dev_t *dev = NULL; libusb_device *device = NULL; uint32_t device_count = 0; struct libusb_device_descriptor dd; @@ -611,14 +605,9 @@ rtlsdr_dev_t *rtlsdr_open(uint32_t index) dev = malloc(sizeof(rtlsdr_dev_t)); memset(dev, 0, sizeof(rtlsdr_dev_t)); - if (1 == ++opened_devices) { - if (!libusb_inited) { - libusb_init(NULL); - libusb_inited = 1; - } - } + libusb_init(&dev->ctx); - cnt = libusb_get_device_list(NULL, &list); + cnt = libusb_get_device_list(dev->ctx, &list); for (i = 0; i < cnt; i++) { device = list[i]; @@ -635,8 +624,10 @@ rtlsdr_dev_t *rtlsdr_open(uint32_t index) device = NULL; } - if (!device) + if (!device) { + r = -1; goto err; + } r = libusb_open(device, &dev->devh); if (r < 0) { @@ -699,9 +690,19 @@ found: r =dev->tuner->init(dev); rtlsdr_set_i2c_repeater(dev, 0); - return dev; + + *out_dev = dev; + + return 0; err: - return NULL; + if (dev) { + if (dev->ctx) + libusb_exit(dev->ctx); + + free(dev); + } + + return r; } int rtlsdr_close(rtlsdr_dev_t *dev) @@ -721,14 +722,9 @@ int rtlsdr_close(rtlsdr_dev_t *dev) free(dev->xfer_buf[i]); } - free(dev); + libusb_exit(dev->ctx); - if (0 == --opened_devices) { - if (libusb_inited) { - libusb_exit(NULL); - libusb_inited = 0; - } - } + free(dev); return 0; } @@ -757,7 +753,7 @@ static void LIBUSB_CALL _libusb_callback(struct libusb_transfer *transfer) if (LIBUSB_TRANSFER_COMPLETED == transfer->status) { rtlsdr_dev_t *dev = (rtlsdr_dev_t *)transfer->user_data; - dev->cb(transfer->buffer, transfer->actual_length, dev->context); + dev->cb(transfer->buffer, transfer->actual_length, dev->cb_ctx); libusb_submit_transfer(transfer); /* resubmit transfer */ } else { @@ -765,7 +761,7 @@ static void LIBUSB_CALL _libusb_callback(struct libusb_transfer *transfer) } } -int rtlsdr_wait_async(rtlsdr_dev_t *dev, rtlsdr_async_read_cb_t cb, void *context) +int rtlsdr_wait_async(rtlsdr_dev_t *dev, rtlsdr_async_read_cb_t cb, void *ctx) { int i, r; @@ -773,7 +769,7 @@ int rtlsdr_wait_async(rtlsdr_dev_t *dev, rtlsdr_async_read_cb_t cb, void *contex return -1; dev->cb = cb; - dev->context = context; + dev->cb_ctx = ctx; for(i = 0; i < BUF_COUNT; ++i) { if (dev->xfer[i]) @@ -804,7 +800,7 @@ int rtlsdr_wait_async(rtlsdr_dev_t *dev, rtlsdr_async_read_cb_t cb, void *contex while (dev->run_async) { struct timeval tv = { 1, 0 }; - r = libusb_handle_events_timeout(NULL, &tv); + r = libusb_handle_events_timeout(dev->ctx, &tv); if (r < 0) { /*fprintf(stderr, "handle_events %d\n", r);*/ break;