-
Notifications
You must be signed in to change notification settings - Fork 1.7k
USB: Descriptor
https://www.beyondlogic.org/usbnutshell/usb5.shtml
Descriptor | Types Value |
---|---|
DEVICE | 1 |
CONFIGURATION | 2 |
STRING | 3 |
INTERFACE | 4 |
ENDPOINT | 5 |
DEVICE_QUALIFIER | 6 |
OTHER_SPEED_CONFIGURATION | 7 |
INTERFACE_POWER | 8 |
USB 2.0 9.4
https://www.usb.org/defined-class-codes
Open
Base Class | Descriptor | Usage Description |
---|---|---|
00h | Device | Use class information in the Interface Descriptors |
01h | Interface | Audio |
02h | Both | Communications and CDC Control |
03h | Interface | HID (Human Interface Device) |
05h | Interface | Physical |
06h | Interface | Image |
07h | Interface | Printer |
08h | Interface | Mass Storage |
09h | Device | Hub |
0Ah | Interface | CDC-Data |
0Bh | Interface | Smart Card |
0Dh | Interface | Content Security |
0Eh | Interface | Video |
0Fh | Interface | Personal Healthcare |
10h | Interface | Audio/Video Devices |
11h | Device | Billboard Device Class |
12h | Interface | USB Type-C Bridge Class |
DCh | Both | Diagnostic Device |
E0h | Interface | Wireless Controller |
EFh | Both | Miscellaneous |
FEh | Interface | Application Specific |
FFh | Both | Vendor Specific |
uint8_t bLength; // Length of this descriptor.
uint8_t bDescriptorType; // DEVICE descriptor type (USB_DESCRIPTOR_DEVICE). 0x01
uint16_t bcdUSB; // USB Spec Release Number (BCD).
uint8_t bDeviceClass; // Class code (assigned by the USB-IF). 0xFF-Vendor specific.
uint8_t bDeviceSubClass; // Subclass code (assigned by the USB-IF).
uint8_t bDeviceProtocol; // Protocol code (assigned by the USB-IF). 0xFF-Vendor specific.
uint8_t bMaxPacketSize0; // Maximum packet size for endpoint 0.
uint16_t idVendor; // Vendor ID (assigned by the USB-IF).
uint16_t idProduct; // Product ID (assigned by the manufacturer).
uint16_t bcdDevice; // Device release number (BCD).
uint8_t iManufacturer; // Index of String Descriptor describing the manufacturer.
uint8_t iProduct; // Index of String Descriptor describing the product.
uint8_t iSerialNumber; // Index of String Descriptor with the device's serial number.
uint8_t bNumConfigurations;// Number of possible configurations.
USB 2.0 Spec 9.6.5
Speed | Value |
---|---|
Low Speed | 8 |
Full Speed | 8/16/32/64 |
High Speed | 64 |
https://wiki.onakasuita.org/pukiwiki/?bMaxPacketSize0
The bcdDevice value indicates the device-defined revision number. The USB driver stack uses bcdDevice, along with idVendor and idProduct, to generate hardware and compatible IDs for the device. You can view the those identifiers in Device Manager.
https://docs.microsoft.com/en-us/windows-hardware/drivers/usbcon/standard-usb-descriptors
When the device is originally enumerated by the USB stack, the USBHUB driver extracts idVendor, idProduct, and bcdDevice from the device descriptor. These three fields are incorporated to generate a USB hardware ID. Note that the vendor, device, and revision numbers are always stored in hexadecimal format.
https://docs.microsoft.com/en-us/windows-hardware/drivers/hid/plug-and-play-support
Should be incremented for Windows when descriptors are updated?
When the host requests the configuration descriptor, all related interface and endpoint descriptors are returned (refer to Section 9.4.3).
An endpoint is not shared among interfaces within a single configuration unless the endpoint is used by alternate settings of the same interface. Endpoints may be shared among interfaces that are part of different configurations without this restriction.
uint8_t bLength; // Length of this descriptor.
uint8_t bDescriptorType; // CONFIGURATION descriptor type 0x02
uint16_t wTotalLength; // Total length of all descriptors for this configuration.
uint8_t bNumInterfaces; // Number of interfaces in this configuration.
uint8_t bConfigurationValue; // Value of this configuration (1 based).
uint8_t iConfiguration; // Index of String Descriptor describing the configuration.
uint8_t bmAttributes; // Configuration characteristics.
uint8_t bMaxPower; // Maximum power consumed by this configuration.
USB 2.0 Spec 9.6.3
bit7: always 1
bit6: Self powered
bit5: Remote wakeup
bit4..0: reserved. 0
An interface descriptor is always returned as part of a configuration descriptor. Interface descriptors cannot be directly accessed with a GetDescriptor() or SetDescriptor() request.
uint8_t bLength; // Size of this descriptor in bytes
uint8_t bDescriptorType; // INTERFACE Descriptor Type 0x04
uint8_t bInterfaceNumber; // Index of the interface in the current configuration
uint8_t bAlternateSetting; // Value used to select this alternate setting for the interface
uint8_t bNumEndpoints; // Number of endpoints used by this interface(excluding endpoint zero)
uint8_t bInterfaceClass; // Interface class code
uint8_t bInterfaceSubClass; // Interface subclass code
uint8_t bInterfaceProtocol; // Interface protocol code
uint8_t iInterface; // Index of the string descriptor describing the interface
USB 2.0 Spec 9.6.5
https://usb.org/sites/default/files/Mass_Storage_Specification_Overview_v1.4_2-19-2010.pdf
https://www.usb.org/sites/default/files/hid1_11.pdf
The bDeviceClass and bDeviceSubClass fields in the Device Descriptor should not be used to identify a device as belonging to the HID class. Instead use the bInterfaceClass and bInterfaceSubClass fields in the Interface descriptor.(5.1)
A HID class device communicates with the HID class driver using either the Control (default) pipe or an Interrupt pipe. Bulk and Isochronous pipes are not used by HID class devices.(4.4)
Subclass Code | Description |
---|---|
0 | No Subclass |
1 | Boot Interface Subclass |
2 - 255 | Reserved |
HID Spec 4.2
Protocol Code | Description |
---|---|
0 | None |
1 | Keyboard |
2 | Mouse |
3 - 255 | Reserved |
HID Spec 4.3
This descriptor contains the information required by the host to determine the bandwidth requirements of each endpoint. An endpoint descriptor is always returned as part of the configuration information returned by a GetDescriptor(Configuration) request.
uint8_t bLength; // Length of this descriptor.
uint8_t bDescriptorType; // ENDPOINT descriptor type 0x05
uint8_t bEndpointAddress; // Endpoint address. Bit 7 indicates direction (0=OUT, 1=IN).
uint8_t bmAttributes; // Endpoint transfer type.
uint16_t wMaxPacketSize; // Maximum packet size.
uint8_t bInterval; // Interval for polling endpoint
Open
The address of the endpoint on the USB device described by this descriptor. The address is encoded as follows:
Bit 3...0: The endpoint number
Bit 6...4: Reserved, reset to zero
Bit 7: Direction, ignored forcontrol endpoints
0 = OUT endpoint
1 = IN endpoint
This field describes the endpoint’s attributes when it isconfigured using the bConfigurationValue.
Bits 1..0: Transfer Type
00 = Control
01 = Isochronous
10 = Bulk
11 = Interrupt
If not an isochronous endpoint, bits 5..2 are reserved and must be set to zero. If isochronous, they are defined as follows:
Bits 3..2: Synchronization Type
00 = No Synchronization
01 = Asynchronous
10 = Adaptive
11 = Synchronous
Bits 5..4: Usage Type
00 = Data endpoint
01 = Feedback endpoint
10 = Implicit feedback Data endpoint
11 = Reserved
For all endpoints, bits 10..0 specify the maximumpacket size (in bytes).
For high-speed isochronous and interrupt endpoints:
Bits 12..11 specify the number of additional transaction opportunities per microframe:
00 = None (1 transaction per microframe)
01 = 1 additional (2 per microframe)
10 = 2 additional (3 per microframe)
11 = Reserved
Bits 15..13 are reserved and must be set to zero.
For full-/low-speed interrupt endpoints, the value of this field may be from 1 to 255.
For full-/high-speed isochronous endpoints and high-speed interrupt endpoints, this value must be from 1 to 16 and is used as the exponent for a 2**(bInterval - 1). e.g., a bInterval of 4 means a period of 8 [2**(4-1)].
For high-speed bulk/control OUT endpoints, the bInterval must specify the maximum NAK rate of the endpoint. A value of 0 indicates the endpoint never NAKs. Other values indicate at most 1 NAK each bInterval number of microframes. This value must be in the range from 0 to 255.
https://www.usb.org/sites/default/files/hid1_11.pdf
uint8_t bLength;
uint8_t bDescriptorType; // HID descriptor type 0x21
uint16_t bcdHID; // Major(8), Minor(4), Revision(4)
uint8_t bCountryCode;
uint8_t bNumDescriptors; // Total number of HID report descriptors for the interface.
uint8_t bDescriptorType2[0]; // Type of HID class descriptor
uint16_t wDescriptorLength[0]; // Length of HID class descriptor
: :
uint8_t bDescriptorType2[n]; // There can be multiple HID class descriptors
uint16_t wDescriptorLength[n];
HID Spec 6.2.1
Open
Value | HID Class Descriptor Types |
---|---|
0x21 | HID |
0x22 | Report |
0x23 | Physical descriptor |
0x24-0x2F | Reserved |
HID Spec 7.1
Code (decimal) | Country |
---|---|
00 | Not Supported |
01 | Arabic |
02 | Belgian |
03 | Canadian-Bilingual |
04 | Canadian-French |
05 | Czech Republic |
06 | Danish |
07 | Finnish |
08 | French |
09 | German |
10 | Greek |
11 | Hebrew |
12 | Hungary |
13 | International (ISO) |
14 | Italian |
15 | Japan (Katakana) |
16 | Korean |
17 | Latin American |
18 | Netherlands/Dutch |
19 | Norwegian |
20 | Persian (Farsi) |
21 | Poland |
22 | Portuguese |
23 | Russia |
24 | Slovakia |
25 | Spanish |
26 | Swedish |
27 | Swiss/French |
28 | Swiss/German |
29 | Switzerland |
30 | Taiwan |
31 | Turkish-Q |
32 | UK |
33 | US |
34 | Yugoslavia |
35 | Turkish-F |
36-255 | Reserved |
https://github.com/tmk/tmk_keyboard/wiki/USB:-HID-Report-Descriptor
Index:0
uint8_t bLength // Size of this descriptor in bytes
uint8_t bDescriptorType // Constant STRING Descriptor Type 0x03
uint16_t wLANGID[0] // Number LANGID code
: :
uint16_t wLANGID[n] // Number LANGID code
Index:1-
uint8_t bLength // Size of this descriptor in bytes
uint8_t bDescriptorType // Constant STRING Descriptor Type 0x03
uint16_t bString[x] // UNICODE encoded string x = (bLength - 2) / 2
Identifire | Language |
---|---|
0x0409 | English (United States) |
0x0411 | Japanese |
The device_qualifier descriptor describes information about a high-speed capable device that would change if the device were operating at the other speed.
uint8_t bLength // Number Size of descriptor
uint8_t bDescriptorType // Constant Device Qualifier Type
uint16_t bcdUSB // BCD USB specification version number
uint8_t bDeviceClass // Class Class Code
uint8_t bDeviceSubClass // SubClass SubClass Code
uint8_t bDeviceProtocol // Protocol Protocol Code
uint8_t bMaxPacketSize0 // Number Maximum packet size for other speed
uint8_t bNumConfigurations // Number Number of Other-speed Configurations
uint8_t bReserved // Zero Reserved for future use, must be zero
USB 2.0 Spec 9.6.2
The other_speed_configuration descriptor describes a configuration of a high-speed capable device if it were operating at its other possible speed. The structure of the other_speed_configuration is identical to a configuration descriptor. The host accesses this descriptor using the GetDescriptor() request. The descriptor type in the GetDescriptor() request is set to ther_speed_configuration.
uint8_t bLength; // Length of this descriptor.
uint8_t bDescriptorType; // Other_speed_Configuration descriptor type 0x07
uint16_t wTotalLength; // Total length of data returned
uint8_t bNumInterfaces; // Number of interfaces supported by this speedconfiguration
uint8_t bConfigurationValue; // Value to use to select configuration
uint8_t iConfiguration; // Index of String Descriptor
uint8_t bmAttributes; // Configuration characteristics.
uint8_t bMaxPower; // Maximum power consumed by this configuration.
USB 2.0 Spec 9.6.4
If you have TMK USB-USB converter try this first. It displays USB descriptors including HID Report descriptor in HEX format. https://github.com/tmk/tmk_keyboard/tree/master/converter/usb_desc_dump
Open
- Download prebuilt firmware of USB Descriptor Dumper.
- Flash it onto USB-USB converter.
- Use hid_listen to see USB Descriptor data.
You will see outputs like below in hid_listen.
//////////////////////////////////////////////////////////////////////
// USB_desc_dump
// Address: 01
// Lowspeed: 01
// Devicer dump:
12 01 00 02 00 00 00 08 6A 04 11 00 00 01 00 00
00 01
// Device:
bLength: 12
bDescriptorType: 01
bcdUSB: 0200
bDeviceClass: 00
bDeviceSubClass: 00
bDeviceProtocol: 00
bMaxPacketSize0: 08
idVendor: 046A
idProduct: 0011
bcdDevice: 0100
iManufacturer: 00
iProduct: 00
iSerialNumber: 00
bNumConfigurations: 01
...
USB Descriptor Dumper doesn't parse Report Descriptor, just dump its data in HEX format. To look into contents of Report descriptor closely you can use tools below.
Open
Paste Report Descriptor HEX dump data into Input text box and press parse button.
https://eleccelerator.com/usbdescreqparser/
Give HEX dump data to the parser like below.
$ cat <HEX_dump_data> | xxd -r -p | hidrd-convert -o spec
https://wiki.wireshark.org/CaptureSetup/USB
This works on Linux, MacOS and Windows. You need to check GET_DESCRIPTOR
responses from captured data.
You can use lsusb -v
to get descriptor on Linux. To designate your device give vendor and product ID to -d
option.
lsusb -v -d feed:cafe
Open
You will see output like below.
Bus 001 Device 035: ID feed:caaa
Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 1.10
bDeviceClass 0 (Defined at Interface level)
bDeviceSubClass 0
bDeviceProtocol 0
bMaxPacketSize0 8
idVendor 0xfeed
idProduct 0xcaaa
bcdDevice 1.04
iManufacturer 1 t.m.k.
iProduct 2 HHKB mod
iSerial 0
bNumConfigurations 1
Configuration Descriptor:
bLength 9
bDescriptorType 2
wTotalLength 109
bNumInterfaces 4
bConfigurationValue 1
iConfiguration 0
bmAttributes 0xa0
(Bus Powered)
Remote Wakeup
MaxPower 100mA
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 0
bAlternateSetting 0
bNumEndpoints 1
bInterfaceClass 3 Human Interface Device
bInterfaceSubClass 1 Boot Interface Subclass
bInterfaceProtocol 1 Keyboard
...
Also check this to get HID Report Descriptor.
https://github.com/tmk/tmk_keyboard/wiki/USB:-HID-Report-Descriptor#lsusb-on-linux
Use USB Tree Viewer on Windows.
Open
You may have to run it as administrator to get HID Report descriptor.
Just select your USB device in tree view, the tool shows USB descriptor in right pane.
USB Tree Viewer shows Report Descriptor successfully with some devices but error like below with other devices. This seems to depend on device implementation.
Error reading descriptor : ERROR_INVALID_PARAMETER (due to a obscure limitation of the Win32 USB API, see UsbTreeView.txt)
Tools below may be useful on Windows. Not confirmed.
- https://www.thesycon.de/eng/usb_descriptordumper.shtml (doesn't dump Report Descriptor)
- win-hid-dump
- USBlyzer (Fully functional 33-day trial)
- https://www.eltima.com/products/usb-port-monitor/ (14-day free tiral)
Good method to get USB descriptor on MacOS is not known yet.
These commands may give useuful info, perhaps?
system_profiler SPUSBDataType
ioreg -p IOUSB -w0 -l
Both commands don't seem to give useful informaions so much unfortuantely. Use Windows or Linux for the purpose if possible.
https://gist.github.com/tmk/e9d5b0b514e9d0c353344d7d4424e653
https://gist.github.com/tmk/62ba55c7a26078552084bccbaf70a19d
https://gist.github.com/tmk/267254db25f0039f2e51aa7918666164
https://gist.github.com/tmk/5f22878a7ddca01e9174e5d6224395d2
https://gist.github.com/tmk/5e29450724fc30d06681212b0e9b5056
https://gist.github.com/tmk/7d41f0ca49a21a6c0b2f910d43e9660d
https://gist.github.com/tmk/40a0cc79072a0e5afcd36a599de42bbd
https://gist.github.com/tmk/0626b78f73575d5c1efa86470c4cdb18
https://github.com/tmk/tmk_keyboard/issues/606
https://gist.github.com/tmk/5f2c2fb14fcef03689a21a66f2607ccc
https://gist.github.com/tmk/61232069866950aee280623f4901ff84
https://pastebin.com/fTWMypTS https://geekhack.org/index.php?topic=69169.msg2893824#msg2893824
https://geekhack.org/index.php?topic=69169.msg2897536#msg2897536 https://gist.github.com/tmk/8ee0644a352d8eea3e0f0d584867ddaf
https://gist.github.com/tmk/54342906216b07097582965fa653324f
These two adapters are identical electrically.
- Arvel AU02-PS
- PS2USB2BK
https://gist.github.com/tmk/78dd3ff4507025bcd8b3d574095fe93f
CDC interface: https://gist.github.com/tmk/c2cd88429e08e6b9f8e381c04be80d3b
Bootloader CDC interface: https://gist.github.com/tmk/57898ca51b6f61df9bdb8c2908a3de53
UF2 Bootloader: https://gist.github.com/tmk/ab44c726b06bda1fcdb617b9144161c0
Arduino Sketch: https://gist.github.com/tmk/e7d294052ac864b47c3f0cf1962b24c8
https://gist.github.com/tmk/3e7af2b10b162b9eea853871918a0a2d
https://geekhack.org/index.php?topic=110250.0
https://gist.github.com/tmk/9725596c6726b561ad2bf1f1e07e1523
https://gist.github.com/tmk/2a4026e322a561687485c2537ad4421b
https://gist.github.com/tmk/7c089602ce7eb70b9be64c7e822be3b9
https://gist.github.com/tmk/8e8e6185af93e4e3ccd2660684f9cf7c
https://forum.pjrc.com/threads/52752-USBHost-for-Griffin-Powermate?p=181527&viewfull=1#post181527
This keyboad doesn't have Boot Keyboard support.
Interface0
wMaxPacketSize=8
bInterval=1
6KRO keyboard(not-boot)
Interface1
wMaxPacketSize=4
bInterval=1
Interface2
wMaxPacketSize=64
bInterval=1
**62KRO** keyboard(not-boot)
Interface3
wMaxPacketSize=4
bInterval=1
Consumer keys
https://gist.github.com/tmk/6c9b88c117725446dd768a4270847019
Followings were extracted by USB Device Tree Viewer. No HID Report Descriptor. 1.0.9: https://gist.github.com/tmk/79068a4fcc922e8877691d5518513914
1.0.8?: https://gist.github.com/tmk/2f3a680cfe4cba78b678611032ac20e4
https://gist.github.com/tmk/2407fdaa73deb35082154c3ba81c84ef
https://gist.github.com/tmk/344c185fd2834d2142ae50dccb0916f8
https://gist.github.com/tmk/2541aa5966fdaa3640f141e3a9d2f4bc
https://gist.github.com/tmk/5a8dcd84801a33f286c6677f1fa7e914
https://gist.github.com/tmk/f6ad630003a3052500384188c536a439
Keyboard report is compatible to Boot protocol except for the last byte. The last byte is used for Apple vendor specific use, probably related to 'Fn' key.
https://gist.github.com/tmk/34ba298598aa376346ded28144f99a9c
https://gist.github.com/tmk/db28c9b5cb417780fd24077a729c7f2a
Hub in Aluminum Keyboard: https://gist.github.com/tmk/88dd53305e788937fc78fecc7870c470
https://gist.github.com/tmk/787a00f23874d7d1e2bf3a64618eb8c6
https://gist.github.com/tmk/904775279178c073f25bb49d718dce6c
https://gist.github.com/tmk/774225e2d9e2685df3c6a442893550c1
https://gist.github.com/tmk/54658fb8a2dbab4a3c2550023d2fc24a
https://gist.github.com/tmk/5dd869c19f216ee833c47569c7b4f3f6
Vendor specific: https://gist.github.com/tmk/865cc8e9caac6c817b2b032d271c3865
Vendor specific: https://gist.github.com/tmk/a51be69e460f26b7613c4d1df36d2e9e
Vendor specific: https://gist.github.com/tmk/75342dbc1fb6d7872b11611017efa6e1
CDC interface association: https://gist.github.com/tmk/aaa071e9baf9797c12f3f4bba620841b
CDC interface association: https://gist.github.com/tmk/2e7a3a250940b3ce4797f7cd04c057e3
https://gist.github.com/tmk/51fa7f70e9131c7bca541d13957b438c
https://gist.github.com/tmk/d8a3bfa0e886164c2d75a772c3ef07ae
https://gist.github.com/tmk/a247a9ca9638aa8738a99f049cf69308
This has two boot keyboard intefaces.
https://gist.github.com/tmk/85d504087e73db7acae6611cb007363b
https://gist.github.com/tmk/0ef11df08b783488f03fd4572d1c3bc3
https://gist.github.com/tmk/472e52c9502302be173790c5e5fa0829
https://gist.github.com/tmk/fb0d3f35271596b4771495a837205859
https://gist.github.com/tmk/e80cf735e55c86c68536decf8931c3b3
https://deskthority.net/viewtopic.php?p=110621&sid=9b33a6d18da5f727dc11a615fdc207fe#p110621
https://gist.github.com/tmk/415e64e71d8c6df7eea8e15c92539064
https://gist.github.com/tmk/23bb1bfaf892e942fd4970e7e5586865
https://geekhack.org/index.php?topic=69169.msg3122987#msg3122987
- 3 boot keyboard interfaces
https://gist.github.com/tmk/68d50a2c3d3e3803d5df294bff79a4ab
Cypress controller v7.53 https://sharktastica.co.uk/wiki?id=unicompminim#Controller
https://geekhack.org/index.php?topic=69169.msg3181557#msg3181557
It seems interface 0/1 is boot keyboard/mouse compatible but it does not assert 'Boot Interface' in bInterfaceSubClass.
https://gist.github.com/tmk/c3bfa6df5c19de2e01447489e80a600d
https://geekhack.org/index.php?topic=69169.msg3194615#msg3194615
https://github.com/tmk/tmk_keyboard/issues/778
wireless dongle?
https://gist.github.com/tmk/20e2a574dc45ce7789b93e15e9ca9eb6