listusb: decode USB-CDC descriptors
Change-Id: I36ea15fee28b27332a8092a98a302c22b41ae060 Reviewed-on: https://review.haiku-os.org/c/haiku/+/5225 Reviewed-by: Fredrik Holmqvist <fredrik.holmqvist@gmail.com>
This commit is contained in:
parent
6c02429697
commit
581013b8e3
@ -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
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include <String.h>
|
||||
#include <stdio.h>
|
||||
#include <usb/USB_audio.h>
|
||||
#include <usb/USB_cdc.h>
|
||||
#include <usb/USB_video.h>
|
||||
|
||||
#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;
|
||||
|
Loading…
Reference in New Issue
Block a user