added (untested) isochronous support to glibusb
diff --git a/aos/common/glibusb/glibusb_endpoint.cc b/aos/common/glibusb/glibusb_endpoint.cc
index ee69ec9..2346893 100644
--- a/aos/common/glibusb/glibusb_endpoint.cc
+++ b/aos/common/glibusb/glibusb_endpoint.cc
@@ -216,11 +216,11 @@
int r;
unsigned char transfer_type = LibUsbTransferType(transfer());
- r = do_sync_bulk_transfer(libusb_context_,
- handle_, endpoint_address_and_direction(),
- static_cast<unsigned char *>(p), length,
- &transferred, timeout, transfer_type,
- quit);
+ r = do_sync_transfer(libusb_context_,
+ handle_, endpoint_address_and_direction(),
+ static_cast<unsigned char *>(p), length,
+ &transferred, timeout, transfer_type,
+ quit);
switch (r) {
case LIBUSB_SUCCESS:
@@ -236,20 +236,25 @@
case LIBUSB_ERROR_TIMEOUT:
LOG(DEBUG, "libusb_%s_transfer timeout\n",
TransferTypeName(transfer()));
+ out->Resize(0);
return kTimeout;
case LIBUSB_ERROR_IO:
LOG(DEBUG, "device I/O error\n");
+ out->Resize(0);
return kFail;
case LIBUSB_ERROR_NO_DEVICE:
LOG(DEBUG, "device disconnected\n");
+ out->Resize(0);
return kNoDevice;
case LIBUSB_ERROR_OTHER:
LOG(INFO, "libusb_%s_transfer other error\n", TransferTypeName(transfer()));
+ out->Resize(0);
return kUnknown;
default:
// Most of these are more esoteric.
LOG(INFO, "libusb_%s_transfer failed with %d: %s\n",
TransferTypeName(transfer()), r, libusb_error_name(r));
+ out->Resize(0);
return kFail;
}
}
diff --git a/aos/common/glibusb/glibusb_transfer.cc b/aos/common/glibusb/glibusb_transfer.cc
index ec4cd2c..95a6222 100644
--- a/aos/common/glibusb/glibusb_transfer.cc
+++ b/aos/common/glibusb/glibusb_transfer.cc
@@ -22,31 +22,49 @@
namespace glibusb {
namespace {
+
// Static code from libusb1/sync.c
-void bulk_transfer_cb(struct libusb_transfer *transfer) {
+void transfer_cb(struct libusb_transfer *transfer) {
int *completed = static_cast<int*>(transfer->user_data);
*completed = 1;
LOG(DEBUG, "actual_length=%d\n", transfer->actual_length);
/* caller interprets results and frees transfer */
}
+
+// How many isochronous packets we're going to deal with.
+// TODO(brians): Make this settable per endpoint instead of a constant.
+const int kNumIsoPackets = 1;
+
} // namespace
-int do_sync_bulk_transfer(
+int do_sync_transfer(
struct libusb_context *context,
struct libusb_device_handle *dev_handle,
unsigned char endpoint, unsigned char *buffer, int length,
int *transferred, unsigned int timeout, unsigned char type,
Notification *quit) {
- struct libusb_transfer *transfer = libusb_alloc_transfer(0);
+ bool isochronous = type == LIBUSB_TRANSFER_TYPE_ISOCHRONOUS;
+ struct libusb_transfer *transfer =
+ libusb_alloc_transfer(isochronous ? kNumIsoPackets : 0);
int completed = 0;
int r;
if (!transfer)
return LIBUSB_ERROR_NO_MEM;
- libusb_fill_bulk_transfer(transfer, dev_handle, endpoint, buffer, length,
- bulk_transfer_cb, &completed, timeout);
- transfer->type = type;
+ switch (type) {
+ case LIBUSB_TRANSFER_TYPE_BULK:
+ case LIBUSB_TRANSFER_TYPE_INTERRUPT:
+ libusb_fill_bulk_transfer(transfer, dev_handle, endpoint, buffer, length,
+ transfer_cb, &completed, timeout);
+ case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
+ libusb_fill_iso_transfer(transfer, dev_handle, endpoint, buffer, length,
+ kNumIsoPackets, transfer_cb, &completed,
+ timeout);
+ transfer->iso_packet_desc[0].length = length;
+ default:
+ LOG(FATAL, "unhandled transfer type %hhd\n", type);
+ }
r = libusb_submit_transfer(transfer);
if (r < 0) {
@@ -82,7 +100,8 @@
}
}
- *transferred = transfer->actual_length;
+ *transferred = isochronous ? transfer->iso_packet_desc[0].actual_length :
+ transfer->actual_length;
switch (transfer->status) {
case LIBUSB_TRANSFER_COMPLETED:
r = 0;
diff --git a/aos/common/glibusb/glibusb_transfer.h b/aos/common/glibusb/glibusb_transfer.h
index 9218049..81af49e 100644
--- a/aos/common/glibusb/glibusb_transfer.h
+++ b/aos/common/glibusb/glibusb_transfer.h
@@ -1,5 +1,7 @@
// Copyright 2012 Google Inc. All Rights Reserved.
//
+// Modified by FRC Team 971.
+//
// Alternative libusb call to do transfers that quits when
// a notification is notified.
@@ -15,13 +17,14 @@
namespace glibusb {
-// Bulk transfer code cribbed from libusb1/sync.c
+// Transfer code cribbed from libusb1/sync.c and modified.
+// It supports bulk, isochronous, and interrupt transfers.
// The difference between this and the original code is that the
// transfer now accepts a notification to poll for the quit message.
// When it receives a quit message on the notification, it cancels the transfer.
// The provided API's don't support better reuse of the existing code from what
-// I can tell.
-int do_sync_bulk_transfer(
+// I can tell. It has also been modified to support isochronous transfers.
+int do_sync_transfer(
struct libusb_context *context,
struct libusb_device_handle *dev_handle,
unsigned char endpoint, unsigned char *buffer, int length,