Преглед на файлове

lib: special handling of dongle disconnect for OS != win32

libusb reacts differently to a device loss during runtime,
and sporadic errors can happen when starting a second
instance interfacing another dongle, thus we need to wait
for all transfers to fail before assuming the dongle has
been removed.

Signed-off-by: Steve Markgraf <steve@steve-m.de>
Steve Markgraf преди 12 години
родител
ревизия
f1803fe10f
променени са 1 файла, в които са добавени 17 реда и са изтрити 5 реда
  1. 17 5
      src/librtlsdr.c

+ 17 - 5
src/librtlsdr.c

@@ -90,6 +90,7 @@ struct rtlsdr_dev {
 	int gain; /* tenth dB */
 	struct e4k_state e4k_s;
 	int dev_lost;
+	unsigned int xfer_errors;
 };
 
 void rtlsdr_set_gpio_bit(rtlsdr_dev_t *dev, uint8_t gpio, int val);
@@ -1507,11 +1508,22 @@ static void LIBUSB_CALL _libusb_callback(struct libusb_transfer *xfer)
 			dev->cb(xfer->buffer, xfer->actual_length, dev->cb_ctx);
 
 		libusb_submit_transfer(xfer); /* resubmit transfer */
-	} else if (LIBUSB_TRANSFER_CANCELLED != xfer->status &&
-				LIBUSB_TRANSFER_COMPLETED != xfer->status) {
-		dev->dev_lost = 1;
-		rtlsdr_cancel_async(dev);
-		fprintf(stderr, "cb transfer status: %d, canceling...\n", xfer->status);
+		dev->xfer_errors = 0;
+	} else if (LIBUSB_TRANSFER_CANCELLED != xfer->status) {
+#ifndef _WIN32
+		if (LIBUSB_TRANSFER_ERROR == xfer->status)
+			dev->xfer_errors++;
+
+		if (dev->xfer_errors >= dev->xfer_buf_num ||
+		    LIBUSB_TRANSFER_NO_DEVICE == xfer->status) {
+#endif
+			dev->dev_lost = 1;
+			rtlsdr_cancel_async(dev);
+			fprintf(stderr, "cb transfer status: %d, "
+				"canceling...\n", xfer->status);
+#ifndef _WIN32
+		}
+#endif
 	}
 }