moved back to our custom libusb wrappers instead of glibusb

Glibusb's model is too simplified to work very well at all with
isochronous, so I had to go back to our custom wrapper (which still
needed isochronous support to be finished).
diff --git a/frc971/input/gyro_sensor_receiver.cc b/frc971/input/gyro_sensor_receiver.cc
index 0fafaeb..ed37229 100644
--- a/frc971/input/gyro_sensor_receiver.cc
+++ b/frc971/input/gyro_sensor_receiver.cc
@@ -6,8 +6,6 @@
 #include "aos/atom_code/init.h"
 #include "aos/common/logging/logging.h"
 #include "aos/common/time.h"
-#include "aos/common/glibusb/glibusb.h"
-#include "aos/common/glibusb/gbuffer.h"
 #include "aos/common/util/wrapping_counter.h"
 #include "aos/common/control_loop/ControlLoop.h"
 
@@ -18,6 +16,7 @@
 #include "frc971/control_loops/shooter/shooter_motor.q.h"
 #include "frc971/input/gyro_board_data.h"
 #include "frc971/queues/GyroAngle.q.h"
+#include "gyro_board/src/libusb-driver/libusb_wrap.h"
 
 #ifndef M_PI
 #define M_PI 3.14159265358979323846
@@ -78,20 +77,27 @@
       if (phase_locker_.IsCurrentPacketGood(received_time, sequence_.count())) {
         LOG(DEBUG, "processing data\n");
         ProcessData();
-      } else {
-        LOG(DEBUG, "not processing\n");
       }
     }
   }
 
  private:
-  static const unsigned char kEndpoint = 0x3;
+  static const unsigned char kEndpoint = 0x83;
   // 0 is unlimited
   static constexpr ::aos::time::Time kReadTimeout =
       ::aos::time::Time::InSeconds(1.5);
-  static constexpr ::glibusb::VendorProductId kDeviceId = 
-      ::glibusb::VendorProductId(0x1424  /* vendor ID */,
-                                 0xd243  /* product ID */);
+  // vendor ID
+  static const int32_t kVid = 0x1424;
+  // product ID
+  static const int32_t kPid = 0xd243;
+
+  // A value to put into completed_transfer_ to indicate that it failed.
+  static constexpr libusb::Transfer *kTransferFailed =
+      reinterpret_cast<libusb::Transfer *>(-1);
+
+  // How big of a buffer we're going to give the usb transfer stuff.
+  static const size_t kDataLength = 128;
+  static_assert(kDataLength >= sizeof(GyroBoardData), "buffer is too small");
 
   static const int kPacketsPerLoopCycle = 10;
 
@@ -141,6 +147,7 @@
           --good_phase_;
         }
       } else if (guess_phase_bad_ > kMaxBadGuessCycles) {
+        LOG(INFO, "guessed wrong phase too many times\n");
         Reset();
       }
       if (good_phase_early_ > kSwitchCycles) {
@@ -172,12 +179,14 @@
               guess_phase_offset_ = offset;
             }
           } else if (received_phase == guess_phase_) {
+            LOG(DEBUG, "guessed right phase %d\n", received_phase);
             ++guess_phase_good_;
             guess_phase_bad_ = 0;
             guess_phase_offset_ = (guess_phase_offset_ * 9 + offset) / 10;
           }
         } else if (guess_phase_ != kUnknownPhase &&
                    received_phase == guess_phase_) {
+          LOG(DEBUG, "guessed wrong phase %d\n", received_phase);
           ++guess_phase_bad_;
           guess_phase_good_ = ::std::max(0, guess_phase_good_ -
                                          (kMinGoodGuessCycles / 10));
@@ -240,47 +249,75 @@
     int good_phase_early_, good_phase_late_;
   } phase_locker_;
 
