diff --git a/headers/os/drivers/usb/USB_cdc.h b/headers/os/drivers/usb/USB_cdc.h index 5736328334..fe05a1dee4 100644 --- a/headers/os/drivers/usb/USB_cdc.h +++ b/headers/os/drivers/usb/USB_cdc.h @@ -5,6 +5,7 @@ // Reference: http://www.usb.org/developers/devclass_docs/usbcdc11.pdf #define USB_COMMUNICATION_DEVICE_CLASS 0x02 +#define USB_COMMUNICATION_WIRELESS_DEVICE_CLASS 0xe0 #define USB_CDC_COMMUNICATION_INTERFACE_CLASS 0x02 #define USB_CDC_CLASS_VERSION 0x0101 diff --git a/src/bin/listusb/listusb.cpp b/src/bin/listusb/listusb.cpp index b339ec486d..ec1845278e 100644 --- a/src/bin/listusb/listusb.cpp +++ b/src/bin/listusb/listusb.cpp @@ -12,6 +12,7 @@ #include #include #include +#include #include #include "usbspec_private.h" @@ -129,16 +130,234 @@ ProtocolName(int classNumber, int subclass, int protocol) } case 0xE0: if (subclass == 0x01 && protocol == 0x01) - return " (Bluetooth)"; + return " (Bluetooth control)"; + if (subclass == 0x01 && protocol == 0x02) + return " (UWB Radio)"; + if (subclass == 0x01 && protocol == 0x03) + return " (RNDIS control)"; + if (subclass == 0x01 && protocol == 0x04) + return " (Bluetooth AMP)"; + if (subclass == 0x02 && protocol == 0x01) + return " (Host wire adapter)"; + if (subclass == 0x02 && protocol == 0x02) + return " (Device wire adapter)"; + if (subclass == 0x02 && protocol == 0x03) + return " (Device wire isochronous)"; case 0xEF: + if (subclass == 0x01 && protocol == 0x01) + return " (Microsoft Active Sync)"; + if (subclass == 0x01 && protocol == 0x02) + return " (Palm Sync)"; if (subclass == 0x02 && protocol == 0x01) return " (Interface Association)"; + if (subclass == 0x02 && protocol == 0x02) + return " (Wire adapter multifunction peripheral)"; + if (subclass == 0x03 && protocol == 0x01) + return " (Cable based association framework)"; + if (subclass == 0x04 && protocol == 0x01) + return " (RNDIS Ethernet)"; + if (subclass == 0x04 && protocol == 0x02) + return " (RNDIS Wifi)"; + if (subclass == 0x04 && protocol == 0x03) + return " (RNDIS WiMAX)"; + if (subclass == 0x04 && protocol == 0x04) + return " (RNDIS WWAN)"; + if (subclass == 0x04 && protocol == 0x05) + return " (RNDIS raw IPv4)"; + if (subclass == 0x04 && protocol == 0x06) + return " (RNDIS raw IPv6)"; + if (subclass == 0x04 && protocol == 0x07) + return " (RNDIS GPRS)"; + if (subclass == 0x05 && protocol == 0x00) + return " (USB3 vision control)"; + if (subclass == 0x05 && protocol == 0x01) + return " (USB3 vision event)"; + if (subclass == 0x05 && protocol == 0x02) + return " (USB3 vision streaming)"; + if (subclass == 0x06 && protocol == 0x01) + return " (STEP)"; + if (subclass == 0x06 && protocol == 0x02) + return " (STEP RAW)"; + if (subclass == 0x07 && protocol == 0x01) + return " (DVB Command Interface in IAD)"; + if (subclass == 0x07 && protocol == 0x02) + return " (DVB Command Interface in interface descriptor)"; + if (subclass == 0x07 && protocol == 0x03) + return " (Media interface in interface descriptor)"; break; } return ""; } +void +DumpCDCDescriptor(const usb_generic_descriptor* descriptor, int subclass) +{ + if (descriptor->descriptor_type == 0x24) { + printf(" Type ............. CDC interface descriptor\n"); + printf(" Subtype .......... "); + switch (descriptor->data[0]) { + case USB_CDC_HEADER_FUNCTIONAL_DESCRIPTOR: + printf("Header\n"); + printf(" CDC Version ...... %x.%x\n", + descriptor->data[2], descriptor->data[1]); + return; + case USB_CDC_CM_FUNCTIONAL_DESCRIPTOR: + { + printf("Call management\n"); + const usb_cdc_cm_functional_descriptor* cmDesc + = (const usb_cdc_cm_functional_descriptor*)descriptor; + printf(" Capabilities ..... "); + bool somethingPrinted = false; + if (cmDesc->capabilities & USB_CDC_CM_DOES_CALL_MANAGEMENT != 0) { + printf("Call management"); + somethingPrinted = true; + } + if (cmDesc->capabilities & USB_CDC_CM_OVER_DATA_INTERFACE != 0) { + if (somethingPrinted) + printf(", "); + printf("Over data interface"); + somethingPrinted = true; + } + if (!somethingPrinted) + printf("None"); + printf("\n"); + printf(" Data interface ... %d\n", cmDesc->data_interface); + return; + } + case USB_CDC_ACM_FUNCTIONAL_DESCRIPTOR: + { + printf("Abstract control management\n"); + const usb_cdc_acm_functional_descriptor* acmDesc + = (const usb_cdc_acm_functional_descriptor*)descriptor; + printf(" Capabilities ..... "); + bool somethingPrinted = false; + if (acmDesc->capabilities & USB_CDC_ACM_HAS_COMM_FEATURES != 0) { + printf("Communication features"); + somethingPrinted = true; + } + if (acmDesc->capabilities & USB_CDC_ACM_HAS_LINE_CONTROL != 0) { + if (somethingPrinted) + printf(", "); + printf("Line control"); + somethingPrinted = true; + } + if (acmDesc->capabilities & USB_CDC_ACM_HAS_SEND_BREAK != 0) { + if (somethingPrinted) + printf(", "); + printf("Send break"); + somethingPrinted = true; + } + if (acmDesc->capabilities & USB_CDC_ACM_HAS_NETWORK_CONNECTION != 0) { + if (somethingPrinted) + printf(", "); + printf("Network connection"); + somethingPrinted = true; + } + if (!somethingPrinted) + printf("None"); + printf("\n"); + return; + } + case 0x03: + printf("Direct line management\n"); + break; + case 0x04: + printf("Telephone ringer management\n"); + break; + case 0x05: + printf("Telephone call and line state reporting\n"); + break; + case USB_CDC_UNION_FUNCTIONAL_DESCRIPTOR: + printf("Union\n"); + printf(" Control interface %d\n", descriptor->data[1]); + for (int32 i = 2; i < descriptor->length - 2; i++) + printf(" Subordinate ..... %d\n", descriptor->data[i]); + return; + case 0x07: + printf("Country selection\n"); + break; + case 0x08: + printf("Telephone operational mode\n"); + break; + case 0x09: + printf("USB Terminal\n"); + break; + case 0x0A: + printf("Network channel\n"); + break; + case 0x0B: + printf("Protocol init\n"); + break; + case 0x0C: + printf("Extension unit\n"); + break; + case 0x0D: + printf("Multi-channel management\n"); + break; + case 0x0E: + printf("CAPI control\n"); + break; + case 0x0F: + printf("Ethernet\n"); + break; + case 0x10: + printf("ATM\n"); + break; + case 0x11: + printf("Wireless handset\n"); + break; + case 0x12: + printf("Mobile direct line\n"); + break; + case 0x13: + printf("Mobile direct line detail\n"); + break; + case 0x14: + printf("Device management\n"); + break; + case 0x15: + printf("Object Exchange\n"); + break; + case 0x16: + printf("Command set\n"); + break; + case 0x17: + printf("Command set detail\n"); + break; + case 0x18: + printf("Telephone control\n"); + break; + case 0x19: + printf("Object Exchange service identifier\n"); + break; + case 0x1A: + printf("NCM\n"); + break; + default: + printf("0x%02x\n", descriptor->data[0]); + } + + printf(" Data ............. "); + // len includes len and descriptor_type field + // start at i = 1 because we already dumped the first byte as subtype + for (int32 i = 1; i < descriptor->length - 2; i++) + printf("%02x ", descriptor->data[i]); + printf("\n"); + return; + } + +#if 0 + if (descriptor->descriptor_type == 0x25) { + printf(" Type ............. CDC endpoint descriptor\n", + return; + } +#endif + + DumpDescriptorData(descriptor); +} + + void DumpDescriptorData(const usb_generic_descriptor* descriptor) { @@ -164,6 +383,10 @@ DumpDescriptor(const usb_generic_descriptor* descriptor, case USB_VIDEO_DEVICE_CLASS: DumpVideoDescriptor(descriptor, subclass); break; + case USB_COMMUNICATION_DEVICE_CLASS: + case USB_COMMUNICATION_WIRELESS_DEVICE_CLASS: + DumpCDCDescriptor(descriptor, subclass); + break; default: DumpDescriptorData(descriptor); break;