1 /*****************************************************************************/
4 * lsusb.c -- lspci like utility for the USB bus
6 * Copyright (C) 1999-2001, 2003
7 * Thomas Sailer (t.sailer@alumni.ethz.ch)
8 * Copyright (C) 2003-2005 David Brownell
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
22 /*****************************************************************************/
25 #include <sys/types.h>
35 #ifdef HAVE_BYTESWAP_H
48 #define le16_to_cpu(x) libusb_cpu_to_le16(libusb_cpu_to_le16(x))
50 /* from USB 2.0 spec and updates */
51 #define USB_DT_DEVICE_QUALIFIER 0x06
52 #define USB_DT_OTHER_SPEED_CONFIG 0x07
53 #define USB_DT_OTG 0x09
54 #define USB_DT_DEBUG 0x0a
55 #define USB_DT_INTERFACE_ASSOCIATION 0x0b
56 #define USB_DT_SECURITY 0x0c
57 #define USB_DT_KEY 0x0d
58 #define USB_DT_ENCRYPTION_TYPE 0x0e
59 #define USB_DT_BOS 0x0f
60 #define USB_DT_DEVICE_CAPABILITY 0x10
61 #define USB_DT_WIRELESS_ENDPOINT_COMP 0x11
62 #define USB_DT_WIRE_ADAPTER 0x21
63 #define USB_DT_RPIPE 0x22
64 #define USB_DT_RC_INTERFACE 0x23
65 #define USB_DT_SS_ENDPOINT_COMP 0x30
67 /* Device Capability Type Codes (Wireless USB spec and USB 3.0 bus spec) */
68 #define USB_DC_WIRELESS_USB 0x01
69 #define USB_DC_20_EXTENSION 0x02
70 #define USB_DC_SUPERSPEED 0x03
71 #define USB_DC_CONTAINER_ID 0x04
73 /* Conventional codes for class-specific descriptors. The convention is
74 * defined in the USB "Common Class" Spec (3.11). Individual class specs
75 * are authoritative for their usage, not the "common class" writeup.
77 #define USB_DT_CS_DEVICE (LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_DT_DEVICE)
78 #define USB_DT_CS_CONFIG (LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_DT_CONFIG)
79 #define USB_DT_CS_STRING (LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_DT_STRING)
80 #define USB_DT_CS_INTERFACE (LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_DT_INTERFACE)
81 #define USB_DT_CS_ENDPOINT (LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_DT_ENDPOINT)
83 #ifndef USB_CLASS_CCID
84 #define USB_CLASS_CCID 0x0b
87 #ifndef USB_CLASS_VIDEO
88 #define USB_CLASS_VIDEO 0x0e
91 #ifndef USB_CLASS_APPLICATION
92 #define USB_CLASS_APPLICATION 0xfe
95 #ifndef USB_AUDIO_CLASS_1
96 #define USB_AUDIO_CLASS_1 0x00
99 #ifndef USB_AUDIO_CLASS_2
100 #define USB_AUDIO_CLASS_2 0x20
103 #define VERBLEVEL_DEFAULT 0 /* 0 gives lspci behaviour; 1, lsusb-0.9 */
105 #define CTRL_RETRIES 2
106 #define CTRL_TIMEOUT (5*1000) /* milliseconds */
108 #define HUB_STATUS_BYTELEN 3 /* max 3 bytes status = hub + 23 ports */
110 static const char procbususb[] = "/proc/bus/usb";
111 static unsigned int verblevel = VERBLEVEL_DEFAULT;
112 static int do_report_desc = 1;
113 static const char * const encryption_type[] = {
121 static void dump_interface(libusb_device_handle *dev, const struct libusb_interface *interface);
122 static void dump_endpoint(libusb_device_handle *dev, const struct libusb_interface_descriptor *interface, const struct libusb_endpoint_descriptor *endpoint);
123 static void dump_audiocontrol_interface(libusb_device_handle *dev, const unsigned char *buf, int protocol);
124 static void dump_audiostreaming_interface(libusb_device_handle *dev, const unsigned char *buf, int protocol);
125 static void dump_midistreaming_interface(libusb_device_handle *dev, const unsigned char *buf);
126 static void dump_videocontrol_interface(libusb_device_handle *dev, const unsigned char *buf);
127 static void dump_videostreaming_interface(const unsigned char *buf);
128 static void dump_dfu_interface(const unsigned char *buf);
129 static char *dump_comm_descriptor(libusb_device_handle *dev, const unsigned char *buf, char *indent);
130 static void dump_hid_device(libusb_device_handle *dev, const struct libusb_interface_descriptor *interface, const unsigned char *buf);
131 static void dump_audiostreaming_endpoint(const unsigned char *buf, int protocol);
132 static void dump_midistreaming_endpoint(const unsigned char *buf);
133 static void dump_hub(const char *prefix, const unsigned char *p, int tt_type);
134 static void dump_ccid_device(const unsigned char *buf);
136 /* ---------------------------------------------------------------------- */
138 static unsigned int convert_le_u32 (const unsigned char *buf)
140 return buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24);
143 /* ---------------------------------------------------------------------- */
145 /* workaround libusb API goofs: "byte" should never be sign extended;
146 * using "char" is trouble. Likewise, sizes should never be negative.
149 static inline int typesafe_control_msg(libusb_device_handle *dev,
150 unsigned char requesttype, unsigned char request,
152 unsigned char *bytes, unsigned size, int timeout)
154 int ret = libusb_control_transfer(dev, requesttype, request, value,
155 idx, bytes, size, timeout);
163 #define usb_control_msg typesafe_control_msg
165 static int get_protocol_string(char *buf, size_t size, u_int8_t cls, u_int8_t subcls, u_int8_t proto)
172 if (!(cp = names_protocol(cls, subcls, proto)))
174 return snprintf(buf, size, "%s", cp);
177 static int get_audioterminal_string(char *buf, size_t size, u_int16_t termt)
184 if (!(cp = names_audioterminal(termt)))
186 return snprintf(buf, size, "%s", cp);
189 static int get_videoterminal_string(char *buf, size_t size, u_int16_t termt)
196 if (!(cp = names_videoterminal(termt)))
198 return snprintf(buf, size, "%s", cp);
201 static const char *get_guid(const unsigned char *buf)
203 static char guid[39];
205 /* NOTE: see RFC 4122 for more information about GUID/UUID
206 * structure. The first fields fields are historically big
207 * endian numbers, dating from Apollo mc68000 workstations.
209 sprintf(guid, "{%02x%02x%02x%02x"
213 "-%02x%02x%02x%02x%02x%02x}",
214 buf[0], buf[1], buf[2], buf[3],
218 buf[10], buf[11], buf[12], buf[13], buf[14], buf[15]);
222 /* ---------------------------------------------------------------------- */
224 static void dump_bytes(const unsigned char *buf, unsigned int len)
228 for (i = 0; i < len; i++)
229 printf(" %02x", buf[i]);
233 static void dump_junk(const unsigned char *buf, const char *indent, unsigned int len)
239 printf("%sjunk at descriptor end:", indent);
240 for (i = len; i < buf[0]; i++)
241 printf(" %02x", buf[i]);
246 * General config descriptor dump
249 static void dump_device(
250 libusb_device_handle *dev,
251 struct libusb_device_descriptor *descriptor
254 char vendor[128], product[128];
255 char cls[128], subcls[128], proto[128];
256 char *mfg, *prod, *serial;
258 get_vendor_string(vendor, sizeof(vendor), descriptor->idVendor);
259 get_product_string(product, sizeof(product),
260 descriptor->idVendor, descriptor->idProduct);
261 get_class_string(cls, sizeof(cls), descriptor->bDeviceClass);
262 get_subclass_string(subcls, sizeof(subcls),
263 descriptor->bDeviceClass, descriptor->bDeviceSubClass);
264 get_protocol_string(proto, sizeof(proto), descriptor->bDeviceClass,
265 descriptor->bDeviceSubClass, descriptor->bDeviceProtocol);
267 mfg = get_dev_string(dev, descriptor->iManufacturer);
268 prod = get_dev_string(dev, descriptor->iProduct);
269 serial = get_dev_string(dev, descriptor->iSerialNumber);
271 printf("Device Descriptor:\n"
273 " bDescriptorType %5u\n"
275 " bDeviceClass %5u %s\n"
276 " bDeviceSubClass %5u %s\n"
277 " bDeviceProtocol %5u %s\n"
278 " bMaxPacketSize0 %5u\n"
279 " idVendor 0x%04x %s\n"
280 " idProduct 0x%04x %s\n"
281 " bcdDevice %2x.%02x\n"
282 " iManufacturer %5u %s\n"
285 " bNumConfigurations %5u\n",
286 descriptor->bLength, descriptor->bDescriptorType,
287 descriptor->bcdUSB >> 8, descriptor->bcdUSB & 0xff,
288 descriptor->bDeviceClass, cls,
289 descriptor->bDeviceSubClass, subcls,
290 descriptor->bDeviceProtocol, proto,
291 descriptor->bMaxPacketSize0,
292 descriptor->idVendor, vendor, descriptor->idProduct, product,
293 descriptor->bcdDevice >> 8, descriptor->bcdDevice & 0xff,
294 descriptor->iManufacturer, mfg,
295 descriptor->iProduct, prod,
296 descriptor->iSerialNumber, serial,
297 descriptor->bNumConfigurations);
304 static void dump_wire_adapter(const unsigned char *buf)
307 printf(" Wire Adapter Class Descriptor:\n"
309 " bDescriptorType %5u\n"
310 " bcdWAVersion %2x.%02x\n"
312 " bmAttributes %5u\n"
314 " wRPipeMaxBlock %5u\n"
315 " bRPipeBlockSize %5u\n"
316 " bPwrOn2PwrGood %5u\n"
318 " DeviceRemovable %5u\n",
319 buf[0], buf[1], buf[3], buf[2], buf[4], buf[5],
320 (buf[6] | buf[7] << 8),
321 (buf[8] | buf[9] << 8),
322 buf[10], buf[11], buf[12], buf[13]);
325 static void dump_rc_interface(const unsigned char *buf)
327 printf(" Radio Control Interface Class Descriptor:\n"
329 " bDescriptorType %5u\n"
330 " bcdRCIVersion %2x.%02x\n",
331 buf[0], buf[1], buf[3], buf[2]);
335 static void dump_security(const unsigned char *buf)
337 printf(" Security Descriptor:\n"
339 " bDescriptorType %5u\n"
340 " wTotalLength %5u\n"
341 " bNumEncryptionTypes %5u\n",
342 buf[0], buf[1], (buf[3] << 8 | buf[2]), buf[4]);
345 static void dump_encryption_type(const unsigned char *buf)
347 int b_encryption_type = buf[2] & 0x4;
349 printf(" Encryption Type Descriptor:\n"
351 " bDescriptorType %5u\n"
352 " bEncryptionType %5u %s\n"
353 " bEncryptionValue %5u\n"
354 " bAuthKeyIndex %5u\n",
355 buf[0], buf[1], buf[2],
356 encryption_type[b_encryption_type], buf[3], buf[4]);
359 static void dump_association(libusb_device_handle *dev, const unsigned char *buf)
361 char cls[128], subcls[128], proto[128];
364 get_class_string(cls, sizeof(cls), buf[4]);
365 get_subclass_string(subcls, sizeof(subcls), buf[4], buf[5]);
366 get_protocol_string(proto, sizeof(proto), buf[4], buf[5], buf[6]);
367 func = get_dev_string(dev, buf[7]);
369 printf(" Interface Association:\n"
371 " bDescriptorType %5u\n"
372 " bFirstInterface %5u\n"
373 " bInterfaceCount %5u\n"
374 " bFunctionClass %5u %s\n"
375 " bFunctionSubClass %5u %s\n"
376 " bFunctionProtocol %5u %s\n"
377 " iFunction %5u %s\n",
388 static void dump_config(libusb_device_handle *dev, struct libusb_config_descriptor *config)
393 cfg = get_dev_string(dev, config->iConfiguration);
395 printf(" Configuration Descriptor:\n"
397 " bDescriptorType %5u\n"
398 " wTotalLength %5u\n"
399 " bNumInterfaces %5u\n"
400 " bConfigurationValue %5u\n"
401 " iConfiguration %5u %s\n"
402 " bmAttributes 0x%02x\n",
403 config->bLength, config->bDescriptorType,
404 le16_to_cpu(config->wTotalLength),
405 config->bNumInterfaces, config->bConfigurationValue,
406 config->iConfiguration,
407 cfg, config->bmAttributes);
411 if (!(config->bmAttributes & 0x80))
412 printf(" (Missing must-be-set bit!)\n");
413 if (config->bmAttributes & 0x40)
414 printf(" Self Powered\n");
416 printf(" (Bus Powered)\n");
417 if (config->bmAttributes & 0x20)
418 printf(" Remote Wakeup\n");
419 if (config->bmAttributes & 0x10)
420 printf(" Battery Powered\n");
421 printf(" MaxPower %5umA\n", config->MaxPower * 2);
423 /* avoid re-ordering or hiding descriptors for display */
424 if (config->extra_length) {
425 int size = config->extra_length;
426 const unsigned char *buf = config->extra;
430 dump_junk(buf, " ", size);
435 /* handled separately */
437 case USB_DT_INTERFACE_ASSOCIATION:
438 dump_association(dev, buf);
440 case USB_DT_SECURITY:
443 case USB_DT_ENCRYPTION_TYPE:
444 dump_encryption_type(buf);
447 /* often a misplaced class descriptor */
448 printf(" ** UNRECOGNIZED: ");
449 dump_bytes(buf, buf[0]);
456 for (i = 0 ; i < config->bNumInterfaces ; i++)
457 dump_interface(dev, &config->interface[i]);
460 static void dump_altsetting(libusb_device_handle *dev, const struct libusb_interface_descriptor *interface)
462 char cls[128], subcls[128], proto[128];
465 const unsigned char *buf;
468 get_class_string(cls, sizeof(cls), interface->bInterfaceClass);
469 get_subclass_string(subcls, sizeof(subcls), interface->bInterfaceClass, interface->bInterfaceSubClass);
470 get_protocol_string(proto, sizeof(proto), interface->bInterfaceClass, interface->bInterfaceSubClass, interface->bInterfaceProtocol);
471 ifstr = get_dev_string(dev, interface->iInterface);
473 printf(" Interface Descriptor:\n"
475 " bDescriptorType %5u\n"
476 " bInterfaceNumber %5u\n"
477 " bAlternateSetting %5u\n"
478 " bNumEndpoints %5u\n"
479 " bInterfaceClass %5u %s\n"
480 " bInterfaceSubClass %5u %s\n"
481 " bInterfaceProtocol %5u %s\n"
482 " iInterface %5u %s\n",
483 interface->bLength, interface->bDescriptorType, interface->bInterfaceNumber,
484 interface->bAlternateSetting, interface->bNumEndpoints, interface->bInterfaceClass, cls,
485 interface->bInterfaceSubClass, subcls, interface->bInterfaceProtocol, proto,
486 interface->iInterface, ifstr);
490 /* avoid re-ordering or hiding descriptors for display */
491 if (interface->extra_length) {
492 size = interface->extra_length;
493 buf = interface->extra;
494 while (size >= 2 * sizeof(u_int8_t)) {
496 dump_junk(buf, " ", size);
502 /* This is the polite way to provide class specific
503 * descriptors: explicitly tagged, using common class
506 case USB_DT_CS_DEVICE:
507 case USB_DT_CS_INTERFACE:
508 switch (interface->bInterfaceClass) {
509 case LIBUSB_CLASS_AUDIO:
510 switch (interface->bInterfaceSubClass) {
512 dump_audiocontrol_interface(dev, buf, interface->bInterfaceProtocol);
515 dump_audiostreaming_interface(dev, buf, interface->bInterfaceProtocol);
518 dump_midistreaming_interface(dev, buf);
524 case LIBUSB_CLASS_COMM:
525 dump_comm_descriptor(dev, buf,
528 case USB_CLASS_VIDEO:
529 switch (interface->bInterfaceSubClass) {
531 dump_videocontrol_interface(dev, buf);
534 dump_videostreaming_interface(buf);
540 case USB_CLASS_APPLICATION:
541 switch (interface->bInterfaceSubClass) {
543 dump_dfu_interface(buf);
549 case LIBUSB_CLASS_HID:
550 dump_hid_device(dev, interface, buf);
553 dump_ccid_device(buf);
560 /* This is the ugly way: implicitly tagged,
561 * each class could redefine the type IDs.
564 switch (interface->bInterfaceClass) {
565 case LIBUSB_CLASS_HID:
566 dump_hid_device(dev, interface, buf);
569 dump_ccid_device(buf);
571 case 0xe0: /* wireless */
572 switch (interface->bInterfaceSubClass) {
574 switch (interface->bInterfaceProtocol) {
576 dump_rc_interface(buf);
583 dump_wire_adapter(buf);
589 case LIBUSB_CLASS_AUDIO:
591 /* MISPLACED DESCRIPTOR */
592 case USB_DT_CS_ENDPOINT:
593 switch (interface->bInterfaceSubClass) {
595 dump_audiostreaming_endpoint(buf, interface->bInterfaceProtocol);
606 /* ... not everything is class-specific */
609 /* handled separately */
611 case USB_DT_INTERFACE_ASSOCIATION:
612 dump_association(dev, buf);
616 /* often a misplaced class descriptor */
617 printf(" ** UNRECOGNIZED: ");
618 dump_bytes(buf, buf[0]);
628 for (i = 0 ; i < interface->bNumEndpoints ; i++)
629 dump_endpoint(dev, interface, &interface->endpoint[i]);
632 static void dump_interface(libusb_device_handle *dev, const struct libusb_interface *interface)
636 for (i = 0; i < interface->num_altsetting; i++)
637 dump_altsetting(dev, &interface->altsetting[i]);
640 static void dump_pipe_desc(const unsigned char *buf)
642 static const char *pipe_name[] = {
648 [5 ... 0xDF] = "Reserved",
649 [0xE0 ... 0xEF] = "Vendor specific",
650 [0xF0 ... 0xFF] = "Reserved",
653 if (buf[0] == 4 && buf[1] == 0x24) {
654 printf(" %s (0x%02x)\n", pipe_name[buf[2]], buf[2]);
656 printf(" INTERFACE CLASS: ");
657 dump_bytes(buf, buf[0]);
661 static void dump_endpoint(libusb_device_handle *dev, const struct libusb_interface_descriptor *interface, const struct libusb_endpoint_descriptor *endpoint)
663 static const char * const typeattr[] = {
669 static const char * const syncattr[] = {
675 static const char * const usage[] = {
678 "Implicit feedback Data",
681 static const char * const hb[] = { "1x", "2x", "3x", "(?\?)" };
682 const unsigned char *buf;
684 unsigned wmax = le16_to_cpu(endpoint->wMaxPacketSize);
686 printf(" Endpoint Descriptor:\n"
688 " bDescriptorType %5u\n"
689 " bEndpointAddress 0x%02x EP %u %s\n"
690 " bmAttributes %5u\n"
691 " Transfer Type %s\n"
694 " wMaxPacketSize 0x%04x %s %d bytes\n"
697 endpoint->bDescriptorType,
698 endpoint->bEndpointAddress,
699 endpoint->bEndpointAddress & 0x0f,
700 (endpoint->bEndpointAddress & 0x80) ? "IN" : "OUT",
701 endpoint->bmAttributes,
702 typeattr[endpoint->bmAttributes & 3],
703 syncattr[(endpoint->bmAttributes >> 2) & 3],
704 usage[(endpoint->bmAttributes >> 4) & 3],
705 wmax, hb[(wmax >> 11) & 3], wmax & 0x7ff,
706 endpoint->bInterval);
707 /* only for audio endpoints */
708 if (endpoint->bLength == 9)
709 printf(" bRefresh %5u\n"
710 " bSynchAddress %5u\n",
711 endpoint->bRefresh, endpoint->bSynchAddress);
713 /* avoid re-ordering or hiding descriptors for display */
714 if (endpoint->extra_length) {
715 size = endpoint->extra_length;
716 buf = endpoint->extra;
717 while (size >= 2 * sizeof(u_int8_t)) {
719 dump_junk(buf, " ", size);
723 case USB_DT_CS_ENDPOINT:
724 if (interface->bInterfaceClass == 1 && interface->bInterfaceSubClass == 2)
725 dump_audiostreaming_endpoint(buf, interface->bInterfaceProtocol);
726 else if (interface->bInterfaceClass == 1 && interface->bInterfaceSubClass == 3)
727 dump_midistreaming_endpoint(buf);
729 case USB_DT_CS_INTERFACE:
730 /* MISPLACED DESCRIPTOR ... less indent */
731 switch (interface->bInterfaceClass) {
732 case LIBUSB_CLASS_COMM:
733 case LIBUSB_CLASS_DATA: /* comm data */
734 dump_comm_descriptor(dev, buf,
737 case LIBUSB_CLASS_MASS_STORAGE:
741 printf(" INTERFACE CLASS: ");
742 dump_bytes(buf, buf[0]);
745 case USB_DT_CS_DEVICE:
746 /* MISPLACED DESCRIPTOR ... less indent */
747 switch (interface->bInterfaceClass) {
749 dump_ccid_device(buf);
752 printf(" DEVICE CLASS: ");
753 dump_bytes(buf, buf[0]);
757 /* handled separately */
759 case USB_DT_INTERFACE_ASSOCIATION:
760 dump_association(dev, buf);
762 case USB_DT_SS_ENDPOINT_COMP:
763 printf(" bMaxBurst %15u\n", buf[2]);
764 /* Print bulk streams info or isoc "Mult" */
765 if ((endpoint->bmAttributes & 3) == 2 &&
767 printf(" MaxStreams %14u\n",
768 (unsigned) 1 << buf[3]);
769 if ((endpoint->bmAttributes & 3) == 1 &&
771 printf(" Mult %20u\n",
775 /* often a misplaced class descriptor */
776 printf(" ** UNRECOGNIZED: ");
777 dump_bytes(buf, buf[0]);
786 static void dump_unit(unsigned int data, unsigned int len)
788 char *systems[5] = { "None", "SI Linear", "SI Rotation",
789 "English Linear", "English Rotation" };
791 char *units[5][8] = {
792 { "None", "None", "None", "None", "None",
793 "None", "None", "None" },
794 { "None", "Centimeter", "Gram", "Seconds", "Kelvin",
795 "Ampere", "Candela", "None" },
796 { "None", "Radians", "Gram", "Seconds", "Kelvin",
797 "Ampere", "Candela", "None" },
798 { "None", "Inch", "Slug", "Seconds", "Fahrenheit",
799 "Ampere", "Candela", "None" },
800 { "None", "Degrees", "Slug", "Seconds", "Fahrenheit",
801 "Ampere", "Candela", "None" },
806 int earlier_unit = 0;
808 /* First nibble tells us which system we're in. */
814 printf("System: Vendor defined, Unit: (unknown)\n");
816 printf("System: Reserved, Unit: (unknown)\n");
819 printf("System: %s, Unit: ", systems[sys]);
821 for (i = 1 ; i < len * 2 ; i++) {
822 char nibble = data & 0xf;
825 if (earlier_unit++ > 0)
827 printf("%s", units[sys][i]);
829 /* This is a _signed_ nibble(!) */
831 int val = nibble & 0x7;
833 val = -((0x7 & ~val) + 1);
838 if (earlier_unit == 0)
843 /* ---------------------------------------------------------------------- */
846 * Audio Class descriptor dump
854 static const struct bmcontrol uac2_interface_header_bmcontrols[] = {
855 { "Latency control", 0 },
859 static const struct bmcontrol uac_fu_bmcontrols[] = {
865 { "Graphic Equalizer", 5 },
866 { "Automatic Gain", 6 },
870 { "Input gain", 10 },
871 { "Input gain pad", 11 },
872 { "Phase inverter", 12 },
876 static const struct bmcontrol uac2_input_term_bmcontrols[] = {
877 { "Copy Protect", 0 },
886 static const struct bmcontrol uac2_output_term_bmcontrols[] = {
887 { "Copy Protect", 0 },
895 static const struct bmcontrol uac2_mixer_unit_bmcontrols[] = {
902 static const struct bmcontrol uac2_extension_unit_bmcontrols[] = {
910 static const struct bmcontrol uac2_clock_source_bmcontrols[] = {
911 { "Clock Frequency", 0 },
912 { "Clock Validity", 1 },
916 static const struct bmcontrol uac2_clock_selector_bmcontrols[] = {
917 { "Clock Selector", 0 },
921 static const struct bmcontrol uac2_clock_multiplier_bmcontrols[] = {
922 { "Clock Numerator", 0 },
923 { "Clock Denominator", 1 },
927 static const struct bmcontrol uac2_selector_bmcontrols[] = {
932 static void dump_audio_bmcontrols(const char *prefix, int bmcontrols, const struct bmcontrol *list, int protocol)
936 case USB_AUDIO_CLASS_1:
937 if (bmcontrols & (1 << list->bit))
938 printf("%s%s Control\n", prefix, list->name);
942 case USB_AUDIO_CLASS_2: {
943 const char * const ctrl_type[] = { "read-only", "ILLEGAL (0b10)", "read/write" };
944 int ctrl = (bmcontrols >> (list->bit * 2)) & 0x3;
947 printf("%s%s Control (%s)\n", prefix, list->name, ctrl_type[ctrl-1]);
958 static const char * const chconfig_uac2[] = {
959 "Front Left (FL)", "Front Right (FR)", "Front Center (FC)", "Low Frequency Effects (LFE)",
960 "Back Left (BL)", "Back Right (BR)", "Front Left of Center (FLC)", "Front Right of Center (FRC)", "Back Center (BC)",
961 "Side Left (SL)", "Side Right (SR)",
962 "Top Center (TC)", "Top Front Left (TFL)", "Top Front Center (TFC)", "Top Front Right (TFR)", "Top Back Left (TBL)",
963 "Top Back Center (TBC)", "Top Back Right (TBR)", "Top Front Left of Center (TFLC)", "Top Front Right of Center (TFRC)",
964 "Left Low Frequency Effects (LLFE)", "Right Low Frequency Effects (RLFE)",
965 "Top Side Left (TSL)", "Top Side Right (TSR)", "Bottom Center (BC)",
966 "Back Left of Center (BLC)", "Back Right of Center (BRC)"
969 static void dump_audiocontrol_interface(libusb_device_handle *dev, const unsigned char *buf, int protocol)
971 static const char * const chconfig[] = {
972 "Left Front (L)", "Right Front (R)", "Center Front (C)", "Low Freqency Enhancement (LFE)",
973 "Left Surround (LS)", "Right Surround (RS)", "Left of Center (LC)", "Right of Center (RC)",
974 "Surround (S)", "Side Left (SL)", "Side Right (SR)", "Top (T)"
976 static const char * const clock_source_attrs[] = {
977 "External", "Internal fixed", "Internal variable", "Internal programmable"
979 unsigned int i, chcfg, j, k, N, termt, subtype;
980 char *chnames = NULL, *term = NULL, termts[128];
982 if (buf[1] != USB_DT_CS_INTERFACE)
983 printf(" Warning: Invalid descriptor\n");
985 printf(" Warning: Descriptor too short\n");
986 printf(" AudioControl Interface Descriptor:\n"
988 " bDescriptorType %5u\n"
989 " bDescriptorSubtype %5u ",
990 buf[0], buf[1], buf[2]);
993 * This is an utter mess - UAC2 defines some bDescriptorSubtype differently, so we have to do some ugly remapping here:
995 * bDescriptorSubtype UAC1 UAC2
996 * ------------------------------------------------------------------------
997 * 0x07 PROCESSING_UNIT EFFECT_UNIT
998 * 0x08 EXTENSION_UNIT PROCESSING_UNIT
999 * 0x09 - EXTENSION_UNIT
1003 if (protocol == USB_AUDIO_CLASS_2)
1005 case 0x07: subtype = 0xf0; break; /* effect unit */
1006 case 0x08: subtype = 0x07; break; /* processing unit */
1007 case 0x09: subtype = 0x08; break; /* extension unit */
1008 default: subtype = buf[2]; break; /* everything else is identical */
1014 case 0x01: /* HEADER */
1015 printf("(HEADER)\n");
1017 case USB_AUDIO_CLASS_1:
1018 if (buf[0] < 8+buf[7])
1019 printf(" Warning: Descriptor too short\n");
1020 printf(" bcdADC %2x.%02x\n"
1021 " wTotalLength %5u\n"
1022 " bInCollection %5u\n",
1023 buf[4], buf[3], buf[5] | (buf[6] << 8), buf[7]);
1024 for (i = 0; i < buf[7]; i++)
1025 printf(" baInterfaceNr(%2u) %5u\n", i, buf[8+i]);
1026 dump_junk(buf, " ", 8+buf[7]);
1028 case USB_AUDIO_CLASS_2:
1030 printf(" Warning: Descriptor too short\n");
1031 printf(" bcdADC %2x.%02x\n"
1033 " wTotalLength %5u\n"
1034 " bmControl 0x%02x\n",
1035 buf[4], buf[3], buf[5], buf[6] | (buf[7] << 8), buf[8]);
1036 dump_audio_bmcontrols(" ", buf[8], uac2_interface_header_bmcontrols, protocol);
1041 case 0x02: /* INPUT_TERMINAL */
1042 printf("(INPUT_TERMINAL)\n");
1043 termt = buf[4] | (buf[5] << 8);
1044 get_audioterminal_string(termts, sizeof(termts), termt);
1047 case USB_AUDIO_CLASS_1:
1048 chnames = get_dev_string(dev, buf[10]);
1049 term = get_dev_string(dev, buf[11]);
1051 printf(" Warning: Descriptor too short\n");
1052 chcfg = buf[8] | (buf[9] << 8);
1053 printf(" bTerminalID %5u\n"
1054 " wTerminalType 0x%04x %s\n"
1055 " bAssocTerminal %5u\n"
1056 " bNrChannels %5u\n"
1057 " wChannelConfig 0x%04x\n",
1058 buf[3], termt, termts, buf[6], buf[7], chcfg);
1059 for (i = 0; i < 12; i++)
1060 if ((chcfg >> i) & 1)
1061 printf(" %s\n", chconfig[i]);
1062 printf(" iChannelNames %5u %s\n"
1063 " iTerminal %5u %s\n",
1064 buf[10], chnames, buf[11], term);
1065 dump_junk(buf, " ", 12);
1067 case USB_AUDIO_CLASS_2:
1068 chnames = get_dev_string(dev, buf[13]);
1069 term = get_dev_string(dev, buf[16]);
1071 printf(" Warning: Descriptor too short\n");
1072 chcfg = buf[9] | (buf[10] << 8) | (buf[11] << 16) | (buf[12] << 24);
1073 printf(" bTerminalID %5u\n"
1074 " wTerminalType 0x%04x %s\n"
1075 " bAssocTerminal %5u\n"
1077 " bNrChannels %5u\n"
1078 " bmChannelConfig 0x%08x\n",
1079 buf[3], termt, termts, buf[6], buf[7], buf[8], chcfg);
1080 for (i = 0; i < 26; i++)
1081 if ((chcfg >> i) & 1)
1082 printf(" %s\n", chconfig_uac2[i]);
1083 printf(" bmControls 0x%04x\n", buf[14] | (buf[15] << 8));
1084 dump_audio_bmcontrols(" ", buf[14] | (buf[15] << 8), uac2_input_term_bmcontrols, protocol);
1085 printf(" iChannelNames %5u %s\n"
1086 " iTerminal %5u %s\n",
1087 buf[13], chnames, buf[16], term);
1088 dump_junk(buf, " ", 17);
1090 } /* switch (protocol) */
1094 case 0x03: /* OUTPUT_TERMINAL */
1095 printf("(OUTPUT_TERMINAL)\n");
1097 case USB_AUDIO_CLASS_1:
1098 term = get_dev_string(dev, buf[8]);
1099 termt = buf[4] | (buf[5] << 8);
1100 get_audioterminal_string(termts, sizeof(termts), termt);
1102 printf(" Warning: Descriptor too short\n");
1103 printf(" bTerminalID %5u\n"
1104 " wTerminalType 0x%04x %s\n"
1105 " bAssocTerminal %5u\n"
1107 " iTerminal %5u %s\n",
1108 buf[3], termt, termts, buf[6], buf[7], buf[8], term);
1109 dump_junk(buf, " ", 9);
1111 case USB_AUDIO_CLASS_2:
1112 term = get_dev_string(dev, buf[11]);
1113 termt = buf[4] | (buf[5] << 8);
1114 get_audioterminal_string(termts, sizeof(termts), termt);
1116 printf(" Warning: Descriptor too short\n");
1117 printf(" bTerminalID %5u\n"
1118 " wTerminalType 0x%04x %s\n"
1119 " bAssocTerminal %5u\n"
1122 " bmControls 0x%04x\n",
1123 buf[3], termt, termts, buf[6], buf[7], buf[8], buf[9] | (buf[10] << 8));
1124 dump_audio_bmcontrols(" ", buf[9] | (buf[10] << 8), uac2_output_term_bmcontrols, protocol);
1125 printf(" iTerminal %5u %s\n", buf[11], term);
1126 dump_junk(buf, " ", 12);
1128 } /* switch (protocol) */
1132 case 0x04: /* MIXER_UNIT */
1133 printf("(MIXER_UNIT)\n");
1136 case USB_AUDIO_CLASS_1:
1139 if (j == 0 || k == 0) {
1140 printf(" Warning: mixer with %5u input and %5u output channels.\n", j, k);
1145 chnames = get_dev_string(dev, buf[8+j]);
1146 term = get_dev_string(dev, buf[9+j+N]);
1147 if (buf[0] < 10+j+N)
1148 printf(" Warning: Descriptor too short\n");
1149 chcfg = buf[6+j] | (buf[7+j] << 8);
1150 printf(" bUnitID %5u\n"
1153 for (i = 0; i < j; i++)
1154 printf(" baSourceID(%2u) %5u\n", i, buf[5+i]);
1155 printf(" bNrChannels %5u\n"
1156 " wChannelConfig 0x%04x\n",
1158 for (i = 0; i < 12; i++)
1159 if ((chcfg >> i) & 1)
1160 printf(" %s\n", chconfig[i]);
1161 printf(" iChannelNames %5u %s\n",
1163 for (i = 0; i < N; i++)
1164 printf(" bmControls 0x%02x\n", buf[9+j+i]);
1165 printf(" iMixer %5u %s\n", buf[9+j+N], term);
1166 dump_junk(buf, " ", 10+j+N);
1169 case USB_AUDIO_CLASS_2:
1171 k = buf[0] - 13 - j;
1172 chnames = get_dev_string(dev, buf[10+j]);
1173 term = get_dev_string(dev, buf[12+j+k]);
1174 chcfg = buf[6+j] | (buf[7+j] << 8) | (buf[8+j] << 16) | (buf[9+j] << 24);
1176 printf(" bUnitID %5u\n"
1179 for (i = 0; i < j; i++)
1180 printf(" baSourceID(%2u) %5u\n", i, buf[5+i]);
1181 printf(" bNrChannels %5u\n"
1182 " bmChannelConfig 0x%08x\n", buf[5+j], chcfg);
1183 for (i = 0; i < 26; i++)
1184 if ((chcfg >> i) & 1)
1185 printf(" %s\n", chconfig_uac2[i]);
1186 printf(" iChannelNames %5u %s\n", buf[10+j], chnames);
1189 for (i = 0; i < k; i++)
1190 N |= buf[11+j+i] << (i * 8);
1192 dump_bytes(buf+11+j, k);
1194 printf(" bmControls %02x\n", buf[11+j+k]);
1195 dump_audio_bmcontrols(" ", buf[11+j+k], uac2_mixer_unit_bmcontrols, protocol);
1197 printf(" iMixer %5u %s\n", buf[12+j+k], term);
1198 dump_junk(buf, " ", 13+j+k);
1200 } /* switch (protocol) */
1203 case 0x05: /* SELECTOR_UNIT */
1204 printf("(SELECTOR_UNIT)\n");
1206 case USB_AUDIO_CLASS_1:
1207 if (buf[0] < 6+buf[4])
1208 printf(" Warning: Descriptor too short\n");
1209 term = get_dev_string(dev, buf[5+buf[4]]);
1211 printf(" bUnitID %5u\n"
1214 for (i = 0; i < buf[4]; i++)
1215 printf(" baSource(%2u) %5u\n", i, buf[5+i]);
1216 printf(" iSelector %5u %s\n",
1217 buf[5+buf[4]], term);
1218 dump_junk(buf, " ", 6+buf[4]);
1220 case USB_AUDIO_CLASS_2:
1221 if (buf[0] < 7+buf[4])
1222 printf(" Warning: Descriptor too short\n");
1223 term = get_dev_string(dev, buf[6+buf[4]]);
1225 printf(" bUnitID %5u\n"
1228 for (i = 0; i < buf[4]; i++)
1229 printf(" baSource(%2u) %5u\n", i, buf[5+i]);
1230 printf(" bmControls 0x%02x\n", buf[5+buf[4]]);
1231 dump_audio_bmcontrols(" ", buf[5+buf[4]], uac2_selector_bmcontrols, protocol);
1232 printf(" iSelector %5u %s\n",
1233 buf[6+buf[4]], term);
1234 dump_junk(buf, " ", 7+buf[4]);
1236 } /* switch (protocol) */
1240 case 0x06: /* FEATURE_UNIT */
1241 printf("(FEATURE_UNIT)\n");
1244 case USB_AUDIO_CLASS_1:
1248 k = (buf[0] - 7) / j;
1249 if (buf[0] < 7+buf[5]*k)
1250 printf(" Warning: Descriptor too short\n");
1251 term = get_dev_string(dev, buf[6+buf[5]*k]);
1252 printf(" bUnitID %5u\n"
1254 " bControlSize %5u\n",
1255 buf[3], buf[4], buf[5]);
1256 for (i = 0; i < k; i++) {
1257 chcfg = buf[6+buf[5]*i];
1259 chcfg |= (buf[7+buf[5]*i] << 8);
1260 for (j = 0; j < buf[5]; j++)
1261 printf(" bmaControls(%2u) 0x%02x\n", i, buf[6+buf[5]*i+j]);
1263 dump_audio_bmcontrols(" ", chcfg, uac_fu_bmcontrols, protocol);
1265 printf(" iFeature %5u %s\n", buf[6+buf[5]*k], term);
1266 dump_junk(buf, " ", 7+buf[5]*k);
1268 case USB_AUDIO_CLASS_2:
1270 printf(" Warning: Descriptor too short\n");
1271 k = (buf[0] - 6) / 4;
1272 printf(" bUnitID %5u\n"
1275 for (i = 0; i < k; i++) {
1276 chcfg = buf[5+(4*i)] |
1278 buf[7+(4*i)] << 16 |
1280 printf(" bmaControls(%2u) 0x%08x\n", i, chcfg);
1281 dump_audio_bmcontrols(" ", chcfg, uac_fu_bmcontrols, protocol);
1283 term = get_dev_string(dev, buf[5+k*4]);
1284 printf(" iFeature %5u %s\n", buf[5+(k*4)], term);
1285 dump_junk(buf, " ", 6+(k*4));
1287 } /* switch (protocol) */
1291 case 0x07: /* PROCESSING_UNIT */
1292 printf("(PROCESSING_UNIT)\n");
1295 case USB_AUDIO_CLASS_1:
1298 chnames = get_dev_string(dev, buf[10+j]);
1299 term = get_dev_string(dev, buf[12+j+k]);
1300 chcfg = buf[8+j] | (buf[9+j] << 8);
1301 if (buf[0] < 13+j+k)
1302 printf(" Warning: Descriptor too short\n");
1303 printf(" bUnitID %5u\n"
1304 " wProcessType %5u\n"
1306 buf[3], buf[4] | (buf[5] << 8), buf[6]);
1307 for (i = 0; i < j; i++)
1308 printf(" baSourceID(%2u) %5u\n", i, buf[7+i]);
1309 printf(" bNrChannels %5u\n"
1310 " wChannelConfig 0x%04x\n", buf[7+j], chcfg);
1311 for (i = 0; i < 12; i++)
1312 if ((chcfg >> i) & 1)
1313 printf(" %s\n", chconfig[i]);
1314 printf(" iChannelNames %5u %s\n"
1315 " bControlSize %5u\n", buf[10+j], chnames, buf[11+j]);
1316 for (i = 0; i < k; i++)
1317 printf(" bmControls(%2u) 0x%02x\n", i, buf[12+j+i]);
1319 printf(" Enable Processing\n");
1320 printf(" iProcessing %5u %s\n"
1321 " Process-Specific ", buf[12+j+k], term);
1322 dump_bytes(buf+(13+j+k), buf[0]-(13+j+k));
1324 case USB_AUDIO_CLASS_2:
1326 k = buf[0] - 17 - j;
1327 chnames = get_dev_string(dev, buf[12+j]);
1328 term = get_dev_string(dev, buf[15+j+k]);
1334 printf(" bUnitID %5u\n"
1335 " wProcessType %5u\n"
1337 buf[3], buf[4] | (buf[5] << 8), buf[6]);
1338 for (i = 0; i < j; i++)
1339 printf(" baSourceID(%2u) %5u\n", i, buf[5+i]);
1340 printf(" bNrChannels %5u\n"
1341 " bmChannelConfig 0x%08x\n", buf[7+j], chcfg);
1342 for (i = 0; i < 26; i++)
1343 if ((chcfg >> i) & 1)
1344 printf(" %s\n", chconfig_uac2[i]);
1345 printf(" iChannelNames %5u %s\n"
1346 " bmControls 0x%04x\n", buf[12+j], chnames, buf[13+j] | (buf[14+j] << 8));
1348 printf(" Enable Processing\n");
1349 printf(" iProcessing %5u %s\n"
1350 " Process-Specific ", buf[15+j], term);
1351 dump_bytes(buf+(16+j), k);
1353 } /* switch (protocol) */
1357 case 0x08: /* EXTENSION_UNIT */
1358 printf("(EXTENSION_UNIT)\n");
1361 case USB_AUDIO_CLASS_1:
1364 chnames = get_dev_string(dev, buf[10+j]);
1365 term = get_dev_string(dev, buf[12+j+k]);
1366 chcfg = buf[8+j] | (buf[9+j] << 8);
1367 if (buf[0] < 13+j+k)
1368 printf(" Warning: Descriptor too short\n");
1369 printf(" bUnitID %5u\n"
1370 " wExtensionCode %5u\n"
1372 buf[3], buf[4] | (buf[5] << 8), buf[6]);
1373 for (i = 0; i < j; i++)
1374 printf(" baSourceID(%2u) %5u\n", i, buf[7+i]);
1375 printf(" bNrChannels %5u\n"
1376 " wChannelConfig %5u\n", buf[7+j], chcfg);
1377 for (i = 0; i < 12; i++)
1378 if ((chcfg >> i) & 1)
1379 printf(" %s\n", chconfig[i]);
1380 printf(" iChannelNames %5u %s\n"
1381 " bControlSize %5u\n", buf[10+j], chnames, buf[11+j]);
1382 for (i = 0; i < k; i++)
1383 printf(" bmControls(%2u) 0x%02x\n", i, buf[12+j+i]);
1385 printf(" Enable Processing\n");
1386 printf(" iExtension %5u %s\n",
1388 dump_junk(buf, " ", 13+j+k);
1390 case USB_AUDIO_CLASS_2:
1392 chnames = get_dev_string(dev, buf[13+j]);
1393 term = get_dev_string(dev, buf[15+j]);
1394 chcfg = buf[9+j] | (buf[10+j] << 8) | (buf[11+j] << 16) | (buf[12+j] << 24);
1396 printf(" Warning: Descriptor too short\n");
1397 printf(" bUnitID %5u\n"
1398 " wExtensionCode %5u\n"
1400 buf[3], buf[4] | (buf[5] << 8), buf[6]);
1401 for (i = 0; i < j; i++)
1402 printf(" baSourceID(%2u) %5u\n", i, buf[7+i]);
1403 printf(" bNrChannels %5u\n"
1404 " wChannelConfig %5u\n", buf[7+j], chcfg);
1405 for (i = 0; i < 12; i++)
1406 if ((chcfg >> i) & 1)
1407 printf(" %s\n", chconfig[i]);
1408 printf(" iChannelNames %5u %s\n"
1409 " bmControls 0x%02x\n", buf[13+j], chnames, buf[14+j]);
1410 dump_audio_bmcontrols(" ", buf[14+j], uac2_extension_unit_bmcontrols, protocol);
1412 printf(" iExtension %5u %s\n",
1414 dump_junk(buf, " ", 16+j);
1416 } /* switch (protocol) */
1420 case 0x0a: /* CLOCK_SOURCE */
1421 printf ("(CLOCK_SOURCE)\n");
1422 if (protocol != USB_AUDIO_CLASS_2)
1423 printf(" Warning: CLOCK_SOURCE descriptors are illegal for UAC1\n");
1426 printf(" Warning: Descriptor too short\n");
1428 printf(" bClockID %5u\n"
1429 " bmAttributes 0x%02x %s Clock %s\n",
1430 buf[3], buf[4], clock_source_attrs[buf[4] & 3],
1431 (buf[4] & 4) ? "(synced to SOF)" : "");
1433 printf(" bmControls 0x%02x\n", buf[5]);
1434 dump_audio_bmcontrols(" ", buf[5], uac2_clock_source_bmcontrols, protocol);
1436 term = get_dev_string(dev, buf[7]);
1437 printf(" bAssocTerminal %5u\n", buf[6]);
1438 printf(" iClockSource %5u %s\n", buf[7], term);
1439 dump_junk(buf, " ", 8);
1442 case 0x0b: /* CLOCK_SELECTOR */
1443 printf("(CLOCK_SELECTOR)\n");
1444 if (protocol != USB_AUDIO_CLASS_2)
1445 printf(" Warning: CLOCK_SELECTOR descriptors are illegal for UAC1\n");
1447 if (buf[0] < 7+buf[4])
1448 printf(" Warning: Descriptor too short\n");
1449 term = get_dev_string(dev, buf[6+buf[4]]);
1451 printf(" bUnitID %5u\n"
1454 for (i = 0; i < buf[4]; i++)
1455 printf(" baCSourceID(%2u) %5u\n", i, buf[5+i]);
1456 printf(" bmControls 0x%02x\n", buf[5+buf[4]]);
1457 dump_audio_bmcontrols(" ", buf[5+buf[4]], uac2_clock_selector_bmcontrols, protocol);
1459 printf(" iClockSelector %5u %s\n",
1460 buf[6+buf[4]], term);
1461 dump_junk(buf, " ", 7+buf[4]);
1464 case 0x0c: /* CLOCK_MULTIPLIER */
1465 printf("(CLOCK_MULTIPLIER)\n");
1466 if (protocol != USB_AUDIO_CLASS_2)
1467 printf(" Warning: CLOCK_MULTIPLIER descriptors are illegal for UAC1\n");
1470 printf(" Warning: Descriptor too short\n");
1472 printf(" bClockID %5u\n"
1473 " bCSourceID %5u\n",
1476 printf(" bmControls 0x%02x\n", buf[5]);
1477 dump_audio_bmcontrols(" ", buf[5], uac2_clock_multiplier_bmcontrols, protocol);
1479 term = get_dev_string(dev, buf[6]);
1480 printf(" iClockMultiplier %5u %s\n", buf[6], term);
1481 dump_junk(buf, " ", 7);
1484 case 0x0d: /* SAMPLE_RATE_CONVERTER_UNIT */
1485 printf("(SAMPLE_RATE_CONVERTER_UNIT)\n");
1486 if (protocol != USB_AUDIO_CLASS_2)
1487 printf(" Warning: SAMPLE_RATE_CONVERTER_UNIT descriptors are illegal for UAC1\n");
1490 printf(" Warning: Descriptor too short\n");
1492 term = get_dev_string(dev, buf[7]);
1493 printf(" bUnitID %5u\n"
1495 " bCSourceInID %5u\n"
1496 " bCSourceOutID %5u\n"
1498 buf[3], buf[4], buf[5], buf[6], buf[7], term);
1499 dump_junk(buf, " ", 8);
1502 case 0xf0: /* EFFECT_UNIT - the real value is 0x07, see above for the reason for remapping */
1503 printf("(EFFECT_UNIT)\n");
1506 printf(" Warning: Descriptor too short\n");
1507 k = (buf[0] - 16) / 4;
1508 term = get_dev_string(dev, buf[15+k*4]);
1509 printf(" bUnitID %5u\n"
1510 " wEffectType %5u\n"
1512 buf[3], buf[4] | (buf[5] << 8), buf[6]);
1513 for (i = 0; i < k; i++) {
1514 chcfg = buf[7+(4*i)] |
1516 buf[9+(4*i)] << 16 |
1517 buf[10+(4*i)] << 24;
1518 printf(" bmaControls(%2u) 0x%08x\n", i, chcfg);
1519 /* TODO: parse effect-specific controls */
1521 printf(" iEffect %5u %s\n", buf[15+(k*4)], term);
1522 dump_junk(buf, " ", 16+(k*4));
1526 printf("(unknown)\n"
1527 " Invalid desc subtype:");
1528 dump_bytes(buf+3, buf[0]-3);
1536 static const struct bmcontrol uac2_as_interface_bmcontrols[] = {
1537 { "Active Alternate Setting", 0 },
1538 { "Valid Alternate Setting", 1 },
1542 static void dump_audiostreaming_interface(libusb_device_handle *dev, const unsigned char *buf, int protocol)
1544 static const char * const fmtItag[] = {
1545 "TYPE_I_UNDEFINED", "PCM", "PCM8", "IEEE_FLOAT", "ALAW", "MULAW" };
1546 static const char * const fmtIItag[] = { "TYPE_II_UNDEFINED", "MPEG", "AC-3" };
1547 static const char * const fmtIIItag[] = {
1548 "TYPE_III_UNDEFINED", "IEC1937_AC-3", "IEC1937_MPEG-1_Layer1",
1549 "IEC1937_MPEG-Layer2/3/NOEXT", "IEC1937_MPEG-2_EXT",
1550 "IEC1937_MPEG-2_Layer1_LS", "IEC1937_MPEG-2_Layer2/3_LS" };
1551 unsigned int i, j, fmttag;
1552 const char *fmtptr = "undefined";
1555 if (buf[1] != USB_DT_CS_INTERFACE)
1556 printf(" Warning: Invalid descriptor\n");
1557 else if (buf[0] < 3)
1558 printf(" Warning: Descriptor too short\n");
1559 printf(" AudioStreaming Interface Descriptor:\n"
1561 " bDescriptorType %5u\n"
1562 " bDescriptorSubtype %5u ",
1563 buf[0], buf[1], buf[2]);
1565 case 0x01: /* AS_GENERAL */
1566 printf("(AS_GENERAL)\n");
1569 case USB_AUDIO_CLASS_1:
1571 printf(" Warning: Descriptor too short\n");
1572 fmttag = buf[5] | (buf[6] << 8);
1574 fmtptr = fmtItag[fmttag];
1575 else if (fmttag >= 0x1000 && fmttag <= 0x1002)
1576 fmtptr = fmtIItag[fmttag & 0xfff];
1577 else if (fmttag >= 0x2000 && fmttag <= 0x2006)
1578 fmtptr = fmtIIItag[fmttag & 0xfff];
1579 printf(" bTerminalLink %5u\n"
1580 " bDelay %5u frames\n"
1581 " wFormatTag %5u %s\n",
1582 buf[3], buf[4], fmttag, fmtptr);
1583 dump_junk(buf, " ", 7);
1585 case USB_AUDIO_CLASS_2:
1587 printf(" Warning: Descriptor too short\n");
1588 printf(" bTerminalLink %5u\n"
1589 " bmControls 0x%02x\n",
1591 dump_audio_bmcontrols(" ", buf[4], uac2_as_interface_bmcontrols, protocol);
1593 printf(" bFormatType %5u\n", buf[5]);
1594 fmttag = buf[6] | (buf[7] << 8) | (buf[8] << 16) | (buf[9] << 24);
1595 printf(" bmFormats 0x%08x\n", fmttag);
1597 if ((fmttag >> i) & 1)
1598 printf(" %s\n", fmtItag[i+1]);
1600 j = buf[11] | (buf[12] << 8) | (buf[13] << 16) | (buf[14] << 24);
1601 printf(" bNrChannels %5u\n"
1602 " bmChannelConfig 0x%08x\n",
1604 for (i = 0; i < 26; i++)
1606 printf(" %s\n", chconfig_uac2[i]);
1608 name = get_dev_string(dev, buf[15]);
1609 printf(" iChannelNames %5u %s\n", buf[15], name);
1610 dump_junk(buf, " ", 16);
1612 } /* switch (protocol) */
1616 case 0x02: /* FORMAT_TYPE */
1617 printf("(FORMAT_TYPE)\n");
1619 case USB_AUDIO_CLASS_1:
1621 printf(" Warning: Descriptor too short\n");
1622 printf(" bFormatType %5u ", buf[3]);
1624 case 0x01: /* FORMAT_TYPE_I */
1625 printf("(FORMAT_TYPE_I)\n");
1626 j = buf[7] ? (buf[7]*3+8) : 14;
1628 printf(" Warning: Descriptor too short\n");
1629 printf(" bNrChannels %5u\n"
1630 " bSubframeSize %5u\n"
1631 " bBitResolution %5u\n"
1632 " bSamFreqType %5u %s\n",
1633 buf[4], buf[5], buf[6], buf[7], buf[7] ? "Discrete" : "Continuous");
1635 printf(" tLowerSamFreq %7u\n"
1636 " tUpperSamFreq %7u\n",
1637 buf[8] | (buf[9] << 8) | (buf[10] << 16), buf[11] | (buf[12] << 8) | (buf[13] << 16));
1639 for (i = 0; i < buf[7]; i++)
1640 printf(" tSamFreq[%2u] %7u\n", i,
1641 buf[8+3*i] | (buf[9+3*i] << 8) | (buf[10+3*i] << 16));
1642 dump_junk(buf, " ", j);
1645 case 0x02: /* FORMAT_TYPE_II */
1646 printf("(FORMAT_TYPE_II)\n");
1647 j = buf[8] ? (buf[7]*3+9) : 15;
1649 printf(" Warning: Descriptor too short\n");
1650 printf(" wMaxBitRate %5u\n"
1651 " wSamplesPerFrame %5u\n"
1652 " bSamFreqType %5u %s\n",
1653 buf[4] | (buf[5] << 8), buf[6] | (buf[7] << 8), buf[8], buf[8] ? "Discrete" : "Continuous");
1655 printf(" tLowerSamFreq %7u\n"
1656 " tUpperSamFreq %7u\n",
1657 buf[9] | (buf[10] << 8) | (buf[11] << 16), buf[12] | (buf[13] << 8) | (buf[14] << 16));
1659 for (i = 0; i < buf[8]; i++)
1660 printf(" tSamFreq[%2u] %7u\n", i,
1661 buf[9+3*i] | (buf[10+3*i] << 8) | (buf[11+3*i] << 16));
1662 dump_junk(buf, " ", j);
1665 case 0x03: /* FORMAT_TYPE_III */
1666 printf("(FORMAT_TYPE_III)\n");
1667 j = buf[7] ? (buf[7]*3+8) : 14;
1669 printf(" Warning: Descriptor too short\n");
1670 printf(" bNrChannels %5u\n"
1671 " bSubframeSize %5u\n"
1672 " bBitResolution %5u\n"
1673 " bSamFreqType %5u %s\n",
1674 buf[4], buf[5], buf[6], buf[7], buf[7] ? "Discrete" : "Continuous");
1676 printf(" tLowerSamFreq %7u\n"
1677 " tUpperSamFreq %7u\n",
1678 buf[8] | (buf[9] << 8) | (buf[10] << 16), buf[11] | (buf[12] << 8) | (buf[13] << 16));
1680 for (i = 0; i < buf[7]; i++)
1681 printf(" tSamFreq[%2u] %7u\n", i,
1682 buf[8+3*i] | (buf[9+3*i] << 8) | (buf[10+3*i] << 16));
1683 dump_junk(buf, " ", j);
1687 printf("(unknown)\n"
1688 " Invalid desc format type:");
1689 dump_bytes(buf+4, buf[0]-4);
1694 case USB_AUDIO_CLASS_2:
1695 printf(" bFormatType %5u ", buf[3]);
1697 case 0x01: /* FORMAT_TYPE_I */
1698 printf("(FORMAT_TYPE_I)\n");
1700 printf(" Warning: Descriptor too short\n");
1701 printf(" bSubslotSize %5u\n"
1702 " bBitResolution %5u\n",
1704 dump_junk(buf, " ", 6);
1707 case 0x02: /* FORMAT_TYPE_II */
1708 printf("(FORMAT_TYPE_II)\n");
1710 printf(" Warning: Descriptor too short\n");
1711 printf(" wMaxBitRate %5u\n"
1712 " wSlotsPerFrame %5u\n",
1713 buf[4] | (buf[5] << 8),
1714 buf[6] | (buf[7] << 8));
1715 dump_junk(buf, " ", 8);
1718 case 0x03: /* FORMAT_TYPE_III */
1719 printf("(FORMAT_TYPE_III)\n");
1721 printf(" Warning: Descriptor too short\n");
1722 printf(" bSubslotSize %5u\n"
1723 " bBitResolution %5u\n",
1725 dump_junk(buf, " ", 6);
1728 case 0x04: /* FORMAT_TYPE_IV */
1729 printf("(FORMAT_TYPE_IV)\n");
1731 printf(" Warning: Descriptor too short\n");
1732 printf(" bFormatType %5u\n", buf[3]);
1733 dump_junk(buf, " ", 4);
1737 printf("(unknown)\n"
1738 " Invalid desc format type:");
1739 dump_bytes(buf+4, buf[0]-4);
1743 } /* switch (protocol) */
1747 case 0x03: /* FORMAT_SPECIFIC */
1748 printf("(FORMAT_SPECIFIC)\n");
1750 printf(" Warning: Descriptor too short\n");
1751 fmttag = buf[3] | (buf[4] << 8);
1753 fmtptr = fmtItag[fmttag];
1754 else if (fmttag >= 0x1000 && fmttag <= 0x1002)
1755 fmtptr = fmtIItag[fmttag & 0xfff];
1756 else if (fmttag >= 0x2000 && fmttag <= 0x2006)
1757 fmtptr = fmtIIItag[fmttag & 0xfff];
1758 printf(" wFormatTag %5u %s\n", fmttag, fmtptr);
1760 case 0x1001: /* MPEG */
1762 printf(" Warning: Descriptor too short\n");
1763 printf(" bmMPEGCapabilities 0x%04x\n",
1764 buf[5] | (buf[6] << 8));
1766 printf(" Layer I\n");
1768 printf(" Layer II\n");
1770 printf(" Layer III\n");
1772 printf(" MPEG-1 only\n");
1774 printf(" MPEG-1 dual-channel\n");
1776 printf(" MPEG-2 second stereo\n");
1778 printf(" MPEG-2 7.1 channel augmentation\n");
1780 printf(" Adaptive multi-channel prediction\n");
1781 printf(" MPEG-2 multilingual support: ");
1782 switch (buf[6] & 3) {
1784 printf("Not supported\n");
1788 printf("Supported at Fs\n");
1792 printf("Reserved\n");
1796 printf("Supported at Fs and 1/2Fs\n");
1799 printf(" bmMPEGFeatures 0x%02x\n", buf[7]);
1800 printf(" Internal Dynamic Range Control: ");
1801 switch ((buf[7] >> 4) & 3) {
1803 printf("not supported\n");
1807 printf("supported but not scalable\n");
1811 printf("scalable, common boost and cut scaling value\n");
1815 printf("scalable, separate boost and cut scaling value\n");
1818 dump_junk(buf, " ", 8);
1821 case 0x1002: /* AC-3 */
1823 printf(" Warning: Descriptor too short\n");
1824 printf(" bmBSID 0x%08x\n"
1825 " bmAC3Features 0x%02x\n",
1826 buf[5] | (buf[6] << 8) | (buf[7] << 16) | (buf[8] << 24), buf[9]);
1828 printf(" RF mode\n");
1830 printf(" Line mode\n");
1832 printf(" Custom0 mode\n");
1834 printf(" Custom1 mode\n");
1835 printf(" Internal Dynamic Range Control: ");
1836 switch ((buf[9] >> 4) & 3) {
1838 printf("not supported\n");
1842 printf("supported but not scalable\n");
1846 printf("scalable, common boost and cut scaling value\n");
1850 printf("scalable, separate boost and cut scaling value\n");
1853 dump_junk(buf, " ", 8);
1857 printf("(unknown)\n"
1858 " Invalid desc format type:");
1859 dump_bytes(buf+4, buf[0]-4);
1864 printf(" Invalid desc subtype:");
1865 dump_bytes(buf+3, buf[0]-3);
1872 static const struct bmcontrol uac2_audio_endpoint_bmcontrols[] = {
1874 { "Data Overrun", 1 },
1875 { "Data Underrun", 2 },
1879 static void dump_audiostreaming_endpoint(const unsigned char *buf, int protocol)
1881 static const char * const lockdelunits[] = { "Undefined", "Milliseconds", "Decoded PCM samples", "Reserved" };
1882 unsigned int lckdelidx;
1884 if (buf[1] != USB_DT_CS_ENDPOINT)
1885 printf(" Warning: Invalid descriptor\n");
1886 else if (buf[0] < ((protocol == USB_AUDIO_CLASS_1) ? 7 : 8))
1887 printf(" Warning: Descriptor too short\n");
1888 printf(" AudioControl Endpoint Descriptor:\n"
1890 " bDescriptorType %5u\n"
1891 " bDescriptorSubtype %5u (%s)\n"
1892 " bmAttributes 0x%02x\n",
1893 buf[0], buf[1], buf[2], buf[2] == 1 ? "EP_GENERAL" : "invalid", buf[3]);
1896 case USB_AUDIO_CLASS_1:
1898 printf(" Sampling Frequency\n");
1902 printf(" MaxPacketsOnly\n");
1906 printf(" bLockDelayUnits %5u %s\n"
1907 " wLockDelay %5u %s\n",
1908 buf[4], lockdelunits[lckdelidx], buf[5] | (buf[6] << 8), lockdelunits[lckdelidx]);
1909 dump_junk(buf, " ", 7);
1912 case USB_AUDIO_CLASS_2:
1914 printf(" MaxPacketsOnly\n");
1916 printf(" bmControls 0x%02x\n", buf[4]);
1917 dump_audio_bmcontrols(" ", buf[4], uac2_audio_endpoint_bmcontrols, protocol);
1922 printf(" bLockDelayUnits %5u %s\n"
1923 " wLockDelay %5u\n",
1924 buf[5], lockdelunits[lckdelidx], buf[6] | (buf[7] << 8));
1925 dump_junk(buf, " ", 8);
1927 } /* switch protocol */
1930 static void dump_midistreaming_interface(libusb_device_handle *dev, const unsigned char *buf)
1932 static const char * const jacktypes[] = {"Undefined", "Embedded", "External"};
1933 char *jackstr = NULL;
1934 unsigned int j, tlength, capssize;
1937 if (buf[1] != USB_DT_CS_INTERFACE)
1938 printf(" Warning: Invalid descriptor\n");
1939 else if (buf[0] < 3)
1940 printf(" Warning: Descriptor too short\n");
1941 printf(" MIDIStreaming Interface Descriptor:\n"
1943 " bDescriptorType %5u\n"
1944 " bDescriptorSubtype %5u ",
1945 buf[0], buf[1], buf[2]);
1948 printf("(HEADER)\n");
1950 printf(" Warning: Descriptor too short\n");
1951 tlength = buf[5] | (buf[6] << 8);
1952 printf(" bcdADC %2x.%02x\n"
1953 " wTotalLength %5u\n",
1954 buf[4], buf[3], tlength);
1955 dump_junk(buf, " ", 7);
1959 printf("(MIDI_IN_JACK)\n");
1961 printf(" Warning: Descriptor too short\n");
1962 jackstr = get_dev_string(dev, buf[5]);
1963 printf(" bJackType %5u %s\n"
1966 buf[3], buf[3] < 3 ? jacktypes[buf[3]] : "Invalid",
1967 buf[4], buf[5], jackstr);
1968 dump_junk(buf, " ", 6);
1972 printf("(MIDI_OUT_JACK)\n");
1974 printf(" Warning: Descriptor too short\n");
1975 printf(" bJackType %5u %s\n"
1977 " bNrInputPins %5u\n",
1978 buf[3], buf[3] < 3 ? jacktypes[buf[3]] : "Invalid",
1980 for (j = 0; j < buf[5]; j++) {
1981 printf(" baSourceID(%2u) %5u\n"
1982 " BaSourcePin(%2u) %5u\n",
1983 j, buf[2*j+6], j, buf[2*j+7]);
1985 j = 6+buf[5]*2; /* midi10.pdf says, incorrectly: 5+2*p */
1986 jackstr = get_dev_string(dev, buf[j]);
1987 printf(" iJack %5u %s\n",
1989 dump_junk(buf, " ", j+1);
1993 printf("(ELEMENT)\n");
1995 printf(" Warning: Descriptor too short\n");
1996 printf(" bElementID %5u\n"
1997 " bNrInputPins %5u\n",
1999 for (j = 0; j < buf[4]; j++) {
2000 printf(" baSourceID(%2u) %5u\n"
2001 " BaSourcePin(%2u) %5u\n",
2002 j, buf[2*j+5], j, buf[2*j+6]);
2005 printf(" bNrOutputPins %5u\n"
2006 " bInTerminalLink %5u\n"
2007 " bOutTerminalLink %5u\n"
2008 " bElCapsSize %5u\n",
2009 buf[j], buf[j+1], buf[j+2], buf[j+3]);
2010 capssize = buf[j+3];
2012 for (j = 0; j < capssize; j++)
2013 caps |= (buf[j+9+buf[4]*2] << (8*j));
2014 printf(" bmElementCaps 0x%08lx\n", caps);
2016 printf(" Undefined\n");
2018 printf(" MIDI Clock\n");
2020 printf(" MTC (MIDI Time Code)\n");
2022 printf(" MMC (MIDI Machine Control)\n");
2024 printf(" GM1 (General MIDI v.1)\n");
2026 printf(" GM2 (General MIDI v.2)\n");
2028 printf(" GS MIDI Extension\n");
2030 printf(" XG MIDI Extension\n");
2034 printf(" MIDI Patch Bay\n");
2036 printf(" DLS1 (Downloadable Sounds Level 1)\n");
2038 printf(" DLS2 (Downloadable Sounds Level 2)\n");
2039 j = 9+2*buf[4]+capssize;
2040 jackstr = get_dev_string(dev, buf[j]);
2041 printf(" iElement %5u %s\n", buf[j], jackstr);
2042 dump_junk(buf, " ", j+1);
2046 printf("\n Invalid desc subtype: ");
2047 dump_bytes(buf+3, buf[0]-3);
2054 static void dump_midistreaming_endpoint(const unsigned char *buf)
2058 if (buf[1] != USB_DT_CS_ENDPOINT)
2059 printf(" Warning: Invalid descriptor\n");
2060 else if (buf[0] < 5)
2061 printf(" Warning: Descriptor too short\n");
2062 printf(" MIDIStreaming Endpoint Descriptor:\n"
2064 " bDescriptorType %5u\n"
2065 " bDescriptorSubtype %5u (%s)\n"
2066 " bNumEmbMIDIJack %5u\n",
2067 buf[0], buf[1], buf[2], buf[2] == 1 ? "GENERAL" : "Invalid", buf[3]);
2068 for (j = 0; j < buf[3]; j++)
2069 printf(" baAssocJackID(%2u) %5u\n", j, buf[4+j]);
2070 dump_junk(buf, " ", 4+buf[3]);
2074 * Video Class descriptor dump
2077 static void dump_videocontrol_interface(libusb_device_handle *dev, const unsigned char *buf)
2079 static const char * const ctrlnames[] = {
2080 "Brightness", "Contrast", "Hue", "Saturation", "Sharpness", "Gamma",
2081 "White Balance Temperature", "White Balance Component", "Backlight Compensation",
2082 "Gain", "Power Line Frequency", "Hue, Auto", "White Balance Temperature, Auto",
2083 "White Balance Component, Auto", "Digital Multiplier", "Digital Multiplier Limit",
2084 "Analog Video Standard", "Analog Video Lock Status"
2086 static const char * const camctrlnames[] = {
2087 "Scanning Mode", "Auto-Exposure Mode", "Auto-Exposure Priority",
2088 "Exposure Time (Absolute)", "Exposure Time (Relative)", "Focus (Absolute)",
2089 "Focus (Relative)", "Iris (Absolute)", "Iris (Relative)", "Zoom (Absolute)",
2090 "Zoom (Relative)", "PanTilt (Absolute)", "PanTilt (Relative)",
2091 "Roll (Absolute)", "Roll (Relative)", "Reserved", "Reserved", "Focus, Auto",
2094 static const char * const stdnames[] = {
2095 "None", "NTSC - 525/60", "PAL - 625/50", "SECAM - 625/50",
2096 "NTSC - 625/50", "PAL - 525/60" };
2097 unsigned int i, ctrls, stds, n, p, termt, freq;
2098 char *term = NULL, termts[128];
2100 if (buf[1] != USB_DT_CS_INTERFACE)
2101 printf(" Warning: Invalid descriptor\n");
2102 else if (buf[0] < 3)
2103 printf(" Warning: Descriptor too short\n");
2104 printf(" VideoControl Interface Descriptor:\n"
2106 " bDescriptorType %5u\n"
2107 " bDescriptorSubtype %5u ",
2108 buf[0], buf[1], buf[2]);
2110 case 0x01: /* HEADER */
2111 printf("(HEADER)\n");
2114 printf(" Warning: Descriptor too short\n");
2115 freq = buf[7] | (buf[8] << 8) | (buf[9] << 16) | (buf[10] << 24);
2116 printf(" bcdUVC %2x.%02x\n"
2117 " wTotalLength %5u\n"
2118 " dwClockFrequency %5u.%06uMHz\n"
2119 " bInCollection %5u\n",
2120 buf[4], buf[3], buf[5] | (buf[6] << 8), freq / 1000000,
2122 for (i = 0; i < n; i++)
2123 printf(" baInterfaceNr(%2u) %5u\n", i, buf[12+i]);
2124 dump_junk(buf, " ", 12+n);
2127 case 0x02: /* INPUT_TERMINAL */
2128 printf("(INPUT_TERMINAL)\n");
2129 term = get_dev_string(dev, buf[7]);
2130 termt = buf[4] | (buf[5] << 8);
2131 n = termt == 0x0201 ? 7 : 0;
2132 get_videoterminal_string(termts, sizeof(termts), termt);
2134 printf(" Warning: Descriptor too short\n");
2135 printf(" bTerminalID %5u\n"
2136 " wTerminalType 0x%04x %s\n"
2137 " bAssocTerminal %5u\n",
2138 buf[3], termt, termts, buf[6]);
2139 printf(" iTerminal %5u %s\n",
2141 if (termt == 0x0201) {
2143 printf(" wObjectiveFocalLengthMin %5u\n"
2144 " wObjectiveFocalLengthMax %5u\n"
2145 " wOcularFocalLength %5u\n"
2146 " bControlSize %5u\n",
2147 buf[8] | (buf[9] << 8), buf[10] | (buf[11] << 8),
2148 buf[12] | (buf[13] << 8), buf[14]);
2150 for (i = 0; i < 3 && i < buf[14]; i++)
2151 ctrls = (ctrls << 8) | buf[8+n-i-1];
2152 printf(" bmControls 0x%08x\n", ctrls);
2153 for (i = 0; i < 19; i++)
2154 if ((ctrls >> i) & 1)
2155 printf(" %s\n", camctrlnames[i]);
2157 dump_junk(buf, " ", 8+n);
2160 case 0x03: /* OUTPUT_TERMINAL */
2161 printf("(OUTPUT_TERMINAL)\n");
2162 term = get_dev_string(dev, buf[8]);
2163 termt = buf[4] | (buf[5] << 8);
2164 get_audioterminal_string(termts, sizeof(termts), termt);
2166 printf(" Warning: Descriptor too short\n");
2167 printf(" bTerminalID %5u\n"
2168 " wTerminalType 0x%04x %s\n"
2169 " bAssocTerminal %5u\n"
2171 " iTerminal %5u %s\n",
2172 buf[3], termt, termts, buf[6], buf[7], buf[8], term);
2173 dump_junk(buf, " ", 9);
2176 case 0x04: /* SELECTOR_UNIT */
2177 printf("(SELECTOR_UNIT)\n");
2180 printf(" Warning: Descriptor too short\n");
2181 term = get_dev_string(dev, buf[5+p]);
2183 printf(" bUnitID %5u\n"
2186 for (i = 0; i < p; i++)
2187 printf(" baSource(%2u) %5u\n", i, buf[5+i]);
2188 printf(" iSelector %5u %s\n",
2190 dump_junk(buf, " ", 6+p);
2193 case 0x05: /* PROCESSING_UNIT */
2194 printf("(PROCESSING_UNIT)\n");
2196 term = get_dev_string(dev, buf[8+n]);
2198 printf(" Warning: Descriptor too short\n");
2199 printf(" bUnitID %5u\n"
2201 " wMaxMultiplier %5u\n"
2202 " bControlSize %5u\n",
2203 buf[3], buf[4], buf[5] | (buf[6] << 8), n);
2205 for (i = 0; i < 3 && i < n; i++)
2206 ctrls = (ctrls << 8) | buf[8+n-i-1];
2207 printf(" bmControls 0x%08x\n", ctrls);
2208 for (i = 0; i < 18; i++)
2209 if ((ctrls >> i) & 1)
2210 printf(" %s\n", ctrlnames[i]);
2212 printf(" iProcessing %5u %s\n"
2213 " bmVideoStandards 0x%2x\n", buf[8+n], term, stds);
2214 for (i = 0; i < 6; i++)
2215 if ((stds >> i) & 1)
2216 printf(" %s\n", stdnames[i]);
2219 case 0x06: /* EXTENSION_UNIT */
2220 printf("(EXTENSION_UNIT)\n");
2223 term = get_dev_string(dev, buf[23+p+n]);
2224 if (buf[0] < 24+p+n)
2225 printf(" Warning: Descriptor too short\n");
2226 printf(" bUnitID %5u\n"
2227 " guidExtensionCode %s\n"
2228 " bNumControl %5u\n"
2230 buf[3], get_guid(&buf[4]), buf[20], buf[21]);
2231 for (i = 0; i < p; i++)
2232 printf(" baSourceID(%2u) %5u\n", i, buf[22+i]);
2233 printf(" bControlSize %5u\n", buf[22+p]);
2234 for (i = 0; i < n; i++)
2235 printf(" bmControls(%2u) 0x%02x\n", i, buf[23+p+i]);
2236 printf(" iExtension %5u %s\n",
2238 dump_junk(buf, " ", 24+p+n);
2242 printf("(unknown)\n"
2243 " Invalid desc subtype:");
2244 dump_bytes(buf+3, buf[0]-3);
2251 static void dump_videostreaming_interface(const unsigned char *buf)
2253 static const char * const colorPrims[] = { "Unspecified", "BT.709,sRGB",
2254 "BT.470-2 (M)", "BT.470-2 (B,G)", "SMPTE 170M", "SMPTE 240M" };
2255 static const char * const transferChars[] = { "Unspecified", "BT.709",
2256 "BT.470-2 (M)", "BT.470-2 (B,G)", "SMPTE 170M", "SMPTE 240M",
2258 static const char * const matrixCoeffs[] = { "Unspecified", "BT.709",
2259 "FCC", "BT.470-2 (B,G)", "SMPTE 170M (BT.601)", "SMPTE 240M" };
2260 unsigned int i, m, n, p, flags, len;
2262 if (buf[1] != USB_DT_CS_INTERFACE)
2263 printf(" Warning: Invalid descriptor\n");
2264 else if (buf[0] < 3)
2265 printf(" Warning: Descriptor too short\n");
2266 printf(" VideoStreaming Interface Descriptor:\n"
2268 " bDescriptorType %5u\n"
2269 " bDescriptorSubtype %5u ",
2270 buf[0], buf[1], buf[2]);
2272 case 0x01: /* INPUT_HEADER */
2273 printf("(INPUT_HEADER)\n");
2276 if (buf[0] < 13+p*n)
2277 printf(" Warning: Descriptor too short\n");
2278 printf(" bNumFormats %5u\n"
2279 " wTotalLength %5u\n"
2280 " bEndPointAddress %5u\n"
2282 " bTerminalLink %5u\n"
2283 " bStillCaptureMethod %5u\n"
2284 " bTriggerSupport %5u\n"
2285 " bTriggerUsage %5u\n"
2286 " bControlSize %5u\n",
2287 p, buf[4] | (buf[5] << 8), buf[6], buf[7], buf[8],
2288 buf[9], buf[10], buf[11], n);
2289 for (i = 0; i < p; i++)
2291 " bmaControls(%2u) %5u\n",
2293 dump_junk(buf, " ", 13+p*n);
2296 case 0x02: /* OUTPUT_HEADER */
2297 printf("(OUTPUT_HEADER)\n");
2301 printf(" Warning: Descriptor too short\n");
2302 printf(" bNumFormats %5u\n"
2303 " wTotalLength %5u\n"
2304 " bEndpointAddress %5u\n"
2305 " bTerminalLink %5u\n"
2306 " bControlSize %5u\n",
2307 p, buf[4] | (buf[5] << 8), buf[6], buf[7], n);
2308 for (i = 0; i < p; i++)
2310 " bmaControls(%2u) %5u\n",
2312 dump_junk(buf, " ", 9+p*n);
2315 case 0x03: /* STILL_IMAGE_FRAME */
2316 printf("(STILL_IMAGE_FRAME)\n");
2319 if (buf[0] < 6+4*n+m)
2320 printf(" Warning: Descriptor too short\n");
2321 printf(" bEndpointAddress %5u\n"
2322 " bNumImageSizePatterns %3u\n",
2324 for (i = 0; i < n; i++)
2325 printf(" wWidth(%2u) %5u\n"
2326 " wHeight(%2u) %5u\n",
2327 i, buf[5+4*i] | (buf[6+4*i] << 8),
2328 i, buf[7+4*i] | (buf[8+4*i] << 8));
2329 printf(" bNumCompressionPatterns %3u\n", n);
2330 for (i = 0; i < m; i++)
2331 printf(" bCompression(%2u) %5u\n",
2333 dump_junk(buf, " ", 6+4*n+m);
2336 case 0x04: /* FORMAT_UNCOMPRESSED */
2337 case 0x10: /* FORMAT_FRAME_BASED */
2338 if (buf[2] == 0x04) {
2339 printf("(FORMAT_UNCOMPRESSED)\n");
2342 printf("(FORMAT_FRAME_BASED)\n");
2346 printf(" Warning: Descriptor too short\n");
2348 printf(" bFormatIndex %5u\n"
2349 " bNumFrameDescriptors %5u\n"
2351 " bBitsPerPixel %5u\n"
2352 " bDefaultFrameIndex %5u\n"
2353 " bAspectRatioX %5u\n"
2354 " bAspectRatioY %5u\n"
2355 " bmInterlaceFlags 0x%02x\n",
2356 buf[3], buf[4], get_guid(&buf[5]), buf[21], buf[22],
2357 buf[23], buf[24], flags);
2358 printf(" Interlaced stream or variable: %s\n",
2359 (flags & (1 << 0)) ? "Yes" : "No");
2360 printf(" Fields per frame: %u fields\n",
2361 (flags & (1 << 1)) ? 1 : 2);
2362 printf(" Field 1 first: %s\n",
2363 (flags & (1 << 2)) ? "Yes" : "No");
2364 printf(" Field pattern: ");
2365 switch ((flags >> 4) & 0x03) {
2367 printf("Field 1 only\n");
2370 printf("Field 2 only\n");
2373 printf("Regular pattern of fields 1 and 2\n");
2376 printf("Random pattern of fields 1 and 2\n");
2379 printf(" bCopyProtect %5u\n", buf[26]);
2381 printf(" bVariableSize %5u\n", buf[27]);
2382 dump_junk(buf, " ", len);
2385 case 0x05: /* FRAME UNCOMPRESSED */
2386 case 0x07: /* FRAME_MJPEG */
2387 case 0x11: /* FRAME_FRAME_BASED */
2388 if (buf[2] == 0x05) {
2389 printf("(FRAME_UNCOMPRESSED)\n");
2391 } else if (buf[2] == 0x07) {
2392 printf("(FRAME_MJPEG)\n");
2395 printf("(FRAME_FRAME_BASED)\n");
2398 len = (buf[n] != 0) ? (26+buf[n]*4) : 38;
2400 printf(" Warning: Descriptor too short\n");
2402 printf(" bFrameIndex %5u\n"
2403 " bmCapabilities 0x%02x\n",
2405 printf(" Still image %ssupported\n",
2406 (flags & (1 << 0)) ? "" : "un");
2407 if (flags & (1 << 1))
2408 printf(" Fixed frame-rate\n");
2409 printf(" wWidth %5u\n"
2411 " dwMinBitRate %9u\n"
2412 " dwMaxBitRate %9u\n",
2413 buf[5] | (buf[6] << 8), buf[7] | (buf[8] << 8),
2414 buf[9] | (buf[10] << 8) | (buf[11] << 16) | (buf[12] << 24),
2415 buf[13] | (buf[14] << 8) | (buf[15] << 16) | (buf[16] << 24));
2417 printf(" dwDefaultFrameInterval %9u\n"
2418 " bFrameIntervalType %5u\n"
2419 " dwBytesPerLine %9u\n",
2420 buf[17] | (buf[18] << 8) | (buf[19] << 16) | (buf[20] << 24),
2422 buf[22] | (buf[23] << 8) | (buf[24] << 16) | (buf[25] << 24));
2424 printf(" dwMaxVideoFrameBufferSize %9u\n"
2425 " dwDefaultFrameInterval %9u\n"
2426 " bFrameIntervalType %5u\n",
2427 buf[17] | (buf[18] << 8) | (buf[19] << 16) | (buf[20] << 24),
2428 buf[21] | (buf[22] << 8) | (buf[23] << 16) | (buf[24] << 24),
2431 printf(" dwMinFrameInterval %9u\n"
2432 " dwMaxFrameInterval %9u\n"
2433 " dwFrameIntervalStep %9u\n",
2434 buf[26] | (buf[27] << 8) | (buf[28] << 16) | (buf[29] << 24),
2435 buf[30] | (buf[31] << 8) | (buf[32] << 16) | (buf[33] << 24),
2436 buf[34] | (buf[35] << 8) | (buf[36] << 16) | (buf[37] << 24));
2438 for (i = 0; i < buf[n]; i++)
2439 printf(" dwFrameInterval(%2u) %9u\n",
2440 i, buf[26+4*i] | (buf[27+4*i] << 8) |
2441 (buf[28+4*i] << 16) | (buf[29+4*i] << 24));
2442 dump_junk(buf, " ", len);
2445 case 0x06: /* FORMAT_MJPEG */
2446 printf("(FORMAT_MJPEG)\n");
2448 printf(" Warning: Descriptor too short\n");
2450 printf(" bFormatIndex %5u\n"
2451 " bNumFrameDescriptors %5u\n"
2453 buf[3], buf[4], flags);
2454 printf(" Fixed-size samples: %s\n",
2455 (flags & (1 << 0)) ? "Yes" : "No");
2457 printf(" bDefaultFrameIndex %5u\n"
2458 " bAspectRatioX %5u\n"
2459 " bAspectRatioY %5u\n"
2460 " bmInterlaceFlags 0x%02x\n",
2461 buf[6], buf[7], buf[8], flags);
2462 printf(" Interlaced stream or variable: %s\n",
2463 (flags & (1 << 0)) ? "Yes" : "No");
2464 printf(" Fields per frame: %u fields\n",
2465 (flags & (1 << 1)) ? 2 : 1);
2466 printf(" Field 1 first: %s\n",
2467 (flags & (1 << 2)) ? "Yes" : "No");
2468 printf(" Field pattern: ");
2469 switch ((flags >> 4) & 0x03) {
2471 printf("Field 1 only\n");
2474 printf("Field 2 only\n");
2477 printf("Regular pattern of fields 1 and 2\n");
2480 printf("Random pattern of fields 1 and 2\n");
2483 printf(" bCopyProtect %5u\n", buf[10]);
2484 dump_junk(buf, " ", 11);
2487 case 0x0a: /* FORMAT_MPEG2TS */
2488 printf("(FORMAT_MPEG2TS)\n");
2489 len = buf[0] < 23 ? 7 : 23;
2491 printf(" Warning: Descriptor too short\n");
2492 printf(" bFormatIndex %5u\n"
2493 " bDataOffset %5u\n"
2494 " bPacketLength %5u\n"
2495 " bStrideLength %5u\n",
2496 buf[3], buf[4], buf[5], buf[6]);
2498 printf(" guidStrideFormat %s\n",
2500 dump_junk(buf, " ", len);
2503 case 0x0d: /* COLORFORMAT */
2504 printf("(COLORFORMAT)\n");
2506 printf(" Warning: Descriptor too short\n");
2507 printf(" bColorPrimaries %5u (%s)\n",
2508 buf[3], (buf[3] <= 5) ? colorPrims[buf[3]] : "Unknown");
2509 printf(" bTransferCharacteristics %5u (%s)\n",
2510 buf[4], (buf[4] <= 7) ? transferChars[buf[4]] : "Unknown");
2511 printf(" bMatrixCoefficients %5u (%s)\n",
2512 buf[5], (buf[5] <= 5) ? matrixCoeffs[buf[5]] : "Unknown");
2513 dump_junk(buf, " ", 6);
2517 printf(" Invalid desc subtype:");
2518 dump_bytes(buf+3, buf[0]-3);
2523 static void dump_dfu_interface(const unsigned char *buf)
2525 if (buf[1] != USB_DT_CS_DEVICE)
2526 printf(" Warning: Invalid descriptor\n");
2527 else if (buf[0] < 7)
2528 printf(" Warning: Descriptor too short\n");
2529 printf(" Device Firmware Upgrade Interface Descriptor:\n"
2531 " bDescriptorType %5u\n"
2532 " bmAttributes %5u\n",
2533 buf[0], buf[1], buf[2]);
2535 printf(" (unknown attributes!)\n");
2536 printf(" Will %sDetach\n", (buf[2] & 0x08) ? "" : "Not ");
2537 printf(" Manifestation %s\n", (buf[2] & 0x04) ? "Tolerant" : "Intolerant");
2538 printf(" Upload %s\n", (buf[2] & 0x02) ? "Supported" : "Unsupported");
2539 printf(" Download %s\n", (buf[2] & 0x01) ? "Supported" : "Unsupported");
2540 printf(" wDetachTimeout %5u milliseconds\n"
2541 " wTransferSize %5u bytes\n",
2542 buf[3] | (buf[4] << 8), buf[5] | (buf[6] << 8));
2544 /* DFU 1.0 defines no version code, DFU 1.1 does */
2547 printf(" bcdDFUVersion %x.%02x\n",
2551 static void dump_hub(const char *prefix, const unsigned char *p, int tt_type)
2553 unsigned int l, i, j;
2554 unsigned int offset;
2555 unsigned int wHubChar = (p[4] << 8) | p[3];
2557 printf("%sHub Descriptor:\n", prefix);
2558 printf("%s bLength %3u\n", prefix, p[0]);
2559 printf("%s bDescriptorType %3u\n", prefix, p[1]);
2560 printf("%s nNbrPorts %3u\n", prefix, p[2]);
2561 printf("%s wHubCharacteristic 0x%04x\n", prefix, wHubChar);
2562 switch (wHubChar & 0x03) {
2564 printf("%s Ganged power switching\n", prefix);
2567 printf("%s Per-port power switching\n", prefix);
2570 printf("%s No power switching (usb 1.0)\n", prefix);
2573 if (wHubChar & 0x04)
2574 printf("%s Compound device\n", prefix);
2575 switch ((wHubChar >> 3) & 0x03) {
2577 printf("%s Ganged overcurrent protection\n", prefix);
2580 printf("%s Per-port overcurrent protection\n", prefix);
2583 printf("%s No overcurrent protection\n", prefix);
2586 /* USB 3.0 hubs don't have TTs. */
2587 if (tt_type >= 1 && tt_type < 3) {
2588 l = (wHubChar >> 5) & 0x03;
2589 printf("%s TT think time %d FS bits\n", prefix, (l + 1) * 8);
2591 /* USB 3.0 hubs don't have port indicators. Sad face. */
2592 if (tt_type != 3 && wHubChar & (1<<7))
2593 printf("%s Port indicators\n", prefix);
2594 printf("%s bPwrOn2PwrGood %3u * 2 milli seconds\n", prefix, p[5]);
2596 /* USB 3.0 hubs report current in units of aCurrentUnit, or 4 mA */
2598 printf("%s bHubContrCurrent %4u milli Ampere\n",
2601 printf("%s bHubContrCurrent %3u milli Ampere\n",
2605 printf("%s bHubDecLat 0.%1u micro seconds\n",
2607 printf("%s wHubDelay %4u nano seconds\n",
2608 prefix, (p[8] << 4) +(p[7]));
2614 l = (p[2] >> 3) + 1; /* this determines the variable number of bytes following */
2615 if (l > HUB_STATUS_BYTELEN)
2616 l = HUB_STATUS_BYTELEN;
2617 printf("%s DeviceRemovable ", prefix);
2618 for (i = 0; i < l; i++)
2619 printf(" 0x%02x", p[offset+i]);
2622 printf("\n%s PortPwrCtrlMask ", prefix);
2623 for (j = 0; j < l; j++)
2624 printf(" 0x%02x", p[offset+i+j]);
2629 static void dump_ccid_device(const unsigned char *buf)
2634 printf(" Warning: Descriptor too short\n");
2637 printf(" ChipCard Interface Descriptor:\n"
2639 " bDescriptorType %5u\n"
2640 " bcdCCID %2x.%02x",
2641 buf[0], buf[1], buf[3], buf[2]);
2642 if (buf[3] != 1 || buf[2] != 0)
2643 fputs(" (Warning: Only accurate for version 1.0)", stdout);
2646 printf(" nMaxSlotIndex %5u\n"
2647 " bVoltageSupport %5u %s%s%s\n",
2650 (buf[5] & 1) ? "5.0V " : "",
2651 (buf[5] & 2) ? "3.0V " : "",
2652 (buf[5] & 4) ? "1.8V " : "");
2654 us = convert_le_u32 (buf+6);
2655 printf(" dwProtocols %5u ", us);
2657 fputs(" T=0", stdout);
2659 fputs(" T=1", stdout);
2661 fputs(" (Invalid values detected)", stdout);
2664 us = convert_le_u32(buf+10);
2665 printf(" dwDefaultClock %5u\n", us);
2666 us = convert_le_u32(buf+14);
2667 printf(" dwMaxiumumClock %5u\n", us);
2668 printf(" bNumClockSupported %5u\n", buf[18]);
2669 us = convert_le_u32(buf+19);
2670 printf(" dwDataRate %7u bps\n", us);
2671 us = convert_le_u32(buf+23);
2672 printf(" dwMaxDataRate %7u bps\n", us);
2673 printf(" bNumDataRatesSupp. %5u\n", buf[27]);
2675 us = convert_le_u32(buf+28);
2676 printf(" dwMaxIFSD %5u\n", us);
2678 us = convert_le_u32(buf+32);
2679 printf(" dwSyncProtocols %08X ", us);
2681 fputs(" 2-wire", stdout);
2683 fputs(" 3-wire", stdout);
2685 fputs(" I2C", stdout);
2688 us = convert_le_u32(buf+36);
2689 printf(" dwMechanical %08X ", us);
2691 fputs(" accept", stdout);
2693 fputs(" eject", stdout);
2695 fputs(" capture", stdout);
2697 fputs(" lock", stdout);
2700 us = convert_le_u32(buf+40);
2701 printf(" dwFeatures %08X\n", us);
2703 fputs(" Auto configuration based on ATR\n", stdout);
2705 fputs(" Auto activation on insert\n", stdout);
2707 fputs(" Auto voltage selection\n", stdout);
2709 fputs(" Auto clock change\n", stdout);
2711 fputs(" Auto baud rate change\n", stdout);
2713 fputs(" Auto parameter negotation made by CCID\n", stdout);
2714 else if ((us & 0x0080))
2715 fputs(" Auto PPS made by CCID\n", stdout);
2716 else if ((us & (0x0040 | 0x0080)))
2717 fputs(" WARNING: conflicting negotation features\n", stdout);
2720 fputs(" CCID can set ICC in clock stop mode\n", stdout);
2722 fputs(" NAD value other than 0x00 accpeted\n", stdout);
2724 fputs(" Auto IFSD exchange\n", stdout);
2726 if ((us & 0x00010000))
2727 fputs(" TPDU level exchange\n", stdout);
2728 else if ((us & 0x00020000))
2729 fputs(" Short APDU level exchange\n", stdout);
2730 else if ((us & 0x00040000))
2731 fputs(" Short and extended APDU level exchange\n", stdout);
2732 else if ((us & 0x00070000))
2733 fputs(" WARNING: conflicting exchange levels\n", stdout);
2735 us = convert_le_u32(buf+44);
2736 printf(" dwMaxCCIDMsgLen %5u\n", us);
2738 printf(" bClassGetResponse ");
2739 if (buf[48] == 0xff)
2740 fputs("echo\n", stdout);
2742 printf(" %02X\n", buf[48]);
2744 printf(" bClassEnvelope ");
2745 if (buf[49] == 0xff)
2746 fputs("echo\n", stdout);
2748 printf(" %02X\n", buf[48]);
2750 printf(" wlcdLayout ");
2751 if (!buf[50] && !buf[51])
2752 fputs("none\n", stdout);
2754 printf("%u cols %u lines\n", buf[50], buf[51]);
2756 printf(" bPINSupport %5u ", buf[52]);
2758 fputs(" verification", stdout);
2760 fputs(" modification", stdout);
2763 printf(" bMaxCCIDBusySlots %5u\n", buf[53]);
2766 fputs(" junk ", stdout);
2767 dump_bytes(buf+54, buf[0]-54);
2771 /* ---------------------------------------------------------------------- */
2777 static void dump_report_desc(unsigned char *b, int l)
2779 unsigned int j, bsize, btag, btype, data = 0xffff, hut = 0xffff;
2781 char *types[4] = { "Main", "Global", "Local", "reserved" };
2782 char indent[] = " ";
2784 printf(" Report Descriptor: (length is %d)\n", l);
2785 for (i = 0; i < l; ) {
2786 bsize = b[i] & 0x03;
2789 btype = b[i] & (0x03 << 2);
2790 btag = b[i] & ~0x03; /* 2 LSB bits encode length */
2791 printf(" Item(%-6s): %s, data=", types[btype>>2],
2792 names_reporttag(btag));
2796 for (j = 0; j < bsize; j++) {
2797 printf("0x%02x ", b[i+1+j]);
2798 data += (b[i+1+j] << (8*j));
2800 printf("] %d", data);
2805 case 0x04: /* Usage Page */
2806 printf("%s%s\n", indent, names_huts(data));
2810 case 0x08: /* Usage */
2811 case 0x18: /* Usage Minimum */
2812 case 0x28: /* Usage Maximum */
2813 printf("%s%s\n", indent,
2814 names_hutus((hut << 16) + data));
2817 case 0x54: /* Unit Exponent */
2818 printf("%sUnit Exponent: %i\n", indent,
2822 case 0x64: /* Unit */
2823 printf("%s", indent);
2824 dump_unit(data, bsize);
2827 case 0xa0: /* Collection */
2828 printf("%s", indent);
2831 printf("Physical\n");
2835 printf("Application\n");
2839 printf("Logical\n");
2847 printf("Named Array\n");
2851 printf("Usage Switch\n");
2855 printf("Usage Modifier\n");
2860 printf("Vendor defined\n");
2862 printf("Reserved for future use.\n");
2865 case 0x80: /* Input */
2866 case 0x90: /* Output */
2867 case 0xb0: /* Feature */
2868 printf("%s%s %s %s %s %s\n%s%s %s %s %s\n",
2870 data & 0x01 ? "Constant" : "Data",
2871 data & 0x02 ? "Variable" : "Array",
2872 data & 0x04 ? "Relative" : "Absolute",
2873 data & 0x08 ? "Wrap" : "No_Wrap",
2874 data & 0x10 ? "Non_Linear" : "Linear",
2876 data & 0x20 ? "No_Preferred_State" : "Preferred_State",
2877 data & 0x40 ? "Null_State" : "No_Null_Position",
2878 data & 0x80 ? "Volatile" : "Non_Volatile",
2879 data & 0x100 ? "Buffered Bytes" : "Bitfield");
2886 static void dump_hid_device(libusb_device_handle *dev,
2887 const struct libusb_interface_descriptor *interface,
2888 const unsigned char *buf)
2890 unsigned int i, len;
2892 unsigned char dbuf[8192];
2894 if (buf[1] != LIBUSB_DT_HID)
2895 printf(" Warning: Invalid descriptor\n");
2896 else if (buf[0] < 6+3*buf[5])
2897 printf(" Warning: Descriptor too short\n");
2898 printf(" HID Device Descriptor:\n"
2900 " bDescriptorType %5u\n"
2901 " bcdHID %2x.%02x\n"
2902 " bCountryCode %5u %s\n"
2903 " bNumDescriptors %5u\n",
2904 buf[0], buf[1], buf[3], buf[2], buf[4],
2905 names_countrycode(buf[4]) ? : "Unknown", buf[5]);
2906 for (i = 0; i < buf[5]; i++)
2907 printf(" bDescriptorType %5u %s\n"
2908 " wDescriptorLength %5u\n",
2909 buf[6+3*i], names_hid(buf[6+3*i]),
2910 buf[7+3*i] | (buf[8+3*i] << 8));
2911 dump_junk(buf, " ", 6+3*buf[5]);
2912 if (!do_report_desc)
2916 printf(" Report Descriptors: \n"
2917 " ** UNAVAILABLE **\n");
2921 for (i = 0; i < buf[5]; i++) {
2922 /* we are just interested in report descriptors*/
2923 if (buf[6+3*i] != LIBUSB_DT_REPORT)
2925 len = buf[7+3*i] | (buf[8+3*i] << 8);
2926 if (len > (unsigned int)sizeof(dbuf)) {
2927 printf("report descriptor too long\n");
2930 if (libusb_claim_interface(dev, interface->bInterfaceNumber) == 0) {
2933 while (n < len && retries--)
2934 n = usb_control_msg(dev,
2935 LIBUSB_ENDPOINT_IN | LIBUSB_REQUEST_TYPE_STANDARD
2936 | LIBUSB_RECIPIENT_INTERFACE,
2937 LIBUSB_REQUEST_GET_DESCRIPTOR,
2938 (LIBUSB_DT_REPORT << 8),
2939 interface->bInterfaceNumber,
2945 printf(" Warning: incomplete report descriptor\n");
2946 dump_report_desc(dbuf, n);
2948 libusb_release_interface(dev, interface->bInterfaceNumber);
2950 /* recent Linuxes require claim() for RECIP_INTERFACE,
2951 * so "rmmod hid" will often make these available.
2953 printf(" Report Descriptors: \n"
2954 " ** UNAVAILABLE **\n");
2960 dump_comm_descriptor(libusb_device_handle *dev, const unsigned char *buf, char *indent)
2971 printf("%sCDC Header:\n"
2972 "%s bcdCDC %x.%02x\n",
2974 indent, buf[4], buf[3]);
2976 case 0x01: /* call management functional desc */
2977 type = "Call Management";
2980 printf("%sCDC Call Management:\n"
2981 "%s bmCapabilities 0x%02x\n",
2985 printf("%s call management\n", indent);
2987 printf("%s use DataInterface\n", indent);
2988 printf("%s bDataInterface %d\n", indent, buf[4]);
2990 case 0x02: /* acm functional desc */
2994 printf("%sCDC ACM:\n"
2995 "%s bmCapabilities 0x%02x\n",
2999 printf("%s connection notifications\n", indent);
3001 printf("%s sends break\n", indent);
3003 printf("%s line coding and serial state\n", indent);
3005 printf("%s get/set/clear comm features\n", indent);
3008 case 0x03: /* direct line management */
3009 case 0x04: /* telephone ringer */
3010 case 0x05: /* telephone call and line state reporting */
3012 case 0x06: /* union desc */
3016 printf("%sCDC Union:\n"
3017 "%s bMasterInterface %d\n"
3018 "%s bSlaveInterface ",
3022 for (tmp = 4; tmp < buf[0]; tmp++)
3023 printf("%d ", buf[tmp]);
3026 case 0x07: /* country selection functional desc */
3027 type = "Country Selection";
3028 if (buf[0] < 6 || (buf[0] & 1) != 0)
3030 str = get_dev_string(dev, buf[3]);
3031 printf("%sCountry Selection:\n"
3032 "%s iCountryCodeRelDate %4d %s\n",
3034 indent, buf[3], (buf[3] && *str) ? str : "(?\?)");
3035 for (tmp = 4; tmp < buf[0]; tmp += 2) {
3036 printf("%s wCountryCode 0x%02x%02x\n",
3037 indent, buf[tmp], buf[tmp + 1]);
3040 case 0x08: /* telephone operational modes */
3041 type = "Telephone Operations";
3044 printf("%sCDC Telephone operations:\n"
3045 "%s bmCapabilities 0x%02x\n",
3049 printf("%s computer centric mode\n", indent);
3051 printf("%s standalone mode\n", indent);
3053 printf("%s simple mode\n", indent);
3056 case 0x09: /* USB terminal */
3058 case 0x0a: /* network channel terminal */
3059 type = "Network Channel Terminal";
3062 str = get_dev_string(dev, buf[4]);
3063 printf("%sNetwork Channel Terminal:\n"
3064 "%s bEntityId %3d\n"
3066 "%s bChannelIndex %3d\n"
3067 "%s bPhysicalInterface %3d\n",
3070 indent, buf[4], str,
3075 case 0x0b: /* protocol unit */
3076 case 0x0c: /* extension unit */
3077 case 0x0d: /* multi-channel management */
3078 case 0x0e: /* CAPI control management*/
3080 case 0x0f: /* ethernet functional desc */
3084 str = get_dev_string(dev, buf[3]);
3086 tmp |= buf[6]; tmp <<= 8;
3087 tmp |= buf[5]; tmp <<= 8;
3089 printf("%sCDC Ethernet:\n"
3090 "%s iMacAddress %10d %s\n"
3091 "%s bmEthernetStatistics 0x%08x\n",
3093 indent, buf[3], (buf[3] && *str) ? str : "(?\?)",
3095 /* FIXME dissect ALL 28 bits */
3096 printf("%s wMaxSegmentSize %10d\n"
3097 "%s wNumberMCFilters 0x%04x\n"
3098 "%s bNumberPowerFilters %10d\n",
3099 indent, (buf[9]<<8)|buf[8],
3100 indent, (buf[11]<<8)|buf[10],
3104 case 0x10: /* ATM networking */
3106 case 0x11: /* WHCM functional desc */
3107 type = "WHCM version";
3110 printf("%sCDC WHCM:\n"
3111 "%s bcdVersion %x.%02x\n",
3113 indent, buf[4], buf[3]);
3115 case 0x12: /* MDLM functional desc */
3119 printf("%sCDC MDLM:\n"
3120 "%s bcdCDC %x.%02x\n"
3123 indent, buf[4], buf[3],
3124 indent, get_guid(buf + 5));
3126 case 0x13: /* MDLM detail desc */
3127 type = "MDLM detail";
3130 printf("%sCDC MDLM detail:\n"
3131 "%s bGuidDescriptorType %02x\n"
3136 dump_bytes(buf + 4, buf[0] - 4);
3138 case 0x14: /* device management functional desc */
3139 type = "Device Management";
3142 printf("%sCDC Device Management:\n"
3143 "%s bcdVersion %x.%02x\n"
3144 "%s wMaxCommand %d\n",
3146 indent, buf[4], buf[3],
3147 indent, (buf[6] << 8) | buf[5]);
3149 case 0x15: /* OBEX functional desc */
3153 printf("%sCDC OBEX:\n"
3154 "%s bcdVersion %x.%02x\n",
3156 indent, buf[4], buf[3]);
3158 case 0x16: /* command set functional desc */
3159 type = "Command Set";
3162 str = get_dev_string(dev, buf[5]);
3163 printf("%sCDC Command Set:\n"
3164 "%s bcdVersion %x.%02x\n"
3165 "%s iCommandSet %4d %s\n"
3168 indent, buf[4], buf[3],
3169 indent, buf[5], (buf[5] && *str) ? str : "(?\?)",
3170 indent, get_guid(buf + 6));
3173 case 0x17: /* command set detail desc */
3174 case 0x18: /* telephone control model functional desc */
3176 case 0x1a: /* NCM functional desc */
3180 printf("%sCDC NCM:\n"
3181 "%s bcdNcmVersion %x.%02x\n"
3182 "%s bmNetworkCapabilities 0x%02x\n",
3184 indent, buf[4], buf[3],
3187 printf("%s 8-byte ntb input size\n", indent);
3189 printf("%s crc mode\n", indent);
3191 printf("%s max datagram size\n", indent);
3193 printf("%s encapsulated commands\n", indent);
3195 printf("%s net address\n", indent);
3197 printf("%s packet filter\n", indent);
3199 case 0x1b: /* MBIM functional desc */
3203 printf("%sCDC MBIM:\n"
3204 "%s bcdMBIMVersion %x.%02x\n"
3205 "%s wMaxControlMessage %d\n"
3206 "%s bNumberFilters %d\n"
3207 "%s bMaxFilterSize %d\n"
3208 "%s wMaxSegmentSize %d\n"
3209 "%s bmNetworkCapabilities 0x%02x\n",
3211 indent, buf[4], buf[3],
3212 indent, (buf[6] << 8) | buf[5],
3215 indent, (buf[10] << 8) | buf[9],
3218 printf("%s 8-byte ntb input size\n", indent);
3220 printf("%s max datagram size\n", indent);
3223 /* FIXME there are about a dozen more descriptor types */
3224 printf("%sUNRECOGNIZED CDC: ", indent);
3225 dump_bytes(buf, buf[0]);
3226 return "unrecognized comm descriptor";
3234 printf("%sINVALID CDC (%s): ", indent, type);
3235 dump_bytes(buf, buf[0]);
3236 return "corrupt comm descriptor";
3239 /* ---------------------------------------------------------------------- */
3241 static void do_hub(libusb_device_handle *fd, unsigned tt_type, unsigned speed)
3243 unsigned char buf[7 /* base descriptor */
3244 + 2 /* bitmasks */ * HUB_STATUS_BYTELEN];
3246 unsigned int link_state;
3247 char *link_state_descriptions[] = {
3262 /* USB 3.0 hubs have a slightly different descriptor */
3263 if (speed == 0x0300)
3268 ret = usb_control_msg(fd,
3269 LIBUSB_ENDPOINT_IN | LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_RECIPIENT_DEVICE,
3270 LIBUSB_REQUEST_GET_DESCRIPTOR,
3272 buf, sizeof buf, CTRL_TIMEOUT);
3273 if (ret < 9 /* at least one port's bitmasks */) {
3276 "incomplete hub descriptor, %d bytes\n",
3278 /* Linux returns EHOSTUNREACH for suspended devices */
3279 else if (errno != EHOSTUNREACH)
3280 perror("can't get hub descriptor");
3283 dump_hub("", buf, tt_type);
3285 printf(" Hub Port Status:\n");
3286 for (i = 0; i < buf[2]; i++) {
3287 unsigned char status[4];
3289 ret = usb_control_msg(fd,
3290 LIBUSB_ENDPOINT_IN | LIBUSB_REQUEST_TYPE_CLASS
3291 | LIBUSB_RECIPIENT_OTHER,
3292 LIBUSB_REQUEST_GET_STATUS,
3294 status, sizeof status,
3298 "cannot read port %d status, %s (%d)\n",
3299 i + 1, strerror(errno), errno);
3303 printf(" Port %d: %02x%02x.%02x%02x", i + 1,
3304 status[3], status[2],
3305 status[1], status[0]);
3306 /* CAPS are used to highlight "transient" states */
3307 if (speed != 0x0300) {
3308 printf("%s%s%s%s%s",
3309 (status[2] & 0x10) ? " C_RESET" : "",
3310 (status[2] & 0x08) ? " C_OC" : "",
3311 (status[2] & 0x04) ? " C_SUSPEND" : "",
3312 (status[2] & 0x02) ? " C_ENABLE" : "",
3313 (status[2] & 0x01) ? " C_CONNECT" : "");
3314 printf("%s%s%s%s%s%s%s%s%s%s\n",
3315 (status[1] & 0x10) ? " indicator" : "",
3316 (status[1] & 0x08) ? " test" : "",
3317 (status[1] & 0x04) ? " highspeed" : "",
3318 (status[1] & 0x02) ? " lowspeed" : "",
3319 (status[1] & 0x01) ? " power" : "",
3320 (status[0] & 0x10) ? " RESET" : "",
3321 (status[0] & 0x08) ? " oc" : "",
3322 (status[0] & 0x04) ? " suspend" : "",
3323 (status[0] & 0x02) ? " enable" : "",
3324 (status[0] & 0x01) ? " connect" : "");
3326 link_state = ((status[0] & 0xe0) >> 5) +
3327 ((status[1] & 0x1) << 3);
3328 printf("%s%s%s%s%s%s",
3329 (status[2] & 0x80) ? " C_CONFIG_ERROR" : "",
3330 (status[2] & 0x40) ? " C_LINK_STATE" : "",
3331 (status[2] & 0x20) ? " C_BH_RESET" : "",
3332 (status[2] & 0x10) ? " C_RESET" : "",
3333 (status[2] & 0x08) ? " C_OC" : "",
3334 (status[2] & 0x01) ? " C_CONNECT" : "");
3336 ((status[1] & 0x1C) == 0) ? " 5Gbps" : " Unknown Speed",
3337 (status[1] & 0x02) ? " power" : "");
3338 /* Link state is bits 8:5 */
3339 if (link_state < (sizeof(link_state_descriptions) /
3340 sizeof(*link_state_descriptions)))
3341 printf("%s", link_state_descriptions[link_state]);
3342 printf("%s%s%s%s\n",
3343 (status[0] & 0x10) ? " RESET" : "",
3344 (status[0] & 0x08) ? " oc" : "",
3345 (status[0] & 0x02) ? " enable" : "",
3346 (status[0] & 0x01) ? " connect" : "");
3351 static void do_dualspeed(libusb_device_handle *fd)
3353 unsigned char buf[10];
3354 char cls[128], subcls[128], proto[128];
3357 ret = usb_control_msg(fd,
3358 LIBUSB_ENDPOINT_IN | LIBUSB_REQUEST_TYPE_STANDARD | LIBUSB_RECIPIENT_DEVICE,
3359 LIBUSB_REQUEST_GET_DESCRIPTOR,
3360 USB_DT_DEVICE_QUALIFIER << 8, 0,
3361 buf, sizeof buf, CTRL_TIMEOUT);
3362 if (ret < 0 && errno != EPIPE)
3363 perror("can't get device qualifier");
3365 /* all dual-speed devices have a qualifier */
3366 if (ret != sizeof buf
3368 || buf[1] != USB_DT_DEVICE_QUALIFIER)
3371 get_class_string(cls, sizeof(cls),
3373 get_subclass_string(subcls, sizeof(subcls),
3375 get_protocol_string(proto, sizeof(proto),
3376 buf[4], buf[5], buf[6]);
3377 printf("Device Qualifier (for other device speed):\n"
3379 " bDescriptorType %5u\n"
3380 " bcdUSB %2x.%02x\n"
3381 " bDeviceClass %5u %s\n"
3382 " bDeviceSubClass %5u %s\n"
3383 " bDeviceProtocol %5u %s\n"
3384 " bMaxPacketSize0 %5u\n"
3385 " bNumConfigurations %5u\n",
3393 /* FIXME also show the OTHER_SPEED_CONFIG descriptors */
3396 static void do_debug(libusb_device_handle *fd)
3398 unsigned char buf[4];
3401 ret = usb_control_msg(fd,
3402 LIBUSB_ENDPOINT_IN | LIBUSB_REQUEST_TYPE_STANDARD | LIBUSB_RECIPIENT_DEVICE,
3403 LIBUSB_REQUEST_GET_DESCRIPTOR,
3404 USB_DT_DEBUG << 8, 0,
3405 buf, sizeof buf, CTRL_TIMEOUT);
3406 if (ret < 0 && errno != EPIPE)
3407 perror("can't get debug descriptor");
3409 /* some high speed devices are also "USB2 debug devices", meaning
3410 * you can use them with some EHCI implementations as another kind
3411 * of system debug channel: like JTAG, RS232, or a console.
3413 if (ret != sizeof buf
3415 || buf[1] != USB_DT_DEBUG)
3418 printf("Debug descriptor:\n"
3420 " bDescriptorType %4u\n"
3421 " bDebugInEndpoint 0x%02x\n"
3422 " bDebugOutEndpoint 0x%02x\n",
3427 static const unsigned char *find_otg(const unsigned char *buf, int buflen)
3431 while (buflen >= 3) {
3432 if (buf[0] == 3 && buf[1] == USB_DT_OTG)
3434 if (buf[0] > buflen)
3442 static int do_otg(struct libusb_config_descriptor *config)
3446 const unsigned char *desc;
3448 /* each config of an otg device has an OTG descriptor */
3449 desc = find_otg(config->extra, config->extra_length);
3450 for (i = 0; !desc && i < config->bNumInterfaces; i++) {
3451 const struct libusb_interface *intf;
3453 intf = &config->interface[i];
3454 for (j = 0; !desc && j < intf->num_altsetting; j++) {
3455 const struct libusb_interface_descriptor *alt;
3457 alt = &intf->altsetting[j];
3458 desc = find_otg(alt->extra, alt->extra_length);
3459 for (k = 0; !desc && k < alt->bNumEndpoints; k++) {
3460 const struct libusb_endpoint_descriptor *ep;
3462 ep = &alt->endpoint[k];
3463 desc = find_otg(ep->extra, ep->extra_length);
3470 printf("OTG Descriptor:\n"
3472 " bDescriptorType %3u\n"
3473 " bmAttributes 0x%02x\n"
3475 desc[0], desc[1], desc[2],
3477 ? " SRP (Session Request Protocol)\n" : "",
3479 ? " HNP (Host Negotiation Protocol)\n" : "");
3484 dump_device_status(libusb_device_handle *fd, int otg, int wireless, int super_speed)
3486 unsigned char status[8];
3489 ret = usb_control_msg(fd, LIBUSB_ENDPOINT_IN | LIBUSB_REQUEST_TYPE_STANDARD
3490 | LIBUSB_RECIPIENT_DEVICE,
3491 LIBUSB_REQUEST_GET_STATUS,
3497 "cannot read device status, %s (%d)\n",
3498 strerror(errno), errno);
3502 printf("Device Status: 0x%02x%02x\n",
3503 status[1], status[0]);
3504 if (status[0] & (1 << 0))
3505 printf(" Self Powered\n");
3507 printf(" (Bus Powered)\n");
3508 if (status[0] & (1 << 1))
3509 printf(" Remote Wakeup Enabled\n");
3510 if (status[0] & (1 << 2) && !super_speed) {
3511 /* for high speed devices */
3513 printf(" Test Mode\n");
3514 /* for devices with Wireless USB support */
3516 printf(" Battery Powered\n");
3519 if (status[0] & (1 << 2))
3520 printf(" U1 Enabled\n");
3521 if (status[0] & (1 << 3))
3522 printf(" U2 Enabled\n");
3523 if (status[0] & (1 << 4))
3524 printf(" Latency Tolerance Messaging (LTM) Enabled\n");
3526 /* if both HOST and DEVICE support OTG */
3528 if (status[0] & (1 << 3))
3529 printf(" HNP Enabled\n");
3530 if (status[0] & (1 << 4))
3531 printf(" HNP Capable\n");
3532 if (status[0] & (1 << 5))
3533 printf(" ALT port is HNP Capable\n");
3535 /* for high speed devices with debug descriptors */
3536 if (status[0] & (1 << 6))
3537 printf(" Debug Mode\n");
3542 /* Wireless USB exposes FIVE different types of device status,
3543 * accessed by distinct wIndex values.
3545 ret = usb_control_msg(fd, LIBUSB_ENDPOINT_IN | LIBUSB_REQUEST_TYPE_STANDARD
3546 | LIBUSB_RECIPIENT_DEVICE,
3547 LIBUSB_REQUEST_GET_STATUS,
3548 0, 1 /* wireless status */,
3553 "cannot read wireless %s, %s (%d)\n",
3555 strerror(errno), errno);
3558 printf("Wireless Status: 0x%02x\n", status[0]);
3559 if (status[0] & (1 << 0))
3560 printf(" TX Drp IE\n");
3561 if (status[0] & (1 << 1))
3562 printf(" Transmit Packet\n");
3563 if (status[0] & (1 << 2))
3564 printf(" Count Packets\n");
3565 if (status[0] & (1 << 3))
3566 printf(" Capture Packet\n");
3568 ret = usb_control_msg(fd, LIBUSB_ENDPOINT_IN | LIBUSB_REQUEST_TYPE_STANDARD
3569 | LIBUSB_RECIPIENT_DEVICE,
3570 LIBUSB_REQUEST_GET_STATUS,
3571 0, 2 /* Channel Info */,
3576 "cannot read wireless %s, %s (%d)\n",
3578 strerror(errno), errno);
3581 printf("Channel Info: 0x%02x\n", status[0]);
3583 /* 3=Received data: many bytes, for count packets or capture packet */
3585 ret = usb_control_msg(fd, LIBUSB_ENDPOINT_IN | LIBUSB_REQUEST_TYPE_STANDARD
3586 | LIBUSB_RECIPIENT_DEVICE,
3587 LIBUSB_REQUEST_GET_STATUS,
3588 0, 3 /* MAS Availability */,
3593 "cannot read wireless %s, %s (%d)\n",
3595 strerror(errno), errno);
3598 printf("MAS Availability: ");
3599 dump_bytes(status, 8);
3601 ret = usb_control_msg(fd, LIBUSB_ENDPOINT_IN | LIBUSB_REQUEST_TYPE_STANDARD
3602 | LIBUSB_RECIPIENT_DEVICE,
3603 LIBUSB_REQUEST_GET_STATUS,
3604 0, 5 /* Current Transmit Power */,
3609 "cannot read wireless %s, %s (%d)\n",
3611 strerror(errno), errno);
3614 printf("Transmit Power:\n");
3615 printf(" TxNotification: 0x%02x\n", status[0]);
3616 printf(" TxBeacon: : 0x%02x\n", status[1]);
3619 static int do_wireless(libusb_device_handle *fd)
3621 /* FIXME fetch and dump BOS etc */
3627 static void dump_usb2_device_capability_desc(unsigned char *buf)
3631 wide = buf[3] + (buf[4] << 8) +
3632 (buf[5] << 16) + (buf[6] << 24);
3633 printf(" USB 2.0 Extension Device Capability:\n"
3635 " bDescriptorType %5u\n"
3636 " bDevCapabilityType %5u\n"
3637 " bmAttributes 0x%08x\n",
3638 buf[0], buf[1], buf[2], wide);
3640 printf(" (Missing must-be-set LPM bit!)\n");
3642 printf(" Link Power Management (LPM)"
3646 static void dump_ss_device_capability_desc(unsigned char *buf)
3649 printf(" Bad SuperSpeed USB Device Capability descriptor.\n");
3652 printf(" SuperSpeed USB Device Capability:\n"
3654 " bDescriptorType %5u\n"
3655 " bDevCapabilityType %5u\n"
3656 " bmAttributes 0x%02x\n",
3657 buf[0], buf[1], buf[2], buf[3]);
3659 printf(" Latency Tolerance Messages (LTM)"
3661 printf(" wSpeedsSupported 0x%02x%02x\n", buf[5], buf[4]);
3662 if (buf[4] & (1 << 0))
3663 printf(" Device can operate at Low Speed (1Mbps)\n");
3664 if (buf[4] & (1 << 1))
3665 printf(" Device can operate at Full Speed (12Mbps)\n");
3666 if (buf[4] & (1 << 2))
3667 printf(" Device can operate at High Speed (480Mbps)\n");
3668 if (buf[4] & (1 << 3))
3669 printf(" Device can operate at SuperSpeed (5Gbps)\n");
3671 printf(" bFunctionalitySupport %3u\n", buf[6]);
3674 printf(" Lowest fully-functional device speed is "
3675 "Low Speed (1Mbps)\n");
3678 printf(" Lowest fully-functional device speed is "
3679 "Full Speed (12Mbps)\n");
3682 printf(" Lowest fully-functional device speed is "
3683 "High Speed (480Mbps)\n");
3686 printf(" Lowest fully-functional device speed is "
3687 "SuperSpeed (5Gbps)\n");
3690 printf(" Lowest fully-functional device speed is "
3691 "at an unknown speed!\n");
3694 printf(" bU1DevExitLat %4u micro seconds\n", buf[7]);
3695 printf(" bU2DevExitLat %8u micro seconds\n", buf[8] + (buf[9] << 8));
3698 static void dump_container_id_device_capability_desc(unsigned char *buf)
3701 printf(" Bad Container ID Device Capability descriptor.\n");
3704 printf(" Container ID Device Capability:\n"
3706 " bDescriptorType %5u\n"
3707 " bDevCapabilityType %5u\n"
3709 buf[0], buf[1], buf[2], buf[3]);
3710 printf(" ContainerID %s\n",
3714 static void dump_bos_descriptor(libusb_device_handle *fd)
3716 /* Total for all known BOS descriptors is 43 bytes:
3717 * 6 bytes for Wireless USB, 7 bytes for USB 2.0 extension,
3718 * 10 bytes for SuperSpeed, 20 bytes for Container ID.
3720 unsigned char bos_desc[43];
3721 unsigned int bos_desc_size;
3725 /* Get the first 5 bytes to get the wTotalLength field */
3726 ret = usb_control_msg(fd,
3727 LIBUSB_ENDPOINT_IN | LIBUSB_RECIPIENT_DEVICE,
3728 LIBUSB_REQUEST_GET_DESCRIPTOR,
3730 bos_desc, 5, CTRL_TIMEOUT);
3733 else if (bos_desc[0] != 5 || bos_desc[1] != USB_DT_BOS)
3736 bos_desc_size = bos_desc[2] + (bos_desc[3] << 8);
3737 printf("Binary Object Store Descriptor:\n"
3739 " bDescriptorType %5u\n"
3740 " wTotalLength %5u\n"
3741 " bNumDeviceCaps %5u\n",
3742 bos_desc[0], bos_desc[1],
3743 bos_desc_size, bos_desc[4]);
3745 if (bos_desc_size <= 5) {
3746 if (bos_desc[4] > 0)
3747 fprintf(stderr, "Couldn't get "
3748 "device capability descriptors\n");
3751 if (bos_desc_size > sizeof bos_desc) {
3752 fprintf(stderr, "FIXME: alloc bigger buffer for "
3753 "device capability descriptors\n");
3757 ret = usb_control_msg(fd,
3758 LIBUSB_ENDPOINT_IN | LIBUSB_RECIPIENT_DEVICE,
3759 LIBUSB_REQUEST_GET_DESCRIPTOR,
3761 bos_desc, bos_desc_size, CTRL_TIMEOUT);
3763 fprintf(stderr, "Couldn't get device capability descriptors\n");
3767 size = bos_desc_size - 5;
3772 printf("buf[0] = %u\n", buf[0]);
3776 case USB_DC_WIRELESS_USB:
3779 case USB_DC_20_EXTENSION:
3780 dump_usb2_device_capability_desc(buf);
3782 case USB_DC_SUPERSPEED:
3783 dump_ss_device_capability_desc(buf);
3785 case USB_DC_CONTAINER_ID:
3786 dump_container_id_device_capability_desc(buf);
3789 printf(" ** UNRECOGNIZED: ");
3790 dump_bytes(buf, buf[0]);
3798 static void dumpdev(libusb_device *dev)
3800 libusb_device_handle *udev;
3801 struct libusb_device_descriptor desc;
3806 ret = libusb_open(dev, &udev);
3808 fprintf(stderr, "Couldn't open device, some information "
3809 "will be missing\n");
3813 libusb_get_device_descriptor(dev, &desc);
3814 dump_device(udev, &desc);
3815 if (desc.bcdUSB == 0x0250)
3816 wireless = do_wireless(udev);
3817 if (desc.bNumConfigurations) {
3818 struct libusb_config_descriptor *config;
3820 ret = libusb_get_config_descriptor(dev, 0, &config);
3822 fprintf(stderr, "Couldn't get configuration descriptor 0, "
3823 "some information will be missing\n");
3825 otg = do_otg(config) || otg;
3826 libusb_free_config_descriptor(config);
3829 for (i = 0; i < desc.bNumConfigurations; ++i) {
3830 ret = libusb_get_config_descriptor(dev, i, &config);
3832 fprintf(stderr, "Couldn't get configuration "
3833 "descriptor %d, some information will "
3836 dump_config(udev, config);
3837 libusb_free_config_descriptor(config);
3844 if (desc.bDeviceClass == LIBUSB_CLASS_HUB)
3845 do_hub(udev, desc.bDeviceProtocol, desc.bcdUSB);
3846 if (desc.bcdUSB >= 0x0201) {
3847 dump_bos_descriptor(udev);
3849 if (desc.bcdUSB == 0x0200) {
3853 dump_device_status(udev, otg, wireless, desc.bcdUSB >= 0x0300);
3857 /* ---------------------------------------------------------------------- */
3859 static int dump_one_device(libusb_context *ctx, const char *path)
3862 struct libusb_device_descriptor desc;
3863 char vendor[128], product[128];
3865 dev = get_usb_device(ctx, path);
3867 fprintf(stderr, "Cannot open %s\n", path);
3870 libusb_get_device_descriptor(dev, &desc);
3871 get_vendor_string(vendor, sizeof(vendor), desc.idVendor);
3872 get_product_string(product, sizeof(product), desc.idVendor, desc.idProduct);
3873 printf("Device: ID %04x:%04x %s %s\n", desc.idVendor,
3881 static int list_devices(libusb_context *ctx, int busnum, int devnum, int vendorid, int productid)
3883 libusb_device **list;
3884 struct libusb_device_descriptor desc;
3885 char vendor[128], product[128];
3887 ssize_t num_devs, i;
3889 status = 1; /* 1 device not found, 0 device found */
3891 num_devs = libusb_get_device_list(ctx, &list);
3895 for (i = 0; i < num_devs; ++i) {
3896 libusb_device *dev = list[i];
3897 uint8_t bnum = libusb_get_bus_number(dev);
3898 uint8_t dnum = libusb_get_device_address(dev);
3900 if ((busnum != -1 && busnum != bnum) ||
3901 (devnum != -1 && devnum != dnum))
3903 libusb_get_device_descriptor(dev, &desc);
3904 if ((vendorid != -1 && vendorid != desc.idVendor) ||
3905 (productid != -1 && productid != desc.idProduct))
3908 get_vendor_string(vendor, sizeof(vendor), desc.idVendor);
3909 get_product_string(product, sizeof(product),
3910 desc.idVendor, desc.idProduct);
3913 printf("Bus %03u Device %03u: ID %04x:%04x %s %s\n",
3922 libusb_free_device_list(list, 0);
3928 /* ---------------------------------------------------------------------- */
3930 int main(int argc, char *argv[])
3932 static const struct option long_options[] = {
3933 { "version", 0, 0, 'V' },
3934 { "verbose", 0, 0, 'v' },
3935 { "help", 0, 0, 'h' },
3936 { "tree", 0, 0, 't' },
3939 libusb_context *ctx;
3941 unsigned int treemode = 0;
3942 int bus = -1, devnum = -1, vendor = -1, product = -1;
3943 const char *devdump = NULL;
3948 setlocale(LC_CTYPE, "");
3950 while ((c = getopt_long(argc, argv, "D:vtP:p:s:d:Vh",
3951 long_options, NULL)) != EOF) {
3954 printf("lsusb (" PACKAGE ") " VERSION "\n");
3955 return EXIT_SUCCESS;
3969 cp = strchr(optarg, ':');
3973 bus = strtoul(optarg, NULL, 10);
3975 devnum = strtoul(cp, NULL, 10);
3978 devnum = strtoul(optarg, NULL, 10);
3983 cp = strchr(optarg, ':');
3990 vendor = strtoul(optarg, NULL, 16);
3992 product = strtoul(cp, NULL, 16);
4005 if (err || argc > optind || help) {
4006 fprintf(stderr, "Usage: lsusb [options]...\n"
4007 "List USB devices\n"
4009 " Increase verbosity (show descriptors)\n"
4010 " -s [[bus]:][devnum]\n"
4011 " Show only devices with specified device and/or\n"
4012 " bus numbers (in decimal)\n"
4013 " -d vendor:[product]\n"
4014 " Show only devices with the specified vendor and\n"
4015 " product ID numbers (in hexadecimal)\n"
4017 " Selects which device lsusb will examine\n"
4019 " Dump the physical USB device hierarchy as a tree\n"
4021 " Show version of program\n"
4023 " Show usage and help\n"
4025 return EXIT_FAILURE;
4029 /* by default, print names as well as numbers */
4030 err = names_init(DATADIR "/usb.ids");
4033 err = names_init(DATADIR "/usb.ids.gz");
4036 fprintf(stderr, "%s: cannot open \"%s\", %s\n",
4043 /* treemode requires at least verblevel 1 */
4044 verblevel += 1 - VERBLEVEL_DEFAULT;
4050 err = libusb_init(&ctx);
4052 fprintf(stderr, "unable to initialize libusb: %i\n", err);
4053 return EXIT_FAILURE;
4057 status = dump_one_device(ctx, devdump);
4059 status = list_devices(ctx, bus, devnum, vendor, product);