Skip to content

USB: HID Report Descriptor

hasu@tmk edited this page May 5, 2022 · 40 revisions

Specification

https://www.usb.org/hid

Device Class Definition HID

HID Usage Tables

https://github.com/tmk/tmk_keyboard/wiki/USB:-HID-Usage-Table

Report Descriptor Parser

Online Parser

http://eleccelerator.com/usbdescreqparser/

hid-tools - hid-decode

https://gitlab.freedesktop.org/libevdev/hid-tools

hidrd-convert

https://github.com/DIGImend/hidrd

usbutils - lsusb

https://github.com/gregkh/usbutils/blob/1f1d41338d40a16096e0f321e7330031d9c8efc6/lsusb.c#L2271 https://github.com/gregkh/usbutils/blob/1a3f8b662e3cce40768d45be3dd2c9fb93808065/usb-spec.h

USB Host Shiled 2.0 - ReportDescParser

https://github.com/felis/USB_Host_Shield_2.0/blob/master/hidescriptorparser.cpp#L993

How to get Report Descriptor

USB Descriptor Dumper

If you have TMK USB-USB converter you can use this to dump Report descriptor. See https://github.com/tmk/tmk_keyboard/wiki/USB:-Descriptor#usb-descriptor-dumper

lshid

report_desc_parse.sh

You can use this script on Linux and it requires hidrd-convert and od command.

https://gist.github.com/tmk/e7eea510e41b51305c8a8bcb650059c2

Example
$ ~/bin/report_desc_parse.sh -h

Usage: report_desc_parse.sh  [options] [vendor:[product]]

Options:
    vendor:[product]
        USB vendor/product ID in hexadecimal
        (or any string to match with file path)
    -x
        dump in hexadecimal
    -p
        parse using 'hidrd-convert'
    -l
        list file path only
    -h
        display this help message

$ ~/bin/report_desc_parse.sh -p                                                
// /sys/bus/usb/drivers/usbhid/3-2.3.4:1.0/0003:FEED:CAFE.0821/report_descriptor:                                                                             
Usage Page (Desktop),               ; Generic desktop controls (01h)                                                                                          
Usage (Keyboard),                   ; Keyboard (06h, application collection)                                                                                  
Collection (Application),                                                      
    Usage Page (Keyboard),          ; Keyboard/keypad (07h)                    
    Usage Minimum (KB Leftcontrol), ; Keyboard left control (E0h, dynamic value)                                                                              
    Usage Maximum (KB Right GUI),   ; Keyboard right GUI (E7h, dynamic value)  
    Logical Minimum (0),                                                       
    Logical Maximum (1),                                                       
    Report Count (8),                                                          
    Report Size (1),                                                                                                                                          
    Input (Variable),              
    Usage Page (LED),               ; LEDs (08h)                                                                                                              
    Usage Minimum (01h),                          
...

hid-tools

hid-tools is a set of tools to interact with the kernel's HID subsystem. This is used on Linux to get HID Report descriptor. It can dump HID data also.

https://gitlab.freedesktop.org/libevdev/hid-tools

Example
$ sudo hid-recorder
Available devices:
/dev/hidraw0:   EIZO EIZO USB HID Monitor
/dev/hidraw1:   Logitech MX518 Gaming Mouse
/dev/hidraw2:   Logitech MX518 Gaming Mouse
/dev/hidraw3:   TMK HHKB Alt Controller
/dev/hidraw4:   TMK HHKB Alt Controller
/dev/hidraw5:   t.m.k. USB to USB keyboard converter
/dev/hidraw6:   t.m.k. USB to USB keyboard converter
Select the device event number [0-6]: 0                                                                                                                       
# EIZO EIZO USB HID Monitor                                                                                                                                   
# 0x05, 0x80,                    // Usage Page (Monitor)                0                                                                                     
# 0x09, 0x01,                    // Usage (Monitor Control)             2                                                                                     
# 0xa1, 0x01,                    // Collection (Application)            4                                                                                     
# 0x06, 0x30, 0xff,              //  Usage Page (Vendor Usage Page 0xff30) 6                                                                                  
# 0x85, 0x01,                    //  Report ID (1)                      9    
...
$ find  /sys/devices -name "report_descriptor"
/sys/devices/pci0000:00/0000:00:08.1/0000:38:00.3/usb3/3-4/3-4:1.0/0003:FEED:005B.085F/report_descriptor
/sys/devices/pci0000:00/0000:00:08.1/0000:38:00.3/usb3/3-2/3-2.3/3-2.3.4/3-2.3.4:1.1/0003:FEED:CAFE.0822/report_descriptor
/sys/devices/pci0000:00/0000:00:08.1/0000:38:00.3/usb3/3-2/3-2.3/3-2.3.4/3-2.3.4:1.0/0003:FEED:CAFE.0821/report_descriptor
/sys/devices/pci0000:00/0000:00:08.1/0000:38:00.3/usb3/3-2/3-2.4/3-2.4:1.1/0003:046D:C08E.0838/report_descriptor
/sys/devices/pci0000:00/0000:00:08.1/0000:38:00.3/usb3/3-2/3-2.4/3-2.4:1.0/0003:046D:C08E.0837/report_descriptor
/sys/devices/pci0000:00/0000:00:08.1/0000:38:00.3/usb3/3-3/3-3.3/3-3.3:1.0/0003:056D:4026.0857/report_descriptor