+  static void StaticTransferCallback(libusb::Transfer *transfer, void *self) {
+    static_cast<GyroSensorReceiver *>(self)->TransferCallback(transfer);
+  }
+  void TransferCallback(libusb::Transfer *transfer) {
+    if (transfer->status() == LIBUSB_TRANSFER_COMPLETED) {
+      LOG(DEBUG, "transfer %p completed\n", transfer);
+      completed_transfer_ = transfer;
+    } else if (transfer->status() == LIBUSB_TRANSFER_TIMED_OUT) {
+      LOG(WARNING, "transfer %p timed out\n", transfer);
+      completed_transfer_ = kTransferFailed;
+    } else if (transfer->status() == LIBUSB_TRANSFER_CANCELLED) {
+      LOG(DEBUG, "transfer %p cancelled\n", transfer);
+    } else {
+      LOG(FATAL, "transfer %p has status %d\n", transfer, transfer->status());
+    }
+    transfer->Submit();
+  }
+
   // Returns true if receiving failed and we should try a Reset().
   bool ReceiveData() {
     // Loop and then return once we get a good one.
     while (true) {
-      using ::glibusb::UsbEndpoint;
-      UsbEndpoint::IoStatus result =
-          endpoint_->ReadAtMostWithTimeout(sizeof(GyroBoardData),
-                                           kReadTimeout.ToMSec(),
-                                           &buffer_);
-      switch (result) {
-        case UsbEndpoint::kSuccess:
-          sequence_.Update(data()->sequence);
-          return false;
-        case UsbEndpoint::kTimeout:
-          LOG(WARNING, "read timed out\n");
-          return true;
-        case UsbEndpoint::kNoDevice:
-          LOG(ERROR, "no device\n");
-          return true;
-        case UsbEndpoint::kUnknown:
-        case UsbEndpoint::kFail:
-        case UsbEndpoint::kAbort:
-          LOG(ERROR, "read failed\n");
-          continue;
+      completed_transfer_ = NULL;
+      while (completed_transfer_ == NULL) {
+        libusb_.HandleEvents();
       }
+      if (completed_transfer_ == kTransferFailed) {
+        LOG(WARNING, "transfer failed\n");
+        return true;
+      }
+
+      if (completed_transfer_->read_bytes() <
+          static_cast<ssize_t>(sizeof(GyroBoardData))) {
+        LOG(ERROR, "read %d bytes instead of at least %zd\n",
+            completed_transfer_->read_bytes(), sizeof(GyroBoardData));
+        continue;
+      }
+
+      memcpy(data(), completed_transfer_->data(),
+             sizeof(GyroBoardData));
+      sequence_.Update(data()->sequence);
+      return false;
     }
   }
 
   GyroBoardData *data() {
-    return static_cast<GyroBoardData *>(
-        buffer_.GetBufferPointer(sizeof(GyroBoardData)));
+    return &data_;
   }
 
   void Reset() {
-    // Make sure to delete the endpoint before its device.
-    endpoint_.reset();
-    device_ = ::std::unique_ptr< ::glibusb::UsbDevice>(
-        libusb_.FindSingleMatchingDeviceOrLose(kDeviceId));
-    CHECK(device_);
-    endpoint_ = ::std::unique_ptr< ::glibusb::UsbInEndpoint>(
-        device_->InEndpoint(kEndpoint));
+    transfer1_.reset();
+    transfer2_.reset();
+    dev_handle_ = ::std::unique_ptr<LibUSBDeviceHandle>(
+        libusb_.FindDeviceWithVIDPID(kVid, kPid));
+    if (!dev_handle_) {
+      LOG(ERROR, "couldn't find device. exiting\n");
+      exit(1);
+    }
+    transfer1_ = ::std::unique_ptr<libusb::IsochronousTransfer>(
+        new libusb::IsochronousTransfer(kDataLength, 1,
+                                        StaticTransferCallback, this));
+    transfer2_ = ::std::unique_ptr<libusb::IsochronousTransfer>(
+        new libusb::IsochronousTransfer(kDataLength, 1,
+                                        StaticTransferCallback, this));
+    transfer1_->FillIsochronous(dev_handle_.get(), kEndpoint, kReadTimeout);
+    transfer2_->FillIsochronous(dev_handle_.get(), kEndpoint, kReadTimeout);
+    transfer1_->Submit();
+    transfer2_->Submit();
+
     sequence_.Reset();
     phase_locker_.Reset();
   }
@@ -354,13 +391,16 @@
         .Send();
   }
 
