"Fossies" - the Fresh Open Source Software Archive

Member "usbutils-014/lsusb.c" (4 Aug 2021, 118068 Bytes) of package /linux/misc/usbutils-014.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "lsusb.c" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 013_vs_014.

    1 // SPDX-License-Identifier: GPL-2.0-or-later
    2 /*
    3  * lspci like utility for the USB bus
    4  *
    5  * Copyright (C) 1999-2001, 2003 Thomas Sailer (t.sailer@alumni.ethz.ch)
    6  * Copyright (C) 2003-2005 David Brownell
    7  */
    8 
    9 #include "config.h"
   10 #include <stdint.h>
   11 #include <sys/stat.h>
   12 #include <fcntl.h>
   13 #include <locale.h>
   14 #include <string.h>
   15 #include <errno.h>
   16 #include <stdio.h>
   17 #include <stdlib.h>
   18 #include <stdarg.h>
   19 #include <stdbool.h>
   20 
   21 #ifdef HAVE_BYTESWAP_H
   22 #include <byteswap.h>
   23 #endif
   24 
   25 #include <libusb.h>
   26 #include <unistd.h>
   27 
   28 #include "lsusb.h"
   29 #include "names.h"
   30 #include "sysfs.h"
   31 #include "usbmisc.h"
   32 #include "desc-defs.h"
   33 #include "desc-dump.h"
   34 
   35 #include <getopt.h>
   36 
   37 #define le16_to_cpu(x) libusb_cpu_to_le16(libusb_cpu_to_le16(x))
   38 
   39 /* from USB 2.0 spec and updates */
   40 #define USB_DT_DEVICE_QUALIFIER     0x06
   41 #define USB_DT_OTHER_SPEED_CONFIG   0x07
   42 #define USB_DT_OTG          0x09
   43 #define USB_DT_DEBUG            0x0a
   44 #define USB_DT_INTERFACE_ASSOCIATION    0x0b
   45 #define USB_DT_SECURITY         0x0c
   46 #define USB_DT_KEY          0x0d
   47 #define USB_DT_ENCRYPTION_TYPE      0x0e
   48 #define USB_DT_BOS          0x0f
   49 #define USB_DT_DEVICE_CAPABILITY    0x10
   50 #define USB_DT_WIRELESS_ENDPOINT_COMP   0x11
   51 #define USB_DT_WIRE_ADAPTER     0x21
   52 #define USB_DT_RPIPE            0x22
   53 #define USB_DT_RC_INTERFACE     0x23
   54 #define USB_DT_SS_ENDPOINT_COMP     0x30
   55 
   56 /* Device Capability Type Codes (Wireless USB spec and USB 3.0 bus spec) */
   57 #define USB_DC_WIRELESS_USB     0x01
   58 #define USB_DC_20_EXTENSION     0x02
   59 #define USB_DC_SUPERSPEED       0x03
   60 #define USB_DC_CONTAINER_ID     0x04
   61 #define USB_DC_PLATFORM         0x05
   62 #define USB_DC_SUPERSPEEDPLUS       0x0a
   63 #define USB_DC_BILLBOARD        0x0d
   64 #define USB_DC_BILLBOARD_ALT_MODE   0x0f
   65 #define USB_DC_CONFIGURATION_SUMMARY    0x10
   66 
   67 /* Conventional codes for class-specific descriptors.  The convention is
   68  * defined in the USB "Common Class" Spec (3.11).  Individual class specs
   69  * are authoritative for their usage, not the "common class" writeup.
   70  */
   71 #define USB_DT_CS_DEVICE        (LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_DT_DEVICE)
   72 #define USB_DT_CS_CONFIG        (LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_DT_CONFIG)
   73 #define USB_DT_CS_STRING        (LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_DT_STRING)
   74 #define USB_DT_CS_INTERFACE     (LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_DT_INTERFACE)
   75 #define USB_DT_CS_ENDPOINT      (LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_DT_ENDPOINT)
   76 
   77 #ifndef USB_CLASS_CCID
   78 #define USB_CLASS_CCID          0x0b
   79 #endif
   80 
   81 #ifndef USB_CLASS_VIDEO
   82 #define USB_CLASS_VIDEO         0x0e
   83 #endif
   84 
   85 #ifndef USB_CLASS_APPLICATION
   86 #define USB_CLASS_APPLICATION           0xfe
   87 #endif
   88 
   89 #ifndef USB_AUDIO_CLASS_1
   90 #define USB_AUDIO_CLASS_1       0x00
   91 #endif
   92 
   93 #ifndef USB_AUDIO_CLASS_2
   94 #define USB_AUDIO_CLASS_2       0x20
   95 #endif
   96 
   97 /* USB DCD for Audio Devices Release 3.0: Section A.6, pp139 */
   98 #ifndef USB_AUDIO_CLASS_3
   99 #define USB_AUDIO_CLASS_3       0x30
  100 #endif
  101 
  102 #ifndef USB_VIDEO_PROTOCOL_15
  103 #define USB_VIDEO_PROTOCOL_15       0x01
  104 #endif
  105 
  106 #define VERBLEVEL_DEFAULT 0 /* 0 gives lspci behaviour; 1, lsusb-0.9 */
  107 
  108 #define CTRL_TIMEOUT    (5*1000)    /* milliseconds */
  109 
  110 #define HUB_STATUS_BYTELEN  3   /* max 3 bytes status = hub + 23 ports */
  111 
  112 #define BILLBOARD_MAX_NUM_ALT_MODE  (0x34)
  113 
  114 /* from WebUSB specification : https://wicg.github.io/webusb/ */
  115 #define WEBUSB_GUID     "{3408b638-09a9-47a0-8bfd-a0768815b665}"
  116 #define WEBUSB_GET_URL      0x02
  117 #define USB_DT_WEBUSB_URL   0x03
  118 
  119 unsigned int verblevel = VERBLEVEL_DEFAULT;
  120 static int do_report_desc = 1;
  121 static const char * const encryption_type[] = {
  122     "UNSECURE",
  123     "WIRED",
  124     "CCM_1",
  125     "RSA_1",
  126     "RESERVED"
  127 };
  128 
  129 static const char * const vconn_power[] = {
  130     "1W",
  131     "1.5W",
  132     "2W",
  133     "3W",
  134     "4W",
  135     "5W",
  136     "6W",
  137     "reserved"
  138 };
  139 
  140 static const char * const alt_mode_state[] = {
  141     "Unspecified Error",
  142     "Alternate Mode configuration not attempted",
  143     "Alternate Mode configuration attempted but unsuccessful",
  144     "Alternate Mode configuration successful"
  145 };
  146 
  147 static void dump_interface(libusb_device_handle *dev, const struct libusb_interface *interface);
  148 static void dump_endpoint(libusb_device_handle *dev, const struct libusb_interface_descriptor *interface, const struct libusb_endpoint_descriptor *endpoint);
  149 static void dump_audiocontrol_interface(libusb_device_handle *dev, const unsigned char *buf, int protocol);
  150 static void dump_audiostreaming_interface(libusb_device_handle *dev, const unsigned char *buf, int protocol);
  151 static void dump_midistreaming_interface(libusb_device_handle *dev, const unsigned char *buf);
  152 static void dump_videocontrol_interface(libusb_device_handle *dev, const unsigned char *buf, int protocol);
  153 static void dump_videostreaming_interface(const unsigned char *buf);
  154 static void dump_dfu_interface(const unsigned char *buf);
  155 static char *dump_comm_descriptor(libusb_device_handle *dev, const unsigned char *buf, char *indent);
  156 static void dump_hid_device(libusb_device_handle *dev, const struct libusb_interface_descriptor *interface, const unsigned char *buf);
  157 static void dump_printer_device(libusb_device_handle *dev, const struct libusb_interface_descriptor *interface, const unsigned char *buf);
  158 static void dump_audiostreaming_endpoint(libusb_device_handle *dev, const unsigned char *buf, int protocol);
  159 static void dump_midistreaming_endpoint(const unsigned char *buf);
  160 static void dump_hub(const char *prefix, const unsigned char *p, int tt_type);
  161 static void dump_ccid_device(const unsigned char *buf);
  162 static void dump_billboard_device_capability_desc(libusb_device_handle *dev, unsigned char *buf);
  163 static void dump_billboard_alt_mode_capability_desc(libusb_device_handle *dev, unsigned char *buf);
  164 
  165 /* ---------------------------------------------------------------------- */
  166 
  167 static unsigned int convert_le_u32 (const unsigned char *buf)
  168 {
  169     return buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24);
  170 }
  171 
  172 static unsigned int convert_le_u16 (const unsigned char *buf)
  173 {
  174     return buf[0] | (buf[1] << 8);
  175 }
  176 
  177 /* ---------------------------------------------------------------------- */
  178 
  179 /* workaround libusb API goofs:  "byte" should never be sign extended;
  180  * using "char" is trouble.
  181  */
  182 
  183 static inline int typesafe_control_msg(libusb_device_handle *dev,
  184     unsigned char requesttype, unsigned char request,
  185     int value, int idx,
  186     unsigned char *bytes, unsigned size, int timeout)
  187 {
  188     int ret = libusb_control_transfer(dev, requesttype, request, value,
  189                     idx, bytes, size, timeout);
  190 
  191     return ret;
  192 }
  193 
  194 #define usb_control_msg     typesafe_control_msg
  195 
  196 static int get_protocol_string(char *buf, size_t size, uint8_t cls, uint8_t subcls, uint8_t proto)
  197 {
  198     const char *cp;
  199 
  200     if (size < 1)
  201         return 0;
  202     *buf = 0;
  203     if (!(cp = names_protocol(cls, subcls, proto)))
  204         return 0;
  205     return snprintf(buf, size, "%s", cp);
  206 }
  207 
  208 static int get_videoterminal_string(char *buf, size_t size, uint16_t termt)
  209 {
  210     const char *cp;
  211 
  212     if (size < 1)
  213         return 0;
  214     *buf = 0;
  215     if (!(cp = names_videoterminal(termt)))
  216         return 0;
  217     return snprintf(buf, size, "%s", cp);
  218 }
  219 
  220 static const char *get_guid(const unsigned char *buf)
  221 {
  222     static char guid[39];
  223 
  224     /* NOTE:  see RFC 4122 for more information about GUID/UUID
  225      * structure.  The first fields fields are historically big
  226      * endian numbers, dating from Apollo mc68000 workstations.
  227      */
  228     sprintf(guid, "{%02x%02x%02x%02x"
  229             "-%02x%02x"
  230             "-%02x%02x"
  231             "-%02x%02x"
  232             "-%02x%02x%02x%02x%02x%02x}",
  233            buf[3], buf[2], buf[1], buf[0],
  234            buf[5], buf[4],
  235            buf[7], buf[6],
  236            buf[8], buf[9],
  237            buf[10], buf[11], buf[12], buf[13], buf[14], buf[15]);
  238     return guid;
  239 }
  240 
  241 /* ---------------------------------------------------------------------- */
  242 
  243 static void dump_bytes(const unsigned char *buf, unsigned int len)
  244 {
  245     unsigned int i;
  246 
  247     for (i = 0; i < len; i++)
  248         printf(" %02x", buf[i]);
  249     printf("\n");
  250 }
  251 
  252 static void dump_junk(const unsigned char *buf, const char *indent, unsigned int len)
  253 {
  254     unsigned int i;
  255 
  256     if (buf[0] <= len)
  257         return;
  258     printf("%sjunk at descriptor end:", indent);
  259     for (i = len; i < buf[0]; i++)
  260         printf(" %02x", buf[i]);
  261     printf("\n");
  262 }
  263 
  264 /*
  265  * General config descriptor dump
  266  */
  267 
  268 static void dump_device(
  269     libusb_device *dev,
  270     struct libusb_device_descriptor *descriptor
  271 )
  272 {
  273     char vendor[128], product[128];
  274     char cls[128], subcls[128], proto[128];
  275     char mfg[128] = {0}, prod[128] = {0}, serial[128] = {0};
  276     char sysfs_name[PATH_MAX];
  277 
  278     get_vendor_string(vendor, sizeof(vendor), descriptor->idVendor);
  279     get_product_string(product, sizeof(product),
  280             descriptor->idVendor, descriptor->idProduct);
  281     get_class_string(cls, sizeof(cls), descriptor->bDeviceClass);
  282     get_subclass_string(subcls, sizeof(subcls),
  283             descriptor->bDeviceClass, descriptor->bDeviceSubClass);
  284     get_protocol_string(proto, sizeof(proto), descriptor->bDeviceClass,
  285             descriptor->bDeviceSubClass, descriptor->bDeviceProtocol);
  286 
  287     if (get_sysfs_name(sysfs_name, sizeof(sysfs_name), dev) >= 0) {
  288         read_sysfs_prop(mfg, sizeof(mfg), sysfs_name, "manufacturer");
  289         read_sysfs_prop(prod, sizeof(prod), sysfs_name, "product");
  290         read_sysfs_prop(serial, sizeof(serial), sysfs_name, "serial");
  291     }
  292 
  293     printf("Device Descriptor:\n"
  294            "  bLength             %5u\n"
  295            "  bDescriptorType     %5u\n"
  296            "  bcdUSB              %2x.%02x\n"
  297            "  bDeviceClass        %5u %s\n"
  298            "  bDeviceSubClass     %5u %s\n"
  299            "  bDeviceProtocol     %5u %s\n"
  300            "  bMaxPacketSize0     %5u\n"
  301            "  idVendor           0x%04x %s\n"
  302            "  idProduct          0x%04x %s\n"
  303            "  bcdDevice           %2x.%02x\n"
  304            "  iManufacturer       %5u %s\n"
  305            "  iProduct            %5u %s\n"
  306            "  iSerial             %5u %s\n"
  307            "  bNumConfigurations  %5u\n",
  308            descriptor->bLength, descriptor->bDescriptorType,
  309            descriptor->bcdUSB >> 8, descriptor->bcdUSB & 0xff,
  310            descriptor->bDeviceClass, cls,
  311            descriptor->bDeviceSubClass, subcls,
  312            descriptor->bDeviceProtocol, proto,
  313            descriptor->bMaxPacketSize0,
  314            descriptor->idVendor, vendor, descriptor->idProduct, product,
  315            descriptor->bcdDevice >> 8, descriptor->bcdDevice & 0xff,
  316            descriptor->iManufacturer, mfg,
  317            descriptor->iProduct, prod,
  318            descriptor->iSerialNumber, serial,
  319            descriptor->bNumConfigurations);
  320 }
  321 
  322 static void dump_wire_adapter(const unsigned char *buf)
  323 {
  324 
  325     printf("      Wire Adapter Class Descriptor:\n"
  326            "        bLength             %5u\n"
  327            "        bDescriptorType     %5u\n"
  328            "        bcdWAVersion        %2x.%02x\n"
  329            "     bNumPorts       %5u\n"
  330            "     bmAttributes        %5u\n"
  331            "     wNumRPRipes         %5u\n"
  332            "     wRPipeMaxBlock      %5u\n"
  333            "     bRPipeBlockSize     %5u\n"
  334            "     bPwrOn2PwrGood      %5u\n"
  335            "     bNumMMCIEs      %5u\n"
  336            "     DeviceRemovable     %5u\n",
  337            buf[0], buf[1], buf[3], buf[2], buf[4], buf[5],
  338            (buf[6] | buf[7] << 8),
  339            (buf[8] | buf[9] << 8),
  340            buf[10], buf[11], buf[12], buf[13]);
  341 }
  342 
  343 static void dump_rc_interface(const unsigned char *buf)
  344 {
  345     printf("      Radio Control Interface Class Descriptor:\n"
  346            "        bLength             %5u\n"
  347            "        bDescriptorType     %5u\n"
  348            "        bcdRCIVersion       %2x.%02x\n",
  349            buf[0], buf[1], buf[3], buf[2]);
  350 
  351 }
  352 
  353 static void dump_security(const unsigned char *buf)
  354 {
  355     printf("    Security Descriptor:\n"
  356            "      bLength             %5u\n"
  357            "      bDescriptorType     %5u\n"
  358            "      wTotalLength       0x%04x\n"
  359            "      bNumEncryptionTypes %5u\n",
  360            buf[0], buf[1], (buf[3] << 8 | buf[2]), buf[4]);
  361 }
  362 
  363 static void dump_encryption_type(const unsigned char *buf)
  364 {
  365     int b_encryption_type = buf[2] & 0x4;
  366 
  367     printf("    Encryption Type Descriptor:\n"
  368            "      bLength             %5u\n"
  369            "      bDescriptorType     %5u\n"
  370            "      bEncryptionType     %5u %s\n"
  371            "      bEncryptionValue    %5u\n"
  372            "      bAuthKeyIndex       %5u\n",
  373            buf[0], buf[1], buf[2],
  374            encryption_type[b_encryption_type], buf[3], buf[4]);
  375 }
  376 
  377 static void dump_association(libusb_device_handle *dev, const unsigned char *buf)
  378 {
  379     char cls[128], subcls[128], proto[128];
  380     char *func;
  381 
  382     get_class_string(cls, sizeof(cls), buf[4]);
  383     get_subclass_string(subcls, sizeof(subcls), buf[4], buf[5]);
  384     get_protocol_string(proto, sizeof(proto), buf[4], buf[5], buf[6]);
  385     func = get_dev_string(dev, buf[7]);
  386 
  387     printf("    Interface Association:\n"
  388            "      bLength             %5u\n"
  389            "      bDescriptorType     %5u\n"
  390            "      bFirstInterface     %5u\n"
  391            "      bInterfaceCount     %5u\n"
  392            "      bFunctionClass      %5u %s\n"
  393            "      bFunctionSubClass   %5u %s\n"
  394            "      bFunctionProtocol   %5u %s\n"
  395            "      iFunction           %5u %s\n",
  396            buf[0], buf[1],
  397            buf[2], buf[3],
  398            buf[4], cls,
  399            buf[5], subcls,
  400            buf[6], proto,
  401            buf[7], func);
  402 
  403     free(func);
  404 }
  405 
  406 static void dump_config(libusb_device_handle *dev, struct libusb_config_descriptor *config, unsigned speed)
  407 {
  408     char *cfg;
  409     int i;
  410 
  411     cfg = get_dev_string(dev, config->iConfiguration);
  412 
  413     printf("  Configuration Descriptor:\n"
  414            "    bLength             %5u\n"
  415            "    bDescriptorType     %5u\n"
  416            "    wTotalLength       0x%04x\n"
  417            "    bNumInterfaces      %5u\n"
  418            "    bConfigurationValue %5u\n"
  419            "    iConfiguration      %5u %s\n"
  420            "    bmAttributes         0x%02x\n",
  421            config->bLength, config->bDescriptorType,
  422            le16_to_cpu(config->wTotalLength),
  423            config->bNumInterfaces, config->bConfigurationValue,
  424            config->iConfiguration,
  425            cfg, config->bmAttributes);
  426 
  427     free(cfg);
  428 
  429     if (!(config->bmAttributes & 0x80))
  430         printf("      (Missing must-be-set bit!)\n");
  431     if (config->bmAttributes & 0x40)
  432         printf("      Self Powered\n");
  433     else
  434         printf("      (Bus Powered)\n");
  435     if (config->bmAttributes & 0x20)
  436         printf("      Remote Wakeup\n");
  437     if (config->bmAttributes & 0x10)
  438         printf("      Battery Powered\n");
  439     printf("    MaxPower            %5umA\n", config->MaxPower * (speed >= 0x0300 ? 8 : 2));
  440 
  441     /* avoid re-ordering or hiding descriptors for display */
  442     if (config->extra_length) {
  443         int     size = config->extra_length;
  444         const unsigned char *buf = config->extra;
  445 
  446         while (size >= 2) {
  447             if (buf[0] < 2) {
  448                 dump_junk(buf, "        ", size);
  449                 break;
  450             }
  451             switch (buf[1]) {
  452             case USB_DT_OTG:
  453                 /* handled separately */
  454                 break;
  455             case USB_DT_INTERFACE_ASSOCIATION:
  456                 dump_association(dev, buf);
  457                 break;
  458             case USB_DT_SECURITY:
  459                 dump_security(buf);
  460                 break;
  461             case USB_DT_ENCRYPTION_TYPE:
  462                 dump_encryption_type(buf);
  463                 break;
  464             default:
  465                 /* often a misplaced class descriptor */
  466                 printf("    ** UNRECOGNIZED: ");
  467                 dump_bytes(buf, buf[0]);
  468                 break;
  469             }
  470             size -= buf[0];
  471             buf += buf[0];
  472         }
  473     }
  474     for (i = 0 ; i < config->bNumInterfaces ; i++)
  475         dump_interface(dev, &config->interface[i]);
  476 }
  477 
  478 static void dump_altsetting(libusb_device_handle *dev, const struct libusb_interface_descriptor *interface)
  479 {
  480     char cls[128], subcls[128], proto[128];
  481     char *ifstr;
  482 
  483     const unsigned char *buf;
  484     unsigned size, i;
  485 
  486     get_class_string(cls, sizeof(cls), interface->bInterfaceClass);
  487     get_subclass_string(subcls, sizeof(subcls), interface->bInterfaceClass, interface->bInterfaceSubClass);
  488     get_protocol_string(proto, sizeof(proto), interface->bInterfaceClass, interface->bInterfaceSubClass, interface->bInterfaceProtocol);
  489     ifstr = get_dev_string(dev, interface->iInterface);
  490 
  491     printf("    Interface Descriptor:\n"
  492            "      bLength             %5u\n"
  493            "      bDescriptorType     %5u\n"
  494            "      bInterfaceNumber    %5u\n"
  495            "      bAlternateSetting   %5u\n"
  496            "      bNumEndpoints       %5u\n"
  497            "      bInterfaceClass     %5u %s\n"
  498            "      bInterfaceSubClass  %5u %s\n"
  499            "      bInterfaceProtocol  %5u %s\n"
  500            "      iInterface          %5u %s\n",
  501            interface->bLength, interface->bDescriptorType, interface->bInterfaceNumber,
  502            interface->bAlternateSetting, interface->bNumEndpoints, interface->bInterfaceClass, cls,
  503            interface->bInterfaceSubClass, subcls, interface->bInterfaceProtocol, proto,
  504            interface->iInterface, ifstr);
  505 
  506     free(ifstr);
  507 
  508     /* avoid re-ordering or hiding descriptors for display */
  509     if (interface->extra_length) {
  510         size = interface->extra_length;
  511         buf = interface->extra;
  512         while (size >= 2 * sizeof(uint8_t)) {
  513             if (buf[0] < 2) {
  514                 dump_junk(buf, "      ", size);
  515                 break;
  516             }
  517 
  518             switch (buf[1]) {
  519 
  520             /* This is the polite way to provide class specific
  521              * descriptors: explicitly tagged, using common class
  522              * spec conventions.
  523              */
  524             case USB_DT_CS_DEVICE:
  525             case USB_DT_CS_INTERFACE:
  526                 switch (interface->bInterfaceClass) {
  527                 case LIBUSB_CLASS_AUDIO:
  528                     switch (interface->bInterfaceSubClass) {
  529                     case 1:
  530                         dump_audiocontrol_interface(dev, buf, interface->bInterfaceProtocol);
  531                         break;
  532                     case 2:
  533                         dump_audiostreaming_interface(dev, buf, interface->bInterfaceProtocol);
  534                         break;
  535                     case 3:
  536                         dump_midistreaming_interface(dev, buf);
  537                         break;
  538                     default:
  539                         goto dump;
  540                     }
  541                     break;
  542                 case LIBUSB_CLASS_COMM:
  543                     dump_comm_descriptor(dev, buf,
  544                         "      ");
  545                     break;
  546                 case USB_CLASS_VIDEO:
  547                     switch (interface->bInterfaceSubClass) {
  548                     case 1:
  549                         dump_videocontrol_interface(dev, buf, interface->bInterfaceProtocol);
  550                         break;
  551                     case 2:
  552                         dump_videostreaming_interface(buf);
  553                         break;
  554                     default:
  555                         goto dump;
  556                     }
  557                     break;
  558                 case USB_CLASS_APPLICATION:
  559                     switch (interface->bInterfaceSubClass) {
  560                     case 1:
  561                         dump_dfu_interface(buf);
  562                         break;
  563                     default:
  564                         goto dump;
  565                     }
  566                     break;
  567                 case LIBUSB_CLASS_HID:
  568                     dump_hid_device(dev, interface, buf);
  569                     break;
  570                 case LIBUSB_CLASS_PRINTER:
  571                     dump_printer_device(dev, interface, buf);
  572                     break;
  573                 case USB_CLASS_CCID:
  574                     dump_ccid_device(buf);
  575                     break;
  576                 default:
  577                     goto dump;
  578                 }
  579                 break;
  580 
  581             /* This is the ugly way:  implicitly tagged,
  582              * each class could redefine the type IDs.
  583              */
  584             default:
  585                 switch (interface->bInterfaceClass) {
  586                 case LIBUSB_CLASS_HID:
  587                     dump_hid_device(dev, interface, buf);
  588                     break;
  589                 case USB_CLASS_CCID:
  590                     dump_ccid_device(buf);
  591                     break;
  592                 case 0xe0:  /* wireless */
  593                     switch (interface->bInterfaceSubClass) {
  594                     case 1:
  595                         switch (interface->bInterfaceProtocol) {
  596                         case 2:
  597                             dump_rc_interface(buf);
  598                             break;
  599                         default:
  600                             goto dump;
  601                         }
  602                         break;
  603                     case 2:
  604                         dump_wire_adapter(buf);
  605                         break;
  606                     default:
  607                         goto dump;
  608                     }
  609                     break;
  610                 case LIBUSB_CLASS_AUDIO:
  611                     switch (buf[1]) {
  612                     /* MISPLACED DESCRIPTOR */
  613                     case USB_DT_CS_ENDPOINT:
  614                         switch (interface->bInterfaceSubClass) {
  615                         case 2:
  616                             dump_audiostreaming_endpoint(dev, buf, interface->bInterfaceProtocol);
  617                             break;
  618                         default:
  619                             goto dump;
  620                         }
  621                         break;
  622                     default:
  623                         goto dump;
  624                     }
  625                     break;
  626                 default:
  627                     /* ... not everything is class-specific */
  628                     switch (buf[1]) {
  629                     case USB_DT_OTG:
  630                         /* handled separately */
  631                         break;
  632                     case USB_DT_INTERFACE_ASSOCIATION:
  633                         dump_association(dev, buf);
  634                         break;
  635                     default:
  636 dump:
  637                         /* often a misplaced class descriptor */
  638                         printf("      ** UNRECOGNIZED: ");
  639                         dump_bytes(buf, buf[0]);
  640                         break;
  641                     }
  642                 }
  643             }
  644             size -= buf[0];
  645             buf += buf[0];
  646         }
  647     }
  648 
  649     for (i = 0 ; i < interface->bNumEndpoints ; i++)
  650         dump_endpoint(dev, interface, &interface->endpoint[i]);
  651 }
  652 
  653 static void dump_interface(libusb_device_handle *dev, const struct libusb_interface *interface)
  654 {
  655     int i;
  656 
  657     for (i = 0; i < interface->num_altsetting; i++)
  658         dump_altsetting(dev, &interface->altsetting[i]);
  659 }
  660 
  661 static void dump_pipe_desc(const unsigned char *buf)
  662 {
  663     static const char *pipe_name[] = {
  664         "Reserved",
  665         "Command pipe",
  666         "Status pipe",
  667         "Data-in pipe",
  668         "Data-out pipe",
  669         [5 ... 0xDF] = "Reserved",
  670         [0xE0 ... 0xEF] = "Vendor specific",
  671         [0xF0 ... 0xFF] = "Reserved",
  672     };
  673 
  674     if (buf[0] == 4 && buf[1] == 0x24) {
  675         printf("        %s (0x%02x)\n", pipe_name[buf[2]], buf[2]);
  676     } else {
  677         printf("        INTERFACE CLASS: ");
  678         dump_bytes(buf, buf[0]);
  679     }
  680 }
  681 
  682 static void dump_endpoint(libusb_device_handle *dev, const struct libusb_interface_descriptor *interface, const struct libusb_endpoint_descriptor *endpoint)
  683 {
  684     static const char * const typeattr[] = {
  685         "Control",
  686         "Isochronous",
  687         "Bulk",
  688         "Interrupt"
  689     };
  690     static const char * const syncattr[] = {
  691         "None",
  692         "Asynchronous",
  693         "Adaptive",
  694         "Synchronous"
  695     };
  696     static const char * const usage[] = {
  697         "Data",
  698         "Feedback",
  699         "Implicit feedback Data",
  700         "(reserved)"
  701     };
  702     static const char * const hb[] = { "1x", "2x", "3x", "(?\?)" };
  703     const unsigned char *buf;
  704     unsigned size;
  705     unsigned wmax = le16_to_cpu(endpoint->wMaxPacketSize);
  706 
  707     printf("      Endpoint Descriptor:\n"
  708            "        bLength             %5u\n"
  709            "        bDescriptorType     %5u\n"
  710            "        bEndpointAddress     0x%02x  EP %u %s\n"
  711            "        bmAttributes        %5u\n"
  712            "          Transfer Type            %s\n"
  713            "          Synch Type               %s\n"
  714            "          Usage Type               %s\n"
  715            "        wMaxPacketSize     0x%04x  %s %d bytes\n"
  716            "        bInterval           %5u\n",
  717            endpoint->bLength,
  718            endpoint->bDescriptorType,
  719            endpoint->bEndpointAddress,
  720            endpoint->bEndpointAddress & 0x0f,
  721            (endpoint->bEndpointAddress & 0x80) ? "IN" : "OUT",
  722            endpoint->bmAttributes,
  723            typeattr[endpoint->bmAttributes & 3],
  724            syncattr[(endpoint->bmAttributes >> 2) & 3],
  725            usage[(endpoint->bmAttributes >> 4) & 3],
  726            wmax, hb[(wmax >> 11) & 3], wmax & 0x7ff,
  727            endpoint->bInterval);
  728     /* only for audio endpoints */
  729     if (endpoint->bLength == 9)
  730         printf("        bRefresh            %5u\n"
  731                "        bSynchAddress       %5u\n",
  732                endpoint->bRefresh, endpoint->bSynchAddress);
  733 
  734     /* avoid re-ordering or hiding descriptors for display */
  735     if (endpoint->extra_length) {
  736         size = endpoint->extra_length;
  737         buf = endpoint->extra;
  738         while (size >= 2 * sizeof(uint8_t)) {
  739             if (buf[0] < 2) {
  740                 dump_junk(buf, "        ", size);
  741                 break;
  742             }
  743             switch (buf[1]) {
  744             case USB_DT_CS_ENDPOINT:
  745                 if (interface->bInterfaceClass == 1 && interface->bInterfaceSubClass == 2)
  746                     dump_audiostreaming_endpoint(dev, buf, interface->bInterfaceProtocol);
  747                 else if (interface->bInterfaceClass == 1 && interface->bInterfaceSubClass == 3)
  748                     dump_midistreaming_endpoint(buf);
  749                 break;
  750             case USB_DT_CS_INTERFACE:
  751                 /* MISPLACED DESCRIPTOR ... less indent */
  752                 switch (interface->bInterfaceClass) {
  753                 case LIBUSB_CLASS_COMM:
  754                 case LIBUSB_CLASS_DATA: /* comm data */
  755                     dump_comm_descriptor(dev, buf,
  756                         "      ");
  757                     break;
  758                 case LIBUSB_CLASS_MASS_STORAGE:
  759                     dump_pipe_desc(buf);
  760                     break;
  761                 default:
  762                     printf("        INTERFACE CLASS: ");
  763                     dump_bytes(buf, buf[0]);
  764                 }
  765                 break;
  766             case USB_DT_CS_DEVICE:
  767                 /* MISPLACED DESCRIPTOR ... less indent */
  768                 switch (interface->bInterfaceClass) {
  769                 case USB_CLASS_CCID:
  770                     dump_ccid_device(buf);
  771                     break;
  772                 default:
  773                     printf("        DEVICE CLASS: ");
  774                     dump_bytes(buf, buf[0]);
  775                 }
  776                 break;
  777             case USB_DT_OTG:
  778                 /* handled separately */
  779                 break;
  780             case USB_DT_INTERFACE_ASSOCIATION:
  781                 dump_association(dev, buf);
  782                 break;
  783             case USB_DT_SS_ENDPOINT_COMP:
  784                 printf("        bMaxBurst %15u\n", buf[2]);
  785                 /* Print bulk streams info or isoc "Mult" */
  786                 if ((endpoint->bmAttributes & 3) == 2 &&
  787                         (buf[3] & 0x1f))
  788                     printf("        MaxStreams %14u\n",
  789                             (unsigned) 1 << buf[3]);
  790                 if ((endpoint->bmAttributes & 3) == 1 &&
  791                         (buf[3] & 0x3))
  792                     printf("        Mult %20u\n",
  793                             buf[3] & 0x3);
  794                 break;
  795             default:
  796                 /* often a misplaced class descriptor */
  797                 printf("        ** UNRECOGNIZED: ");
  798                 dump_bytes(buf, buf[0]);
  799                 break;
  800             }
  801             size -= buf[0];
  802             buf += buf[0];
  803         }
  804     }
  805 }
  806 
  807 static void dump_unit(unsigned int data, unsigned int len)
  808 {
  809     char *systems[5] = { "None", "SI Linear", "SI Rotation",
  810             "English Linear", "English Rotation" };
  811 
  812     char *units[5][8] = {
  813         { "None", "None", "None", "None", "None",
  814                 "None", "None", "None" },
  815         { "None", "Centimeter", "Gram", "Seconds", "Kelvin",
  816                 "Ampere", "Candela", "None" },
  817         { "None", "Radians",    "Gram", "Seconds", "Kelvin",
  818                 "Ampere", "Candela", "None" },
  819         { "None", "Inch",       "Slug", "Seconds", "Fahrenheit",
  820                 "Ampere", "Candela", "None" },
  821         { "None", "Degrees",    "Slug", "Seconds", "Fahrenheit",
  822                 "Ampere", "Candela", "None" },
  823     };
  824 
  825     unsigned int i;
  826     unsigned int sys;
  827     int earlier_unit = 0;
  828 
  829     /* First nibble tells us which system we're in. */
  830     sys = data & 0xf;
  831     data >>= 4;
  832 
  833     if (sys > 4) {
  834         if (sys == 0xf)
  835             printf("System: Vendor defined, Unit: (unknown)\n");
  836         else
  837             printf("System: Reserved, Unit: (unknown)\n");
  838         return;
  839     } else {
  840         printf("System: %s, Unit: ", systems[sys]);
  841     }
  842     for (i = 1 ; i < len * 2 ; i++) {
  843         char nibble = data & 0xf;
  844         data >>= 4;
  845         if (nibble != 0) {
  846             if (earlier_unit++ > 0)
  847                 printf("*");
  848             printf("%s", units[sys][i]);
  849             if (nibble != 1) {
  850                 /* This is a _signed_ nibble(!) */
  851 
  852                 int val = nibble & 0x7;
  853                 if (nibble & 0x08)
  854                     val = -((0x7 & ~val) + 1);
  855                 printf("^%d", val);
  856             }
  857         }
  858     }
  859     if (earlier_unit == 0)
  860         printf("(None)");
  861     printf("\n");
  862 }
  863 
  864 /* ---------------------------------------------------------------------- */
  865 
  866 /*
  867  * Audio Class descriptor dump
  868  */
  869 
  870 static void dump_audio_subtype(libusb_device_handle *dev,
  871                                const char *name,
  872                                const struct desc * const desc[3],
  873                                const unsigned char *buf,
  874                                int protocol,
  875                                unsigned int indent)
  876 {
  877     static const char * const strings[] = { "UAC1", "UAC2", "UAC3" };
  878     unsigned int idx = 0;
  879 
  880     switch (protocol) {
  881     case USB_AUDIO_CLASS_2: idx = 1; break;
  882     case USB_AUDIO_CLASS_3: idx = 2; break;
  883     }
  884 
  885     printf("(%s)\n", name);
  886 
  887     if (desc[idx] == NULL) {
  888         printf("%*sWarning: %s descriptors are illegal for %s\n",
  889                indent * 2, "", name, strings[idx]);
  890         return;
  891     }
  892 
  893     /* Skip the first three bytes; those common fields have already
  894      * been dumped. */
  895     desc_dump(dev, desc[idx], buf + 3, buf[0] - 3, indent);
  896 }
  897 
  898 /* USB Audio Class subtypes */
  899 enum uac_interface_subtype {
  900     UAC_INTERFACE_SUBTYPE_AC_DESCRIPTOR_UNDEFINED = 0x00,
  901     UAC_INTERFACE_SUBTYPE_HEADER                  = 0x01,
  902     UAC_INTERFACE_SUBTYPE_INPUT_TERMINAL          = 0x02,
  903     UAC_INTERFACE_SUBTYPE_OUTPUT_TERMINAL         = 0x03,
  904     UAC_INTERFACE_SUBTYPE_EXTENDED_TERMINAL       = 0x04,
  905     UAC_INTERFACE_SUBTYPE_MIXER_UNIT              = 0x05,
  906     UAC_INTERFACE_SUBTYPE_SELECTOR_UNIT           = 0x06,
  907     UAC_INTERFACE_SUBTYPE_FEATURE_UNIT            = 0x07,
  908     UAC_INTERFACE_SUBTYPE_EFFECT_UNIT             = 0x08,
  909     UAC_INTERFACE_SUBTYPE_PROCESSING_UNIT         = 0x09,
  910     UAC_INTERFACE_SUBTYPE_EXTENSION_UNIT          = 0x0a,
  911     UAC_INTERFACE_SUBTYPE_CLOCK_SOURCE            = 0x0b,
  912     UAC_INTERFACE_SUBTYPE_CLOCK_SELECTOR          = 0x0c,
  913     UAC_INTERFACE_SUBTYPE_CLOCK_MULTIPLIER        = 0x0d,
  914     UAC_INTERFACE_SUBTYPE_SAMPLE_RATE_CONVERTER   = 0x0e,
  915     UAC_INTERFACE_SUBTYPE_CONNECTORS              = 0x0f,
  916     UAC_INTERFACE_SUBTYPE_POWER_DOMAIN            = 0x10,
  917 };
  918 
  919 /*
  920  * UAC1, UAC2, and UAC3 define bDescriptorSubtype differently for the
  921  * AudioControl interface, so we need to do some ugly remapping:
  922  *
  923  * val  | UAC1            | UAC2                  | UAC3
  924  * -----|-----------------|-----------------------|---------------------
  925  * 0x00 | AC UNDEFINED    | AC UNDEFINED          | AC UNDEFINED
  926  * 0x01 | HEADER          | HEADER                | HEADER
  927  * 0x02 | INPUT_TERMINAL  | INPUT_TERMINAL        | INPUT_TERMINAL
  928  * 0x03 | OUTPUT_TERMINAL | OUTPUT_TERMINAL       | OUTPUT_TERMINAL
  929  * 0x04 | MIXER_UNIT      | MIXER_UNIT            | EXTENDED_TERMINAL
  930  * 0x05 | SELECTOR_UNIT   | SELECTOR_UNIT         | MIXER_UNIT
  931  * 0x06 | FEATURE_UNIT    | FEATURE_UNIT          | SELECTOR_UNIT
  932  * 0x07 | PROCESSING_UNIT | EFFECT_UNIT           | FEATURE_UNIT
  933  * 0x08 | EXTENSION_UNIT  | PROCESSING_UNIT       | EFFECT_UNIT
  934  * 0x09 | -               | EXTENSION_UNIT        | PROCESSING_UNIT
  935  * 0x0a | -               | CLOCK_SOURCE          | EXTENSION_UNIT
  936  * 0x0b | -               | CLOCK_SELECTOR        | CLOCK_SOURCE
  937  * 0x0c | -               | CLOCK_MULTIPLIER      | CLOCK_SELECTOR
  938  * 0x0d | -               | SAMPLE_RATE_CONVERTER | CLOCK_MULTIPLIER
  939  * 0x0e | -               | -                     | SAMPLE_RATE_CONVERTER
  940  * 0x0f | -               | -                     | CONNECTORS
  941  * 0x10 | -               | -                     | POWER_DOMAIN
  942  */
  943 static enum uac_interface_subtype get_uac_interface_subtype(unsigned char c, int protocol)
  944 {
  945     switch (protocol) {
  946     case USB_AUDIO_CLASS_1:
  947         switch(c) {
  948         case 0x04: return UAC_INTERFACE_SUBTYPE_MIXER_UNIT;
  949         case 0x05: return UAC_INTERFACE_SUBTYPE_SELECTOR_UNIT;
  950         case 0x06: return UAC_INTERFACE_SUBTYPE_FEATURE_UNIT;
  951         case 0x07: return UAC_INTERFACE_SUBTYPE_PROCESSING_UNIT;
  952         case 0x08: return UAC_INTERFACE_SUBTYPE_EXTENSION_UNIT;
  953         }
  954         break;
  955     case USB_AUDIO_CLASS_2:
  956         switch(c) {
  957         case 0x04: return UAC_INTERFACE_SUBTYPE_MIXER_UNIT;
  958         case 0x05: return UAC_INTERFACE_SUBTYPE_SELECTOR_UNIT;
  959         case 0x06: return UAC_INTERFACE_SUBTYPE_FEATURE_UNIT;
  960         case 0x07: return UAC_INTERFACE_SUBTYPE_EFFECT_UNIT;
  961         case 0x08: return UAC_INTERFACE_SUBTYPE_PROCESSING_UNIT;
  962         case 0x09: return UAC_INTERFACE_SUBTYPE_EXTENSION_UNIT;
  963         case 0x0a: return UAC_INTERFACE_SUBTYPE_CLOCK_SOURCE;
  964         case 0x0b: return UAC_INTERFACE_SUBTYPE_CLOCK_SELECTOR;
  965         case 0x0c: return UAC_INTERFACE_SUBTYPE_CLOCK_MULTIPLIER;
  966         case 0x0d: return UAC_INTERFACE_SUBTYPE_SAMPLE_RATE_CONVERTER;
  967         }
  968         break;
  969     case USB_AUDIO_CLASS_3:
  970         /* No mapping required. */
  971         break;
  972     default:
  973         /* Unknown protocol */
  974         break;
  975     }
  976 
  977     /* If the protocol was unknown, or the value was not known to require
  978      * mapping, just return it unchanged. */
  979     return c;
  980 }
  981 
  982 static void dump_audiocontrol_interface(libusb_device_handle *dev, const unsigned char *buf, int protocol)
  983 {
  984     enum uac_interface_subtype subtype;
  985 
  986     if (buf[1] != USB_DT_CS_INTERFACE)
  987         printf("      Warning: Invalid descriptor\n");
  988     else if (buf[0] < 3)
  989         printf("      Warning: Descriptor too short\n");
  990     printf("      AudioControl Interface Descriptor:\n"
  991            "        bLength             %5u\n"
  992            "        bDescriptorType     %5u\n"
  993            "        bDescriptorSubtype  %5u ",
  994            buf[0], buf[1], buf[2]);
  995 
  996     subtype = get_uac_interface_subtype(buf[2], protocol);
  997 
  998     switch (subtype) {
  999     case UAC_INTERFACE_SUBTYPE_HEADER:
 1000         dump_audio_subtype(dev, "HEADER", desc_audio_ac_header, buf, protocol, 4);
 1001         break;
 1002 
 1003     case UAC_INTERFACE_SUBTYPE_INPUT_TERMINAL:
 1004         dump_audio_subtype(dev, "INPUT_TERMINAL", desc_audio_ac_input_terminal, buf, protocol, 4);
 1005         break;
 1006 
 1007     case UAC_INTERFACE_SUBTYPE_OUTPUT_TERMINAL:
 1008         dump_audio_subtype(dev, "OUTPUT_TERMINAL", desc_audio_ac_output_terminal, buf, protocol, 4);
 1009         break;
 1010 
 1011     case UAC_INTERFACE_SUBTYPE_MIXER_UNIT:
 1012         dump_audio_subtype(dev, "MIXER_UNIT", desc_audio_ac_mixer_unit, buf, protocol, 4);
 1013         break;
 1014 
 1015     case UAC_INTERFACE_SUBTYPE_SELECTOR_UNIT:
 1016         dump_audio_subtype(dev, "SELECTOR_UNIT", desc_audio_ac_selector_unit, buf, protocol, 4);
 1017         break;
 1018 
 1019     case UAC_INTERFACE_SUBTYPE_FEATURE_UNIT:
 1020         dump_audio_subtype(dev, "FEATURE_UNIT", desc_audio_ac_feature_unit, buf, protocol, 4);
 1021         break;
 1022 
 1023     case UAC_INTERFACE_SUBTYPE_PROCESSING_UNIT:
 1024         dump_audio_subtype(dev, "PROCESSING_UNIT", desc_audio_ac_processing_unit, buf, protocol, 4);
 1025         break;
 1026 
 1027     case UAC_INTERFACE_SUBTYPE_EXTENSION_UNIT:
 1028         dump_audio_subtype(dev, "EXTENSION_UNIT", desc_audio_ac_extension_unit, buf, protocol, 4);
 1029         break;
 1030 
 1031     case UAC_INTERFACE_SUBTYPE_CLOCK_SOURCE:
 1032         dump_audio_subtype(dev, "CLOCK_SOURCE", desc_audio_ac_clock_source, buf, protocol, 4);
 1033         break;
 1034 
 1035     case UAC_INTERFACE_SUBTYPE_CLOCK_SELECTOR:
 1036         dump_audio_subtype(dev, "CLOCK_SELECTOR", desc_audio_ac_clock_selector, buf, protocol, 4);
 1037         break;
 1038 
 1039     case UAC_INTERFACE_SUBTYPE_CLOCK_MULTIPLIER:
 1040         dump_audio_subtype(dev, "CLOCK_MULTIPLIER", desc_audio_ac_clock_multiplier, buf, protocol, 4);
 1041         break;
 1042 
 1043     case UAC_INTERFACE_SUBTYPE_SAMPLE_RATE_CONVERTER:
 1044         dump_audio_subtype(dev, "SAMPLING_RATE_CONVERTER", desc_audio_ac_clock_multiplier, buf, protocol, 4);
 1045         break;
 1046 
 1047     case UAC_INTERFACE_SUBTYPE_EFFECT_UNIT:
 1048         dump_audio_subtype(dev, "EFFECT_UNIT", desc_audio_ac_effect_unit, buf, protocol, 4);
 1049         break;
 1050 
 1051     case UAC_INTERFACE_SUBTYPE_POWER_DOMAIN:
 1052         dump_audio_subtype(dev, "POWER_DOMAIN", desc_audio_ac_power_domain, buf, protocol, 4);
 1053         break;
 1054 
 1055     default:
 1056         printf("(unknown)\n"
 1057                "        Invalid desc subtype:");
 1058         dump_bytes(buf+3, buf[0]-3);
 1059         break;
 1060     }
 1061 }
 1062 
 1063 
 1064 static void dump_audiostreaming_interface(libusb_device_handle *dev, const unsigned char *buf, int protocol)
 1065 {
 1066     static const char * const fmtItag[] = {
 1067         "TYPE_I_UNDEFINED", "PCM", "PCM8", "IEEE_FLOAT", "ALAW", "MULAW" };
 1068     static const char * const fmtIItag[] = { "TYPE_II_UNDEFINED", "MPEG", "AC-3" };
 1069     static const char * const fmtIIItag[] = {
 1070         "TYPE_III_UNDEFINED", "IEC1937_AC-3", "IEC1937_MPEG-1_Layer1",
 1071         "IEC1937_MPEG-Layer2/3/NOEXT", "IEC1937_MPEG-2_EXT",
 1072         "IEC1937_MPEG-2_Layer1_LS", "IEC1937_MPEG-2_Layer2/3_LS" };
 1073     unsigned int i, j, fmttag;
 1074     const char *fmtptr = "undefined";
 1075 
 1076     if (buf[1] != USB_DT_CS_INTERFACE)
 1077         printf("      Warning: Invalid descriptor\n");
 1078     else if (buf[0] < 3)
 1079         printf("      Warning: Descriptor too short\n");
 1080     printf("      AudioStreaming Interface Descriptor:\n"
 1081            "        bLength             %5u\n"
 1082            "        bDescriptorType     %5u\n"
 1083            "        bDescriptorSubtype  %5u ",
 1084            buf[0], buf[1], buf[2]);
 1085     switch (buf[2]) {
 1086     case 0x01: /* AS_GENERAL */
 1087         dump_audio_subtype(dev, "AS_GENERAL", desc_audio_as_interface, buf, protocol, 4);
 1088         break;
 1089 
 1090     case 0x02: /* FORMAT_TYPE */
 1091         printf("(FORMAT_TYPE)\n");
 1092         switch (protocol) {
 1093         case USB_AUDIO_CLASS_1:
 1094             if (buf[0] < 8)
 1095                 printf("      Warning: Descriptor too short\n");
 1096             printf("        bFormatType         %5u ", buf[3]);
 1097             switch (buf[3]) {
 1098             case 0x01: /* FORMAT_TYPE_I */
 1099                 printf("(FORMAT_TYPE_I)\n");
 1100                 j = buf[7] ? (buf[7]*3+8) : 14;
 1101                 if (buf[0] < j)
 1102                     printf("      Warning: Descriptor too short\n");
 1103                 printf("        bNrChannels         %5u\n"
 1104                        "        bSubframeSize       %5u\n"
 1105                        "        bBitResolution      %5u\n"
 1106                        "        bSamFreqType        %5u %s\n",
 1107                        buf[4], buf[5], buf[6], buf[7], buf[7] ? "Discrete" : "Continuous");
 1108                 if (!buf[7])
 1109                     printf("        tLowerSamFreq     %7u\n"
 1110                            "        tUpperSamFreq     %7u\n",
 1111                            buf[8] | (buf[9] << 8) | (buf[10] << 16), buf[11] | (buf[12] << 8) | (buf[13] << 16));
 1112                 else
 1113                     for (i = 0; i < buf[7]; i++)
 1114                         printf("        tSamFreq[%2u]      %7u\n", i,
 1115                                buf[8+3*i] | (buf[9+3*i] << 8) | (buf[10+3*i] << 16));
 1116                 dump_junk(buf, "        ", j);
 1117                 break;
 1118 
 1119             case 0x02: /* FORMAT_TYPE_II */
 1120                 printf("(FORMAT_TYPE_II)\n");
 1121                 j = buf[8] ? (buf[7]*3+9) : 15;
 1122                 if (buf[0] < j)
 1123                     printf("      Warning: Descriptor too short\n");
 1124                 printf("        wMaxBitRate         %5u\n"
 1125                        "        wSamplesPerFrame    %5u\n"
 1126                        "        bSamFreqType        %5u %s\n",
 1127                        buf[4] | (buf[5] << 8), buf[6] | (buf[7] << 8), buf[8], buf[8] ? "Discrete" : "Continuous");
 1128                 if (!buf[8])
 1129                     printf("        tLowerSamFreq     %7u\n"
 1130                            "        tUpperSamFreq     %7u\n",
 1131                            buf[9] | (buf[10] << 8) | (buf[11] << 16), buf[12] | (buf[13] << 8) | (buf[14] << 16));
 1132                 else
 1133                     for (i = 0; i < buf[8]; i++)
 1134                         printf("        tSamFreq[%2u]      %7u\n", i,
 1135                                buf[9+3*i] | (buf[10+3*i] << 8) | (buf[11+3*i] << 16));
 1136                 dump_junk(buf, "        ", j);
 1137                 break;
 1138 
 1139             case 0x03: /* FORMAT_TYPE_III */
 1140                 printf("(FORMAT_TYPE_III)\n");
 1141                 j = buf[7] ? (buf[7]*3+8) : 14;
 1142                 if (buf[0] < j)
 1143                     printf("      Warning: Descriptor too short\n");
 1144                 printf("        bNrChannels         %5u\n"
 1145                        "        bSubframeSize       %5u\n"
 1146                        "        bBitResolution      %5u\n"
 1147                        "        bSamFreqType        %5u %s\n",
 1148                        buf[4], buf[5], buf[6], buf[7], buf[7] ? "Discrete" : "Continuous");
 1149                 if (!buf[7])
 1150                     printf("        tLowerSamFreq     %7u\n"
 1151                            "        tUpperSamFreq     %7u\n",
 1152                            buf[8] | (buf[9] << 8) | (buf[10] << 16), buf[11] | (buf[12] << 8) | (buf[13] << 16));
 1153                 else
 1154                     for (i = 0; i < buf[7]; i++)
 1155                         printf("        tSamFreq[%2u]      %7u\n", i,
 1156                                buf[8+3*i] | (buf[9+3*i] << 8) | (buf[10+3*i] << 16));
 1157                 dump_junk(buf, "        ", j);
 1158                 break;
 1159 
 1160             default:
 1161                 printf("(unknown)\n"
 1162                        "        Invalid desc format type:");
 1163                 dump_bytes(buf+4, buf[0]-4);
 1164             }
 1165 
 1166             break;
 1167 
 1168         case USB_AUDIO_CLASS_2:
 1169             printf("        bFormatType         %5u ", buf[3]);
 1170             switch (buf[3]) {
 1171             case 0x01: /* FORMAT_TYPE_I */
 1172                 printf("(FORMAT_TYPE_I)\n");
 1173                 if (buf[0] < 6)
 1174                     printf("      Warning: Descriptor too short\n");
 1175                 printf("        bSubslotSize        %5u\n"
 1176                        "        bBitResolution      %5u\n",
 1177                        buf[4], buf[5]);
 1178                 dump_junk(buf, "        ", 6);
 1179                 break;
 1180 
 1181             case 0x02: /* FORMAT_TYPE_II */
 1182                 printf("(FORMAT_TYPE_II)\n");
 1183                 if (buf[0] < 8)
 1184                     printf("      Warning: Descriptor too short\n");
 1185                 printf("        wMaxBitRate         %5u\n"
 1186                        "        wSlotsPerFrame      %5u\n",
 1187                        buf[4] | (buf[5] << 8),
 1188                        buf[6] | (buf[7] << 8));
 1189                 dump_junk(buf, "        ", 8);
 1190                 break;
 1191 
 1192             case 0x03: /* FORMAT_TYPE_III */
 1193                 printf("(FORMAT_TYPE_III)\n");
 1194                 if (buf[0] < 6)
 1195                     printf("      Warning: Descriptor too short\n");
 1196                 printf("        bSubslotSize        %5u\n"
 1197                        "        bBitResolution      %5u\n",
 1198                        buf[4], buf[5]);
 1199                 dump_junk(buf, "        ", 6);
 1200                 break;
 1201 
 1202             case 0x04: /* FORMAT_TYPE_IV */
 1203                 printf("(FORMAT_TYPE_IV)\n");
 1204                 if (buf[0] < 4)
 1205                     printf("      Warning: Descriptor too short\n");
 1206                 printf("        bFormatType         %5u\n", buf[3]);
 1207                 dump_junk(buf, "        ", 4);
 1208                 break;
 1209 
 1210             default:
 1211                 printf("(unknown)\n"
 1212                        "        Invalid desc format type:");
 1213                 dump_bytes(buf+4, buf[0]-4);
 1214             }
 1215 
 1216             break;
 1217         } /* switch (protocol) */
 1218 
 1219         break;
 1220 
 1221     case 0x03: /* FORMAT_SPECIFIC */
 1222         printf("(FORMAT_SPECIFIC)\n");
 1223         if (buf[0] < 5)
 1224             printf("      Warning: Descriptor too short\n");
 1225         fmttag = buf[3] | (buf[4] << 8);
 1226         if (fmttag <= 5)
 1227             fmtptr = fmtItag[fmttag];
 1228         else if (fmttag >= 0x1000 && fmttag <= 0x1002)
 1229             fmtptr = fmtIItag[fmttag & 0xfff];
 1230         else if (fmttag >= 0x2000 && fmttag <= 0x2006)
 1231             fmtptr = fmtIIItag[fmttag & 0xfff];
 1232         printf("        wFormatTag          %5u %s\n", fmttag, fmtptr);
 1233         switch (fmttag) {
 1234         case 0x1001: /* MPEG */
 1235             if (buf[0] < 8)
 1236                 printf("      Warning: Descriptor too short\n");
 1237             printf("        bmMPEGCapabilities 0x%04x\n",
 1238                    buf[5] | (buf[6] << 8));
 1239             if (buf[5] & 0x01)
 1240                 printf("          Layer I\n");
 1241             if (buf[5] & 0x02)
 1242                 printf("          Layer II\n");
 1243             if (buf[5] & 0x04)
 1244                 printf("          Layer III\n");
 1245             if (buf[5] & 0x08)
 1246                 printf("          MPEG-1 only\n");
 1247             if (buf[5] & 0x10)
 1248                 printf("          MPEG-1 dual-channel\n");
 1249             if (buf[5] & 0x20)
 1250                 printf("          MPEG-2 second stereo\n");
 1251             if (buf[5] & 0x40)
 1252                 printf("          MPEG-2 7.1 channel augmentation\n");
 1253             if (buf[5] & 0x80)
 1254                 printf("          Adaptive multi-channel prediction\n");
 1255             printf("          MPEG-2 multilingual support: ");
 1256             switch (buf[6] & 3) {
 1257             case 0:
 1258                 printf("Not supported\n");
 1259                 break;
 1260 
 1261             case 1:
 1262                 printf("Supported at Fs\n");
 1263                 break;
 1264 
 1265             case 2:
 1266                 printf("Reserved\n");
 1267                 break;
 1268 
 1269             default:
 1270                 printf("Supported at Fs and 1/2Fs\n");
 1271                 break;
 1272             }
 1273             printf("        bmMPEGFeatures       0x%02x\n", buf[7]);
 1274             printf("          Internal Dynamic Range Control: ");
 1275             switch ((buf[7] >> 4) & 3) {
 1276             case 0:
 1277                 printf("not supported\n");
 1278                 break;
 1279 
 1280             case 1:
 1281                 printf("supported but not scalable\n");
 1282                 break;
 1283 
 1284             case 2:
 1285                 printf("scalable, common boost and cut scaling value\n");
 1286                 break;
 1287 
 1288             default:
 1289                 printf("scalable, separate boost and cut scaling value\n");
 1290                 break;
 1291             }
 1292             dump_junk(buf, "        ", 8);
 1293             break;
 1294 
 1295         case 0x1002: /* AC-3 */
 1296             if (buf[0] < 10)
 1297                 printf("      Warning: Descriptor too short\n");
 1298             printf("        bmBSID         0x%08x\n"
 1299                    "        bmAC3Features        0x%02x\n",
 1300                    buf[5] | (buf[6] << 8) | (buf[7] << 16) | (buf[8] << 24), buf[9]);
 1301             if (buf[9] & 0x01)
 1302                 printf("          RF mode\n");
 1303             if (buf[9] & 0x02)
 1304                 printf("          Line mode\n");
 1305             if (buf[9] & 0x04)
 1306                 printf("          Custom0 mode\n");
 1307             if (buf[9] & 0x08)
 1308                 printf("          Custom1 mode\n");
 1309             printf("          Internal Dynamic Range Control: ");
 1310             switch ((buf[9] >> 4) & 3) {
 1311             case 0:
 1312                 printf("not supported\n");
 1313                 break;
 1314 
 1315             case 1:
 1316                 printf("supported but not scalable\n");
 1317                 break;
 1318 
 1319             case 2:
 1320                 printf("scalable, common boost and cut scaling value\n");
 1321                 break;
 1322 
 1323             default:
 1324                 printf("scalable, separate boost and cut scaling value\n");
 1325                 break;
 1326             }
 1327             dump_junk(buf, "        ", 8);
 1328             break;
 1329 
 1330         default:
 1331             printf("(unknown)\n"
 1332                    "        Invalid desc format type:");
 1333             dump_bytes(buf+4, buf[0]-4);
 1334         }
 1335         break;
 1336 
 1337     default:
 1338         printf("        Invalid desc subtype:");
 1339         dump_bytes(buf+3, buf[0]-3);
 1340         break;
 1341     }
 1342 }
 1343 
 1344 static void dump_audiostreaming_endpoint(libusb_device_handle *dev, const unsigned char *buf, int protocol)
 1345 {
 1346     static const char * const subtype[] = { "invalid", "EP_GENERAL" };
 1347 
 1348     if (buf[1] != USB_DT_CS_ENDPOINT)
 1349         printf("      Warning: Invalid descriptor\n");
 1350 
 1351     printf("        AudioStreaming Endpoint Descriptor:\n"
 1352            "          bLength             %5u\n"
 1353            "          bDescriptorType     %5u\n"
 1354            "          bDescriptorSubtype  %5u ",
 1355            buf[0], buf[1], buf[2]);
 1356 
 1357     dump_audio_subtype(dev, subtype[buf[2] == 1],
 1358             desc_audio_as_isochronous_audio_data_endpoint, buf, protocol, 5);
 1359 }
 1360 
 1361 static void dump_midistreaming_interface(libusb_device_handle *dev, const unsigned char *buf)
 1362 {
 1363     static const char * const jacktypes[] = {"Undefined", "Embedded", "External"};
 1364     char *jackstr = NULL;
 1365     unsigned int j, tlength, capssize;
 1366     unsigned long caps;
 1367 
 1368     if (buf[1] != USB_DT_CS_INTERFACE)
 1369         printf("      Warning: Invalid descriptor\n");
 1370     else if (buf[0] < 3)
 1371         printf("      Warning: Descriptor too short\n");
 1372     printf("      MIDIStreaming Interface Descriptor:\n"
 1373            "        bLength             %5u\n"
 1374            "        bDescriptorType     %5u\n"
 1375            "        bDescriptorSubtype  %5u ",
 1376            buf[0], buf[1], buf[2]);
 1377     switch (buf[2]) {
 1378     case 0x01:
 1379         printf("(HEADER)\n");
 1380         if (buf[0] < 7)
 1381             printf("      Warning: Descriptor too short\n");
 1382         tlength = buf[5] | (buf[6] << 8);
 1383         printf("        bcdADC              %2x.%02x\n"
 1384                "        wTotalLength       0x%04x\n",
 1385                buf[4], buf[3], tlength);
 1386         dump_junk(buf, "        ", 7);
 1387         break;
 1388 
 1389     case 0x02:
 1390         printf("(MIDI_IN_JACK)\n");
 1391         if (buf[0] < 6)
 1392             printf("      Warning: Descriptor too short\n");
 1393         jackstr = get_dev_string(dev, buf[5]);
 1394         printf("        bJackType           %5u %s\n"
 1395                "        bJackID             %5u\n"
 1396                "        iJack               %5u %s\n",
 1397                buf[3], buf[3] < 3 ? jacktypes[buf[3]] : "Invalid",
 1398                buf[4], buf[5], jackstr);
 1399         dump_junk(buf, "        ", 6);
 1400         break;
 1401 
 1402     case 0x03:
 1403         printf("(MIDI_OUT_JACK)\n");
 1404         if (buf[0] < 9)
 1405             printf("      Warning: Descriptor too short\n");
 1406         printf("        bJackType           %5u %s\n"
 1407                "        bJackID             %5u\n"
 1408                "        bNrInputPins        %5u\n",
 1409                buf[3], buf[3] < 3 ? jacktypes[buf[3]] : "Invalid",
 1410                buf[4], buf[5]);
 1411         for (j = 0; j < buf[5]; j++) {
 1412             printf("        baSourceID(%2u)      %5u\n"
 1413                    "        BaSourcePin(%2u)     %5u\n",
 1414                    j, buf[2*j+6], j, buf[2*j+7]);
 1415         }
 1416         j = 6+buf[5]*2; /* midi10.pdf says, incorrectly: 5+2*p */
 1417         jackstr = get_dev_string(dev, buf[j]);
 1418         printf("        iJack               %5u %s\n",
 1419                buf[j], jackstr);
 1420         dump_junk(buf, "        ", j+1);
 1421         break;
 1422 
 1423     case 0x04:
 1424         printf("(ELEMENT)\n");
 1425         if (buf[0] < 12)
 1426             printf("      Warning: Descriptor too short\n");
 1427         printf("        bElementID          %5u\n"
 1428                "        bNrInputPins        %5u\n",
 1429                buf[3], buf[4]);
 1430         for (j = 0; j < buf[4]; j++) {
 1431             printf("        baSourceID(%2u)      %5u\n"
 1432                    "        BaSourcePin(%2u)     %5u\n",
 1433                    j, buf[2*j+5], j, buf[2*j+6]);
 1434         }
 1435         j = 5+buf[4]*2;
 1436         printf("        bNrOutputPins       %5u\n"
 1437                "        bInTerminalLink     %5u\n"
 1438                "        bOutTerminalLink    %5u\n"
 1439                "        bElCapsSize         %5u\n",
 1440                buf[j], buf[j+1], buf[j+2], buf[j+3]);
 1441         capssize = buf[j+3];
 1442         caps = 0;
 1443         for (j = 0; j < capssize; j++)
 1444             caps |= (buf[j+9+buf[4]*2] << (8*j));
 1445         printf("        bmElementCaps  0x%08lx\n", caps);
 1446         if (caps & 0x01)
 1447             printf("          Undefined\n");
 1448         if (caps & 0x02)
 1449             printf("          MIDI Clock\n");
 1450         if (caps & 0x04)
 1451             printf("          MTC (MIDI Time Code)\n");
 1452         if (caps & 0x08)
 1453             printf("          MMC (MIDI Machine Control)\n");
 1454         if (caps & 0x10)
 1455             printf("          GM1 (General MIDI v.1)\n");
 1456         if (caps & 0x20)
 1457             printf("          GM2 (General MIDI v.2)\n");
 1458         if (caps & 0x40)
 1459             printf("          GS MIDI Extension\n");
 1460         if (caps & 0x80)
 1461             printf("          XG MIDI Extension\n");
 1462         if (caps & 0x100)
 1463             printf("          EFX\n");
 1464         if (caps & 0x200)
 1465             printf("          MIDI Patch Bay\n");
 1466         if (caps & 0x400)
 1467             printf("          DLS1 (Downloadable Sounds Level 1)\n");
 1468         if (caps & 0x800)
 1469             printf("          DLS2 (Downloadable Sounds Level 2)\n");
 1470         j = 9+2*buf[4]+capssize;
 1471         jackstr = get_dev_string(dev, buf[j]);
 1472         printf("        iElement            %5u %s\n", buf[j], jackstr);
 1473         dump_junk(buf, "        ", j+1);
 1474         break;
 1475 
 1476     default:
 1477         printf("\n        Invalid desc subtype: ");
 1478         dump_bytes(buf+3, buf[0]-3);
 1479         break;
 1480     }
 1481 
 1482     free(jackstr);
 1483 }
 1484 
 1485 static void dump_midistreaming_endpoint(const unsigned char *buf)
 1486 {
 1487     unsigned int j;
 1488 
 1489     if (buf[1] != USB_DT_CS_ENDPOINT)
 1490         printf("      Warning: Invalid descriptor\n");
 1491     else if (buf[0] < 5)
 1492         printf("      Warning: Descriptor too short\n");
 1493     printf("        MIDIStreaming Endpoint Descriptor:\n"
 1494            "          bLength             %5u\n"
 1495            "          bDescriptorType     %5u\n"
 1496            "          bDescriptorSubtype  %5u (%s)\n"
 1497            "          bNumEmbMIDIJack     %5u\n",
 1498            buf[0], buf[1], buf[2], buf[2] == 1 ? "GENERAL" : "Invalid", buf[3]);
 1499     for (j = 0; j < buf[3]; j++)
 1500         printf("          baAssocJackID(%2u)   %5u\n", j, buf[4+j]);
 1501     dump_junk(buf, "          ", 4+buf[3]);
 1502 }
 1503 
 1504 /*
 1505  * Video Class descriptor dump
 1506  */
 1507 
 1508 static void dump_videocontrol_interface(libusb_device_handle *dev, const unsigned char *buf, int protocol)
 1509 {
 1510     static const char * const ctrlnames[] = {
 1511         "Brightness", "Contrast", "Hue", "Saturation", "Sharpness", "Gamma",
 1512         "White Balance Temperature", "White Balance Component", "Backlight Compensation",
 1513         "Gain", "Power Line Frequency", "Hue, Auto", "White Balance Temperature, Auto",
 1514         "White Balance Component, Auto", "Digital Multiplier", "Digital Multiplier Limit",
 1515         "Analog Video Standard", "Analog Video Lock Status", "Contrast, Auto"
 1516     };
 1517     static const char * const camctrlnames[] = {
 1518         "Scanning Mode", "Auto-Exposure Mode", "Auto-Exposure Priority",
 1519         "Exposure Time (Absolute)", "Exposure Time (Relative)", "Focus (Absolute)",
 1520         "Focus (Relative)", "Iris (Absolute)", "Iris (Relative)", "Zoom (Absolute)",
 1521         "Zoom (Relative)", "PanTilt (Absolute)", "PanTilt (Relative)",
 1522         "Roll (Absolute)", "Roll (Relative)", "Reserved", "Reserved", "Focus, Auto",
 1523         "Privacy", "Focus, Simple", "Window", "Region of Interest"
 1524     };
 1525     static const char * const enctrlnames[] = {
 1526         "Select Layer", "Profile and Toolset", "Video Resolution", "Minimum Frame Interval",
 1527         "Slice Mode", "Rate Control Mode", "Average Bit Rate", "CPB Size", "Peak Bit Rate",
 1528         "Quantization Parameter", "Synchronization and Long-Term Reference Frame",
 1529         "Long-Term Buffer", "Picture Long-Term Reference", "LTR Validation",
 1530         "Level IDC", "SEI Message", "QP Range", "Priority ID", "Start or Stop Layer/View",
 1531         "Error Resiliency"
 1532     };
 1533     static const char * const stdnames[] = {
 1534         "None", "NTSC - 525/60", "PAL - 625/50", "SECAM - 625/50",
 1535         "NTSC - 625/50", "PAL - 525/60" };
 1536     unsigned int i, ctrls, stds, n, p, termt, freq;
 1537     char *term = NULL, termts[128];
 1538 
 1539     if (buf[1] != USB_DT_CS_INTERFACE)
 1540         printf("      Warning: Invalid descriptor\n");
 1541     else if (buf[0] < 3)
 1542         printf("      Warning: Descriptor too short\n");
 1543     printf("      VideoControl Interface Descriptor:\n"
 1544            "        bLength             %5u\n"
 1545            "        bDescriptorType     %5u\n"
 1546            "        bDescriptorSubtype  %5u ",
 1547            buf[0], buf[1], buf[2]);
 1548     switch (buf[2]) {
 1549     case 0x01:  /* HEADER */
 1550         printf("(HEADER)\n");
 1551         n = buf[11];
 1552         if (buf[0] < 12+n)
 1553             printf("      Warning: Descriptor too short\n");
 1554         freq = buf[7] | (buf[8] << 8) | (buf[9] << 16) | (buf[10] << 24);
 1555         printf("        bcdUVC              %2x.%02x\n"
 1556                "        wTotalLength       0x%04x\n"
 1557                "        dwClockFrequency    %5u.%06uMHz\n"
 1558                "        bInCollection       %5u\n",
 1559                buf[4], buf[3], buf[5] | (buf[6] << 8), freq / 1000000,
 1560                freq % 1000000, n);
 1561         for (i = 0; i < n; i++)
 1562             printf("        baInterfaceNr(%2u)   %5u\n", i, buf[12+i]);
 1563         dump_junk(buf, "        ", 12+n);
 1564         break;
 1565 
 1566     case 0x02:  /* INPUT_TERMINAL */
 1567         printf("(INPUT_TERMINAL)\n");
 1568         term = get_dev_string(dev, buf[7]);
 1569         termt = buf[4] | (buf[5] << 8);
 1570         n = termt == 0x0201 ? 7 : 0;
 1571         get_videoterminal_string(termts, sizeof(termts), termt);
 1572         if (buf[0] < 8 + n)
 1573             printf("      Warning: Descriptor too short\n");
 1574         printf("        bTerminalID         %5u\n"
 1575                "        wTerminalType      0x%04x %s\n"
 1576                "        bAssocTerminal      %5u\n",
 1577                buf[3], termt, termts, buf[6]);
 1578         printf("        iTerminal           %5u %s\n",
 1579                buf[7], term);
 1580         if (termt == 0x0201) {
 1581             n += buf[14];
 1582             printf("        wObjectiveFocalLengthMin  %5u\n"
 1583                    "        wObjectiveFocalLengthMax  %5u\n"
 1584                    "        wOcularFocalLength        %5u\n"
 1585                    "        bControlSize              %5u\n",
 1586                    buf[8] | (buf[9] << 8), buf[10] | (buf[11] << 8),
 1587                    buf[12] | (buf[13] << 8), buf[14]);
 1588             ctrls = 0;
 1589             for (i = 0; i < 3 && i < buf[14]; i++)
 1590                 ctrls = (ctrls << 8) | buf[8+n-i-1];
 1591             printf("        bmControls           0x%08x\n", ctrls);
 1592             if (protocol == USB_VIDEO_PROTOCOL_15) {
 1593                 for (i = 0; i < 22; i++)
 1594                     if ((ctrls >> i) & 1)
 1595                         printf("          %s\n", camctrlnames[i]);
 1596             }
 1597             else {
 1598                 for (i = 0; i < 19; i++)
 1599                     if ((ctrls >> i) & 1)
 1600                         printf("          %s\n", camctrlnames[i]);
 1601             }
 1602         }
 1603         dump_junk(buf, "        ", 8+n);
 1604         break;
 1605 
 1606     case 0x03:  /* OUTPUT_TERMINAL */
 1607         printf("(OUTPUT_TERMINAL)\n");
 1608         term = get_dev_string(dev, buf[8]);
 1609         termt = buf[4] | (buf[5] << 8);
 1610         get_videoterminal_string(termts, sizeof(termts), termt);
 1611         if (buf[0] < 9)
 1612             printf("      Warning: Descriptor too short\n");
 1613         printf("        bTerminalID         %5u\n"
 1614                "        wTerminalType      0x%04x %s\n"
 1615                "        bAssocTerminal      %5u\n"
 1616                "        bSourceID           %5u\n"
 1617                "        iTerminal           %5u %s\n",
 1618                buf[3], termt, termts, buf[6], buf[7], buf[8], term);
 1619         dump_junk(buf, "        ", 9);
 1620         break;
 1621 
 1622     case 0x04:  /* SELECTOR_UNIT */
 1623         printf("(SELECTOR_UNIT)\n");
 1624         p = buf[4];
 1625         if (buf[0] < 6+p)
 1626             printf("      Warning: Descriptor too short\n");
 1627         term = get_dev_string(dev, buf[5+p]);
 1628 
 1629         printf("        bUnitID             %5u\n"
 1630                "        bNrInPins           %5u\n",
 1631                buf[3], p);
 1632         for (i = 0; i < p; i++)
 1633             printf("        baSource(%2u)        %5u\n", i, buf[5+i]);
 1634         printf("        iSelector           %5u %s\n",
 1635                buf[5+p], term);
 1636         dump_junk(buf, "        ", 6+p);
 1637         break;
 1638 
 1639     case 0x05:  /* PROCESSING_UNIT */
 1640         printf("(PROCESSING_UNIT)\n");
 1641         n = buf[7];
 1642         term = get_dev_string(dev, buf[8+n]);
 1643         if (buf[0] < 10+n)
 1644             printf("      Warning: Descriptor too short\n");
 1645         printf("        bUnitID             %5u\n"
 1646                "        bSourceID           %5u\n"
 1647                "        wMaxMultiplier      %5u\n"
 1648                "        bControlSize        %5u\n",
 1649                buf[3], buf[4], buf[5] | (buf[6] << 8), n);
 1650         ctrls = 0;
 1651         for (i = 0; i < 3 && i < n; i++)
 1652             ctrls = (ctrls << 8) | buf[8+n-i-1];
 1653         printf("        bmControls     0x%08x\n", ctrls);
 1654         if (protocol == USB_VIDEO_PROTOCOL_15) {
 1655             for (i = 0; i < 19; i++)
 1656                 if ((ctrls >> i) & 1)
 1657                     printf("          %s\n", ctrlnames[i]);
 1658         }
 1659         else {
 1660             for (i = 0; i < 18; i++)
 1661                 if ((ctrls >> i) & 1)
 1662                     printf("          %s\n", ctrlnames[i]);
 1663         }
 1664         stds = buf[9+n];
 1665         printf("        iProcessing         %5u %s\n"
 1666                "        bmVideoStandards     0x%02x\n", buf[8+n], term, stds);
 1667         for (i = 0; i < 6; i++)
 1668             if ((stds >> i) & 1)
 1669                 printf("          %s\n", stdnames[i]);
 1670         break;
 1671 
 1672     case 0x06:  /* EXTENSION_UNIT */
 1673         printf("(EXTENSION_UNIT)\n");
 1674         p = buf[21];
 1675         n = buf[22+p];
 1676         term = get_dev_string(dev, buf[23+p+n]);
 1677         if (buf[0] < 24+p+n)
 1678             printf("      Warning: Descriptor too short\n");
 1679         printf("        bUnitID             %5u\n"
 1680                "        guidExtensionCode         %s\n"
 1681                "        bNumControls        %5u\n"
 1682                "        bNrInPins           %5u\n",
 1683                buf[3], get_guid(&buf[4]), buf[20], buf[21]);
 1684         for (i = 0; i < p; i++)
 1685             printf("        baSourceID(%2u)      %5u\n", i, buf[22+i]);
 1686         printf("        bControlSize        %5u\n", buf[22+p]);
 1687         for (i = 0; i < n; i++)
 1688             printf("        bmControls(%2u)       0x%02x\n", i, buf[23+p+i]);
 1689         printf("        iExtension          %5u %s\n",
 1690                buf[23+p+n], term);
 1691         dump_junk(buf, "        ", 24+p+n);
 1692         break;
 1693 
 1694     case 0x07: /* ENCODING UNIT */
 1695         printf("(ENCODING UNIT)\n");
 1696         term = get_dev_string(dev, buf[5]);
 1697         if (buf[0] < 13)
 1698             printf("      Warning: Descriptor too short\n");
 1699         printf("        bUnitID             %5u\n"
 1700                "        bSourceID           %5u\n"
 1701                "        iEncoding           %5u %s\n"
 1702                "        bControlSize        %5u\n",
 1703                buf[3], buf[4], buf[5], term, buf[6]);
 1704         ctrls = 0;
 1705         for (i = 0; i < 3; i++)
 1706             ctrls = (ctrls << 8) | buf[9-i];
 1707         printf("        bmControls              0x%08x\n", ctrls);
 1708         for (i = 0; i < 20;  i++)
 1709             if ((ctrls >> i) & 1)
 1710                 printf("          %s\n", enctrlnames[i]);
 1711         for (i = 0; i< 3; i++)
 1712             ctrls = (ctrls << 8) | buf[12-i];
 1713         printf("        bmControlsRuntime       0x%08x\n", ctrls);
 1714         for (i = 0; i < 20; i++)
 1715             if ((ctrls >> i) & 1)
 1716                 printf("          %s\n", enctrlnames[i]);
 1717         break;
 1718 
 1719     default:
 1720         printf("(unknown)\n"
 1721                "        Invalid desc subtype:");
 1722         dump_bytes(buf+3, buf[0]-3);
 1723         break;
 1724     }
 1725 
 1726     free(term);
 1727 }
 1728 
 1729 static void dump_videostreaming_interface(const unsigned char *buf)
 1730 {
 1731     static const char * const colorPrims[] = { "Unspecified", "BT.709,sRGB",
 1732         "BT.470-2 (M)", "BT.470-2 (B,G)", "SMPTE 170M", "SMPTE 240M" };
 1733     static const char * const transferChars[] = { "Unspecified", "BT.709",
 1734         "BT.470-2 (M)", "BT.470-2 (B,G)", "SMPTE 170M", "SMPTE 240M",
 1735         "Linear", "sRGB"};
 1736     static const char * const matrixCoeffs[] = { "Unspecified", "BT.709",
 1737         "FCC", "BT.470-2 (B,G)", "SMPTE 170M (BT.601)", "SMPTE 240M" };
 1738     unsigned int i, m, n, p, flags, len;
 1739 
 1740     if (buf[1] != USB_DT_CS_INTERFACE)
 1741         printf("      Warning: Invalid descriptor\n");
 1742     else if (buf[0] < 3)
 1743         printf("      Warning: Descriptor too short\n");
 1744     printf("      VideoStreaming Interface Descriptor:\n"
 1745            "        bLength                         %5u\n"
 1746            "        bDescriptorType                 %5u\n"
 1747            "        bDescriptorSubtype              %5u ",
 1748            buf[0], buf[1], buf[2]);
 1749     switch (buf[2]) {
 1750     case 0x01: /* INPUT_HEADER */
 1751         printf("(INPUT_HEADER)\n");
 1752         p = buf[3];
 1753         n = buf[12];
 1754         if (buf[0] < 13+p*n)
 1755             printf("      Warning: Descriptor too short\n");
 1756         printf("        bNumFormats                     %5u\n"
 1757                "        wTotalLength                   0x%04x\n"
 1758                "        bEndpointAddress                 0x%02x  EP %u %s\n"
 1759                "        bmInfo                          %5u\n"
 1760                "        bTerminalLink                   %5u\n"
 1761                "        bStillCaptureMethod             %5u\n"
 1762                "        bTriggerSupport                 %5u\n"
 1763                "        bTriggerUsage                   %5u\n"
 1764                "        bControlSize                    %5u\n",
 1765                p, buf[4] | (buf[5] << 8),
 1766                buf[6], buf[6] & 0x0f, (buf[6] & 0x80) ? "IN" : "OUT",
 1767                buf[7], buf[8], buf[9], buf[10], buf[11], n);
 1768         for (i = 0; i < p; i++)
 1769             printf(
 1770             "        bmaControls(%2u)                 %5u\n",
 1771                 i, buf[13+i*n]);
 1772         dump_junk(buf, "        ", 13+p*n);
 1773         break;
 1774 
 1775     case 0x02: /* OUTPUT_HEADER */
 1776         printf("(OUTPUT_HEADER)\n");
 1777         p = buf[3];
 1778         n = buf[8];
 1779         if (buf[0] < 9+p*n)
 1780             printf("      Warning: Descriptor too short\n");
 1781         printf("        bNumFormats                 %5u\n"
 1782                "        wTotalLength               0x%04x\n"
 1783                "        bEndpointAddress             0x%02x  EP %u %s\n"
 1784                "        bTerminalLink               %5u\n"
 1785                "        bControlSize                %5u\n",
 1786                p, buf[4] | (buf[5] << 8),
 1787                buf[6], buf[6] & 0x0f, (buf[6] & 0x80) ? "IN" : "OUT",
 1788                buf[7], n);
 1789         for (i = 0; i < p; i++)
 1790             printf(
 1791             "        bmaControls(%2u)             %5u\n",
 1792                 i, buf[9+i*n]);
 1793         dump_junk(buf, "        ", 9+p*n);
 1794         break;
 1795 
 1796     case 0x03: /* STILL_IMAGE_FRAME */
 1797         printf("(STILL_IMAGE_FRAME)\n");
 1798         n = buf[4];
 1799         m = buf[5+4*n];
 1800         if (buf[0] < 6+4*n+m)
 1801             printf("      Warning: Descriptor too short\n");
 1802         printf("        bEndpointAddress                 0x%02x  EP %u %s\n"
 1803                "        bNumImageSizePatterns             %3u\n",
 1804                buf[3], buf[3] & 0x0f, (buf[3] & 0x80) ? "IN" : "OUT", n);
 1805         for (i = 0; i < n; i++)
 1806             printf("        wWidth(%2u)                      %5u\n"
 1807                    "        wHeight(%2u)                     %5u\n",
 1808                    i, buf[5+4*i] | (buf[6+4*i] << 8),
 1809                    i, buf[7+4*i] | (buf[8+4*i] << 8));
 1810         printf("        bNumCompressionPatterns           %3u\n", m);
 1811         for (i = 0; i < m; i++)
 1812             printf("        bCompression(%2u)                %5u\n",
 1813                    i, buf[6+4*n+i]);
 1814         dump_junk(buf, "        ", 6+4*n+m);
 1815         break;
 1816 
 1817     case 0x04: /* FORMAT_UNCOMPRESSED */
 1818     case 0x10: /* FORMAT_FRAME_BASED */
 1819         if (buf[2] == 0x04) {
 1820             printf("(FORMAT_UNCOMPRESSED)\n");
 1821             len = 27;
 1822         } else {
 1823             printf("(FORMAT_FRAME_BASED)\n");
 1824             len = 28;
 1825         }
 1826         if (buf[0] < len)
 1827             printf("      Warning: Descriptor too short\n");
 1828         flags = buf[25];
 1829         printf("        bFormatIndex                    %5u\n"
 1830                "        bNumFrameDescriptors            %5u\n"
 1831                "        guidFormat                            %s\n"
 1832                "        bBitsPerPixel                   %5u\n"
 1833                "        bDefaultFrameIndex              %5u\n"
 1834                "        bAspectRatioX                   %5u\n"
 1835                "        bAspectRatioY                   %5u\n"
 1836                "        bmInterlaceFlags                 0x%02x\n",
 1837                buf[3], buf[4], get_guid(&buf[5]), buf[21], buf[22],
 1838                buf[23], buf[24], flags);
 1839         printf("          Interlaced stream or variable: %s\n",
 1840                (flags & (1 << 0)) ? "Yes" : "No");
 1841         printf("          Fields per frame: %u fields\n",
 1842                (flags & (1 << 1)) ? 1 : 2);
 1843         printf("          Field 1 first: %s\n",
 1844                (flags & (1 << 2)) ? "Yes" : "No");
 1845         printf("          Field pattern: ");
 1846         switch ((flags >> 4) & 0x03) {
 1847         case 0:
 1848             printf("Field 1 only\n");
 1849             break;
 1850         case 1:
 1851             printf("Field 2 only\n");
 1852             break;
 1853         case 2:
 1854             printf("Regular pattern of fields 1 and 2\n");
 1855             break;
 1856         case 3:
 1857             printf("Random pattern of fields 1 and 2\n");
 1858             break;
 1859         }
 1860         printf("        bCopyProtect                    %5u\n", buf[26]);
 1861         if (buf[2] == 0x10)
 1862             printf("        bVariableSize                 %5u\n", buf[27]);
 1863         dump_junk(buf, "        ", len);
 1864         break;
 1865 
 1866     case 0x05: /* FRAME UNCOMPRESSED */
 1867     case 0x07: /* FRAME_MJPEG */
 1868     case 0x11: /* FRAME_FRAME_BASED */
 1869         if (buf[2] == 0x05) {
 1870             printf("(FRAME_UNCOMPRESSED)\n");
 1871             n = 25;
 1872         } else if (buf[2] == 0x07) {
 1873             printf("(FRAME_MJPEG)\n");
 1874             n = 25;
 1875         } else {
 1876             printf("(FRAME_FRAME_BASED)\n");
 1877             n = 21;
 1878         }
 1879         len = (buf[n] != 0) ? (26+buf[n]*4) : 38;
 1880         if (buf[0] < len)
 1881             printf("      Warning: Descriptor too short\n");
 1882         flags = buf[4];
 1883         printf("        bFrameIndex                     %5u\n"
 1884                "        bmCapabilities                   0x%02x\n",
 1885                buf[3], flags);
 1886         printf("          Still image %ssupported\n",
 1887                (flags & (1 << 0)) ? "" : "un");
 1888         if (flags & (1 << 1))
 1889             printf("          Fixed frame-rate\n");
 1890         printf("        wWidth                          %5u\n"
 1891                "        wHeight                         %5u\n"
 1892                "        dwMinBitRate                %9u\n"
 1893                "        dwMaxBitRate                %9u\n",
 1894                buf[5] | (buf[6] <<  8), buf[7] | (buf[8] << 8),
 1895                buf[9] | (buf[10] << 8) | (buf[11] << 16) | (buf[12] << 24),
 1896                buf[13] | (buf[14] << 8) | (buf[15] << 16) | (buf[16] << 24));
 1897         if (buf[2] == 0x11)
 1898             printf("        dwDefaultFrameInterval      %9u\n"
 1899                    "        bFrameIntervalType              %5u\n"
 1900                    "        dwBytesPerLine              %9u\n",
 1901                    buf[17] | (buf[18] << 8) | (buf[19] << 16) | (buf[20] << 24),
 1902                    buf[21],
 1903                    buf[22] | (buf[23] << 8) | (buf[24] << 16) | (buf[25] << 24));
 1904         else
 1905             printf("        dwMaxVideoFrameBufferSize   %9u\n"
 1906                    "        dwDefaultFrameInterval      %9u\n"
 1907                    "        bFrameIntervalType              %5u\n",
 1908                    buf[17] | (buf[18] << 8) | (buf[19] << 16) | (buf[20] << 24),
 1909                    buf[21] | (buf[22] << 8) | (buf[23] << 16) | (buf[24] << 24),
 1910                    buf[25]);
 1911         if (buf[n] == 0)
 1912             printf("        dwMinFrameInterval          %9u\n"
 1913                    "        dwMaxFrameInterval          %9u\n"
 1914                    "        dwFrameIntervalStep         %9u\n",
 1915                    buf[26] | (buf[27] << 8) | (buf[28] << 16) | (buf[29] << 24),
 1916                    buf[30] | (buf[31] << 8) | (buf[32] << 16) | (buf[33] << 24),
 1917                    buf[34] | (buf[35] << 8) | (buf[36] << 16) | (buf[37] << 24));
 1918         else
 1919             for (i = 0; i < buf[n]; i++)
 1920                 printf("        dwFrameInterval(%2u)         %9u\n",
 1921                        i, buf[26+4*i] | (buf[27+4*i] << 8) |
 1922                        (buf[28+4*i] << 16) | (buf[29+4*i] << 24));
 1923         dump_junk(buf, "        ", len);
 1924         break;
 1925 
 1926     case 0x06: /* FORMAT_MJPEG */
 1927         printf("(FORMAT_MJPEG)\n");
 1928         if (buf[0] < 11)
 1929             printf("      Warning: Descriptor too short\n");
 1930         flags = buf[5];
 1931         printf("        bFormatIndex                    %5u\n"
 1932                "        bNumFrameDescriptors            %5u\n"
 1933                "        bFlags                          %5u\n",
 1934                buf[3], buf[4], flags);
 1935         printf("          Fixed-size samples: %s\n",
 1936                (flags & (1 << 0)) ? "Yes" : "No");
 1937         flags = buf[9];
 1938         printf("        bDefaultFrameIndex              %5u\n"
 1939                "        bAspectRatioX                   %5u\n"
 1940                "        bAspectRatioY                   %5u\n"
 1941                "        bmInterlaceFlags                 0x%02x\n",
 1942                buf[6], buf[7], buf[8], flags);
 1943         printf("          Interlaced stream or variable: %s\n",
 1944                (flags & (1 << 0)) ? "Yes" : "No");
 1945         printf("          Fields per frame: %u fields\n",
 1946                (flags & (1 << 1)) ? 2 : 1);
 1947         printf("          Field 1 first: %s\n",
 1948                (flags & (1 << 2)) ? "Yes" : "No");
 1949         printf("          Field pattern: ");
 1950         switch ((flags >> 4) & 0x03) {
 1951         case 0:
 1952             printf("Field 1 only\n");
 1953             break;
 1954         case 1:
 1955             printf("Field 2 only\n");
 1956             break;
 1957         case 2:
 1958             printf("Regular pattern of fields 1 and 2\n");
 1959             break;
 1960         case 3:
 1961             printf("Random pattern of fields 1 and 2\n");
 1962             break;
 1963         }
 1964         printf("        bCopyProtect                    %5u\n", buf[10]);
 1965         dump_junk(buf, "        ", 11);
 1966         break;
 1967 
 1968     case 0x0a: /* FORMAT_MPEG2TS */
 1969         printf("(FORMAT_MPEG2TS)\n");
 1970         len = buf[0] < 23 ? 7 : 23;
 1971         if (buf[0] < len)
 1972             printf("      Warning: Descriptor too short\n");
 1973         printf("        bFormatIndex                    %5u\n"
 1974                "        bDataOffset                     %5u\n"
 1975                "        bPacketLength                   %5u\n"
 1976                "        bStrideLength                   %5u\n",
 1977                buf[3], buf[4], buf[5], buf[6]);
 1978         if (len > 7)
 1979             printf("        guidStrideFormat                      %s\n",
 1980                    get_guid(&buf[7]));
 1981         dump_junk(buf, "        ", len);
 1982         break;
 1983 
 1984     case 0x0d: /* COLORFORMAT */
 1985         printf("(COLORFORMAT)\n");
 1986         if (buf[0] < 6)
 1987             printf("      Warning: Descriptor too short\n");
 1988         printf("        bColorPrimaries                 %5u (%s)\n",
 1989                buf[3], (buf[3] <= 5) ? colorPrims[buf[3]] : "Unknown");
 1990         printf("        bTransferCharacteristics        %5u (%s)\n",
 1991                buf[4], (buf[4] <= 7) ? transferChars[buf[4]] : "Unknown");
 1992         printf("        bMatrixCoefficients             %5u (%s)\n",
 1993                buf[5], (buf[5] <= 5) ? matrixCoeffs[buf[5]] : "Unknown");
 1994         dump_junk(buf, "        ", 6);
 1995         break;
 1996 
 1997     case 0x12: /* FORMAT_STREAM_BASED */
 1998         printf("(FORMAT_STREAM_BASED)\n");
 1999         if (buf[0] != 24)
 2000             printf("      Warning: Incorrect descriptor length\n");
 2001 
 2002         printf("        bFormatIndex                    %5u\n"
 2003                "        guidFormat                            %s\n"
 2004                "        dwPacketLength                %7u\n",
 2005                buf[3], get_guid(&buf[4]), buf[20]);
 2006         dump_junk(buf, "        ", 24);
 2007         break;
 2008 
 2009     default:
 2010         printf("        Invalid desc subtype:");
 2011         dump_bytes(buf+3, buf[0]-3);
 2012         break;
 2013     }
 2014 }
 2015 
 2016 static void dump_dfu_interface(const unsigned char *buf)
 2017 {
 2018     if (buf[1] != USB_DT_CS_DEVICE)
 2019         printf("      Warning: Invalid descriptor\n");
 2020     else if (buf[0] < 7)
 2021         printf("      Warning: Descriptor too short\n");
 2022     printf("      Device Firmware Upgrade Interface Descriptor:\n"
 2023            "        bLength                         %5u\n"
 2024            "        bDescriptorType                 %5u\n"
 2025            "        bmAttributes                    %5u\n",
 2026            buf[0], buf[1], buf[2]);
 2027     if (buf[2] & 0xf0)
 2028         printf("          (unknown attributes!)\n");
 2029     printf("          Will %sDetach\n", (buf[2] & 0x08) ? "" : "Not ");
 2030     printf("          Manifestation %s\n", (buf[2] & 0x04) ? "Tolerant" : "Intolerant");
 2031     printf("          Upload %s\n", (buf[2] & 0x02) ? "Supported" : "Unsupported");
 2032     printf("          Download %s\n", (buf[2] & 0x01) ? "Supported" : "Unsupported");
 2033     printf("        wDetachTimeout                  %5u milliseconds\n"
 2034            "        wTransferSize                   %5u bytes\n",
 2035            buf[3] | (buf[4] << 8), buf[5] | (buf[6] << 8));
 2036 
 2037     /* DFU 1.0 defines no version code, DFU 1.1 does */
 2038     if (buf[0] < 9)
 2039         return;
 2040     printf("        bcdDFUVersion                   %x.%02x\n",
 2041             buf[8], buf[7]);
 2042 }
 2043 
 2044 static void dump_hub(const char *prefix, const unsigned char *p, int tt_type)
 2045 {
 2046     unsigned int l, i, j;
 2047     unsigned int offset;
 2048     unsigned int wHubChar = (p[4] << 8) | p[3];
 2049 
 2050     printf("%sHub Descriptor:\n", prefix);
 2051     printf("%s  bLength             %3u\n", prefix, p[0]);
 2052     printf("%s  bDescriptorType     %3u\n", prefix, p[1]);
 2053     printf("%s  nNbrPorts           %3u\n", prefix, p[2]);
 2054     printf("%s  wHubCharacteristic 0x%04x\n", prefix, wHubChar);
 2055     switch (wHubChar & 0x03) {
 2056     case 0:
 2057         printf("%s    Ganged power switching\n", prefix);
 2058         break;
 2059     case 1:
 2060         printf("%s    Per-port power switching\n", prefix);
 2061         break;
 2062     default:
 2063         printf("%s    No power switching (usb 1.0)\n", prefix);
 2064         break;
 2065     }
 2066     if (wHubChar & 0x04)
 2067         printf("%s    Compound device\n", prefix);
 2068     switch ((wHubChar >> 3) & 0x03) {
 2069     case 0:
 2070         printf("%s    Ganged overcurrent protection\n", prefix);
 2071         break;
 2072     case 1:
 2073         printf("%s    Per-port overcurrent protection\n", prefix);
 2074         break;
 2075     default:
 2076         printf("%s    No overcurrent protection\n", prefix);
 2077         break;
 2078     }
 2079     /* USB 3.0 hubs don't have TTs. */
 2080     if (tt_type >= 1 && tt_type < 3) {
 2081         l = (wHubChar >> 5) & 0x03;
 2082         printf("%s    TT think time %d FS bits\n", prefix, (l + 1) * 8);
 2083     }
 2084     /* USB 3.0 hubs don't have port indicators.  Sad face. */
 2085     if (tt_type != 3 && wHubChar & (1<<7))
 2086         printf("%s    Port indicators\n", prefix);
 2087     printf("%s  bPwrOn2PwrGood      %3u * 2 milli seconds\n", prefix, p[5]);
 2088 
 2089     /* USB 3.0 hubs report current in units of aCurrentUnit, or 4 mA */
 2090     if (tt_type == 3)
 2091         printf("%s  bHubContrCurrent   %4u milli Ampere\n",
 2092                 prefix, p[6]*4);
 2093     else
 2094         printf("%s  bHubContrCurrent    %3u milli Ampere\n",
 2095                 prefix, p[6]);
 2096 
 2097     if (tt_type == 3) {
 2098         printf("%s  bHubDecLat          0.%1u micro seconds\n",
 2099                 prefix, p[7]);
 2100         printf("%s  wHubDelay          %4u nano seconds\n",
 2101                 prefix, (p[8] << 4) +(p[7]));
 2102         offset = 10;
 2103     } else {
 2104         offset = 7;
 2105     }
 2106 
 2107     l = (p[2] >> 3) + 1; /* this determines the variable number of bytes following */
 2108     if (l > HUB_STATUS_BYTELEN)
 2109         l = HUB_STATUS_BYTELEN;
 2110     printf("%s  DeviceRemovable   ", prefix);
 2111     for (i = 0; i < l; i++)
 2112         printf(" 0x%02x", p[offset+i]);
 2113 
 2114     if (tt_type != 3) {
 2115         printf("\n%s  PortPwrCtrlMask   ", prefix);
 2116         for (j = 0; j < l; j++)
 2117             printf(" 0x%02x", p[offset+i+j]);
 2118     }
 2119     printf("\n");
 2120 }
 2121 
 2122 static void dump_ccid_device(const unsigned char *buf)
 2123 {
 2124     unsigned int us;
 2125 
 2126     if (buf[0] < 54) {
 2127         printf("      Warning: Descriptor too short\n");
 2128         return;
 2129     }
 2130     printf("      ChipCard Interface Descriptor:\n"
 2131            "        bLength             %5u\n"
 2132            "        bDescriptorType     %5u\n"
 2133            "        bcdCCID             %2x.%02x",
 2134            buf[0], buf[1], buf[3], buf[2]);
 2135     if (buf[3] != 1 || buf[2] != 0)
 2136         fputs("  (Warning: Only accurate for version 1.0)", stdout);
 2137     putchar('\n');
 2138 
 2139     printf("        nMaxSlotIndex       %5u\n"
 2140         "        bVoltageSupport     %5u  %s%s%s\n",
 2141         buf[4],
 2142         buf[5],
 2143            (buf[5] & 1) ? "5.0V " : "",
 2144            (buf[5] & 2) ? "3.0V " : "",
 2145            (buf[5] & 4) ? "1.8V " : "");
 2146 
 2147     us = convert_le_u32 (buf+6);
 2148     printf("        dwProtocols         %5u ", us);
 2149     if ((us & 1))
 2150         fputs(" T=0", stdout);
 2151     if ((us & 2))
 2152         fputs(" T=1", stdout);
 2153     if ((us & ~3))
 2154         fputs(" (Invalid values detected)", stdout);
 2155     putchar('\n');
 2156 
 2157     us = convert_le_u32(buf+10);
 2158     printf("        dwDefaultClock      %5u\n", us);
 2159     us = convert_le_u32(buf+14);
 2160     printf("        dwMaxiumumClock     %5u\n", us);
 2161     printf("        bNumClockSupported  %5u\n", buf[18]);
 2162     us = convert_le_u32(buf+19);
 2163     printf("        dwDataRate        %7u bps\n", us);
 2164     us = convert_le_u32(buf+23);
 2165     printf("        dwMaxDataRate     %7u bps\n", us);
 2166     printf("        bNumDataRatesSupp.  %5u\n", buf[27]);
 2167 
 2168     us = convert_le_u32(buf+28);
 2169     printf("        dwMaxIFSD           %5u\n", us);
 2170 
 2171     us = convert_le_u32(buf+32);
 2172     printf("        dwSyncProtocols  %08X ", us);
 2173     if ((us&1))
 2174         fputs(" 2-wire", stdout);
 2175     if ((us&2))
 2176         fputs(" 3-wire", stdout);
 2177     if ((us&4))
 2178         fputs(" I2C", stdout);
 2179     putchar('\n');
 2180 
 2181     us = convert_le_u32(buf+36);
 2182     printf("        dwMechanical     %08X ", us);
 2183     if ((us & 1))
 2184         fputs(" accept", stdout);
 2185     if ((us & 2))
 2186         fputs(" eject", stdout);
 2187     if ((us & 4))
 2188         fputs(" capture", stdout);
 2189     if ((us & 8))
 2190         fputs(" lock", stdout);
 2191     putchar('\n');
 2192 
 2193     us = convert_le_u32(buf+40);
 2194     printf("        dwFeatures       %08X\n", us);
 2195     if ((us & 0x0002))
 2196         fputs("          Auto configuration based on ATR\n", stdout);
 2197     if ((us & 0x0004))
 2198         fputs("          Auto activation on insert\n", stdout);
 2199     if ((us & 0x0008))
 2200         fputs("          Auto voltage selection\n", stdout);
 2201     if ((us & 0x0010))
 2202         fputs("          Auto clock change\n", stdout);
 2203     if ((us & 0x0020))
 2204         fputs("          Auto baud rate change\n", stdout);
 2205     if ((us & 0x0040))
 2206         fputs("          Auto parameter negotiation made by CCID\n", stdout);
 2207     else if ((us & 0x0080))
 2208         fputs("          Auto PPS made by CCID\n", stdout);
 2209     else if ((us & (0x0040 | 0x0080)))
 2210         fputs("        WARNING: conflicting negotiation features\n", stdout);
 2211 
 2212     if ((us & 0x0100))
 2213         fputs("          CCID can set ICC in clock stop mode\n", stdout);
 2214     if ((us & 0x0200))
 2215         fputs("          NAD value other than 0x00 accepted\n", stdout);
 2216     if ((us & 0x0400))
 2217         fputs("          Auto IFSD exchange\n", stdout);
 2218 
 2219     if ((us & 0x00010000))
 2220         fputs("          TPDU level exchange\n", stdout);
 2221     else if ((us & 0x00020000))
 2222         fputs("          Short APDU level exchange\n", stdout);
 2223     else if ((us & 0x00040000))
 2224         fputs("          Short and extended APDU level exchange\n", stdout);
 2225     else if ((us & 0x00070000))
 2226         fputs("        WARNING: conflicting exchange levels\n", stdout);
 2227 
 2228     us = convert_le_u32(buf+44);
 2229     printf("        dwMaxCCIDMsgLen     %5u\n", us);
 2230 
 2231     printf("        bClassGetResponse    ");
 2232     if (buf[48] == 0xff)
 2233         fputs("echo\n", stdout);
 2234     else
 2235         printf("  %02X\n", buf[48]);
 2236 
 2237     printf("        bClassEnvelope       ");
 2238     if (buf[49] == 0xff)
 2239         fputs("echo\n", stdout);
 2240     else
 2241         printf("  %02X\n", buf[48]);
 2242 
 2243     printf("        wlcdLayout           ");
 2244     if (!buf[50] && !buf[51])
 2245         fputs("none\n", stdout);
 2246     else
 2247         printf("%u cols %u lines\n", buf[50], buf[51]);
 2248 
 2249     printf("        bPINSupport         %5u ", buf[52]);
 2250     if ((buf[52] & 1))
 2251         fputs(" verification", stdout);
 2252     if ((buf[52] & 2))
 2253         fputs(" modification", stdout);
 2254     putchar('\n');
 2255 
 2256     printf("        bMaxCCIDBusySlots   %5u\n", buf[53]);
 2257 
 2258     if (buf[0] > 54) {
 2259         fputs("        junk             ", stdout);
 2260         dump_bytes(buf+54, buf[0]-54);
 2261     }
 2262 }
 2263 
 2264 /* ---------------------------------------------------------------------- */
 2265 
 2266 /*
 2267  * HID descriptor
 2268  */
 2269 
 2270 static void dump_report_desc(unsigned char *b, int l)
 2271 {
 2272     unsigned int j, bsize, btag, btype, data = 0xffff, hut = 0xffff;
 2273     int i;
 2274     char *types[4] = { "Main", "Global", "Local", "reserved" };
 2275     char indent[] = "                            ";
 2276 
 2277     printf("          Report Descriptor: (length is %d)\n", l);
 2278     for (i = 0; i < l; ) {
 2279         bsize = b[i] & 0x03;
 2280         if (bsize == 3)
 2281             bsize = 4;
 2282         btype = b[i] & (0x03 << 2);
 2283         btag = b[i] & ~0x03; /* 2 LSB bits encode length */
 2284         printf("            Item(%-6s): %s, data=", types[btype>>2],
 2285                 names_reporttag(btag));
 2286         if (bsize > 0) {
 2287             printf(" [ ");
 2288             data = 0;
 2289             for (j = 0; j < bsize; j++) {
 2290                 printf("0x%02x ", b[i+1+j]);
 2291                 data += (b[i+1+j] << (8*j));
 2292             }
 2293             printf("] %d", data);
 2294         } else
 2295             printf("none");
 2296         printf("\n");
 2297         switch (btag) {
 2298         case 0x04: /* Usage Page */
 2299             printf("%s%s\n", indent, names_huts(data));
 2300             hut = data;
 2301             break;
 2302 
 2303         case 0x08: /* Usage */
 2304         case 0x18: /* Usage Minimum */
 2305         case 0x28: /* Usage Maximum */
 2306             printf("%s%s\n", indent,
 2307                    names_hutus((hut << 16) + data));
 2308             break;
 2309 
 2310         case 0x54: /* Unit Exponent */
 2311             printf("%sUnit Exponent: %i\n", indent,
 2312                    (signed char)data);
 2313             break;
 2314 
 2315         case 0x64: /* Unit */
 2316             printf("%s", indent);
 2317             dump_unit(data, bsize);
 2318             break;
 2319 
 2320         case 0xa0: /* Collection */
 2321             printf("%s", indent);
 2322             switch (data) {
 2323             case 0x00:
 2324                 printf("Physical\n");
 2325                 break;
 2326 
 2327             case 0x01:
 2328                 printf("Application\n");
 2329                 break;
 2330 
 2331             case 0x02:
 2332                 printf("Logical\n");
 2333                 break;
 2334 
 2335             case 0x03:
 2336                 printf("Report\n");
 2337                 break;
 2338 
 2339             case 0x04:
 2340                 printf("Named Array\n");
 2341                 break;
 2342 
 2343             case 0x05:
 2344                 printf("Usage Switch\n");
 2345                 break;
 2346 
 2347             case 0x06:
 2348                 printf("Usage Modifier\n");
 2349                 break;
 2350 
 2351             default:
 2352                 if (data & 0x80)
 2353                     printf("Vendor defined\n");
 2354                 else
 2355                     printf("Reserved for future use.\n");
 2356             }
 2357             break;
 2358         case 0x80: /* Input */
 2359         case 0x90: /* Output */
 2360         case 0xb0: /* Feature */
 2361             printf("%s%s %s %s %s %s\n%s%s %s %s %s\n",
 2362                    indent,
 2363                    data & 0x01 ? "Constant" : "Data",
 2364                    data & 0x02 ? "Variable" : "Array",
 2365                    data & 0x04 ? "Relative" : "Absolute",
 2366                    data & 0x08 ? "Wrap" : "No_Wrap",
 2367                    data & 0x10 ? "Non_Linear" : "Linear",
 2368                    indent,
 2369                    data & 0x20 ? "No_Preferred_State" : "Preferred_State",
 2370                    data & 0x40 ? "Null_State" : "No_Null_Position",
 2371                    data & 0x80 ? "Volatile" : "Non_Volatile",
 2372                    data & 0x100 ? "Buffered Bytes" : "Bitfield");
 2373             break;
 2374         }
 2375         i += 1 + bsize;
 2376     }
 2377 }
 2378 
 2379 static void dump_printer_device(libusb_device_handle *dev,
 2380                 const struct libusb_interface_descriptor *interface,
 2381                 const unsigned char *buf)
 2382 {
 2383     unsigned int i;
 2384     unsigned int n;
 2385 
 2386     if (interface->bInterfaceProtocol != 0x04)  /* IPP-over-USB */
 2387         return;
 2388 
 2389     printf("        IPP Printer Descriptor:\n"
 2390            "          bLength             %5u\n"
 2391            "          bDescriptorType     %5u\n"
 2392            "          bcdReleaseNumber    %5u\n"
 2393            "          bcdNumDescriptors   %5u\n",
 2394            buf[0], buf[1], buf[2], buf[3]);
 2395 
 2396     n = 4;
 2397     for (i = 0 ; i < buf[3] ; i++) {
 2398         switch (buf[n]) {
 2399         case 0x00: {  /* Basic capabilities */
 2400             uint16_t caps = le16_to_cpu(*((uint16_t*)&buf[n+2]));
 2401             char *uuid = get_dev_string(dev, buf[n+5]);
 2402 
 2403             printf("            iIPPVersionsSupported %5u\n", buf[n+4]);
 2404             printf("            iIPPPrinterUUID       %5u %s\n", buf[n+5], uuid);
 2405             printf("            wBasicCapabilities   0x%04x ", caps);
 2406             if (caps & 0x01)
 2407                 printf(" Print");
 2408             if (caps & 0x02)
 2409                 printf(" Scan");
 2410             if (caps & 0x04)
 2411                 printf(" Fax");
 2412             if (caps & 0x08)
 2413                 printf(" Other");
 2414             if (caps & 0x10)
 2415                 printf(" HTTP-over-USB");
 2416             if ((caps & 0x60) == 0x00)
 2417                 printf(" No-Auth");
 2418             else if ((caps & 0x60) == 0x20)
 2419                 printf(" Username-Auth");
 2420             else if ((caps & 0x60) == 0x40)
 2421                 printf(" Reserved-Auth");
 2422             else if ((caps & 0x60) == 0x60)
 2423                 printf(" Negotiable-Auth");
 2424             printf("\n");
 2425             free(uuid);
 2426             break;
 2427         }
 2428         default:
 2429             /* Vendor Specific, Ignore for now. */
 2430             printf("            UnknownCapabilities   %5u %5u\n", buf[n], buf[n+1]);
 2431             break;
 2432         }
 2433         n += 2 + buf[n+1];
 2434     }
 2435 }
 2436 
 2437 static void dump_hid_device(libusb_device_handle *dev,
 2438                 const struct libusb_interface_descriptor *interface,
 2439                 const unsigned char *buf)
 2440 {
 2441     unsigned int i, len;
 2442     unsigned int n;
 2443     unsigned char dbuf[8192];
 2444 
 2445     if (buf[1] != LIBUSB_DT_HID)
 2446         printf("      Warning: Invalid descriptor\n");
 2447     else if (buf[0] < 6+3*buf[5])
 2448         printf("      Warning: Descriptor too short\n");
 2449     printf("        HID Device Descriptor:\n"
 2450            "          bLength             %5u\n"
 2451            "          bDescriptorType     %5u\n"
 2452            "          bcdHID              %2x.%02x\n"
 2453            "          bCountryCode        %5u %s\n"
 2454            "          bNumDescriptors     %5u\n",
 2455            buf[0], buf[1], buf[3], buf[2], buf[4],
 2456            names_countrycode(buf[4]) ? : "Unknown", buf[5]);
 2457     for (i = 0; i < buf[5]; i++)
 2458         printf("          bDescriptorType     %5u %s\n"
 2459                "          wDescriptorLength   %5u\n",
 2460                buf[6+3*i], names_hid(buf[6+3*i]),
 2461                buf[7+3*i] | (buf[8+3*i] << 8));
 2462     dump_junk(buf, "        ", 6+3*buf[5]);
 2463     if (!do_report_desc)
 2464         return;
 2465 
 2466     if (!dev) {
 2467         printf("         Report Descriptors: \n"
 2468                "           ** UNAVAILABLE **\n");
 2469         return;
 2470     }
 2471 
 2472     for (i = 0; i < buf[5]; i++) {
 2473         /* we are just interested in report descriptors*/
 2474         if (buf[6+3*i] != LIBUSB_DT_REPORT)
 2475             continue;
 2476         len = buf[7+3*i] | (buf[8+3*i] << 8);
 2477         if (len > (unsigned int)sizeof(dbuf)) {
 2478             printf("report descriptor too long\n");
 2479             continue;
 2480         }
 2481         if (libusb_claim_interface(dev, interface->bInterfaceNumber) == 0) {
 2482             int retries = 4;
 2483             n = 0;
 2484             while (n < len && retries--)
 2485                 n = usb_control_msg(dev,
 2486                      LIBUSB_ENDPOINT_IN | LIBUSB_REQUEST_TYPE_STANDARD
 2487                         | LIBUSB_RECIPIENT_INTERFACE,
 2488                      LIBUSB_REQUEST_GET_DESCRIPTOR,
 2489                      (LIBUSB_DT_REPORT << 8),
 2490                      interface->bInterfaceNumber,
 2491                      dbuf, len,
 2492                      CTRL_TIMEOUT);
 2493 
 2494             if (n > 0) {
 2495                 if (n < len)
 2496                     printf("          Warning: incomplete report descriptor\n");
 2497                 dump_report_desc(dbuf, n);
 2498             }
 2499             libusb_release_interface(dev, interface->bInterfaceNumber);
 2500         } else {
 2501             /* recent Linuxes require claim() for RECIP_INTERFACE,
 2502              * so "rmmod hid" will often make these available.
 2503              */
 2504             printf("         Report Descriptors: \n"
 2505                    "           ** UNAVAILABLE **\n");
 2506         }
 2507     }
 2508 }
 2509 
 2510 static char *
 2511 dump_comm_descriptor(libusb_device_handle *dev, const unsigned char *buf, char *indent)
 2512 {
 2513     int     tmp;
 2514     char        *str = NULL;
 2515     char        *type;
 2516 
 2517     switch (buf[2]) {
 2518     case 0:
 2519         type = "Header";
 2520         if (buf[0] != 5)
 2521             goto bad;
 2522         printf("%sCDC Header:\n"
 2523                "%s  bcdCDC               %x.%02x\n",
 2524                indent,
 2525                indent, buf[4], buf[3]);
 2526         break;
 2527     case 0x01:      /* call management functional desc */
 2528         type = "Call Management";
 2529         if (buf[0] != 5)
 2530             goto bad;
 2531         printf("%sCDC Call Management:\n"
 2532                "%s  bmCapabilities       0x%02x\n",
 2533                indent,
 2534                indent, buf[3]);
 2535         if (buf[3] & 0x01)
 2536             printf("%s    call management\n", indent);
 2537         if (buf[3] & 0x02)
 2538             printf("%s    use DataInterface\n", indent);
 2539         printf("%s  bDataInterface          %d\n", indent, buf[4]);
 2540         break;
 2541     case 0x02:      /* acm functional desc */
 2542         type = "ACM";
 2543         if (buf[0] != 4)
 2544             goto bad;
 2545         printf("%sCDC ACM:\n"
 2546                "%s  bmCapabilities       0x%02x\n",
 2547                indent,
 2548                indent, buf[3]);
 2549         if (buf[3] & 0x08)
 2550             printf("%s    connection notifications\n", indent);
 2551         if (buf[3] & 0x04)
 2552             printf("%s    sends break\n", indent);
 2553         if (buf[3] & 0x02)
 2554             printf("%s    line coding and serial state\n", indent);
 2555         if (buf[3] & 0x01)
 2556             printf("%s    get/set/clear comm features\n", indent);
 2557         break;
 2558 #if 0
 2559     case 0x03:      /* direct line management */
 2560     case 0x04:      /* telephone ringer */
 2561     case 0x05:      /* telephone call and line state reporting */
 2562 #endif
 2563     case 0x06:      /* union desc */
 2564         type = "Union";
 2565         if (buf[0] < 5)
 2566             goto bad;
 2567         printf("%sCDC Union:\n"
 2568                "%s  bMasterInterface        %d\n"
 2569                "%s  bSlaveInterface         ",
 2570                indent,
 2571                indent, buf[3],
 2572                indent);
 2573         for (tmp = 4; tmp < buf[0]; tmp++)
 2574             printf("%d ", buf[tmp]);
 2575         printf("\n");
 2576         break;
 2577     case 0x07:      /* country selection functional desc */
 2578         type = "Country Selection";
 2579         if (buf[0] < 6 || (buf[0] & 1) != 0)
 2580             goto bad;
 2581         str = get_dev_string(dev, buf[3]);
 2582         printf("%sCountry Selection:\n"
 2583                "%s  iCountryCodeRelDate     %4d %s\n",
 2584                indent,
 2585                indent, buf[3], (buf[3] && *str) ? str : "(?\?)");
 2586         for (tmp = 4; tmp < buf[0]; tmp += 2) {
 2587             printf("%s  wCountryCode          0x%02x%02x\n",
 2588                 indent, buf[tmp], buf[tmp + 1]);
 2589         }
 2590         break;
 2591     case 0x08:      /* telephone operational modes */
 2592         type = "Telephone Operations";
 2593         if (buf[0] != 4)
 2594             goto bad;
 2595         printf("%sCDC Telephone operations:\n"
 2596                "%s  bmCapabilities       0x%02x\n",
 2597                indent,
 2598                indent, buf[3]);
 2599         if (buf[3] & 0x04)
 2600             printf("%s    computer centric mode\n", indent);
 2601         if (buf[3] & 0x02)
 2602             printf("%s    standalone mode\n", indent);
 2603         if (buf[3] & 0x01)
 2604             printf("%s    simple mode\n", indent);
 2605         break;
 2606 #if 0
 2607     case 0x09:      /* USB terminal */
 2608 #endif
 2609     case 0x0a:      /* network channel terminal */
 2610         type = "Network Channel Terminal";
 2611         if (buf[0] != 7)
 2612             goto bad;
 2613         str = get_dev_string(dev, buf[4]);
 2614         printf("%sNetwork Channel Terminal:\n"
 2615                "%s  bEntityId               %3d\n"
 2616                "%s  iName                   %3d %s\n"
 2617                "%s  bChannelIndex           %3d\n"
 2618                "%s  bPhysicalInterface      %3d\n",
 2619                indent,
 2620                indent, buf[3],
 2621                indent, buf[4], str,
 2622                indent, buf[5],
 2623                indent, buf[6]);
 2624         break;
 2625 #if 0
 2626     case 0x0b:      /* protocol unit */
 2627     case 0x0c:      /* extension unit */
 2628     case 0x0d:      /* multi-channel management */
 2629     case 0x0e:      /* CAPI control management*/
 2630 #endif
 2631     case 0x0f:      /* ethernet functional desc */
 2632         type = "Ethernet";
 2633         if (buf[0] != 13)
 2634             goto bad;
 2635         str = get_dev_string(dev, buf[3]);
 2636         tmp = buf[7] << 8;
 2637         tmp |= buf[6]; tmp <<= 8;
 2638         tmp |= buf[5]; tmp <<= 8;
 2639         tmp |= buf[4];
 2640         printf("%sCDC Ethernet:\n"
 2641                "%s  iMacAddress             %10d %s\n"
 2642                "%s  bmEthernetStatistics    0x%08x\n",
 2643                indent,
 2644                indent, buf[3], (buf[3] && *str) ? str : "(?\?)",
 2645                indent, tmp);
 2646         /* FIXME dissect ALL 28 bits */
 2647         printf("%s  wMaxSegmentSize         %10d\n"
 2648                "%s  wNumberMCFilters            0x%04x\n"
 2649                "%s  bNumberPowerFilters     %10d\n",
 2650                indent, (buf[9]<<8)|buf[8],
 2651                indent, (buf[11]<<8)|buf[10],
 2652                indent, buf[12]);
 2653         break;
 2654 #if 0
 2655     case 0x10:      /* ATM networking */
 2656 #endif
 2657     case 0x11:      /* WHCM functional desc */
 2658         type = "WHCM version";
 2659         if (buf[0] != 5)
 2660             goto bad;
 2661         printf("%sCDC WHCM:\n"
 2662                "%s  bcdVersion           %x.%02x\n",
 2663                indent,
 2664                indent, buf[4], buf[3]);
 2665         break;
 2666     case 0x12:      /* MDLM functional desc */
 2667         type = "MDLM";
 2668         if (buf[0] != 21)
 2669             goto bad;
 2670         printf("%sCDC MDLM:\n"
 2671                "%s  bcdCDC               %x.%02x\n"
 2672                "%s  bGUID               %s\n",
 2673                indent,
 2674                indent, buf[4], buf[3],
 2675                indent, get_guid(buf + 5));
 2676         break;
 2677     case 0x13:      /* MDLM detail desc */
 2678         type = "MDLM detail";
 2679         if (buf[0] < 5)
 2680             goto bad;
 2681         printf("%sCDC MDLM detail:\n"
 2682                "%s  bGuidDescriptorType  %02x\n"
 2683                "%s  bDetailData         ",
 2684                indent,
 2685                indent, buf[3],
 2686                indent);
 2687         dump_bytes(buf + 4, buf[0] - 4);
 2688         break;
 2689     case 0x14:      /* device management functional desc */
 2690         type = "Device Management";
 2691         if (buf[0] != 7)
 2692             goto bad;
 2693         printf("%sCDC Device Management:\n"
 2694                "%s  bcdVersion           %x.%02x\n"
 2695                "%s  wMaxCommand          %d\n",
 2696                indent,
 2697                indent, buf[4], buf[3],
 2698                indent, (buf[6] << 8) | buf[5]);
 2699         break;
 2700     case 0x15:      /* OBEX functional desc */
 2701         type = "OBEX";
 2702         if (buf[0] != 5)
 2703             goto bad;
 2704         printf("%sCDC OBEX:\n"
 2705                "%s  bcdVersion           %x.%02x\n",
 2706                indent,
 2707                indent, buf[4], buf[3]);
 2708         break;
 2709     case 0x16:      /* command set functional desc */
 2710         type = "Command Set";
 2711         if (buf[0] != 22)
 2712             goto bad;
 2713         str = get_dev_string(dev, buf[5]);
 2714         printf("%sCDC Command Set:\n"
 2715                "%s  bcdVersion           %x.%02x\n"
 2716                "%s  iCommandSet          %4d %s\n"
 2717                "%s  bGUID                %s\n",
 2718                indent,
 2719                indent, buf[4], buf[3],
 2720                indent, buf[5], (buf[5] && *str) ? str : "(?\?)",
 2721                indent, get_guid(buf + 6));
 2722         break;
 2723 #if 0
 2724     case 0x17:      /* command set detail desc */
 2725     case 0x18:      /* telephone control model functional desc */
 2726 #endif
 2727     case 0x1a:      /* NCM functional desc */
 2728         type = "NCM";
 2729         if (buf[0] != 6)
 2730             goto bad;
 2731         printf("%sCDC NCM:\n"
 2732                "%s  bcdNcmVersion        %x.%02x\n"
 2733                "%s  bmNetworkCapabilities 0x%02x\n",
 2734                indent,
 2735                indent, buf[4], buf[3],
 2736                indent, buf[5]);
 2737         if (buf[5] & 1<<5)
 2738             printf("%s    8-byte ntb input size\n", indent);
 2739         if (buf[5] & 1<<4)
 2740             printf("%s    crc mode\n", indent);
 2741         if (buf[5] & 1<<3)
 2742             printf("%s    max datagram size\n", indent);
 2743         if (buf[5] & 1<<2)
 2744             printf("%s    encapsulated commands\n", indent);
 2745         if (buf[5] & 1<<1)
 2746             printf("%s    net address\n", indent);
 2747         if (buf[5] & 1<<0)
 2748             printf("%s    packet filter\n", indent);
 2749         break;
 2750     case 0x1b:      /* MBIM functional desc */
 2751         type = "MBIM";
 2752         if (buf[0] != 12)
 2753             goto bad;
 2754         printf("%sCDC MBIM:\n"
 2755                "%s  bcdMBIMVersion       %x.%02x\n"
 2756                "%s  wMaxControlMessage   %d\n"
 2757                "%s  bNumberFilters       %d\n"
 2758                "%s  bMaxFilterSize       %d\n"
 2759                "%s  wMaxSegmentSize      %d\n"
 2760                "%s  bmNetworkCapabilities 0x%02x\n",
 2761                indent,
 2762                indent, buf[4], buf[3],
 2763                indent, (buf[6] << 8) | buf[5],
 2764                indent, buf[7],
 2765                indent, buf[8],
 2766                indent, (buf[10] << 8) | buf[9],
 2767                indent, buf[11]);
 2768         if (buf[11] & 0x20)
 2769             printf("%s    8-byte ntb input size\n", indent);
 2770         if (buf[11] & 0x08)
 2771             printf("%s    max datagram size\n", indent);
 2772         break;
 2773     case 0x1c:      /* MBIM extended functional desc */
 2774         type = "MBIM Extended";
 2775         if (buf[0] != 8)
 2776             goto bad;
 2777         printf("%sCDC MBIM Extended:\n"
 2778                "%s  bcdMBIMExtendedVersion          %2x.%02x\n"
 2779                "%s  bMaxOutstandingCommandMessages    %3d\n"
 2780                "%s  wMTU                            %5d\n",
 2781                indent,
 2782                indent, buf[4], buf[3],
 2783                indent, buf[5],
 2784                indent, buf[6] | (buf[7] << 8));
 2785         break;
 2786     default:
 2787         /* FIXME there are about a dozen more descriptor types */
 2788         printf("%sUNRECOGNIZED CDC: ", indent);
 2789         dump_bytes(buf, buf[0]);
 2790         return "unrecognized comm descriptor";
 2791     }
 2792 
 2793     free(str);
 2794 
 2795     return 0;
 2796 
 2797 bad:
 2798     printf("%sINVALID CDC (%s): ", indent, type);
 2799     dump_bytes(buf, buf[0]);
 2800     return "corrupt comm descriptor";
 2801 }
 2802 
 2803 /* ---------------------------------------------------------------------- */
 2804 
 2805 static void do_hub(libusb_device_handle *fd, unsigned tt_type, unsigned speed)
 2806 {
 2807     unsigned char buf[7 /* base descriptor */
 2808             + 2 /* bitmasks */ * HUB_STATUS_BYTELEN];
 2809     int i, ret, value;
 2810     unsigned int link_state;
 2811     const char * const link_state_descriptions[] = {
 2812         "U0",
 2813         "U1",
 2814         "U2",
 2815         "suspend",
 2816         "SS.disabled",
 2817         "Rx.Detect",
 2818         "SS.Inactive",
 2819         "Polling",
 2820         "Recovery",
 2821         "Hot Reset",
 2822         "Compliance",
 2823         "Loopback",
 2824     };
 2825 
 2826     /* USB 3.x hubs have a slightly different descriptor */
 2827     if (speed >= 0x0300)
 2828         value = 0x2A;
 2829     else
 2830         value = 0x29;
 2831 
 2832     ret = usb_control_msg(fd,
 2833             LIBUSB_ENDPOINT_IN | LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_RECIPIENT_DEVICE,
 2834             LIBUSB_REQUEST_GET_DESCRIPTOR,
 2835             value << 8, 0,
 2836             buf, sizeof buf, CTRL_TIMEOUT);
 2837     if (ret < 0) {
 2838         /* Linux returns EHOSTUNREACH for suspended devices */
 2839         if (errno != EHOSTUNREACH)
 2840             fprintf(stderr, "can't get hub descriptor, %s (%s)\n",
 2841                 libusb_error_name(ret), strerror(errno));
 2842         return;
 2843     }
 2844     if (ret < 9 /* at least one port's bitmasks */) {
 2845         fprintf(stderr,
 2846             "incomplete hub descriptor, %d bytes\n",
 2847             ret);
 2848         return;
 2849     }
 2850     dump_hub("", buf, tt_type);
 2851 
 2852     printf(" Hub Port Status:\n");
 2853     for (i = 0; i < buf[2]; i++) {
 2854         unsigned char status[4];
 2855 
 2856         ret = usb_control_msg(fd,
 2857                 LIBUSB_ENDPOINT_IN | LIBUSB_REQUEST_TYPE_CLASS
 2858                     | LIBUSB_RECIPIENT_OTHER,
 2859                 LIBUSB_REQUEST_GET_STATUS,
 2860                 0, i + 1,
 2861                 status, sizeof status,
 2862                 CTRL_TIMEOUT);
 2863         if (ret < 0) {
 2864             fprintf(stderr,
 2865                 "cannot read port %d status, %s (%d)\n",
 2866                 i + 1, strerror(errno), errno);
 2867             break;
 2868         }
 2869 
 2870         printf("   Port %d: %02x%02x.%02x%02x", i + 1,
 2871             status[3], status[2],
 2872             status[1], status[0]);
 2873         /* CAPS are used to highlight "transient" states */
 2874         if (speed != 0x0300) {
 2875             printf("%s%s%s%s%s",
 2876                     (status[2] & 0x10) ? " C_RESET" : "",
 2877                     (status[2] & 0x08) ? " C_OC" : "",
 2878                     (status[2] & 0x04) ? " C_SUSPEND" : "",
 2879                     (status[2] & 0x02) ? " C_ENABLE" : "",
 2880                     (status[2] & 0x01) ? " C_CONNECT" : "");
 2881             printf("%s%s%s%s%s%s%s%s%s%s%s\n",
 2882                     (status[1] & 0x10) ? " indicator" : "",
 2883                     (status[1] & 0x08) ? " test" : "",
 2884                     (status[1] & 0x04) ? " highspeed" : "",
 2885                     (status[1] & 0x02) ? " lowspeed" : "",
 2886                     (status[1] & 0x01) ? " power" : "",
 2887                     (status[0] & 0x20) ? " L1" : "",
 2888                     (status[0] & 0x10) ? " RESET" : "",
 2889                     (status[0] & 0x08) ? " oc" : "",
 2890                     (status[0] & 0x04) ? " suspend" : "",
 2891                     (status[0] & 0x02) ? " enable" : "",
 2892                     (status[0] & 0x01) ? " connect" : "");
 2893         } else {
 2894             link_state = ((status[0] & 0xe0) >> 5) +
 2895                 ((status[1] & 0x1) << 3);
 2896             printf("%s%s%s%s%s%s",
 2897                     (status[2] & 0x80) ? " C_CONFIG_ERROR" : "",
 2898                     (status[2] & 0x40) ? " C_LINK_STATE" : "",
 2899                     (status[2] & 0x20) ? " C_BH_RESET" : "",
 2900                     (status[2] & 0x10) ? " C_RESET" : "",
 2901                     (status[2] & 0x08) ? " C_OC" : "",
 2902                     (status[2] & 0x01) ? " C_CONNECT" : "");
 2903             printf("%s%s",
 2904                     ((status[1] & 0x1C) == 0) ? " 5Gbps" : " Unknown Speed",
 2905                     (status[1] & 0x02) ? " power" : "");
 2906             /* Link state is bits 8:5 */
 2907             if (link_state < (sizeof(link_state_descriptions) /
 2908                         sizeof(*link_state_descriptions)))
 2909                 printf(" %s", link_state_descriptions[link_state]);
 2910             printf("%s%s%s%s\n",
 2911                     (status[0] & 0x10) ? " RESET" : "",
 2912                     (status[0] & 0x08) ? " oc" : "",
 2913                     (status[0] & 0x02) ? " enable" : "",
 2914                     (status[0] & 0x01) ? " connect" : "");
 2915         }
 2916     }
 2917 }
 2918 
 2919 static void do_dualspeed(libusb_device_handle *fd)
 2920 {
 2921     unsigned char buf[10];
 2922     char cls[128], subcls[128], proto[128];
 2923     int ret;
 2924 
 2925     ret = usb_control_msg(fd,
 2926             LIBUSB_ENDPOINT_IN | LIBUSB_REQUEST_TYPE_STANDARD | LIBUSB_RECIPIENT_DEVICE,
 2927             LIBUSB_REQUEST_GET_DESCRIPTOR,
 2928             USB_DT_DEVICE_QUALIFIER << 8, 0,
 2929             buf, sizeof buf, CTRL_TIMEOUT);
 2930 
 2931     /* We don't need to complain to the user if the device is claimed
 2932      * and we aren't allowed to access the device qualifier.
 2933      */
 2934     if (ret < 0 && errno != EPIPE) {
 2935         if (verblevel > 1 || errno != EAGAIN)
 2936             perror("can't get device qualifier");
 2937     }
 2938 
 2939     /* all dual-speed devices have a qualifier */
 2940     if (ret != sizeof buf
 2941             || buf[0] != ret
 2942             || buf[1] != USB_DT_DEVICE_QUALIFIER)
 2943         return;
 2944 
 2945     get_class_string(cls, sizeof(cls),
 2946             buf[4]);
 2947     get_subclass_string(subcls, sizeof(subcls),
 2948             buf[4], buf[5]);
 2949     get_protocol_string(proto, sizeof(proto),
 2950             buf[4], buf[5], buf[6]);
 2951     printf("Device Qualifier (for other device speed):\n"
 2952            "  bLength             %5u\n"
 2953            "  bDescriptorType     %5u\n"
 2954            "  bcdUSB              %2x.%02x\n"
 2955            "  bDeviceClass        %5u %s\n"
 2956            "  bDeviceSubClass     %5u %s\n"
 2957            "  bDeviceProtocol     %5u %s\n"
 2958            "  bMaxPacketSize0     %5u\n"
 2959            "  bNumConfigurations  %5u\n",
 2960            buf[0], buf[1],
 2961            buf[3], buf[2],
 2962            buf[4], cls,
 2963            buf[5], subcls,
 2964            buf[6], proto,
 2965            buf[7], buf[8]);
 2966 
 2967     /* FIXME also show the OTHER_SPEED_CONFIG descriptors */
 2968 }
 2969 
 2970 static void do_debug(libusb_device_handle *fd)
 2971 {
 2972     unsigned char buf[4];
 2973     int ret;
 2974 
 2975     ret = usb_control_msg(fd,
 2976             LIBUSB_ENDPOINT_IN | LIBUSB_REQUEST_TYPE_STANDARD | LIBUSB_RECIPIENT_DEVICE,
 2977             LIBUSB_REQUEST_GET_DESCRIPTOR,
 2978             USB_DT_DEBUG << 8, 0,
 2979             buf, sizeof buf, CTRL_TIMEOUT);
 2980 
 2981     /* We don't need to complain to the user if the device is claimed
 2982      * and we aren't allowed to access the debug descriptor.
 2983      */
 2984     if (ret < 0 && errno != EPIPE) {
 2985         if (verblevel > 1 || errno != EAGAIN)
 2986             perror("can't get debug descriptor");
 2987     }
 2988 
 2989     /* some high speed devices are also "USB2 debug devices", meaning
 2990      * you can use them with some EHCI implementations as another kind
 2991      * of system debug channel:  like JTAG, RS232, or a console.
 2992      */
 2993     if (ret != sizeof buf
 2994             || buf[0] != ret
 2995             || buf[1] != USB_DT_DEBUG)
 2996         return;
 2997 
 2998     printf("Debug descriptor:\n"
 2999            "  bLength              %4u\n"
 3000            "  bDescriptorType      %4u\n"
 3001            "  bDebugInEndpoint     0x%02x\n"
 3002            "  bDebugOutEndpoint    0x%02x\n",
 3003            buf[0], buf[1],
 3004            buf[2], buf[3]);
 3005 }
 3006 
 3007 static const unsigned char *find_otg(const unsigned char *buf, int buflen)
 3008 {
 3009     if (!buf)
 3010         return 0;
 3011     while (buflen >= 3) {
 3012         if (buf[0] == 3 && buf[1] == USB_DT_OTG)
 3013             return buf;
 3014         if (buf[0] > buflen)
 3015             return 0;
 3016         buflen -= buf[0];
 3017         buf += buf[0];
 3018     }
 3019     return 0;
 3020 }
 3021 
 3022 static int do_otg(struct libusb_config_descriptor *config)
 3023 {
 3024     unsigned    i, k;
 3025     int     j;
 3026     const unsigned char *desc;
 3027 
 3028     /* each config of an otg device has an OTG descriptor */
 3029     desc = find_otg(config->extra, config->extra_length);
 3030     for (i = 0; !desc && i < config->bNumInterfaces; i++) {
 3031         const struct libusb_interface *intf;
 3032 
 3033         intf = &config->interface[i];
 3034         for (j = 0; !desc && j < intf->num_altsetting; j++) {
 3035             const struct libusb_interface_descriptor *alt;
 3036 
 3037             alt = &intf->altsetting[j];
 3038             desc = find_otg(alt->extra, alt->extra_length);
 3039             for (k = 0; !desc && k < alt->bNumEndpoints; k++) {
 3040                 const struct libusb_endpoint_descriptor *ep;
 3041 
 3042                 ep = &alt->endpoint[k];
 3043                 desc = find_otg(ep->extra, ep->extra_length);
 3044             }
 3045         }
 3046     }
 3047     if (!desc)
 3048         return 0;
 3049 
 3050     printf("OTG Descriptor:\n"
 3051         "  bLength               %3u\n"
 3052         "  bDescriptorType       %3u\n"
 3053         "  bmAttributes         0x%02x\n"
 3054         "%s%s",
 3055         desc[0], desc[1], desc[2],
 3056         (desc[2] & 0x01)
 3057             ? "    SRP (Session Request Protocol)\n" : "",
 3058         (desc[2] & 0x02)
 3059             ? "    HNP (Host Negotiation Protocol)\n" : "");
 3060     return 1;
 3061 }
 3062 
 3063 static void
 3064 dump_device_status(libusb_device_handle *fd, int otg, int wireless, int super_speed)
 3065 {
 3066     unsigned char status[8];
 3067     int ret;
 3068 
 3069     ret = usb_control_msg(fd, LIBUSB_ENDPOINT_IN | LIBUSB_REQUEST_TYPE_STANDARD
 3070                 | LIBUSB_RECIPIENT_DEVICE,
 3071             LIBUSB_REQUEST_GET_STATUS,
 3072             0, 0,
 3073             status, 2,
 3074             CTRL_TIMEOUT);
 3075     if (ret < 0) {
 3076         fprintf(stderr,
 3077             "cannot read device status, %s (%d)\n",
 3078             strerror(errno), errno);
 3079         return;
 3080     }
 3081 
 3082     printf("Device Status:     0x%02x%02x\n",
 3083             status[1], status[0]);
 3084     if (status[0] & (1 << 0))
 3085         printf("  Self Powered\n");
 3086     else
 3087         printf("  (Bus Powered)\n");
 3088     if (status[0] & (1 << 1))
 3089         printf("  Remote Wakeup Enabled\n");
 3090     if (status[0] & (1 << 2) && !super_speed) {
 3091         /* for high speed devices */
 3092         if (!wireless)
 3093             printf("  Test Mode\n");
 3094         /* for devices with Wireless USB support */
 3095         else
 3096             printf("  Battery Powered\n");
 3097     }
 3098     if (super_speed) {
 3099         if (status[0] & (1 << 2))
 3100             printf("  U1 Enabled\n");
 3101         if (status[0] & (1 << 3))
 3102             printf("  U2 Enabled\n");
 3103         if (status[0] & (1 << 4))
 3104             printf("  Latency Tolerance Messaging (LTM) Enabled\n");
 3105     }
 3106     /* if both HOST and DEVICE support OTG */
 3107     if (otg) {
 3108         if (status[0] & (1 << 3))
 3109             printf("  HNP Enabled\n");
 3110         if (status[0] & (1 << 4))
 3111             printf("  HNP Capable\n");
 3112         if (status[0] & (1 << 5))
 3113             printf("  ALT port is HNP Capable\n");
 3114     }
 3115     /* for high speed devices with debug descriptors */
 3116     if (status[0] & (1 << 6))
 3117         printf("  Debug Mode\n");
 3118 
 3119     if (!wireless)
 3120         return;
 3121 
 3122     /* Wireless USB exposes FIVE different types of device status,
 3123      * accessed by distinct wIndex values.
 3124      */
 3125     ret = usb_control_msg(fd, LIBUSB_ENDPOINT_IN | LIBUSB_REQUEST_TYPE_STANDARD
 3126                 | LIBUSB_RECIPIENT_DEVICE,
 3127             LIBUSB_REQUEST_GET_STATUS,
 3128             0, 1 /* wireless status */,
 3129             status, 1,
 3130             CTRL_TIMEOUT);
 3131     if (ret < 0) {
 3132         fprintf(stderr,
 3133             "cannot read wireless %s, %s (%d)\n",
 3134             "status",
 3135             strerror(errno), errno);
 3136         return;
 3137     }
 3138     printf("Wireless Status:     0x%02x\n", status[0]);
 3139     if (status[0] & (1 << 0))
 3140         printf("  TX Drp IE\n");
 3141     if (status[0] & (1 << 1))
 3142         printf("  Transmit Packet\n");
 3143     if (status[0] & (1 << 2))
 3144         printf("  Count Packets\n");
 3145     if (status[0] & (1 << 3))
 3146         printf("  Capture Packet\n");
 3147 
 3148     ret = usb_control_msg(fd, LIBUSB_ENDPOINT_IN | LIBUSB_REQUEST_TYPE_STANDARD
 3149                 | LIBUSB_RECIPIENT_DEVICE,
 3150             LIBUSB_REQUEST_GET_STATUS,
 3151             0, 2 /* Channel Info */,
 3152             status, 1,
 3153             CTRL_TIMEOUT);
 3154     if (ret < 0) {
 3155         fprintf(stderr,
 3156             "cannot read wireless %s, %s (%d)\n",
 3157             "channel info",
 3158             strerror(errno), errno);
 3159         return;
 3160     }
 3161     printf("Channel Info:        0x%02x\n", status[0]);
 3162 
 3163     /* 3=Received data: many bytes, for count packets or capture packet */
 3164 
 3165     ret = usb_control_msg(fd, LIBUSB_ENDPOINT_IN | LIBUSB_REQUEST_TYPE_STANDARD
 3166                 | LIBUSB_RECIPIENT_DEVICE,
 3167             LIBUSB_REQUEST_GET_STATUS,
 3168             0, 3 /* MAS Availability */,
 3169             status, 8,
 3170             CTRL_TIMEOUT);
 3171     if (ret < 0) {
 3172         fprintf(stderr,
 3173             "cannot read wireless %s, %s (%d)\n",
 3174             "MAS info",
 3175             strerror(errno), errno);
 3176         return;
 3177     }
 3178     printf("MAS Availability:    ");
 3179     dump_bytes(status, 8);
 3180 
 3181     ret = usb_control_msg(fd, LIBUSB_ENDPOINT_IN | LIBUSB_REQUEST_TYPE_STANDARD
 3182                 | LIBUSB_RECIPIENT_DEVICE,
 3183             LIBUSB_REQUEST_GET_STATUS,
 3184             0, 5 /* Current Transmit Power */,
 3185             status, 2,
 3186             CTRL_TIMEOUT);
 3187     if (ret < 0) {
 3188         fprintf(stderr,
 3189             "cannot read wireless %s, %s (%d)\n",
 3190             "transmit power",
 3191             strerror(errno), errno);
 3192         return;
 3193     }
 3194     printf("Transmit Power:\n");
 3195     printf(" TxNotification:     0x%02x\n", status[0]);
 3196     printf(" TxBeacon:     :     0x%02x\n", status[1]);
 3197 }
 3198 
 3199 static int do_wireless(libusb_device_handle *fd)
 3200 {
 3201     /* FIXME fetch and dump BOS etc */
 3202     if (fd)
 3203         return 0;
 3204     return 0;
 3205 }
 3206 
 3207 static void dump_usb2_device_capability_desc(unsigned char *buf)
 3208 {
 3209     unsigned int wide;
 3210 
 3211     wide = buf[3] + (buf[4] << 8) +
 3212         (buf[5] << 16) + (buf[6] << 24);
 3213     printf("  USB 2.0 Extension Device Capability:\n"
 3214             "    bLength             %5u\n"
 3215             "    bDescriptorType     %5u\n"
 3216             "    bDevCapabilityType  %5u\n"
 3217             "    bmAttributes   0x%08x\n",
 3218             buf[0], buf[1], buf[2], wide);
 3219     if (!(wide & 0x02))
 3220         printf("      (Missing must-be-set LPM bit!)\n");
 3221     else if (!(wide & 0x04))
 3222         printf("      HIRD Link Power Management (LPM)"
 3223                 " Supported\n");
 3224     else {
 3225         printf("      BESL Link Power Management (LPM)"
 3226                 " Supported\n");
 3227         if (wide & 0x08)
 3228             printf("    BESL value    %5u us \n", wide & 0xf00);
 3229         if (wide & 0x10)
 3230             printf("    Deep BESL value    %5u us \n",
 3231                     wide & 0xf000);
 3232     }
 3233 }
 3234 
 3235 static void dump_ss_device_capability_desc(unsigned char *buf)
 3236 {
 3237     if (buf[0] < 10) {
 3238         fprintf(stderr, "  Bad SuperSpeed USB Device Capability descriptor.\n");
 3239         return;
 3240     }
 3241     printf("  SuperSpeed USB Device Capability:\n"
 3242             "    bLength             %5u\n"
 3243             "    bDescriptorType     %5u\n"
 3244             "    bDevCapabilityType  %5u\n"
 3245             "    bmAttributes         0x%02x\n",
 3246             buf[0], buf[1], buf[2], buf[3]);
 3247     if (buf[3] & 0x02)
 3248         printf("      Latency Tolerance Messages (LTM)"
 3249                 " Supported\n");
 3250     printf("    wSpeedsSupported   0x%02x%02x\n", buf[5], buf[4]);
 3251     if (buf[4] & (1 << 0))
 3252         printf("      Device can operate at Low Speed (1Mbps)\n");
 3253     if (buf[4] & (1 << 1))
 3254         printf("      Device can operate at Full Speed (12Mbps)\n");
 3255     if (buf[4] & (1 << 2))
 3256         printf("      Device can operate at High Speed (480Mbps)\n");
 3257     if (buf[4] & (1 << 3))
 3258         printf("      Device can operate at SuperSpeed (5Gbps)\n");
 3259 
 3260     printf("    bFunctionalitySupport %3u\n", buf[6]);
 3261     switch(buf[6]) {
 3262     case 0:
 3263         printf("      Lowest fully-functional device speed is "
 3264                 "Low Speed (1Mbps)\n");
 3265         break;
 3266     case 1:
 3267         printf("      Lowest fully-functional device speed is "
 3268                 "Full Speed (12Mbps)\n");
 3269         break;
 3270     case 2:
 3271         printf("      Lowest fully-functional device speed is "
 3272                 "High Speed (480Mbps)\n");
 3273         break;
 3274     case 3:
 3275         printf("      Lowest fully-functional device speed is "
 3276                 "SuperSpeed (5Gbps)\n");
 3277         break;
 3278     default:
 3279         printf("      Lowest fully-functional device speed is "
 3280                 "at an unknown speed!\n");
 3281         break;
 3282     }
 3283     printf("    bU1DevExitLat        %4u micro seconds\n", buf[7]);
 3284     printf("    bU2DevExitLat    %8u micro seconds\n", buf[8] + (buf[9] << 8));
 3285 }
 3286 
 3287 static void dump_ssp_device_capability_desc(unsigned char *buf)
 3288 {
 3289     int i;
 3290     unsigned int bm_attr, ss_attr;
 3291     char bitrate_prefix[] = " KMG";
 3292 
 3293     if (buf[0] < 12) {
 3294         fprintf(stderr, "  Bad SuperSpeedPlus USB Device Capability descriptor.\n");
 3295         return;
 3296     }
 3297 
 3298     bm_attr = convert_le_u32(buf + 4);
 3299     printf("  SuperSpeedPlus USB Device Capability:\n"
 3300             "    bLength             %5u\n"
 3301             "    bDescriptorType     %5u\n"
 3302             "    bDevCapabilityType  %5u\n"
 3303             "    bmAttributes         0x%08x\n",
 3304             buf[0], buf[1], buf[2], bm_attr);
 3305 
 3306     printf("      Sublink Speed Attribute count %u\n", buf[4] & 0x1f);
 3307     printf("      Sublink Speed ID count %u\n", (bm_attr >> 5) & 0xf);
 3308     printf("    wFunctionalitySupport   0x%02x%02x\n", buf[9], buf[8]);
 3309 
 3310     for (i = 0; i <= (buf[4] & 0x1f); i++) {
 3311         ss_attr = convert_le_u32(buf + 12 + (i * 4));
 3312         printf("    bmSublinkSpeedAttr[%u]   0x%08x\n", i, ss_attr);
 3313         printf("      Speed Attribute ID: %u %u%cb/s %s %s SuperSpeed%s\n",
 3314                ss_attr & 0x0f,
 3315                ss_attr >> 16,
 3316                (bitrate_prefix[((ss_attr >> 4) & 0x3)]),
 3317                (ss_attr & 0x40)? "Asymmetric" : "Symmetric",
 3318                (ss_attr & 0x80)? "TX" : "RX",
 3319                (ss_attr & 0x4000)? "Plus": "" );
 3320     }
 3321 }
 3322 
 3323 static void dump_container_id_device_capability_desc(unsigned char *buf)
 3324 {
 3325     if (buf[0] < 20) {
 3326         fprintf(stderr, "  Bad Container ID Device Capability descriptor.\n");
 3327         return;
 3328     }
 3329     printf("  Container ID Device Capability:\n"
 3330             "    bLength             %5u\n"
 3331             "    bDescriptorType     %5u\n"
 3332             "    bDevCapabilityType  %5u\n"
 3333             "    bReserved           %5u\n",
 3334             buf[0], buf[1], buf[2], buf[3]);
 3335     printf("    ContainerID             %s\n",
 3336             get_guid(&buf[4]));
 3337 }
 3338 
 3339 static char *get_webusb_url(libusb_device_handle *fd, uint8_t vendor_req, uint8_t id)
 3340 {
 3341     unsigned char url_buf[255];
 3342     char *scheme;
 3343     char *url, *chr;
 3344     unsigned char i;
 3345     int ret;
 3346 
 3347     ret = usb_control_msg(fd,
 3348             LIBUSB_ENDPOINT_IN | LIBUSB_RECIPIENT_DEVICE | LIBUSB_REQUEST_TYPE_VENDOR,
 3349             vendor_req, id, WEBUSB_GET_URL,
 3350             url_buf, sizeof(url_buf), CTRL_TIMEOUT);
 3351     if (ret <= 0)
 3352         return strdup("");
 3353     else if (url_buf[0] <= 3 || url_buf[1] != USB_DT_WEBUSB_URL || ret != url_buf[0])
 3354         return strdup("");
 3355 
 3356     switch (url_buf[2]) {
 3357     case 0:
 3358         scheme = "http://";
 3359         break;
 3360     case 1:
 3361         scheme = "https://";
 3362         break;
 3363     case 255:
 3364         scheme = "";
 3365         break;
 3366     default:
 3367         fprintf(stderr, "Bad URL scheme.\n");
 3368         return strdup("");
 3369     }
 3370     url = malloc(strlen(scheme) + (url_buf[0] - 3)  + 1);
 3371     if (!url)
 3372         return strdup("");
 3373     strcpy(url, scheme);
 3374     chr = url + strlen(scheme);
 3375     for (i = 3; i < url_buf[0]; i++)
 3376         /* crude UTF-8 to ASCII conversion */
 3377         if (url_buf[i] < 0x80)
 3378             *chr++ = url_buf[i];
 3379     *chr = '\0';
 3380 
 3381     return url;
 3382 }
 3383 
 3384 static void dump_platform_device_capability_desc(libusb_device_handle *fd, unsigned char *buf)
 3385 {
 3386     unsigned char desc_len = buf[0];
 3387     unsigned char cap_data_len = desc_len - 20;
 3388     unsigned char i;
 3389     const char *guid;
 3390     if (desc_len < 20) {
 3391         fprintf(stderr, "  Bad Platform Device Capability descriptor.\n");
 3392         return;
 3393     }
 3394     printf("  Platform Device Capability:\n"
 3395             "    bLength             %5u\n"
 3396             "    bDescriptorType     %5u\n"
 3397             "    bDevCapabilityType  %5u\n"
 3398             "    bReserved           %5u\n",
 3399             buf[0], buf[1], buf[2], buf[3]);
 3400     guid = get_guid(&buf[4]);
 3401     printf("    PlatformCapabilityUUID    %s\n", guid);
 3402 
 3403     if (!strcmp(WEBUSB_GUID , guid) && desc_len == 24) {
 3404         /* WebUSB platform descriptor */
 3405         char *url = get_webusb_url(fd, buf[22], buf[23]);
 3406         printf("      WebUSB:\n"
 3407                 "        bcdVersion   %2x.%02x\n"
 3408                 "        bVendorCode  %5u\n"
 3409                 "        iLandingPage %5u %s\n",
 3410                 buf[21], buf[20], buf[22], buf[23], url);
 3411         free(url);
 3412         return;
 3413     }
 3414 
 3415     for (i = 0; i < cap_data_len; i++) {
 3416         printf("    CapabilityData[%u]    0x%02x\n", i, buf[20 + i]);
 3417     }
 3418 }
 3419 
 3420 static void dump_billboard_device_capability_desc(libusb_device_handle *dev, unsigned char *buf)
 3421 {
 3422     char *url, *alt_mode_str;
 3423     int w_vconn_power, alt_mode, i, svid, state;
 3424     const char *vconn;
 3425     unsigned char *bmConfigured;
 3426 
 3427     if (buf[0] < 48) {
 3428         fprintf(stderr, "  Bad Billboard Capability descriptor.\n");
 3429         return;
 3430     }
 3431 
 3432     if (buf[4] > BILLBOARD_MAX_NUM_ALT_MODE) {
 3433         fprintf(stderr, "  Invalid value for bNumberOfAlternateModes.\n");
 3434         return;
 3435     }
 3436 
 3437     if (buf[0] < (44 + buf[4] * 4)) {
 3438         fprintf(stderr, "  bLength does not match with bNumberOfAlternateModes.\n");
 3439         return;
 3440     }
 3441 
 3442     url = get_dev_string(dev, buf[3]);
 3443     w_vconn_power = convert_le_u16(buf+6);
 3444     if (w_vconn_power & (1 << 15)) {
 3445         vconn = "VCONN power not required";
 3446     } else if (w_vconn_power < 7) {
 3447         vconn = vconn_power[w_vconn_power & 0x7];
 3448     } else {
 3449         vconn = "reserved";
 3450     }
 3451     printf("  Billboard Capability:\n"
 3452             "    bLength                 %5u\n"
 3453             "    bDescriptorType         %5u\n"
 3454             "    bDevCapabilityType      %5u\n"
 3455             "    iAdditionalInfoURL      %5u %s\n"
 3456             "    bNumberOfAlternateModes %5u\n"
 3457             "    bPreferredAlternateMode %5u\n"
 3458             "    VCONN Power             %5u %s\n",
 3459             buf[0], buf[1], buf[2],
 3460             buf[3], url,
 3461             buf[4], buf[5],
 3462             w_vconn_power, vconn);
 3463 
 3464     bmConfigured = &buf[8];
 3465 
 3466     printf("    bmConfigured               ");
 3467     dump_bytes(bmConfigured, 32);
 3468 
 3469     printf(
 3470             "    bcdVersion              %2x.%02x\n"
 3471             "    bAdditionalFailureInfo  %5u\n"
 3472             "    bReserved               %5u\n",
 3473             (buf[41] == 0) ? 1 : buf[41], buf[40],
 3474             buf[42], buf[43]);
 3475 
 3476     printf("    Alternate Modes supported by Device Container:\n");
 3477     i = 44; /* Alternate mode 0 starts at index 44 */
 3478     for (alt_mode = 0; alt_mode < buf[4]; alt_mode++) {
 3479         svid = convert_le_u16(buf+i);
 3480         alt_mode_str = get_dev_string(dev, buf[i+3]);
 3481         state = ((bmConfigured[alt_mode >> 2]) >> ((alt_mode & 0x3) << 1)) & 0x3;
 3482         printf(
 3483             "    Alternate Mode %d : %s\n"
 3484             "      wSVID[%d]                    0x%04X\n"
 3485             "      bAlternateMode[%d]       %5u\n"
 3486             "      iAlternateModeString[%d] %5u %s\n",
 3487             alt_mode, alt_mode_state[state],
 3488             alt_mode, svid,
 3489             alt_mode, buf[i+2],
 3490             alt_mode, buf[i+3], alt_mode_str);
 3491         free(alt_mode_str);
 3492         i += 4;
 3493     }
 3494 
 3495     free (url);
 3496 }
 3497 
 3498 static void dump_billboard_alt_mode_capability_desc(libusb_device_handle *dev, unsigned char *buf)
 3499 {
 3500     if (buf[0] != 8) {
 3501         fprintf(stderr, "  Bad Billboard Alternate Mode Capability descriptor.\n");
 3502         return;
 3503     }
 3504 
 3505     printf("  Billboard Alternate Mode Capability:\n"
 3506             "    bLength                 %5u\n"
 3507             "    bDescriptorType         %5u\n"
 3508             "    bDevCapabilityType      %5u\n"
 3509             "    bIndex                  %5u\n"
 3510             "    dwAlternateModeVdo          0x%02X%02X%02X%02X\n",
 3511             buf[0], buf[1], buf[2], buf[3],
 3512             buf[4], buf[5], buf[6], buf[7]);
 3513 }
 3514 
 3515 static void dump_bos_descriptor(libusb_device_handle *fd)
 3516 {
 3517     /* Total length of BOS descriptors varies.
 3518      * Read first static 5 bytes which include the total length before
 3519      * allocating and reading the full BOS
 3520      */
 3521 
 3522     unsigned char bos_desc_static[5];
 3523     unsigned char *bos_desc;
 3524     unsigned int bos_desc_size;
 3525     int size, ret;
 3526     unsigned char *buf;
 3527 
 3528     /* Get the first 5 bytes to get the wTotalLength field */
 3529     ret = usb_control_msg(fd,
 3530             LIBUSB_ENDPOINT_IN | LIBUSB_RECIPIENT_DEVICE,
 3531             LIBUSB_REQUEST_GET_DESCRIPTOR,
 3532             USB_DT_BOS << 8, 0,
 3533             bos_desc_static, 5, CTRL_TIMEOUT);
 3534     if (ret <= 0)
 3535         return;
 3536     else if (bos_desc_static[0] != 5 || bos_desc_static[1] != USB_DT_BOS)
 3537         return;
 3538 
 3539     bos_desc_size = bos_desc_static[2] + (bos_desc_static[3] << 8);
 3540     printf("Binary Object Store Descriptor:\n"
 3541            "  bLength             %5u\n"
 3542            "  bDescriptorType     %5u\n"
 3543            "  wTotalLength       0x%04x\n"
 3544            "  bNumDeviceCaps      %5u\n",
 3545            bos_desc_static[0], bos_desc_static[1],
 3546            bos_desc_size, bos_desc_static[4]);
 3547 
 3548     if (bos_desc_size <= 5) {
 3549         if (bos_desc_static[4] > 0)
 3550             fprintf(stderr, "Couldn't get "
 3551                     "device capability descriptors\n");
 3552         return;
 3553     }
 3554     bos_desc = malloc(bos_desc_size);
 3555     if (!bos_desc)
 3556         return;
 3557     memset(bos_desc, 0, bos_desc_size);
 3558 
 3559     ret = usb_control_msg(fd,
 3560             LIBUSB_ENDPOINT_IN | LIBUSB_RECIPIENT_DEVICE,
 3561             LIBUSB_REQUEST_GET_DESCRIPTOR,
 3562             USB_DT_BOS << 8, 0,
 3563             bos_desc, bos_desc_size, CTRL_TIMEOUT);
 3564     if (ret < 0) {
 3565         fprintf(stderr, "Couldn't get device capability descriptors\n");
 3566         goto out;
 3567     }
 3568 
 3569     size = bos_desc_size - 5;
 3570     buf = &bos_desc[5];
 3571 
 3572     while (size >= 3) {
 3573         if (buf[0] < 3) {
 3574             printf("buf[0] = %u\n", buf[0]);
 3575             goto out;
 3576         }
 3577         switch (buf[2]) {
 3578         case USB_DC_WIRELESS_USB:
 3579             /* FIXME */
 3580             break;
 3581         case USB_DC_20_EXTENSION:
 3582             dump_usb2_device_capability_desc(buf);
 3583             break;
 3584         case USB_DC_SUPERSPEED:
 3585             dump_ss_device_capability_desc(buf);
 3586             break;
 3587         case USB_DC_SUPERSPEEDPLUS:
 3588             dump_ssp_device_capability_desc(buf);
 3589             break;
 3590         case USB_DC_CONTAINER_ID:
 3591             dump_container_id_device_capability_desc(buf);
 3592             break;
 3593         case USB_DC_PLATFORM:
 3594             dump_platform_device_capability_desc(fd, buf);
 3595             break;
 3596         case USB_DC_BILLBOARD:
 3597             dump_billboard_device_capability_desc(fd, buf);
 3598             break;
 3599         case USB_DC_BILLBOARD_ALT_MODE:
 3600             dump_billboard_alt_mode_capability_desc(fd, buf);
 3601             break;
 3602         case USB_DC_CONFIGURATION_SUMMARY:
 3603             printf("  Configuration Summary Device Capability:\n");
 3604             desc_dump(fd, desc_usb3_dc_configuration_summary,
 3605                     buf, DESC_BUF_LEN_FROM_BUF, 2);
 3606             break;
 3607         default:
 3608             printf("  ** UNRECOGNIZED: ");
 3609             dump_bytes(buf, buf[0]);
 3610             break;
 3611         }
 3612         size -= buf[0];
 3613         buf += buf[0];
 3614     }
 3615 out:
 3616     free(bos_desc);
 3617 }
 3618 
 3619 static void dumpdev(libusb_device *dev)
 3620 {
 3621     libusb_device_handle *udev;
 3622     struct libusb_device_descriptor desc;
 3623     int i, ret;
 3624     int otg, wireless;
 3625 
 3626     otg = wireless = 0;
 3627     ret = libusb_open(dev, &udev);
 3628     if (ret) {
 3629         fprintf(stderr, "Couldn't open device, some information "
 3630             "will be missing\n");
 3631         udev = NULL;
 3632     }
 3633 
 3634     libusb_get_device_descriptor(dev, &desc);
 3635     dump_device(dev, &desc);
 3636     if (desc.bcdUSB == 0x0250)
 3637         wireless = do_wireless(udev);
 3638     if (desc.bNumConfigurations) {
 3639         struct libusb_config_descriptor *config;
 3640 
 3641         ret = libusb_get_config_descriptor(dev, 0, &config);
 3642         if (ret) {
 3643             fprintf(stderr, "Couldn't get configuration descriptor 0, "
 3644                     "some information will be missing\n");
 3645         } else {
 3646             otg = do_otg(config) || otg;
 3647             libusb_free_config_descriptor(config);
 3648         }
 3649 
 3650         for (i = 0; i < desc.bNumConfigurations; ++i) {
 3651             ret = libusb_get_config_descriptor(dev, i, &config);
 3652             if (ret) {
 3653                 fprintf(stderr, "Couldn't get configuration "
 3654                         "descriptor %d, some information will "
 3655                         "be missing\n", i);
 3656             } else {
 3657                 dump_config(udev, config, desc.bcdUSB);
 3658                 libusb_free_config_descriptor(config);
 3659             }
 3660         }
 3661     }
 3662     if (!udev)
 3663         return;
 3664 
 3665     if (desc.bDeviceClass == LIBUSB_CLASS_HUB)
 3666         do_hub(udev, desc.bDeviceProtocol, desc.bcdUSB);
 3667     if (desc.bcdUSB >= 0x0201) {
 3668         dump_bos_descriptor(udev);
 3669     }
 3670     if (desc.bcdUSB == 0x0200) {
 3671         do_dualspeed(udev);
 3672     }
 3673     do_debug(udev);
 3674     dump_device_status(udev, otg, wireless, desc.bcdUSB >= 0x0300);
 3675     libusb_close(udev);
 3676 }
 3677 
 3678 /* ---------------------------------------------------------------------- */
 3679 
 3680 /*
 3681  * Attempt to get friendly vendor and product names from the udev hwdb. If
 3682  * either or both are not present, instead populate those from the device's
 3683  * own string descriptors.
 3684  */
 3685 static void get_vendor_product_with_fallback(char *vendor, int vendor_len,
 3686                          char *product, int product_len,
 3687                          libusb_device *dev)
 3688 {
 3689     struct libusb_device_descriptor desc;
 3690     char sysfs_name[PATH_MAX];
 3691     bool have_vendor, have_product;
 3692 
 3693     libusb_get_device_descriptor(dev, &desc);
 3694 
 3695     have_vendor = !!get_vendor_string(vendor, vendor_len, desc.idVendor);
 3696     have_product = !!get_product_string(product, product_len,
 3697             desc.idVendor, desc.idProduct);
 3698 
 3699     if (have_vendor && have_product)
 3700         return;
 3701 
 3702     if (get_sysfs_name(sysfs_name, sizeof(sysfs_name), dev) >= 0) {
 3703         if (!have_vendor)
 3704             read_sysfs_prop(vendor, vendor_len, sysfs_name,
 3705                     "manufacturer");
 3706         if (!have_product)
 3707             read_sysfs_prop(product, product_len, sysfs_name,
 3708                     "product");
 3709     }
 3710 }
 3711 
 3712 static int dump_one_device(libusb_context *ctx, const char *path)
 3713 {
 3714     libusb_device *dev;
 3715     struct libusb_device_descriptor desc;
 3716     char vendor[128], product[128];
 3717 
 3718     dev = get_usb_device(ctx, path);
 3719     if (!dev) {
 3720         fprintf(stderr, "Cannot open %s\n", path);
 3721         return 1;
 3722     }
 3723     libusb_get_device_descriptor(dev, &desc);
 3724     get_vendor_product_with_fallback(vendor, sizeof(vendor),
 3725             product, sizeof(product), dev);
 3726     printf("Device: ID %04x:%04x %s %s\n", desc.idVendor,
 3727                            desc.idProduct,
 3728                            vendor,
 3729                            product);
 3730     dumpdev(dev);
 3731     return 0;
 3732 }
 3733 
 3734 static int list_devices(libusb_context *ctx, int busnum, int devnum, int vendorid, int productid)
 3735 {
 3736     libusb_device **list;
 3737     struct libusb_device_descriptor desc;
 3738     char vendor[128], product[128];
 3739     int status;
 3740     ssize_t num_devs, i;
 3741 
 3742     status = 1; /* 1 device not found, 0 device found */
 3743 
 3744     num_devs = libusb_get_device_list(ctx, &list);
 3745     if (num_devs < 0)
 3746         goto error;
 3747 
 3748     for (i = 0; i < num_devs; ++i) {
 3749         libusb_device *dev = list[i];
 3750         uint8_t bnum = libusb_get_bus_number(dev);
 3751         uint8_t dnum = libusb_get_device_address(dev);
 3752 
 3753         if ((busnum != -1 && busnum != bnum) ||
 3754             (devnum != -1 && devnum != dnum))
 3755             continue;
 3756         libusb_get_device_descriptor(dev, &desc);
 3757         if ((vendorid != -1 && vendorid != desc.idVendor) ||
 3758             (productid != -1 && productid != desc.idProduct))
 3759             continue;
 3760         status = 0;
 3761 
 3762         get_vendor_product_with_fallback(vendor, sizeof(vendor),
 3763                 product, sizeof(product), dev);
 3764 
 3765         if (verblevel > 0)
 3766             printf("\n");
 3767         printf("Bus %03u Device %03u: ID %04x:%04x %s %s\n",
 3768                 bnum, dnum,
 3769                 desc.idVendor,
 3770                 desc.idProduct,
 3771                 vendor, product);
 3772         if (verblevel > 0)
 3773             dumpdev(dev);
 3774     }
 3775 
 3776     libusb_free_device_list(list, 0);
 3777 error:
 3778     return status;
 3779 }
 3780 
 3781 
 3782 /* ---------------------------------------------------------------------- */
 3783 
 3784 int main(int argc, char *argv[])
 3785 {
 3786     static const struct option long_options[] = {
 3787         { "version", 0, 0, 'V' },
 3788         { "verbose", 0, 0, 'v' },
 3789         { "help", 0, 0, 'h' },
 3790         { "tree", 0, 0, 't' },
 3791         { 0, 0, 0, 0 }
 3792     };
 3793     libusb_context *ctx;
 3794     int c, err = 0;
 3795     unsigned int treemode = 0;
 3796     int bus = -1, devnum = -1, vendor = -1, product = -1;
 3797     const char *devdump = NULL;
 3798     int help = 0;
 3799     char *cp;
 3800     int status;
 3801 
 3802     setlocale(LC_CTYPE, "");
 3803 
 3804     while ((c = getopt_long(argc, argv, "D:vtP:p:s:d:Vh",
 3805             long_options, NULL)) != EOF) {
 3806         switch (c) {
 3807         case 'V':
 3808             printf("lsusb (" PACKAGE ") " VERSION "\n");
 3809             return EXIT_SUCCESS;
 3810         case 'v':
 3811             verblevel++;
 3812             break;
 3813 
 3814         case 'h':
 3815             help=1;
 3816             break;
 3817 
 3818         case 't':
 3819             treemode = 1;
 3820             break;
 3821 
 3822         case 's':
 3823             cp = strchr(optarg, ':');
 3824             if (cp) {
 3825                 *cp++ = 0;
 3826                 if (*optarg)
 3827                     bus = strtoul(optarg, NULL, 10);
 3828                 if (*cp)
 3829                     devnum = strtoul(cp, NULL, 10);
 3830             } else {
 3831                 if (*optarg)
 3832                     devnum = strtoul(optarg, NULL, 10);
 3833             }
 3834             break;
 3835 
 3836         case 'd':
 3837             cp = strchr(optarg, ':');
 3838             if (!cp) {
 3839                 err++;
 3840                 break;
 3841             }
 3842             *cp++ = 0;
 3843             if (*optarg)
 3844                 vendor = strtoul(optarg, NULL, 16);
 3845             if (*cp)
 3846                 product = strtoul(cp, NULL, 16);
 3847             break;
 3848 
 3849         case 'D':
 3850             devdump = optarg;
 3851             break;
 3852 
 3853         case '?':
 3854         default:
 3855             err++;
 3856             break;
 3857         }
 3858     }
 3859     if (err || argc > optind || help) {
 3860         fprintf(stderr, "Usage: lsusb [options]...\n"
 3861             "List USB devices\n"
 3862             "  -v, --verbose\n"
 3863             "      Increase verbosity (show descriptors)\n"
 3864             "  -s [[bus]:][devnum]\n"
 3865             "      Show only devices with specified device and/or\n"
 3866             "      bus numbers (in decimal)\n"
 3867             "  -d vendor:[product]\n"
 3868             "      Show only devices with the specified vendor and\n"
 3869             "      product ID numbers (in hexadecimal)\n"
 3870             "  -D device\n"
 3871             "      Selects which device lsusb will examine\n"
 3872             "  -t, --tree\n"
 3873             "      Dump the physical USB device hierarchy as a tree\n"
 3874             "  -V, --version\n"
 3875             "      Show version of program\n"
 3876             "  -h, --help\n"
 3877             "      Show usage and help\n"
 3878             );
 3879         return EXIT_FAILURE;
 3880     }
 3881 
 3882 
 3883     /* by default, print names as well as numbers */
 3884     if (names_init() < 0)
 3885         fprintf(stderr, "unable to initialize usb spec");
 3886 
 3887     status = 0;
 3888 
 3889     if (treemode) {
 3890         status = lsusb_t();
 3891         names_exit();
 3892         return status;
 3893     }
 3894 
 3895     err = libusb_init(&ctx);
 3896     if (err) {
 3897         fprintf(stderr, "unable to initialize libusb: %i\n", err);
 3898         return EXIT_FAILURE;
 3899     }
 3900 
 3901     if (devdump)
 3902         status = dump_one_device(ctx, devdump);
 3903     else
 3904         status = list_devices(ctx, bus, devnum, vendor, product);
 3905 
 3906     names_exit();
 3907     libusb_exit(ctx);
 3908     return status;
 3909 }