$ hid-decode /sys/devices/pci0000:00/0000:00:08.1/0000:38:00.3/usb3/3-3/3-3.3/3-3.3:1.0/0003:056D:4026.0857/report_descriptor
# device 0:0                                                                   
# 0x05, 0x80,                    // Usage Page (Monitor)                0  
# 0x09, 0x01,                    // Usage (Monitor Control)             2  
# 0xa1, 0x01,                    // Collection (Application)            4  
# 0x06, 0x30, 0xff,              //  Usage Page (Vendor Usage Page 0xff30) 6
# 0x85, 0x01,                    //  Report ID (1)                      9  
# 0x75, 0x08,                    //  Report Size (8)                    11 
# 0x96, 0x04, 0x02,              //  Report Count (516)                 13 
# 0x15, 0x00,                    //  Logical Minimum (0)                16 
...

hidrd-convert

Hidrd is a library and a tool for reading, writing and converting HID report descriptors in/between various formats.

https://github.com/DIGImend/hidrd

Example

Search report_descriptor files under sysfs.

$ find  /sys/devices -name "report_descriptor"
/sys/devices/pci0000:00/0000:00:08.1/0000:38:00.3/usb3/3-4/3-4:1.0/0003:FEED:005B.085F/report_descriptor
/sys/devices/pci0000:00/0000:00:08.1/0000:38:00.3/usb3/3-2/3-2.3/3-2.3.4/3-2.3.4:1.1/0003:FEED:CAFE.0822/report_descriptor
/sys/devices/pci0000:00/0000:00:08.1/0000:38:00.3/usb3/3-2/3-2.3/3-2.3.4/3-2.3.4:1.0/0003:FEED:CAFE.0821/report_descriptor
/sys/devices/pci0000:00/0000:00:08.1/0000:38:00.3/usb3/3-2/3-2.4/3-2.4:1.1/0003:046D:C08E.0860/report_descriptor
/sys/devices/pci0000:00/0000:00:08.1/0000:38:00.3/usb3/3-2/3-2.4/3-2.4:1.0/0003:046D:C08E.0861/report_descriptor
/sys/devices/pci0000:00/0000:00:08.1/0000:38:00.3/usb3/3-3/3-3.3/3-3.3:1.0/0003:056D:4026.0857/report_descriptor

And parse it.

$ cat /sys/devices/pci0000:00/0000:00:08.1/0000:38:00.3/usb3/3-3/3-3.3/3-3.3:1.0/0003:056D:4026.0857/report_descriptor | hidrd-convert -inatv -ospec          
Usage Page (Monitor),           ; USB monitor (80h, monitor page)                                                                                             
Usage (01h),                                                                                                                                                  
Collection (Application),                                                                                                                                     
    Usage Page (FF30h),         ; FF30h, vendor-defined                                                                                                       
    Report ID (1),                                                                                                                                            
    Report Size (8),                                                                                                                                          
    Report Count (516),                                                                                                                                       
    Logical Minimum (0),                                                                                                                                      
    Logical Maximum (255),                                                                                                                                    
    Usage (01h),      
    ...

lsusb

You can use this lsusb method on Linux.

Example

Get vendor and product ID(VID:PID) of device you are interested. Let's say 046d:c08e of Logitech mouse here.

