copied glibusb in and started making it compile
diff --git a/aos/common/glibusb/glibusb_transfer.cc b/aos/common/glibusb/glibusb_transfer.cc
new file mode 100644
index 0000000..a700cf2
--- /dev/null
+++ b/aos/common/glibusb/glibusb_transfer.cc
@@ -0,0 +1,136 @@
+// Copyright 2012 Google Inc. All Rights Reserved.
+//
+// Alternative libusb call to do transfers that quits when
+// a notification is notified.
+//
+// This code was originally from third_party/libusb/libusb1/sync.c
+// and has been slightly modified to poll the notification.
+
+#include "glibusb_transfer.h"
+
+#include <stddef.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <sys/time.h>
+#include <gflags/gflags.h>
+#include <glog/logging.h>
+#include <libusb.h>
+
+#include "glibusb_endpoint.h"
+
+
+DEFINE_int32(notification_poll,
+             60,
+             "Time in seconds to wait between checking the quit notification "
+             "when waiting for USB messages.");
+
+namespace {
+
+static bool GEQZero(const char* flagname, int32_t value) {
+  if (value < 0) {
+    printf("Invalid value for --%s: %d\n", flagname, value);
+    return false;
+  }
+  return true;
+}
+
+static const bool notification_poll_dummy = google::RegisterFlagValidator(
+  &FLAGS_notification_poll, &GEQZero);
+
+}  // namespace
+
+
+namespace glibusb {
+
+namespace {
+// Static code from libusb1/sync.c
+void bulk_transfer_cb(struct libusb_transfer *transfer) {
+  int *completed = static_cast<int*>(transfer->user_data);
+  *completed = 1;
+  VLOG(3) << "actual_length=" << transfer->actual_length;
+  /* caller interprets results and frees transfer */
+}
+}  // namespace
+
+int do_sync_bulk_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);
+  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;
+
+  r = libusb_submit_transfer(transfer);
+  if (r < 0) {
+    libusb_free_transfer(transfer);
+    return r;
+  }
+
+  while (!completed) {
+    struct timeval tv;
+    tv.tv_sec = 1;
+    tv.tv_usec = 0;
+    r = libusb_handle_events_timeout_completed(context, &tv, &completed);
+    if (quit != NULL && quit->HasBeenNotified()) {
+      LOG(WARNING) << "Caught quit notification.  Canceling transfer.";
+      r = LIBUSB_ERROR_TIMEOUT;
+    }
+    if (r < 0) {
+      if (r == LIBUSB_ERROR_INTERRUPTED) {
+        continue;
+      }
+      libusb_cancel_transfer(transfer);
+      while (!completed) {
+        struct timeval cancel_tv;
+        cancel_tv.tv_sec = (quit == NULL ? FLAGS_notification_poll : 60);
+        cancel_tv.tv_usec = 0;
+        if (libusb_handle_events_timeout_completed(context, &cancel_tv,
+                                                   &completed) < 0) {
+          break;
+        }
+      }
+      libusb_free_transfer(transfer);
+      return r;
+    }
+  }
+
+  *transferred = transfer->actual_length;
+  switch (transfer->status) {
+    case LIBUSB_TRANSFER_COMPLETED:
+      r = 0;
+      break;
+    case LIBUSB_TRANSFER_TIMED_OUT:
+      r = LIBUSB_ERROR_TIMEOUT;
+      break;
+    case LIBUSB_TRANSFER_STALL:
+      r = LIBUSB_ERROR_PIPE;
+      break;
+    case LIBUSB_TRANSFER_OVERFLOW:
+      r = LIBUSB_ERROR_OVERFLOW;
+      break;
+    case LIBUSB_TRANSFER_NO_DEVICE:
+      r = LIBUSB_ERROR_NO_DEVICE;
+      break;
+    case LIBUSB_TRANSFER_ERROR:
+    case LIBUSB_TRANSFER_CANCELLED:
+      r = LIBUSB_ERROR_IO;
+      break;
+    default:
+      LOG(WARNING) << "unrecognised status code " << transfer->status;
+      r = LIBUSB_ERROR_OTHER;
+  }
+
+  libusb_free_transfer(transfer);
+  return r;
+}
+
+}  // namespace glibusb