tuna-f1sh / cyme

List system USB buses and devices; a lib and modern cross-platform lsusb that attempts to maintain compatibility with, but also add new features
GNU General Public License v3.0
141 stars 7 forks source link

HID Device Descriptor support #15

Open haata opened 7 months ago

haata commented 7 months ago

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/)

haata commented 7 months ago

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)
tuna-f1sh commented 7 months ago

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.

tuna-f1sh commented 7 months ago

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

tuna-f1sh commented 7 months ago

Working branch for this https://github.com/tuna-f1sh/cyme/tree/dumps in case anyone is interested.

tuna-f1sh commented 4 months ago

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