$ lsusb
...
Bus 004 Device 012: ID 045b:0210 Hitachi, Ltd 
Bus 004 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 003 Device 100: ID feed:005b TMK USB Descriptor Dumper
Bus 003 Device 091: ID 056d:4026 EIZO Corp. EIZO USB HID Monitor
Bus 003 Device 090: ID 045b:0209 Hitachi, Ltd 
Bus 003 Device 082: ID 046d:c08e Logitech, Inc. MX518 Gaming Mouse
Bus 003 Device 055: ID feed:cafe TMK HHKB Alt Controller
...
Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

Find file path of the device by its VID and PID(046d:c08e). Device can have multiple paths.

$ find  /sys/devices -name "report_descriptor"
/sys/devices/pci0000:00/0000:00:08.1/0000:38:00.3/usb3/3-4/3-4:1.0/0003:FEED:005B.0862/report_descriptor
/sys/devices/pci0000:00/0000:00:08.1/0000:38:00.3/usb3/3-2/3-2.3/3-2.3.4/3-2.3.4:1.1/0003:FEED:CAFE.0822/report_descriptor
/sys/devices/pci0000:00/0000:00:08.1/0000:38:00.3/usb3/3-2/3-2.3/3-2.3.4/3-2.3.4:1.0/0003:FEED:CAFE.0821/report_descriptor
/sys/devices/pci0000:00/0000:00:08.1/0000:38:00.3/usb3/3-2/3-2.4/3-2.4:1.1/0003:046D:C08E.0860/report_descriptor
/sys/devices/pci0000:00/0000:00:08.1/0000:38:00.3/usb3/3-2/3-2.4/3-2.4:1.0/0003:046D:C08E.0861/report_descriptor
/sys/devices/pci0000:00/0000:00:08.1/0000:38:00.3/usb3/3-3/3-3.3/3-3.3:1.0/0003:056D:4026.0857/report_descriptor

Unbind the device from HID driver. Note that the device stops working until you bind it later.

$ echo -n 3-2.4:1.0 | sudo tee /sys/bus/usb/drivers/usbhid/unbind
$ echo -n 3-2.4:1.1 | sudo tee /sys/bus/usb/drivers/usbhid/unbind

Dump report descriptor with lsusb -v.

$ sudo lsusb -v -d 046d:c08e

Bus 003 Device 082: ID 046d:c08e Logitech, Inc. USB Descriptor Dumper
Device Descriptor:
  bLength                18
  bDescriptorType         1
  bcdUSB               2.00
  bDeviceClass            0
  bDeviceSubClass         0
  bDeviceProtocol         0
  bMaxPacketSize0        64
  idVendor           0x046d Logitech, Inc.
  idProduct          0xc08e
  bcdDevice           40.00
  iManufacturer           1 Logitech
  iProduct                2 MX518 Gaming Mouse
  iSerial                 3 0689386F3831
  bNumConfigurations      1
  Configuration Descriptor:
  ...

Bind the deivce and it starts working again.

$ echo -n 3-2.4:1.0 | sudo tee /sys/bus/usb/drivers/usbhid/bind
$ echo -n 3-2.4:1.1 | sudo tee /sys/bus/usb/drivers/usbhid/bind

See this also. http://www.slashdev.ca/2010/05/08/get-usb-report-descriptor-with-linux/

usbhid-dump

usbhid-dump can dump descriptor and report data.

https://github.com/DIGImend/usbhid-dump

Example

Dump Report Descriptor.

$ sudo usbhid-dump -d046d:c08e -ed
001:005:000:DESCRIPTOR         1468982571.405056
 05 01 09 02 A1 01 09 01 A1 00 05 09 19 01 29 08
 15 00 25 01 95 08 75 01 81 02 95 00 81 03 06 00
 FF 09 40 95 02 75 08 15 81 25 7F 81 02 05 01 09
 38 15 81 25 7F 75 08 95 01 81 06 09 30 09 31 16
 01 F8 26 FF 07 75 0C 95 02 81 06 C0 C0          

Dump Report data.

$ sudo usbhid-dump -d046d:c08e -es
Starting dumping interrupt transfer stream      
with 1 minute timeout.  

003:082:000:STREAM             1633500214.472733
 00 00 01 00 00 00 00 00

003:082:000:STREAM             1633500214.476710
 00 00 01 00 00 00 00 00

003:082:000:STREAM             1633500214.478692
 00 00 01 00 00 00 00 00
...

How to build hid-dump:

$ git clone https://github.com/DIGImend/hidrd.git
$ git clone https://github.com/DIGImend/usbhid-dump.git
$ cd hidrd # or usbhid-dump
$ autoreconf --force --install
$ ./configure
$ make
Clone this wiki locally