|
@@ -118,8 +118,16 @@ static rtlsdr_device_t devices[] = {
|
|
{ 0x0458, 0x707f, "Genius TVGo DVB-T03 USB dongle (Ver. B)" },
|
|
{ 0x0458, 0x707f, "Genius TVGo DVB-T03 USB dongle (Ver. B)" },
|
|
};
|
|
};
|
|
|
|
|
|
|
|
+#define BUF_COUNT 32
|
|
|
|
+#define BUF_LENGTH (16 * 16384)
|
|
|
|
+
|
|
typedef struct rtlsdr_dev {
|
|
typedef struct rtlsdr_dev {
|
|
struct libusb_device_handle *devh;
|
|
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;
|
|
|
|
+ int run_async;
|
|
rtlsdr_tuner_t *tuner;
|
|
rtlsdr_tuner_t *tuner;
|
|
int rate; /* Hz */
|
|
int rate; /* Hz */
|
|
} rtlsdr_dev_t;
|
|
} rtlsdr_dev_t;
|
|
@@ -698,11 +706,21 @@ err:
|
|
|
|
|
|
int rtlsdr_close(rtlsdr_dev_t *dev)
|
|
int rtlsdr_close(rtlsdr_dev_t *dev)
|
|
{
|
|
{
|
|
|
|
+ int i;
|
|
|
|
+
|
|
if (!dev)
|
|
if (!dev)
|
|
return -1;
|
|
return -1;
|
|
|
|
|
|
libusb_release_interface(dev->devh, 0);
|
|
libusb_release_interface(dev->devh, 0);
|
|
libusb_close(dev->devh);
|
|
libusb_close(dev->devh);
|
|
|
|
+
|
|
|
|
+ for(i = 0; i < BUF_COUNT; ++i) {
|
|
|
|
+ if (dev->xfer[i])
|
|
|
|
+ libusb_free_transfer(dev->xfer[i]);
|
|
|
|
+ if (dev->xfer_buf[i])
|
|
|
|
+ free(dev->xfer_buf[i]);
|
|
|
|
+ }
|
|
|
|
+
|
|
free(dev);
|
|
free(dev);
|
|
|
|
|
|
if (0 == --opened_devices) {
|
|
if (0 == --opened_devices) {
|
|
@@ -733,11 +751,78 @@ int rtlsdr_read_sync(rtlsdr_dev_t *dev, void *buf, int len, int *n_read)
|
|
|
|
|
|
return libusb_bulk_transfer(dev->devh, 0x81, buf, len, n_read, 3000);
|
|
return libusb_bulk_transfer(dev->devh, 0x81, buf, len, n_read, 3000);
|
|
}
|
|
}
|
|
-#if 0
|
|
|
|
-typedef void(*rtlsdr_async_read_cb_t)(const char *buf, uint32_t len, void *ctx);
|
|
|
|
|
|
|
|
-int rtlsdr_async_loop(rtlsdr_dev_t *dev, rtlsdr_async_read_cb_t cb, void *ctx)
|
|
|
|
|
|
+static void LIBUSB_CALL _libusb_callback(struct libusb_transfer *transfer)
|
|
{
|
|
{
|
|
- return 0;
|
|
|
|
|
|
+ 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);
|
|
|
|
+
|
|
|
|
+ libusb_submit_transfer(transfer); /* resubmit transfer */
|
|
|
|
+ } else {
|
|
|
|
+ /*fprintf(stderr, "transfer %d\n", transfer->status);*/
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+int rtlsdr_wait_async(rtlsdr_dev_t *dev, rtlsdr_async_read_cb_t cb, void *context)
|
|
|
|
+{
|
|
|
|
+ int i, r;
|
|
|
|
+
|
|
|
|
+ if (!dev)
|
|
|
|
+ return -1;
|
|
|
|
+
|
|
|
|
+ dev->cb = cb;
|
|
|
|
+ dev->context = context;
|
|
|
|
+
|
|
|
|
+ for(i = 0; i < BUF_COUNT; ++i) {
|
|
|
|
+ if (dev->xfer[i])
|
|
|
|
+ continue;
|
|
|
|
+
|
|
|
|
+ dev->xfer[i] = libusb_alloc_transfer(0);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ for(i = 0; i < BUF_COUNT; ++i) {
|
|
|
|
+ if (dev->xfer_buf[i])
|
|
|
|
+ continue;
|
|
|
|
+
|
|
|
|
+ dev->xfer_buf[i] = (unsigned char *)malloc(BUF_LENGTH);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ for(i = 0; i < BUF_COUNT; ++i) {
|
|
|
|
+ libusb_fill_bulk_transfer(dev->xfer[i],
|
|
|
|
+ dev->devh,
|
|
|
|
+ 0x81,
|
|
|
|
+ dev->xfer_buf[i], BUF_LENGTH,
|
|
|
|
+ _libusb_callback,
|
|
|
|
+ (void *)dev, 0);
|
|
|
|
+
|
|
|
|
+ libusb_submit_transfer(dev->xfer[i]);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ dev->run_async = 1;
|
|
|
|
+
|
|
|
|
+ while (dev->run_async) {
|
|
|
|
+ struct timeval tv = { 1, 0 };
|
|
|
|
+ r = libusb_handle_events_timeout(NULL, &tv);
|
|
|
|
+ if (r < 0) {
|
|
|
|
+ /*fprintf(stderr, "handle_events %d\n", r);*/
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return r;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+int rtlsdr_cancel_async(rtlsdr_dev_t *dev)
|
|
|
|
+{
|
|
|
|
+ if (!dev)
|
|
|
|
+ return -1;
|
|
|
|
+
|
|
|
|
+ if (dev->run_async) {
|
|
|
|
+ dev->run_async = 0;
|
|
|
|
+ return 0;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return -2;
|
|
}
|
|
}
|
|
-#endif
|
|
|