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;