Home | History | Annotate | Download | only in client
      1 /*
      2  * Copyright (C) 2016 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #include "usb.h"
     18 
     19 #include "sysdeps.h"
     20 
     21 #include <stdint.h>
     22 
     23 #include <atomic>
     24 #include <chrono>
     25 #include <memory>
     26 #include <mutex>
     27 #include <string>
     28 #include <thread>
     29 #include <unordered_map>
     30 
     31 #include <libusb/libusb.h>
     32 
     33 #include <android-base/file.h>
     34 #include <android-base/logging.h>
     35 #include <android-base/quick_exit.h>
     36 #include <android-base/stringprintf.h>
     37 #include <android-base/strings.h>
     38 
     39 #include "adb.h"
     40 #include "adb_utils.h"
     41 #include "transport.h"
     42 #include "usb.h"
     43 
     44 using namespace std::literals;
     45 
     46 using android::base::StringPrintf;
     47 
     48 // RAII wrappers for libusb.
     49 struct ConfigDescriptorDeleter {
     50     void operator()(libusb_config_descriptor* desc) {
     51         libusb_free_config_descriptor(desc);
     52     }
     53 };
     54 
     55 using unique_config_descriptor = std::unique_ptr<libusb_config_descriptor, ConfigDescriptorDeleter>;
     56 
     57 struct DeviceHandleDeleter {
     58     void operator()(libusb_device_handle* h) {
     59         libusb_close(h);
     60     }
     61 };
     62 
     63 using unique_device_handle = std::unique_ptr<libusb_device_handle, DeviceHandleDeleter>;
     64 
     65 struct transfer_info {
     66     transfer_info(const char* name, uint16_t zero_mask, bool is_bulk_out)
     67         : name(name),
     68           transfer(libusb_alloc_transfer(0)),
     69           is_bulk_out(is_bulk_out),
     70           zero_mask(zero_mask) {}
     71 
     72     ~transfer_info() {
     73         libusb_free_transfer(transfer);
     74     }
     75 
     76     const char* name;
     77     libusb_transfer* transfer;
     78     bool is_bulk_out;
     79     bool transfer_complete;
     80     std::condition_variable cv;
     81     std::mutex mutex;
     82     uint16_t zero_mask;
     83 
     84     void Notify() {
     85         LOG(DEBUG) << "notifying " << name << " transfer complete";
     86         transfer_complete = true;
     87         cv.notify_one();
     88     }
     89 };
     90 
     91 namespace libusb {
     92 struct usb_handle : public ::usb_handle {
     93     usb_handle(const std::string& device_address, const std::string& serial,
     94                unique_device_handle&& device_handle, uint8_t interface, uint8_t bulk_in,
     95                uint8_t bulk_out, size_t zero_mask, size_t max_packet_size)
     96         : device_address(device_address),
     97           serial(serial),
     98           closing(false),
     99           device_handle(device_handle.release()),
    100           read("read", zero_mask, false),
    101           write("write", zero_mask, true),
    102           interface(interface),
    103           bulk_in(bulk_in),
    104           bulk_out(bulk_out),
    105           max_packet_size(max_packet_size) {}
    106 
    107     ~usb_handle() {
    108         Close();
    109     }
    110 
    111     void Close() {
    112         std::unique_lock<std::mutex> lock(device_handle_mutex);
    113         // Cancelling transfers will trigger more Closes, so make sure this only happens once.
    114         if (closing) {
    115             return;
    116         }
    117         closing = true;
    118 
    119         // Make sure that no new transfers come in.
    120         libusb_device_handle* handle = device_handle;
    121         if (!handle) {
    122             return;
    123         }
    124 
    125         device_handle = nullptr;
    126 
    127         // Cancel already dispatched transfers.
    128         libusb_cancel_transfer(read.transfer);
    129         libusb_cancel_transfer(write.transfer);
    130 
    131         libusb_release_interface(handle, interface);
    132         libusb_close(handle);
    133     }
    134 
    135     std::string device_address;
    136     std::string serial;
    137 
    138     std::atomic<bool> closing;
    139     std::mutex device_handle_mutex;
    140     libusb_device_handle* device_handle;
    141 
    142     transfer_info read;
    143     transfer_info write;
    144 
    145     uint8_t interface;
    146     uint8_t bulk_in;
    147     uint8_t bulk_out;
    148 
    149     size_t max_packet_size;
    150 };
    151 
    152 static auto& usb_handles = *new std::unordered_map<std::string, std::unique_ptr<usb_handle>>();
    153 static auto& usb_handles_mutex = *new std::mutex();
    154 
    155 static libusb_hotplug_callback_handle hotplug_handle;
    156 
    157 static std::string get_device_address(libusb_device* device) {
    158     return StringPrintf("usb:%d:%d", libusb_get_bus_number(device),
    159                         libusb_get_device_address(device));
    160 }
    161 
    162 #if defined(__linux__)
    163 static std::string get_device_serial_path(libusb_device* device) {
    164     uint8_t ports[7];
    165     int port_count = libusb_get_port_numbers(device, ports, 7);
    166     if (port_count < 0) return "";
    167 
    168     std::string path =
    169         StringPrintf("/sys/bus/usb/devices/%d-%d", libusb_get_bus_number(device), ports[0]);
    170     for (int port = 1; port < port_count; ++port) {
    171         path += StringPrintf(".%d", ports[port]);
    172     }
    173     path += "/serial";
    174     return path;
    175 }
    176 
    177 static std::string get_device_dev_path(libusb_device* device) {
    178     uint8_t ports[7];
    179     int port_count = libusb_get_port_numbers(device, ports, 7);
    180     if (port_count < 0) return "";
    181     return StringPrintf("/dev/bus/usb/%03u/%03u", libusb_get_bus_number(device), ports[0]);
    182 }
    183 #endif
    184 
    185 static bool endpoint_is_output(uint8_t endpoint) {
    186     return (endpoint & LIBUSB_ENDPOINT_DIR_MASK) == LIBUSB_ENDPOINT_OUT;
    187 }
    188 
    189 static bool should_perform_zero_transfer(uint8_t endpoint, size_t write_length, uint16_t zero_mask) {
    190     return endpoint_is_output(endpoint) && write_length != 0 && zero_mask != 0 &&
    191            (write_length & zero_mask) == 0;
    192 }
    193 
    194 static void process_device(libusb_device* device) {
    195     std::string device_address = get_device_address(device);
    196     std::string device_serial;
    197 
    198     // Figure out if we want to open the device.
    199     libusb_device_descriptor device_desc;
    200     int rc = libusb_get_device_descriptor(device, &device_desc);
    201     if (rc != 0) {
    202         LOG(WARNING) << "failed to get device descriptor for device at " << device_address << ": "
    203                      << libusb_error_name(rc);
    204         return;
    205     }
    206 
    207     if (device_desc.bDeviceClass != LIBUSB_CLASS_PER_INTERFACE) {
    208         // Assume that all Android devices have the device class set to per interface.
    209         // TODO: Is this assumption valid?
    210         LOG(VERBOSE) << "skipping device with incorrect class at " << device_address;
    211         return;
    212     }
    213 
    214     libusb_config_descriptor* config_raw;
    215     rc = libusb_get_active_config_descriptor(device, &config_raw);
    216     if (rc != 0) {
    217         LOG(WARNING) << "failed to get active config descriptor for device at " << device_address
    218                      << ": " << libusb_error_name(rc);
    219         return;
    220     }
    221     const unique_config_descriptor config(config_raw);
    222 
    223     // Use size_t for interface_num so <iostream>s don't mangle it.
    224     size_t interface_num;
    225     uint16_t zero_mask;
    226     uint8_t bulk_in = 0, bulk_out = 0;
    227     size_t packet_size = 0;
    228     bool found_adb = false;
    229 
    230     for (interface_num = 0; interface_num < config->bNumInterfaces; ++interface_num) {
    231         const libusb_interface& interface = config->interface[interface_num];
    232         if (interface.num_altsetting != 1) {
    233             // Assume that interfaces with alternate settings aren't adb interfaces.
    234             // TODO: Is this assumption valid?
    235             LOG(VERBOSE) << "skipping interface with incorrect num_altsetting at " << device_address
    236                          << " (interface " << interface_num << ")";
    237             continue;
    238         }
    239 
    240         const libusb_interface_descriptor& interface_desc = interface.altsetting[0];
    241         if (!is_adb_interface(interface_desc.bInterfaceClass, interface_desc.bInterfaceSubClass,
    242                               interface_desc.bInterfaceProtocol)) {
    243             LOG(VERBOSE) << "skipping non-adb interface at " << device_address << " (interface "
    244                          << interface_num << ")";
    245             continue;
    246         }
    247 
    248         LOG(VERBOSE) << "found potential adb interface at " << device_address << " (interface "
    249                      << interface_num << ")";
    250 
    251         bool found_in = false;
    252         bool found_out = false;
    253         for (size_t endpoint_num = 0; endpoint_num < interface_desc.bNumEndpoints; ++endpoint_num) {
    254             const auto& endpoint_desc = interface_desc.endpoint[endpoint_num];
    255             const uint8_t endpoint_addr = endpoint_desc.bEndpointAddress;
    256             const uint8_t endpoint_attr = endpoint_desc.bmAttributes;
    257 
    258             const uint8_t transfer_type = endpoint_attr & LIBUSB_TRANSFER_TYPE_MASK;
    259 
    260             if (transfer_type != LIBUSB_TRANSFER_TYPE_BULK) {
    261                 continue;
    262             }
    263 
    264             if (endpoint_is_output(endpoint_addr) && !found_out) {
    265                 found_out = true;
    266                 bulk_out = endpoint_addr;
    267                 zero_mask = endpoint_desc.wMaxPacketSize - 1;
    268             } else if (!endpoint_is_output(endpoint_addr) && !found_in) {
    269                 found_in = true;
    270                 bulk_in = endpoint_addr;
    271             }
    272 
    273             size_t endpoint_packet_size = endpoint_desc.wMaxPacketSize;
    274             CHECK(endpoint_packet_size != 0);
    275             if (packet_size == 0) {
    276                 packet_size = endpoint_packet_size;
    277             } else {
    278                 CHECK(packet_size == endpoint_packet_size);
    279             }
    280         }
    281 
    282         if (found_in && found_out) {
    283             found_adb = true;
    284             break;
    285         } else {
    286             LOG(VERBOSE) << "rejecting potential adb interface at " << device_address
    287                          << "(interface " << interface_num << "): missing bulk endpoints "
    288                          << "(found_in = " << found_in << ", found_out = " << found_out << ")";
    289         }
    290     }
    291 
    292     if (!found_adb) {
    293         LOG(VERBOSE) << "skipping device with no adb interfaces at " << device_address;
    294         return;
    295     }
    296 
    297     {
    298         std::unique_lock<std::mutex> lock(usb_handles_mutex);
    299         if (usb_handles.find(device_address) != usb_handles.end()) {
    300             LOG(VERBOSE) << "device at " << device_address
    301                          << " has already been registered, skipping";
    302             return;
    303         }
    304     }
    305 
    306     bool writable = true;
    307     libusb_device_handle* handle_raw = nullptr;
    308     rc = libusb_open(device, &handle_raw);
    309     unique_device_handle handle(handle_raw);
    310     if (rc == 0) {
    311         LOG(DEBUG) << "successfully opened adb device at " << device_address << ", "
    312                    << StringPrintf("bulk_in = %#x, bulk_out = %#x", bulk_in, bulk_out);
    313 
    314         device_serial.resize(255);
    315         rc = libusb_get_string_descriptor_ascii(handle_raw, device_desc.iSerialNumber,
    316                                                 reinterpret_cast<unsigned char*>(&device_serial[0]),
    317                                                 device_serial.length());
    318         if (rc == 0) {
    319             LOG(WARNING) << "received empty serial from device at " << device_address;
    320             return;
    321         } else if (rc < 0) {
    322             LOG(WARNING) << "failed to get serial from device at " << device_address
    323                          << libusb_error_name(rc);
    324             return;
    325         }
    326         device_serial.resize(rc);
    327 
    328         // WARNING: this isn't released via RAII.
    329         rc = libusb_claim_interface(handle.get(), interface_num);
    330         if (rc != 0) {
    331             LOG(WARNING) << "failed to claim adb interface for device '" << device_serial << "'"
    332                          << libusb_error_name(rc);
    333             return;
    334         }
    335 
    336         rc = libusb_set_interface_alt_setting(handle.get(), interface_num, 0);
    337         if (rc != 0) {
    338             LOG(WARNING) << "failed to set interface alt setting for device '" << device_serial
    339                          << "'" << libusb_error_name(rc);
    340             return;
    341         }
    342 
    343         for (uint8_t endpoint : {bulk_in, bulk_out}) {
    344             rc = libusb_clear_halt(handle.get(), endpoint);
    345             if (rc != 0) {
    346                 LOG(WARNING) << "failed to clear halt on device '" << device_serial
    347                              << "' endpoint 0x" << std::hex << endpoint << ": "
    348                              << libusb_error_name(rc);
    349                 libusb_release_interface(handle.get(), interface_num);
    350                 return;
    351             }
    352         }
    353     } else {
    354         LOG(WARNING) << "failed to open usb device at " << device_address << ": "
    355                      << libusb_error_name(rc);
    356         writable = false;
    357 
    358 #if defined(__linux__)
    359         // libusb doesn't think we should be messing around with devices we don't have
    360         // write access to, but Linux at least lets us get the serial number anyway.
    361         if (!android::base::ReadFileToString(get_device_serial_path(device), &device_serial)) {
    362             // We don't actually want to treat an unknown serial as an error because
    363             // devices aren't able to communicate a serial number in early bringup.
    364             // http://b/20883914
    365             device_serial = "unknown";
    366         }
    367         device_serial = android::base::Trim(device_serial);
    368 #else
    369         // On Mac OS and Windows, we're screwed. But I don't think this situation actually
    370         // happens on those OSes.
    371         return;
    372 #endif
    373     }
    374 
    375     auto result =
    376         std::make_unique<usb_handle>(device_address, device_serial, std::move(handle),
    377                                      interface_num, bulk_in, bulk_out, zero_mask, packet_size);
    378     usb_handle* usb_handle_raw = result.get();
    379 
    380     {
    381         std::unique_lock<std::mutex> lock(usb_handles_mutex);
    382         usb_handles[device_address] = std::move(result);
    383 
    384         register_usb_transport(usb_handle_raw, device_serial.c_str(), device_address.c_str(),
    385                                writable);
    386     }
    387     LOG(INFO) << "registered new usb device '" << device_serial << "'";
    388 }
    389 
    390 static std::atomic<int> connecting_devices(0);
    391 
    392 static void device_connected(libusb_device* device) {
    393 #if defined(__linux__)
    394     // Android's host linux libusb uses netlink instead of udev for device hotplug notification,
    395     // which means we can get hotplug notifications before udev has updated ownership/perms on the
    396     // device. Since we're not going to be able to link against the system's libudev any time soon,
    397     // hack around this by inserting a sleep.
    398     auto thread = std::thread([device]() {
    399         std::string device_path = get_device_dev_path(device);
    400         std::this_thread::sleep_for(1s);
    401 
    402         process_device(device);
    403         if (--connecting_devices == 0) {
    404             adb_notify_device_scan_complete();
    405         }
    406     });
    407     thread.detach();
    408 #else
    409     process_device(device);
    410 #endif
    411 }
    412 
    413 static void device_disconnected(libusb_device* device) {
    414     std::string device_address = get_device_address(device);
    415 
    416     LOG(INFO) << "device disconnected: " << device_address;
    417     std::unique_lock<std::mutex> lock(usb_handles_mutex);
    418     auto it = usb_handles.find(device_address);
    419     if (it != usb_handles.end()) {
    420         if (!it->second->device_handle) {
    421             // If the handle is null, we were never able to open the device.
    422 
    423             // Temporarily release the usb handles mutex to avoid deadlock.
    424             std::unique_ptr<usb_handle> handle = std::move(it->second);
    425             usb_handles.erase(it);
    426             lock.unlock();
    427             unregister_usb_transport(handle.get());
    428             lock.lock();
    429         } else {
    430             // Closure of the transport will erase the usb_handle.
    431         }
    432     }
    433 }
    434 
    435 static auto& hotplug_queue = *new BlockingQueue<std::pair<libusb_hotplug_event, libusb_device*>>();
    436 static void hotplug_thread() {
    437     adb_thread_setname("libusb hotplug");
    438     while (true) {
    439         hotplug_queue.PopAll([](std::pair<libusb_hotplug_event, libusb_device*> pair) {
    440             libusb_hotplug_event event = pair.first;
    441             libusb_device* device = pair.second;
    442             if (event == LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED) {
    443                 device_connected(device);
    444             } else if (event == LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT) {
    445                 device_disconnected(device);
    446             }
    447         });
    448     }
    449 }
    450 
    451 static int hotplug_callback(libusb_context*, libusb_device* device, libusb_hotplug_event event,
    452                             void*) {
    453     // We're called with the libusb lock taken. Call these on a separate thread outside of this
    454     // function so that the usb_handle mutex is always taken before the libusb mutex.
    455     static std::once_flag once;
    456     std::call_once(once, []() { std::thread(hotplug_thread).detach(); });
    457 
    458     if (event == LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED) {
    459         ++connecting_devices;
    460     }
    461     hotplug_queue.Push({event, device});
    462     return 0;
    463 }
    464 
    465 void usb_init() {
    466     LOG(DEBUG) << "initializing libusb...";
    467     int rc = libusb_init(nullptr);
    468     if (rc != 0) {
    469         LOG(FATAL) << "failed to initialize libusb: " << libusb_error_name(rc);
    470     }
    471 
    472     // Register the hotplug callback.
    473     rc = libusb_hotplug_register_callback(
    474         nullptr, static_cast<libusb_hotplug_event>(LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED |
    475                                                    LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT),
    476         LIBUSB_HOTPLUG_ENUMERATE, LIBUSB_HOTPLUG_MATCH_ANY, LIBUSB_HOTPLUG_MATCH_ANY,
    477         LIBUSB_CLASS_PER_INTERFACE, hotplug_callback, nullptr, &hotplug_handle);
    478 
    479     if (rc != LIBUSB_SUCCESS) {
    480         LOG(FATAL) << "failed to register libusb hotplug callback";
    481     }
    482 
    483     // Spawn a thread for libusb_handle_events.
    484     std::thread([]() {
    485         adb_thread_setname("libusb");
    486         while (true) {
    487             libusb_handle_events(nullptr);
    488         }
    489     }).detach();
    490 }
    491 
    492 void usb_cleanup() {
    493     libusb_hotplug_deregister_callback(nullptr, hotplug_handle);
    494 }
    495 
    496 // Dispatch a libusb transfer, unlock |device_lock|, and then wait for the result.
    497 static int perform_usb_transfer(usb_handle* h, transfer_info* info,
    498                                 std::unique_lock<std::mutex> device_lock) {
    499     libusb_transfer* transfer = info->transfer;
    500 
    501     transfer->user_data = info;
    502     transfer->callback = [](libusb_transfer* transfer) {
    503         transfer_info* info = static_cast<transfer_info*>(transfer->user_data);
    504 
    505         LOG(DEBUG) << info->name << " transfer callback entered";
    506 
    507         // Make sure that the original submitter has made it to the condition_variable wait.
    508         std::unique_lock<std::mutex> lock(info->mutex);
    509 
    510         LOG(DEBUG) << info->name << " callback successfully acquired lock";
    511 
    512         if (transfer->status != LIBUSB_TRANSFER_COMPLETED) {
    513             LOG(WARNING) << info->name
    514                          << " transfer failed: " << libusb_error_name(transfer->status);
    515             info->Notify();
    516             return;
    517         }
    518 
    519         // usb_read() can return when receiving some data.
    520         if (info->is_bulk_out && transfer->actual_length != transfer->length) {
    521             LOG(DEBUG) << info->name << " transfer incomplete, resubmitting";
    522             transfer->length -= transfer->actual_length;
    523             transfer->buffer += transfer->actual_length;
    524             int rc = libusb_submit_transfer(transfer);
    525             if (rc != 0) {
    526                 LOG(WARNING) << "failed to submit " << info->name
    527                              << " transfer: " << libusb_error_name(rc);
    528                 transfer->status = LIBUSB_TRANSFER_ERROR;
    529                 info->Notify();
    530             }
    531             return;
    532         }
    533 
    534         if (should_perform_zero_transfer(transfer->endpoint, transfer->length, info->zero_mask)) {
    535             LOG(DEBUG) << "submitting zero-length write";
    536             transfer->length = 0;
    537             int rc = libusb_submit_transfer(transfer);
    538             if (rc != 0) {
    539                 LOG(WARNING) << "failed to submit zero-length write: " << libusb_error_name(rc);
    540                 transfer->status = LIBUSB_TRANSFER_ERROR;
    541                 info->Notify();
    542             }
    543             return;
    544         }
    545 
    546         LOG(VERBOSE) << info->name << "transfer fully complete";
    547         info->Notify();
    548     };
    549 
    550     LOG(DEBUG) << "locking " << info->name << " transfer_info mutex";
    551     std::unique_lock<std::mutex> lock(info->mutex);
    552     info->transfer_complete = false;
    553     LOG(DEBUG) << "submitting " << info->name << " transfer";
    554     int rc = libusb_submit_transfer(transfer);
    555     if (rc != 0) {
    556         LOG(WARNING) << "failed to submit " << info->name << " transfer: " << libusb_error_name(rc);
    557         errno = EIO;
    558         return -1;
    559     }
    560 
    561     LOG(DEBUG) << info->name << " transfer successfully submitted";
    562     device_lock.unlock();
    563     info->cv.wait(lock, [info]() { return info->transfer_complete; });
    564     if (transfer->status != 0) {
    565         errno = EIO;
    566         return -1;
    567     }
    568 
    569     return 0;
    570 }
    571 
    572 int usb_write(usb_handle* h, const void* d, int len) {
    573     LOG(DEBUG) << "usb_write of length " << len;
    574 
    575     std::unique_lock<std::mutex> lock(h->device_handle_mutex);
    576     if (!h->device_handle) {
    577         errno = EIO;
    578         return -1;
    579     }
    580 
    581     transfer_info* info = &h->write;
    582     info->transfer->dev_handle = h->device_handle;
    583     info->transfer->flags = 0;
    584     info->transfer->endpoint = h->bulk_out;
    585     info->transfer->type = LIBUSB_TRANSFER_TYPE_BULK;
    586     info->transfer->length = len;
    587     info->transfer->buffer = reinterpret_cast<unsigned char*>(const_cast<void*>(d));
    588     info->transfer->num_iso_packets = 0;
    589 
    590     int rc = perform_usb_transfer(h, info, std::move(lock));
    591     LOG(DEBUG) << "usb_write(" << len << ") = " << rc;
    592     return rc;
    593 }
    594 
    595 int usb_read(usb_handle* h, void* d, int len) {
    596     LOG(DEBUG) << "usb_read of length " << len;
    597 
    598     std::unique_lock<std::mutex> lock(h->device_handle_mutex);
    599     if (!h->device_handle) {
    600         errno = EIO;
    601         return -1;
    602     }
    603 
    604     transfer_info* info = &h->read;
    605     info->transfer->dev_handle = h->device_handle;
    606     info->transfer->flags = 0;
    607     info->transfer->endpoint = h->bulk_in;
    608     info->transfer->type = LIBUSB_TRANSFER_TYPE_BULK;
    609     info->transfer->length = len;
    610     info->transfer->buffer = reinterpret_cast<unsigned char*>(d);
    611     info->transfer->num_iso_packets = 0;
    612 
    613     int rc = perform_usb_transfer(h, info, std::move(lock));
    614     LOG(DEBUG) << "usb_read(" << len << ") = " << rc << ", actual_length "
    615                << info->transfer->actual_length;
    616     if (rc < 0) {
    617         return rc;
    618     }
    619     return info->transfer->actual_length;
    620 }
    621 
    622 int usb_close(usb_handle* h) {
    623     std::unique_lock<std::mutex> lock(usb_handles_mutex);
    624     auto it = usb_handles.find(h->device_address);
    625     if (it == usb_handles.end()) {
    626         LOG(FATAL) << "attempted to close unregistered usb_handle for '" << h->serial << "'";
    627     }
    628     usb_handles.erase(h->device_address);
    629     return 0;
    630 }
    631 
    632 void usb_kick(usb_handle* h) {
    633     h->Close();
    634 }
    635 
    636 size_t usb_get_max_packet_size(usb_handle* h) {
    637     CHECK(h->max_packet_size != 0);
    638     return h->max_packet_size;
    639 }
    640 
    641 } // namespace libusb
    642