-  ::std::unique_ptr< ::glibusb::UsbDevice> device_;
-  ::std::unique_ptr< ::glibusb::UsbInEndpoint> endpoint_;
-  ::glibusb::Buffer buffer_;
+  GyroBoardData data_;
 
   WrappingCounter sequence_;
 
-  ::glibusb::Libusb libusb_;
+  LibUSB libusb_;
+  ::std::unique_ptr<LibUSBDeviceHandle> dev_handle_;
+  ::std::unique_ptr<libusb::IsochronousTransfer> transfer1_, transfer2_;
+  // Temporary variable for holding a completed transfer to communicate that
+  // information from the callback to the code that wants it.
+  libusb::Transfer *completed_transfer_;
 
   WrappingCounter top_rise_;
   WrappingCounter top_fall_;
@@ -368,7 +408,6 @@
   WrappingCounter bottom_fall_delay_;
   WrappingCounter bottom_fall_;
 };
-constexpr ::glibusb::VendorProductId GyroSensorReceiver::kDeviceId;
 constexpr ::aos::time::Time GyroSensorReceiver::kReadTimeout;
 constexpr ::aos::time::Time GyroSensorReceiver::kDesiredOffset;
 
diff --git a/frc971/input/input.gyp b/frc971/input/input.gyp
index 8682eee..130e50f 100644
--- a/frc971/input/input.gyp
+++ b/frc971/input/input.gyp
@@ -37,10 +37,9 @@
         '<(AOS)/atom_code/atom_code.gyp:init',
         '<(AOS)/build/aos.gyp:logging',
         '<(AOS)/common/common.gyp:time',
-        '<(AOS)/common/glibusb/glibusb.gyp:glibusb',
-        '<(AOS)/common/glibusb/glibusb.gyp:gbuffer',
         '<(AOS)/common/util/util.gyp:wrapping_counter',
         '<(AOS)/common/common.gyp:controls',
+        '<(DEPTH)/gyro_board/src/libusb-driver/libusb-driver.gyp:libusb_wrap',
       ],
     },
     {
diff --git a/gyro_board/src/libusb-driver/libusb-driver.gyp b/gyro_board/src/libusb-driver/libusb-driver.gyp
index 1c50633..ab2bf70 100644
--- a/gyro_board/src/libusb-driver/libusb-driver.gyp
+++ b/gyro_board/src/libusb-driver/libusb-driver.gyp
@@ -11,6 +11,10 @@
         '<(AOS)/common/util/util.gyp:thread',
         'libusb_wrap',
         '<(AOS)/build/aos.gyp:logging',
+        '<(AOS)/common/common.gyp:time',
+      ],
+      'export_dependent_settings': [
+        '<(AOS)/common/common.gyp:time',
       ],
     },
     {
diff --git a/gyro_board/src/libusb-driver/libusb_wrap.cc b/gyro_board/src/libusb-driver/libusb_wrap.cc
index 83cf245..0026ef3 100644
--- a/gyro_board/src/libusb-driver/libusb_wrap.cc
+++ b/gyro_board/src/libusb-driver/libusb_wrap.cc
@@ -1,5 +1,7 @@
 #include "libusb_wrap.h"
 
+#include <string.h>
+
 #include <iostream>
 
 #include "aos/common/logging/logging.h"
@@ -115,8 +117,9 @@
 
 Transfer::Transfer(size_t data_length,
                    void (*callback)(Transfer *, void *),
-                   void *user_data)
-    : transfer_(libusb_alloc_transfer(0)),
+                   void *user_data,
+                   int num_iso_packets)
+    : transfer_(libusb_alloc_transfer(num_iso_packets)),
       data_(new uint8_t[data_length]),
       data_length_(data_length),
       callback_(callback),
