Home | History | Annotate | Download | only in usb
      1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "chrome/browser/usb/usb_device_handle.h"
      6 
      7 #include <algorithm>
      8 #include <vector>
      9 
     10 #include "base/message_loop/message_loop.h"
     11 #include "base/stl_util.h"
     12 #include "base/strings/string16.h"
     13 #include "base/synchronization/lock.h"
     14 #include "chrome/browser/usb/usb_context.h"
     15 #include "chrome/browser/usb/usb_device.h"
     16 #include "chrome/browser/usb/usb_interface.h"
     17 #include "chrome/browser/usb/usb_service.h"
     18 #include "content/public/browser/browser_thread.h"
     19 #include "third_party/libusb/src/libusb/libusb.h"
     20 
     21 using content::BrowserThread;
     22 void HandleTransferCompletion(PlatformUsbTransferHandle transfer);
     23 
     24 namespace {
     25 
     26 static uint8 ConvertTransferDirection(
     27     const UsbEndpointDirection direction) {
     28   switch (direction) {
     29     case USB_DIRECTION_INBOUND:
     30       return LIBUSB_ENDPOINT_IN;
     31     case USB_DIRECTION_OUTBOUND:
     32       return LIBUSB_ENDPOINT_OUT;
     33     default:
     34       NOTREACHED();
     35       return LIBUSB_ENDPOINT_IN;
     36   }
     37 }
     38 
     39 static uint8 CreateRequestType(const UsbEndpointDirection direction,
     40     const UsbDeviceHandle::TransferRequestType request_type,
     41     const UsbDeviceHandle::TransferRecipient recipient) {
     42   uint8 result = ConvertTransferDirection(direction);
     43 
     44   switch (request_type) {
     45     case UsbDeviceHandle::STANDARD:
     46       result |= LIBUSB_REQUEST_TYPE_STANDARD;
     47       break;
     48     case UsbDeviceHandle::CLASS:
     49       result |= LIBUSB_REQUEST_TYPE_CLASS;
     50       break;
     51     case UsbDeviceHandle::VENDOR:
     52       result |= LIBUSB_REQUEST_TYPE_VENDOR;
     53       break;
     54     case UsbDeviceHandle::RESERVED:
     55       result |= LIBUSB_REQUEST_TYPE_RESERVED;
     56       break;
     57   }
     58 
     59   switch (recipient) {
     60     case UsbDeviceHandle::DEVICE:
     61       result |= LIBUSB_RECIPIENT_DEVICE;
     62       break;
     63     case UsbDeviceHandle::INTERFACE:
     64       result |= LIBUSB_RECIPIENT_INTERFACE;
     65       break;
     66     case UsbDeviceHandle::ENDPOINT:
     67       result |= LIBUSB_RECIPIENT_ENDPOINT;
     68       break;
     69     case UsbDeviceHandle::OTHER:
     70       result |= LIBUSB_RECIPIENT_OTHER;
     71       break;
     72   }
     73 
     74   return result;
     75 }
     76 
     77 static UsbTransferStatus ConvertTransferStatus(
     78     const libusb_transfer_status status) {
     79   switch (status) {
     80     case LIBUSB_TRANSFER_COMPLETED:
     81       return USB_TRANSFER_COMPLETED;
     82     case LIBUSB_TRANSFER_ERROR:
     83       return USB_TRANSFER_ERROR;
     84     case LIBUSB_TRANSFER_TIMED_OUT:
     85       return USB_TRANSFER_TIMEOUT;
     86     case LIBUSB_TRANSFER_STALL:
     87       return USB_TRANSFER_STALLED;
     88     case LIBUSB_TRANSFER_NO_DEVICE:
     89       return USB_TRANSFER_DISCONNECT;
     90     case LIBUSB_TRANSFER_OVERFLOW:
     91       return USB_TRANSFER_OVERFLOW;
     92     case LIBUSB_TRANSFER_CANCELLED:
     93       return USB_TRANSFER_CANCELLED;
     94     default:
     95       NOTREACHED();
     96       return USB_TRANSFER_ERROR;
     97   }
     98 }
     99 
    100 static void LIBUSB_CALL PlatformTransferCompletionCallback(
    101     PlatformUsbTransferHandle transfer) {
    102   BrowserThread::PostTask(BrowserThread::FILE,
    103                           FROM_HERE,
    104                           base::Bind(HandleTransferCompletion, transfer));
    105 }
    106 
    107 }  // namespace
    108 
    109 void HandleTransferCompletion(PlatformUsbTransferHandle transfer) {
    110   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
    111   UsbDeviceHandle* const device_handle =
    112       reinterpret_cast<UsbDeviceHandle*>(transfer->user_data);
    113   CHECK(device_handle) << "Device handle is closed before transfer finishes.";
    114   device_handle->TransferComplete(transfer);
    115   libusb_free_transfer(transfer);
    116 }
    117 
    118 
    119 class UsbDeviceHandle::InterfaceClaimer
    120     : public base::RefCountedThreadSafe<UsbDeviceHandle::InterfaceClaimer> {
    121  public:
    122   InterfaceClaimer(const scoped_refptr<UsbDeviceHandle> handle,
    123                    const int interface_number);
    124 
    125   bool Claim() const;
    126 
    127   int alternate_setting() const { return alternate_setting_; }
    128   void set_alternate_setting(const int alternate_setting) {
    129     alternate_setting_ = alternate_setting;
    130   }
    131 
    132  private:
    133   friend class UsbDevice;
    134   friend class base::RefCountedThreadSafe<InterfaceClaimer>;
    135   ~InterfaceClaimer();
    136 
    137   const scoped_refptr<UsbDeviceHandle> handle_;
    138   const int interface_number_;
    139   int alternate_setting_;
    140 
    141   DISALLOW_COPY_AND_ASSIGN(InterfaceClaimer);
    142 };
    143 
    144 UsbDeviceHandle::InterfaceClaimer::InterfaceClaimer(
    145     const scoped_refptr<UsbDeviceHandle> handle, const int interface_number)
    146     : handle_(handle),
    147       interface_number_(interface_number),
    148       alternate_setting_(0) {
    149 }
    150 
    151 UsbDeviceHandle::InterfaceClaimer::~InterfaceClaimer() {
    152   libusb_release_interface(handle_->handle(), interface_number_);
    153 }
    154 
    155 bool UsbDeviceHandle::InterfaceClaimer::Claim() const {
    156   return libusb_claim_interface(handle_->handle(), interface_number_) == 0;
    157 }
    158 
    159 struct UsbDeviceHandle::Transfer {
    160   Transfer();
    161   ~Transfer();
    162 
    163   UsbTransferType transfer_type;
    164   scoped_refptr<net::IOBuffer> buffer;
    165   scoped_refptr<UsbDeviceHandle::InterfaceClaimer> claimed_interface;
    166   scoped_refptr<base::MessageLoopProxy> message_loop_proxy;
    167   size_t length;
    168   UsbTransferCallback callback;
    169 };
    170 
    171 UsbDeviceHandle::Transfer::Transfer()
    172     : transfer_type(USB_TRANSFER_CONTROL),
    173       length(0) {
    174 }
    175 
    176 UsbDeviceHandle::Transfer::~Transfer() {}
    177 
    178 UsbDeviceHandle::UsbDeviceHandle(
    179     scoped_refptr<UsbContext> context,
    180     UsbDevice* device,
    181     PlatformUsbDeviceHandle handle)
    182     : device_(device), handle_(handle), context_(context) {
    183   DCHECK(thread_checker_.CalledOnValidThread());
    184   DCHECK(handle) << "Cannot create device with NULL handle.";
    185   interfaces_ = new UsbConfigDescriptor();
    186   device->ListInterfaces(interfaces_.get());
    187 }
    188 
    189 UsbDeviceHandle::UsbDeviceHandle() : device_(NULL), handle_(NULL) {
    190 }
    191 
    192 UsbDeviceHandle::~UsbDeviceHandle() {
    193   DCHECK(thread_checker_.CalledOnValidThread());
    194 
    195   libusb_close(handle_);
    196   handle_ = NULL;
    197 }
    198 
    199 scoped_refptr<UsbDevice> UsbDeviceHandle::device() const {
    200   return device_;
    201 }
    202 
    203 void UsbDeviceHandle::Close() {
    204   DCHECK(thread_checker_.CalledOnValidThread());
    205   if (device_)
    206     device_->Close(this);
    207 }
    208 
    209 void UsbDeviceHandle::TransferComplete(PlatformUsbTransferHandle handle) {
    210   DCHECK(ContainsKey(transfers_, handle)) << "Missing transfer completed";
    211 
    212   Transfer transfer = transfers_[handle];
    213   transfers_.erase(handle);
    214 
    215   DCHECK_GE(handle->actual_length, 0) << "Negative actual length received";
    216   size_t actual_length =
    217       static_cast<size_t>(std::max(handle->actual_length, 0));
    218 
    219   DCHECK(transfer.length >= actual_length) <<
    220       "data too big for our buffer (libusb failure?)";
    221 
    222   scoped_refptr<net::IOBuffer> buffer = transfer.buffer;
    223   switch (transfer.transfer_type) {
    224     case USB_TRANSFER_CONTROL:
    225       // If the transfer is a control transfer we do not expose the control
    226       // setup header to the caller. This logic strips off the header if
    227       // present before invoking the callback provided with the transfer.
    228       if (actual_length > 0) {
    229         CHECK(transfer.length >= LIBUSB_CONTROL_SETUP_SIZE) <<
    230             "buffer was not correctly set: too small for the control header";
    231 
    232         if (transfer.length >= actual_length &&
    233             actual_length >= LIBUSB_CONTROL_SETUP_SIZE) {
    234           // If the payload is zero bytes long, pad out the allocated buffer
    235           // size to one byte so that an IOBuffer of that size can be allocated.
    236           scoped_refptr<net::IOBuffer> resized_buffer = new net::IOBuffer(
    237               std::max(actual_length, static_cast<size_t>(1)));
    238           memcpy(resized_buffer->data(),
    239                  buffer->data() + LIBUSB_CONTROL_SETUP_SIZE,
    240                  actual_length);
    241           buffer = resized_buffer;
    242         }
    243       }
    244       break;
    245 
    246     case USB_TRANSFER_ISOCHRONOUS:
    247       // Isochronous replies might carry data in the different isoc packets even
    248       // if the transfer actual_data value is zero. Furthermore, not all of the
    249       // received packets might contain data, so we need to calculate how many
    250       // data bytes we are effectively providing and pack the results.
    251       if (actual_length == 0) {
    252         size_t packet_buffer_start = 0;
    253         for (int i = 0; i < handle->num_iso_packets; ++i) {
    254           PlatformUsbIsoPacketDescriptor packet = &handle->iso_packet_desc[i];
    255           if (packet->actual_length > 0) {
    256             // We don't need to copy as long as all packets until now provide
    257             // all the data the packet can hold.
    258             if (actual_length < packet_buffer_start) {
    259               CHECK(packet_buffer_start + packet->actual_length <=
    260                     transfer.length);
    261               memmove(buffer->data() + actual_length,
    262                       buffer->data() + packet_buffer_start,
    263                       packet->actual_length);
    264             }
    265             actual_length += packet->actual_length;
    266           }
    267 
    268           packet_buffer_start += packet->length;
    269         }
    270       }
    271       break;
    272 
    273     case USB_TRANSFER_BULK:
    274     case USB_TRANSFER_INTERRUPT:
    275       break;
    276 
    277     default:
    278       NOTREACHED() << "Invalid usb transfer type";
    279       break;
    280   }
    281 
    282   transfer.message_loop_proxy->PostTask(
    283       FROM_HERE,
    284       base::Bind(transfer.callback,
    285                  ConvertTransferStatus(handle->status),
    286                  buffer,
    287                  actual_length));
    288 
    289   // Must release interface first before actually delete this.
    290   transfer.claimed_interface = NULL;
    291 }
    292 
    293 bool UsbDeviceHandle::ClaimInterface(const int interface_number) {
    294   DCHECK(thread_checker_.CalledOnValidThread());
    295   if (!device_) return false;
    296   if (ContainsKey(claimed_interfaces_, interface_number)) return true;
    297 
    298   scoped_refptr<InterfaceClaimer> claimer =
    299       new InterfaceClaimer(this, interface_number);
    300 
    301   if (claimer->Claim()) {
    302     claimed_interfaces_[interface_number]= claimer;
    303     RefreshEndpointMap();
    304     return true;
    305   }
    306   return false;
    307 }
    308 
    309 bool UsbDeviceHandle::ReleaseInterface(const int interface_number) {
    310   DCHECK(thread_checker_.CalledOnValidThread());
    311   if (!device_) return false;
    312   if (!ContainsKey(claimed_interfaces_, interface_number)) return false;
    313 
    314   // Cancel all the transfers on that interface.
    315   InterfaceClaimer* interface_claimer =
    316       claimed_interfaces_[interface_number].get();
    317   for (TransferMap::iterator it = transfers_.begin();
    318       it != transfers_.end(); ++it) {
    319     if (it->second.claimed_interface.get() == interface_claimer)
    320       libusb_cancel_transfer(it->first);
    321   }
    322   claimed_interfaces_.erase(interface_number);
    323 
    324   RefreshEndpointMap();
    325   return true;
    326 }
    327 
    328 bool UsbDeviceHandle::SetInterfaceAlternateSetting(
    329     const int interface_number,
    330     const int alternate_setting) {
    331   DCHECK(thread_checker_.CalledOnValidThread());
    332   if (!device_) return false;
    333   if (!ContainsKey(claimed_interfaces_, interface_number)) return false;
    334   const int rv = libusb_set_interface_alt_setting(handle_,
    335       interface_number, alternate_setting);
    336   if (rv == 0) {
    337     claimed_interfaces_[interface_number]->
    338       set_alternate_setting(alternate_setting);
    339     RefreshEndpointMap();
    340     return true;
    341   }
    342   return false;
    343 }
    344 
    345 bool UsbDeviceHandle::ResetDevice() {
    346   DCHECK(thread_checker_.CalledOnValidThread());
    347   if (!device_) return false;
    348 
    349   return libusb_reset_device(handle_) == 0;
    350 }
    351 
    352 bool UsbDeviceHandle::GetSerial(base::string16* serial) {
    353   DCHECK(thread_checker_.CalledOnValidThread());
    354   PlatformUsbDevice device = libusb_get_device(handle_);
    355   libusb_device_descriptor desc;
    356 
    357   if (libusb_get_device_descriptor(device, &desc) != LIBUSB_SUCCESS)
    358     return false;
    359 
    360   if (desc.iSerialNumber == 0)
    361     return false;
    362 
    363   // Getting supported language ID.
    364   uint16 langid[128] = { 0 };
    365 
    366   int size = libusb_get_string_descriptor(
    367       handle_, 0, 0,
    368       reinterpret_cast<unsigned char*>(&langid[0]), sizeof(langid));
    369   if (size < 0)
    370     return false;
    371 
    372   int language_count = (size - 2) / 2;
    373 
    374   for (int i = 1; i <= language_count; ++i) {
    375     // Get the string using language ID.
    376     char16 text[256] = { 0 };
    377     size = libusb_get_string_descriptor(
    378         handle_, desc.iSerialNumber, langid[i],
    379         reinterpret_cast<unsigned char*>(&text[0]), sizeof(text));
    380     if (size <= 2)
    381       continue;
    382     if ((text[0] >> 8) != LIBUSB_DT_STRING)
    383       continue;
    384     if ((text[0] & 255) > size)
    385       continue;
    386 
    387     size = size / 2 - 1;
    388     *serial = base::string16(text + 1, size);
    389     return true;
    390   }
    391   return false;
    392 }
    393 
    394 void UsbDeviceHandle::ControlTransfer(const UsbEndpointDirection direction,
    395     const TransferRequestType request_type, const TransferRecipient recipient,
    396     const uint8 request, const uint16 value, const uint16 index,
    397     net::IOBuffer* buffer, const size_t length, const unsigned int timeout,
    398     const UsbTransferCallback& callback) {
    399   if (!device_) {
    400     callback.Run(USB_TRANSFER_DISCONNECT, buffer, 0);
    401     return;
    402   }
    403 
    404   const size_t resized_length = LIBUSB_CONTROL_SETUP_SIZE + length;
    405   scoped_refptr<net::IOBuffer> resized_buffer(new net::IOBufferWithSize(
    406       resized_length));
    407   memcpy(resized_buffer->data() + LIBUSB_CONTROL_SETUP_SIZE, buffer->data(),
    408          length);
    409 
    410   PlatformUsbTransferHandle const transfer = libusb_alloc_transfer(0);
    411   const uint8 converted_type = CreateRequestType(direction, request_type,
    412                                                  recipient);
    413   libusb_fill_control_setup(reinterpret_cast<uint8*>(resized_buffer->data()),
    414                             converted_type, request, value, index, length);
    415   libusb_fill_control_transfer(
    416       transfer,
    417       handle_,
    418       reinterpret_cast<uint8*>(resized_buffer->data()),
    419       PlatformTransferCompletionCallback,
    420       this,
    421       timeout);
    422 
    423   BrowserThread::PostTask(
    424       BrowserThread::FILE,
    425       FROM_HERE,
    426       base::Bind(&UsbDeviceHandle::SubmitTransfer,
    427                  this,
    428                  transfer,
    429                  USB_TRANSFER_CONTROL,
    430                  resized_buffer,
    431                  resized_length,
    432                  base::MessageLoopProxy::current(),
    433                  callback));
    434 }
    435 
    436 void UsbDeviceHandle::BulkTransfer(const UsbEndpointDirection direction,
    437     const uint8 endpoint, net::IOBuffer* buffer, const size_t length,
    438     const unsigned int timeout, const UsbTransferCallback& callback) {
    439   if (!device_) {
    440     callback.Run(USB_TRANSFER_DISCONNECT, buffer, 0);
    441     return;
    442   }
    443 
    444   PlatformUsbTransferHandle const transfer = libusb_alloc_transfer(0);
    445   const uint8 new_endpoint = ConvertTransferDirection(direction) | endpoint;
    446   libusb_fill_bulk_transfer(transfer, handle_, new_endpoint,
    447       reinterpret_cast<uint8*>(buffer->data()), length,
    448       PlatformTransferCompletionCallback, this, timeout);
    449 
    450   BrowserThread::PostTask(
    451       BrowserThread::FILE,
    452       FROM_HERE,
    453       base::Bind(&UsbDeviceHandle::SubmitTransfer,
    454                  this,
    455                  transfer,
    456                  USB_TRANSFER_BULK,
    457                  make_scoped_refptr(buffer),
    458                  length,
    459                  base::MessageLoopProxy::current(),
    460                  callback));
    461 }
    462 
    463 void UsbDeviceHandle::InterruptTransfer(const UsbEndpointDirection direction,
    464     const uint8 endpoint, net::IOBuffer* buffer, const size_t length,
    465     const unsigned int timeout, const UsbTransferCallback& callback) {
    466   if (!device_) {
    467     callback.Run(USB_TRANSFER_DISCONNECT, buffer, 0);
    468     return;
    469   }
    470 
    471   PlatformUsbTransferHandle const transfer = libusb_alloc_transfer(0);
    472   const uint8 new_endpoint = ConvertTransferDirection(direction) | endpoint;
    473   libusb_fill_interrupt_transfer(transfer, handle_, new_endpoint,
    474       reinterpret_cast<uint8*>(buffer->data()), length,
    475       PlatformTransferCompletionCallback, this, timeout);
    476   BrowserThread::PostTask(
    477       BrowserThread::FILE,
    478       FROM_HERE,
    479       base::Bind(&UsbDeviceHandle::SubmitTransfer,
    480                  this,
    481                  transfer,
    482                  USB_TRANSFER_INTERRUPT,
    483                  make_scoped_refptr(buffer),
    484                  length,
    485                  base::MessageLoopProxy::current(),
    486                  callback));
    487 }
    488 
    489 void UsbDeviceHandle::IsochronousTransfer(const UsbEndpointDirection direction,
    490     const uint8 endpoint, net::IOBuffer* buffer, const size_t length,
    491     const unsigned int packets, const unsigned int packet_length,
    492     const unsigned int timeout, const UsbTransferCallback& callback) {
    493   if (!device_) {
    494     callback.Run(USB_TRANSFER_DISCONNECT, buffer, 0);
    495     return;
    496   }
    497 
    498   const uint64 total_length = packets * packet_length;
    499   CHECK(packets <= length && total_length <= length) <<
    500       "transfer length is too small";
    501 
    502   PlatformUsbTransferHandle const transfer = libusb_alloc_transfer(packets);
    503   const uint8 new_endpoint = ConvertTransferDirection(direction) | endpoint;
    504   libusb_fill_iso_transfer(transfer, handle_, new_endpoint,
    505       reinterpret_cast<uint8*>(buffer->data()), length, packets,
    506       PlatformTransferCompletionCallback, this, timeout);
    507   libusb_set_iso_packet_lengths(transfer, packet_length);
    508 
    509   BrowserThread::PostTask(
    510       BrowserThread::FILE,
    511       FROM_HERE,
    512       base::Bind(&UsbDeviceHandle::SubmitTransfer,
    513                  this,
    514                  transfer,
    515                  USB_TRANSFER_ISOCHRONOUS,
    516                  make_scoped_refptr(buffer),
    517                  length,
    518                  base::MessageLoopProxy::current(),
    519                  callback));
    520 }
    521 
    522 void UsbDeviceHandle::RefreshEndpointMap() {
    523   DCHECK(thread_checker_.CalledOnValidThread());
    524   endpoint_map_.clear();
    525   for (ClaimedInterfaceMap::iterator it = claimed_interfaces_.begin();
    526       it != claimed_interfaces_.end(); ++it) {
    527     scoped_refptr<const UsbInterfaceDescriptor> interface_desc =
    528         interfaces_->GetInterface(it->first)->GetAltSetting(
    529             it->second->alternate_setting());
    530     for (size_t i = 0; i < interface_desc->GetNumEndpoints(); i++) {
    531       scoped_refptr<const UsbEndpointDescriptor> endpoint =
    532           interface_desc->GetEndpoint(i);
    533       endpoint_map_[endpoint->GetAddress()] = it->first;
    534     }
    535   }
    536 }
    537 
    538 scoped_refptr<UsbDeviceHandle::InterfaceClaimer>
    539     UsbDeviceHandle::GetClaimedInterfaceForEndpoint(unsigned char endpoint) {
    540   unsigned char address = endpoint & LIBUSB_ENDPOINT_ADDRESS_MASK;
    541   if (ContainsKey(endpoint_map_, address))
    542     return claimed_interfaces_[endpoint_map_[address]];
    543   return NULL;
    544 }
    545 
    546 void UsbDeviceHandle::SubmitTransfer(
    547     PlatformUsbTransferHandle handle,
    548     UsbTransferType transfer_type,
    549     net::IOBuffer* buffer,
    550     const size_t length,
    551     scoped_refptr<base::MessageLoopProxy> message_loop_proxy,
    552     const UsbTransferCallback& callback) {
    553   DCHECK(thread_checker_.CalledOnValidThread());
    554   if (!device_) {
    555     message_loop_proxy->PostTask(
    556         FROM_HERE,
    557         base::Bind(callback, USB_TRANSFER_DISCONNECT,
    558                    make_scoped_refptr(buffer), 0));
    559   }
    560 
    561   Transfer transfer;
    562   transfer.transfer_type = transfer_type;
    563   transfer.buffer = buffer;
    564   transfer.length = length;
    565   transfer.callback = callback;
    566   transfer.message_loop_proxy = message_loop_proxy;
    567 
    568   // It's OK for this method to return NULL. libusb_submit_transfer will fail if
    569   // it requires an interface we didn't claim.
    570   transfer.claimed_interface = GetClaimedInterfaceForEndpoint(handle->endpoint);
    571 
    572   if (libusb_submit_transfer(handle) == LIBUSB_SUCCESS) {
    573     transfers_[handle] = transfer;
    574   } else {
    575     message_loop_proxy->PostTask(
    576         FROM_HERE,
    577         base::Bind(callback, USB_TRANSFER_ERROR,
    578                    make_scoped_refptr(buffer), 0));
    579   }
    580 }
    581 
    582 void UsbDeviceHandle::InternalClose() {
    583   DCHECK(thread_checker_.CalledOnValidThread());
    584   if (!device_) return;
    585 
    586   // Cancel all the transfers.
    587   for (TransferMap::iterator it = transfers_.begin();
    588       it != transfers_.end(); ++it) {
    589     // The callback will be called some time later.
    590     libusb_cancel_transfer(it->first);
    591   }
    592 
    593   // Attempt-release all the interfaces.
    594   // It will be retained until the transfer cancellation is finished.
    595   claimed_interfaces_.clear();
    596 
    597   // Cannot close device handle here. Need to wait for libusb_cancel_transfer to
    598   // finish.
    599   device_ = NULL;
    600 }
    601