cyme
cyme copied to clipboard
HID Device Descriptor support
I don't need this right now, but it's something missing on Linux (and I think there's an opportunity to show more info than lsusb, even with root).
lsusb
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
iInterface 5 Boot Keyboard
HID Device Descriptor:
bLength 9
bDescriptorType 33
bcdHID 1.11
bCountryCode 0 Not supported
bNumDescriptors 1
bDescriptorType 34 Report
wDescriptorLength 68
Report Descriptors:
** UNAVAILABLE **
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x81 EP 1 IN
bmAttributes 3
Transfer Type Interrupt
Synch Type None
Usage Type Data
wMaxPacketSize 0x0008 1x 8 bytes
bInterval 1
susb lsusb (to show that UNAVAILABLE doesn't change)
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
iInterface 5
HID Device Descriptor:
bLength 9
bDescriptorType 33
bcdHID 1.11
bCountryCode 0 Not supported
bNumDescriptors 1
bDescriptorType 34 Report
wDescriptorLength 68
Report Descriptors:
** UNAVAILABLE **
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x81 EP 1 IN
bmAttributes 3
Transfer Type Interrupt
Synch Type None
Usage Type Data
wMaxPacketSize 0x0008 1x 8 bytes
bInterval 1
cyme --lsusb
Interface Descriptor:
bInterfaceNumber 0
bAlternateSetting 0
bNumEndpoints 1
bInterfaceClass 3 HID
bInterfaceSubClass 1
bInterfaceProtocol 1
iInterface 5 Boot Keyboard
Endpoint Descriptor:
bEndpointAddress 0x81 EP 1 IN
bmAttributes:
Transfer Type Interrupt
Sync Type None
Usage Type Data
wMaxPacketSize 0x0008 1x 8 bytes
bInterval 1
The main issue is that cyme doesn't attempt to look at the HID Device Descriptor.
On Linux there (usually) is a cached sysfs copy of the report_descriptor
if there is an associated driver with the device (hid generic, hid raw, etc.).
ls /sys/bus/usb/devices/5-4.3:*/*/report_descriptor
5-4.3:1.0/0003:308F:0013.004E/report_descriptor 5-4.3:1.3/0003:308F:0013.0051/report_descriptor
5-4.3:1.1/0003:308F:0013.004F/report_descriptor 5-4.3:1.4/0003:308F:0013.0052/report_descriptor
5-4.3:1.2/0003:308F:0013.0050/report_descriptor
(these descriptors can be read using hid-decode
).
# device 4:0
# 0x06, 0x1c, 0xff, // Usage Page (Vendor Usage Page 0xff1c) 0
# 0x0a, 0x00, 0x11, // Usage (Vendor Usage 0x1100) 3
# 0xa1, 0x01, // Collection (Application) 6
# 0x75, 0x08, // Report Size (8) 8
# 0x15, 0x00, // Logical Minimum (0) 10
# 0x26, 0xff, 0x00, // Logical Maximum (255) 12
# 0x95, 0x40, // Report Count (64) 15
# 0x09, 0x01, // Usage (Vendor Usage 0x01) 17
# 0x91, 0x02, // Output (Data,Var,Abs) 19
# 0x95, 0x40, // Report Count (64) 21
# 0x09, 0x02, // Usage (Vendor Usage 0x02) 23
# 0x81, 0x02, // Input (Data,Var,Abs) 25
# 0xc0, // End Collection 27
#
R: 28 06 1c ff 0a 00 11 a1 01 75 08 15 00 26 ff 00 95 40 09 01 91 02 95 40 09 02 81 02 c0
N: device 4:0
I: 3 0001 0001
I'll have to dig up another keyboard and I can show what it looks like when you unbind the driver (as per https://www.slashdev.ca/2010/05/08/get-usb-report-descriptor-with-linux/)
Here's a different example with a CDC descriptor (looks like it can show the whole thing in this case). Though (I have a udev rule for this device so it might have some extra permissions).
[udev_istring_support]: lsusb -d 03eb: -v
Bus 005 Device 006: ID 03eb:6124 Atmel Corp. at91sam SAMBA bootloader
Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 1.10
bDeviceClass 2 Communications
bDeviceSubClass 0 [unknown]
bDeviceProtocol 0
bMaxPacketSize0 8
idVendor 0x03eb Atmel Corp.
idProduct 0x6124 at91sam SAMBA bootloader
bcdDevice 1.10
iManufacturer 0
iProduct 0
iSerial 0
bNumConfigurations 1
Configuration Descriptor:
bLength 9
bDescriptorType 2
wTotalLength 0x0043
bNumInterfaces 2
bConfigurationValue 1
iConfiguration 0
bmAttributes 0xc0
Self Powered
MaxPower 0mA
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 0
bAlternateSetting 0
bNumEndpoints 1
bInterfaceClass 2 Communications
bInterfaceSubClass 2 Abstract (modem)
bInterfaceProtocol 0
iInterface 0
CDC Header:
bcdCDC 1.10
CDC ACM:
bmCapabilities 0x00
CDC Union:
bMasterInterface 0
bSlaveInterface 1
CDC Call Management:
bmCapabilities 0x00
bDataInterface 1
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x83 EP 3 IN
bmAttributes 3
Transfer Type Interrupt
Synch Type None
Usage Type Data
wMaxPacketSize 0x0008 1x 8 bytes
bInterval 255
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 1
bAlternateSetting 0
bNumEndpoints 2
bInterfaceClass 10 CDC Data
bInterfaceSubClass 0 [unknown]
bInterfaceProtocol 0
iInterface 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x01 EP 1 OUT
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0040 1x 64 bytes
bInterval 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x82 EP 2 IN
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0040 1x 64 bytes
bInterval 0
Device Status: 0x0000
(Bus Powered)
Yes I agree and this is something I've had on my feature list for a while after looking at the lsusb code. lsusb
will dump quite a few other descriptors including HID (audio, video etc.): https://github.com/gregkh/usbutils/blob/master/lsusb.c#L149C14-L149C14
I believe the information can be grabbed from the attributes on sysfs or udev. So the main task it porting the formatting and also adding to the current structs in a nice way. Then it can be printed with cyme
display.rs as well as this.
It should be possible with the rusb extra bytes: https://docs.rs/rusb/latest/rusb/struct.InterfaceDescriptor.html#method.extra and then processing the raw buffer depending on a class match like lsusb
: https://github.com/gregkh/usbutils/blob/master/lsusb.c#L507
Working branch for this https://github.com/tuna-f1sh/cyme/tree/dumps in case anyone is interested.
You might be interested, I've been working on and off on this. It's quite a lot of grunt work porting the descriptors and the exact formatting from lsusb
but I'm sort of getting somewhere. It's not particularly pretty or Rust like and I'll probably refactor into specific extra descriptors so they are useful as a module not just for the lsusb compatibility mode.
Most the class specific descriptors are now implemented including the CDC. I'm left to implement (but started) the Audio Class descriptors since they are much more comprehensive and even the lsusb
codebase opted to handle them in a more generic way, unlike the others.
Here's a CDC device:
Bus 002 Device 001: ID 1366:1050 SEGGER J-Link
Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 2.00
bDeviceClass 239 Miscellaneous Device
bDeviceSubClass 2 ?
bDeviceProtocol 1 Interface Association
bMaxPacketSize0 64
idVendor 0x1366 SEGGER
idProduct 0x1050
bcdDevice 1.00
iManufacturer 2 SEGGER
iProduct 1 J-Link
iSerialNumber 3 001050027328
bNumConfigurations 1
Configuration Descriptor:
bLength 9
bDescriptorType 2
wTotalLength 0x00a4
bNumInterfaces 5
bConfigurationValue 1
iConfiguration 4 Configuration
bmAttributes 0x80
(Bus Powered)
MaxPower 100mA
Interface Association:
bLength 8
bDescriptorType 11
bFirstInterface 0
bInterfaceCount 2
bFunctionClass 2 Communications
bFunctionSubClass 2 Abstract (modem)
bFunctionProtocol 0 None
iFunction 5 CDC
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 0
bAlternateSetting 0
bNumEndpoints 1
bInterfaceClass 2 Communications
bInterfaceSubClass 2 Abstract (modem)
bInterfaceProtocol 1 AT-commands (v.25ter)
iInterface 5 CDC
CDC Header:
bcdCDC 1.10
CDC Call Management:
bmCapabilities 0x03
call management
use cd.dataInterface
CDC ACM:
bmCapabilities 0x06
sends break
line coding and serial state
CDC Union:
bMasterInterface 0
bSlaveInterface 1
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x82 EP 2 IN
bmAttributes: 3
Transfer Type Interrupt
Sync Type None
Usage Type Data
wMaxPacketSize 0x0040 1x 64 bytes
bInterval 1
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 1
bAlternateSetting 0
bNumEndpoints 2
bInterfaceClass 10 CDC Data
bInterfaceSubClass 0 Unused
bInterfaceProtocol 0
iInterface 6 CDC DATA interface
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x81 EP 1 IN
bmAttributes: 2
Transfer Type Bulk
Sync Type None
Usage Type Data
wMaxPacketSize 0x0040 1x 64 bytes
bInterval 1
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x01 EP 1 OUT
bmAttributes: 2
Transfer Type Bulk
Sync Type None
Usage Type Data
wMaxPacketSize 0x0040 1x 64 bytes
bInterval 1
Interface Association:
bLength 8
bDescriptorType 11
bFirstInterface 2
bInterfaceCount 2
bFunctionClass 2 Communications
bFunctionSubClass 2 Abstract (modem)
bFunctionProtocol 0 None
iFunction 7 CDC
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 2
bAlternateSetting 0
bNumEndpoints 1
bInterfaceClass 2 Communications
bInterfaceSubClass 2 Abstract (modem)
bInterfaceProtocol 1 AT-commands (v.25ter)
iInterface 7 CDC
CDC Header:
bcdCDC 1.10
CDC Call Management:
bmCapabilities 0x03
call management
use cd.dataInterface
CDC ACM:
bmCapabilities 0x06
sends break
line coding and serial state
CDC Union:
bMasterInterface 2
bSlaveInterface 3
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x84 EP 4 IN
bmAttributes: 3
Transfer Type Interrupt
Sync Type None
Usage Type Data
wMaxPacketSize 0x0040 1x 64 bytes
bInterval 1
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 3
bAlternateSetting 0
bNumEndpoints 2
bInterfaceClass 10 CDC Data
bInterfaceSubClass 0 Unused
bInterfaceProtocol 0
iInterface 8 CDC DATA interface
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x83 EP 3 IN
bmAttributes: 2
Transfer Type Bulk
Sync Type None
Usage Type Data
wMaxPacketSize 0x0040 1x 64 bytes
bInterval 1
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x02 EP 2 OUT
bmAttributes: 2
Transfer Type Bulk
Sync Type None
Usage Type Data
wMaxPacketSize 0x0040 1x 64 bytes
bInterval 1
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 4
bAlternateSetting 0
bNumEndpoints 2
bInterfaceClass 255 Vendor Specific Class
bInterfaceSubClass 255 Vendor Specific Subclass
bInterfaceProtocol 255 Vendor Specific Protocol
iInterface 9 BULK interface
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x85 EP 5 IN
bmAttributes: 2
Transfer Type Bulk
Sync Type None
Usage Type Data
wMaxPacketSize 0x0040 1x 64 bytes
bInterval 1
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x03 EP 3 OUT
bmAttributes: 2
Transfer Type Bulk
Sync Type None
Usage Type Data
wMaxPacketSize 0x0040 1x 64 bytes
bInterval 1
And also the Video descriptors are quite interesting from my display:
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 0
bAlternateSetting 0
bNumEndpoints 0
bInterfaceClass 14 Video
bInterfaceSubClass 1 Video Control
bInterfaceProtocol 0
iInterface 28 Studio Display Camera
VideoControl Interface Descriptor:
bLength 13
bDescriptorType 4
bDescriptorSubType 1 (HEADER)
bcdUVC 1.50
wTotalLength 0x0036
dwClockFrequency 1.000000MHz
bInCollection 1
baInterfaceNr( 0) 1
VideoControl Interface Descriptor:
bLength 18
bDescriptorType 4
bDescriptorSubType 2 (INPUT_TERMINAL)
bTerminalID 1
wTerminalType 0x0201 Camera Sensor
bAssocTerminal 0
iTerminal 0 Љ
wObjectiveFocalLengthMin 0
wObjectiveFocalLengthMax 0
wOcularFocalLength 0
bControlSize 3
bmControls 0x00202a06
Auto-Exposure Mode
Auto-Exposure Priority
Zoom (Absolute)
PanTilt (Absolute)
Roll (Absolute)
VideoControl Interface Descriptor:
bLength 9
bDescriptorType 4
bDescriptorSubType 3 (OUTPUT_TERMINAL)
bTerminalID 2
wTerminalType 0x0101 USB Streaming
bAssocTerminal 0
bSourceID 3
iTerminal 0 Љ
VideoControl Interface Descriptor:
bLength 14
bDescriptorType 4
bDescriptorSubType 5 (PROCESSING_UNIT)
bUnitID 3
bSourceID 1
wMaxMultiplier 0
bControlSize 4
bmControls 0x00000014
Hue
Sharpness
iProcessing 0 Љ
bmVideoStandards 0x00
VideoControl Interface Descriptor:
bLength 26
bDescriptorType 4
bDescriptorSubType 6 (EXTENSION_UNIT)
bUnitID 4
guidExtensionCode {e93a4108-46af-db45-3750-94e9e0608a81}
bNumControls 5
bNrInPins 1
baSourceID( 0) 1
bControlSize 1
bmControls( 0) 0x1f
iExtension 0 Љ
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 1
bAlternateSetting 0
bNumEndpoints 0
bInterfaceClass 14 Video
bInterfaceSubClass 2 Video Streaming
bInterfaceProtocol 0
iInterface 0
VideoStreaming Interface Descriptor:
bLength 14
bDescriptorType 4
bDescriptorSubType 1 (INPUT_HEADER)
bNumFormats 1
wTotalLength 0x0267
bEndpointAddress 0x81 EP 1 IN
bmInfo 0
bTerminalLink 2
bStillCaptureMethod 0
bTriggerSupport 0
bTriggerUsage 0
bControlSize 1
bmaControls( 0) 0
VideoStreaming Interface Descriptor:
bLength 11
bDescriptorType 4
bDescriptorSubType 6 (FORMAT_MJPEG)
bFormatIndex 1
bNumFrameDescriptors 4
bFlags 0
Fixed-sized samples: No
bDefaultFrameIndex 4
bAspectRatioX 0
bAspectRatioY 0
bmInterlaceFlags 0x00
Interlaced stream or variable: No
Fields per frame: 2
Field 1 first: No
Field pattern: Field 1 only
bCopyProtect 0
VideoStreaming Interface Descriptor:
bLength 146
bDescriptorType 4
bDescriptorSubType 7 (FRAME_MJPEG)
bFrameIndex 1
bmCapabilities 0x00
Still image unsupported
wWidth 640
wHeight 480
dwMinBitRate 460800
dwMaxBitRate 13824000
dwMaxVideoFrameBufferSize 460800
dwDefaultFrameInterval 333333
bFrameIntervalType 30
dwFrameInterval( 0) 85333278
dwFrameInterval( 1) 88275712
dwFrameInterval( 2) 91428352
dwFrameInterval( 3) 94814720
dwFrameInterval( 4) 98461440
dwFrameInterval( 5) 102400000
dwFrameInterval( 6) 106666496
dwFrameInterval( 7) 111304192
dwFrameInterval( 8) 116363520
dwFrameInterval( 9) 121904640
dwFrameInterval(10) 128000000
dwFrameInterval(11) 134736640
dwFrameInterval(12) 142222080
dwFrameInterval(13) 150588160
dwFrameInterval(14) 160000000
dwFrameInterval(15) 170666496
dwFrameInterval(16) 182856960
dwFrameInterval(17) 196922880
dwFrameInterval(18) 213333248
dwFrameInterval(19) 232727040
dwFrameInterval(20) 256000000
dwFrameInterval(21) 284444416
dwFrameInterval(22) 320000000
dwFrameInterval(23) 365714176
dwFrameInterval(24) 426666496
dwFrameInterval(25) 512000000
dwFrameInterval(26) 640000000
dwFrameInterval(27) 853333248
dwFrameInterval(28) 1280000000
dwFrameInterval(29) 2560000000