@@ -146,16 +149,16 @@
     if (ret == LIBUSB_ERROR_BUSY) {
       LOG(FATAL, "transfer %p already submitted\n", this);
     }
-    LOG(FATAL, "libusb error %d submitting transfer %p\n",
-        ret, this);
+    LOG(FATAL, "libusb error %d submitting transfer %p. errno %d: %s\n",
+        ret, this, errno, strerror(errno));
   }
 }
 
 void Transfer::Cancel() {
   int ret = libusb_cancel_transfer(transfer_);
   if (ret != 0) {
-    LOG(FATAL, "libusb error %d cancelling transfer %p\n",
-        ret, this);
+    LOG(FATAL, "libusb error %d cancelling transfer %p. errno %d: %s\n",
+        ret, this, errno, strerror(errno));
   }
 }
 
@@ -167,17 +170,14 @@
                                          int num_packets,
                                          void (*callback)(Transfer *, void *),
                                          void *user_data)
-    : Transfer(packet_length * num_packets, callback, user_data),
+    : Transfer(packet_length * num_packets, callback, user_data, num_packets),
       num_packets_(num_packets) {
 }
 
 void IsochronousTransfer::FillIsochronous(LibUSBDeviceHandle *device,
                                unsigned char endpoint,
-                               unsigned int timeout) {
-  (void)device;
-  (void)endpoint;
-  (void)timeout;
-  /*libusb_fill_iso_transfer(transfer_,
+                               const ::aos::time::Time &timeout) {
+  libusb_fill_iso_transfer(transfer_,
                            device->dev_handle_,
                            endpoint,
                            data_,
@@ -185,7 +185,8 @@
                            num_packets_,
                            StaticTransferCallback,
                            this,
-                           timeout);*/
+                           timeout.ToMSec());
+  transfer_->iso_packet_desc[0].length = data_length_;
 }
 
 }  // namespace libusb
diff --git a/gyro_board/src/libusb-driver/libusb_wrap.h b/gyro_board/src/libusb-driver/libusb_wrap.h
index 261cded..6056c66 100644
--- a/gyro_board/src/libusb-driver/libusb_wrap.h
+++ b/gyro_board/src/libusb-driver/libusb_wrap.h
@@ -4,6 +4,7 @@
 #include <libusb-1.0/libusb.h>
 
 #include "aos/common/macros.h"
+#include "aos/common/time.h"
 
 class LibUSBDeviceHandle;
 namespace libusb {
@@ -61,7 +62,8 @@
  public:
   Transfer(size_t data_length,
            void (*callback)(Transfer *, void *),
-           void *user_data);
+           void *user_data,
+           int num_iso_packets = 0);
   ~Transfer();
 
   void FillInterrupt(LibUSBDeviceHandle *device,
@@ -72,7 +74,7 @@
   void Cancel();
 
   libusb_transfer_status status() { return transfer_->status; }
-  int read_bytes() { return transfer_->actual_length; }
+  virtual int read_bytes() { return transfer_->actual_length; }
 
   const uint8_t *data() { return data_; }
 
@@ -81,20 +83,22 @@
     static_cast<Transfer *>(self->user_data)->TransferCallback();
   }
 
- private:
-  void TransferCallback();
-
+ protected:
   libusb_transfer *const transfer_;
 
   uint8_t *const data_;
   size_t data_length_;
 
+ private:
+  void TransferCallback();
+
   void (*const callback_)(Transfer *, void *);
   void *const user_data_;
 
   DISALLOW_COPY_AND_ASSIGN(Transfer);
 };
 
+// TODO(brians): Make this actually work for num_packets != 1.
 class IsochronousTransfer : public Transfer {
  public:
   IsochronousTransfer(size_t packet_length,
@@ -104,7 +108,11 @@
 
   void FillIsochronous(LibUSBDeviceHandle *device,
                        unsigned char endpoint,
-                       unsigned int timeout);
+                       const ::aos::time::Time &timeout);
+
+  virtual int read_bytes() {
+    return transfer_->iso_packet_desc[0].actual_length;
+  }
 
  private:
   const int num_packets_;