Skip to content

Latest commit

 

History

History
286 lines (273 loc) · 15.1 KB

Readme.org

File metadata and controls

286 lines (273 loc) · 15.1 KB

What?

We store some information about certain mice in here for debuggging purpose.

Get USB debugging data from your mouse

Identify your mouse

Run a sudo dmesg -w and unplug/replug your mouse. The kernel messages look like

[ 6353.296752] usb 5-1.1: USB disconnect, device number 4
[ 6355.573380] usb 5-1.1: new full-speed USB device number 10 using xhci_hcd
[ 6355.857686] usb 5-1.1: New USB device found, idVendor=1038, idProduct=1724, bcdDevice= 2.34
[ 6355.857698] usb 5-1.1: New USB device strings: Mfr=1, Product=2, SerialNumber=0
[ 6355.857705] usb 5-1.1: Product: SteelSeries Rival 600
[ 6355.857709] usb 5-1.1: Manufacturer: SteelSeries
[ 6355.884557] hid-generic 0003:1038:1724.0016: hiddev0,hidraw3: USB HID v1.11 Device [SteelSeries SteelSeries Rival 600] on usb-0000:06:00.0-1.1/input0
[ 6355.886002] input: SteelSeries SteelSeries Rival 600 as /devices/pci0000:00/0000:00:1c.4/0000:06:00.0/usb5/5-1/5-1.1/5-1.1:1.1/0003:1038:1724.0017/input/input51
[ 6355.886541] hid-generic 0003:1038:1724.0017: input,hidraw6: USB HID v1.11 Mouse [SteelSeries SteelSeries Rival 600] on usb-0000:06:00.0-1.1/input1
[ 6355.888456] input: SteelSeries SteelSeries Rival 600 Keyboard as /devices/pci0000:00/0000:00:1c.4/0000:06:00.0/usb5/5-1/5-1.1/5-1.1:1.2/0003:1038:1724.0018/input/input52
[ 6355.943755] input: SteelSeries SteelSeries Rival 600 Consumer Control as /devices/pci0000:00/0000:00:1c.4/0000:06:00.0/usb5/5-1/5-1.1/5-1.1:1.2/0003:1038:1724.0018/input/input53
[ 6355.944183] hid-generic 0003:1038:1724.0018: input,hidraw9: USB HID v1.11 Keyboard [SteelSeries SteelSeries Rival 600] on usb-0000:06:00.0-1.1/input2d

From that you can extract important information for the next steps: The idVendor and idProduct

Grab the device information

With aboves instruction, you need to run the following command with passing idVendor:idProduct to lsusb

# Replace 1038:1724 with idVendor:idProduct and steelseries_rival600.txt with <Vendor Name>_<Product Name>.txt
lsusb -vd 1038:1724 > steelseries_rival600.txt

This writes the following content to the dump file

Bus 005 Device 010: ID 1038:1724 SteelSeries ApS SteelSeries Rival 600
Couldn't open device, some information will be missing
Device Descriptor:
  bLength                18
  bDescriptorType         1
  bcdUSB               2.00
  bDeviceClass            0 
  bDeviceSubClass         0 
  bDeviceProtocol         0 
  bMaxPacketSize0        64
  idVendor           0x1038 SteelSeries ApS
  idProduct          0x1724 
  bcdDevice            2.34
  iManufacturer           1 SteelSeries
  iProduct                2 SteelSeries Rival 600
  iSerial                 0 
  bNumConfigurations      1
  Configuration Descriptor:
    bLength                 9
    bDescriptorType         2
    wTotalLength       0x0054
    bNumInterfaces          3
    bConfigurationValue     1
    iConfiguration          0 
    bmAttributes         0xa0
      (Bus Powered)
      Remote Wakeup
    MaxPower              200mA
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        0
      bAlternateSetting       0
      bNumEndpoints           1
      bInterfaceClass         3 Human Interface Device
      bInterfaceSubClass      0 
      bInterfaceProtocol      0 
      iInterface              0 
        HID Device Descriptor:
          bLength                 9
          bDescriptorType        33
          bcdHID               1.11
          bCountryCode            0 Not supported
          bNumDescriptors         1
          bDescriptorType        34 Report
          wDescriptorLength      37
        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     0x0020  1x 32 bytes
        bInterval               1
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        1
      bAlternateSetting       0
      bNumEndpoints           1
      bInterfaceClass         3 Human Interface Device
      bInterfaceSubClass      1 Boot Interface Subclass
      bInterfaceProtocol      2 Mouse
      iInterface              0 
        HID Device Descriptor:
          bLength                 9
          bDescriptorType        33
          bcdHID               1.11
          bCountryCode            0 Not supported
          bNumDescriptors         1
          bDescriptorType        34 Report
          wDescriptorLength      98
        Report Descriptors: 
          ** UNAVAILABLE **
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x82  EP 2 IN
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0009  1x 9 bytes
        bInterval               1
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        2
      bAlternateSetting       0
      bNumEndpoints           1
      bInterfaceClass         3 Human Interface Device
      bInterfaceSubClass      0 
      bInterfaceProtocol      0 
      iInterface              0 
        HID Device Descriptor:
          bLength                 9
          bDescriptorType        33
          bcdHID               1.11
          bCountryCode            0 Not supported
          bNumDescriptors         1
          bDescriptorType        34 Report
          wDescriptorLength      76
        Report Descriptors: 
          ** UNAVAILABLE **
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x83  EP 3 IN
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0009  1x 9 bytes
        bInterval               1

Report Descriptor is missing???

You see, that the report descriptor in the dump of the previous paragraph is missing (Report Descriptors: ** UNAVAILABLE **). This descriptor basically tells you, in what kind of format the mouse is sending you data to the host. So we definitely want to have this descriptor!

Extracting the report descriptor (HEX)

Run

# Replace 1038:1724 with idVendor:idProduct and steelseries_rival600_raw.txt with <Vendor Name>_<Product Name>_raw.txt
sudo usbhid-dump -d 1038:1724 > steelseries_rival600_descriptor_raw.txt

This will spew the raw Report Descriptor in hex form to the file

005:004:002:DESCRIPTOR         1617489710.244663
05 01 09 06 A1 01 85 01 05 07 19 E0 29 E7 15 00
25 01 75 01 95 08 81 02 75 08 95 01 81 01 05 07
19 00 2A FF 00 15 00 26 FF 00 75 08 95 06 81 00
C0 05 0C 09 01 A1 01 85 02 05 0C 19 00 2A FF 0F
15 00 26 FF 0F 75 10 95 02 81 00 C0

005:004:001:DESCRIPTOR         1617489710.245521
# Starting from here. this is the interesting part (comment for next paragraph!)
05 01 09 02 A1 01 09 01 A1 00 A1 02 05 09 19 01
29 08 15 00 25 01 95 08 75 01 81 02 05 01 09 30
09 31 16 01 80 26 FF 7F 75 10 95 02 81 06 09 38
15 81 25 7F 75 08 95 01 81 06 C0 A1 02 05 0C 0A
38 02 15 81 25 7F 75 08 95 01 81 06 C0 A1 02 06
C1 FF 15 00 26 FF 00 75 08 09 F0 95 02 81 02 C0
C0 C0

005:004:000:DESCRIPTOR         1617489710.246510
06 C0 FF 09 01 A1 01 06 C1 FF 15 00 26 FF 00 75
08 09 F0 95 20 81 02 09 F1 95 20 91 02 09 F2 96
42 02 B1 02 C0

Converting Report Descriptor (HEX) to human readable

Using an Online USB Descriptor parser (preferred)

I recently stumpled upon this nice USB Descriptor Parser which directly relates each HEX value to the human readable structure.

Copy over the interesting HEX sequence (see previous paragraph on the hex values), and click on the USB HID Report Descriptor button. This will give you an output like this

0x05, 0x01,        // Usage Page (Generic Desktop Ctrls)
0x09, 0x02,        // Usage (Mouse)
0xA1, 0x01,        // Collection (Application)
0x09, 0x01,        //   Usage (Pointer)
0xA1, 0x00,        //   Collection (Physical)
0xA1, 0x02,        //     Collection (Logical)
0x05, 0x09,        //       Usage Page (Button)
0x19, 0x01,        //       Usage Minimum (0x01)
0x29, 0x08,        //       Usage Maximum (0x08)
0x15, 0x00,        //       Logical Minimum (0)
0x25, 0x01,        //       Logical Maximum (1)
0x95, 0x08,        //       Report Count (8)
0x75, 0x01,        //       Report Size (1)
0x81, 0x02,        //       Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x05, 0x01,        //       Usage Page (Generic Desktop Ctrls)
0x09, 0x30,        //       Usage (X)
0x09, 0x31,        //       Usage (Y)
0x16, 0x01, 0x80,  //       Logical Minimum (-32767)
0x26, 0xFF, 0x7F,  //       Logical Maximum (32767)
0x75, 0x10,        //       Report Size (16)
0x95, 0x02,        //       Report Count (2)
0x81, 0x06,        //       Input (Data,Var,Rel,No Wrap,Linear,Preferred State,No Null Position)
0x09, 0x38,        //       Usage (Wheel)
0x15, 0x81,        //       Logical Minimum (-127)
0x25, 0x7F,        //       Logical Maximum (127)
0x75, 0x08,        //       Report Size (8)
0x95, 0x01,        //       Report Count (1)
0x81, 0x06,        //       Input (Data,Var,Rel,No Wrap,Linear,Preferred State,No Null Position)
0xC0,              //     End Collection
0xA1, 0x02,        //     Collection (Logical)
0x05, 0x0C,        //       Usage Page (Consumer)
0x0A, 0x38, 0x02,  //       Usage (AC Pan)
0x15, 0x81,        //       Logical Minimum (-127)
0x25, 0x7F,        //       Logical Maximum (127)
0x75, 0x08,        //       Report Size (8)
0x95, 0x01,        //       Report Count (1)
0x81, 0x06,        //       Input (Data,Var,Rel,No Wrap,Linear,Preferred State,No Null Position)
0xC0,              //     End Collection
0xA1, 0x02,        //     Collection (Logical)
0x06, 0xC1, 0xFF,  //       Usage Page (Vendor Defined 0xFFC1)
0x15, 0x00,        //       Logical Minimum (0)
0x26, 0xFF, 0x00,  //       Logical Maximum (255)
0x75, 0x08,        //       Report Size (8)
0x09, 0xF0,        //       Usage (0xF0)
0x95, 0x02,        //       Report Count (2)
0x81, 0x02,        //       Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0xC0,              //     End Collection
0xC0,              //   End Collection
0xC0,              // End Collection

// 98 bytes

Note on how you can now clearly see the datastructur of this device, when it reports to the system

TypeLength (bits)
Button8*1 = 8
X,Y displacement2*16 = 32
Mousewheel1*8 = 8
Vendor Specific2*8 = 16
Local via CLI (if the link to the parser above dies)

You will need to install hidrd and xxd. For arch, you can use the AUR package yay -Sy hidrd-git and sudo pacman -Sy xxd

For the aboves example, there were 3 inerfaces. Therfore run the following for each interface (note the increment in the parameter -i

sudo usbhid-dump -d 1038:1724 -i0 | grep -v : | xxd -r -p | hidrd-convert -o spec >> steelseries_rival600_descriptor.txt
sudo usbhid-dump -d 1038:1724 -i1 | grep -v : | xxd -r -p | hidrd-convert -o spec >> steelseries_rival600_descriptor.txt
sudo usbhid-dump -d 1038:1724 -i2 | grep -v : | xxd -r -p | hidrd-convert -o spec >> steelseries_rival600_descriptor.txt

NOTE The output is helpful, but a clear HEX to Human readable representation would be nice, wouldn’t it? This is, why I prefere the online parser (see previous paragraph)

Why?

USB is a pretty interesting protocol. According to the specifications a device can host several distinct interfaces. And theses interfaces can be of different (predefined) subclass type (See pp.8 of the pdf). Particularily, there are generic HID devices like Keyboards and Mice, which are most interesting here for now. However, since there are a ton of different HID devices around the world, which would like to implement special features (more mouse buttons, RGB, media keys - you name it) the USB consortium implemented a way to implement these features

  • By default, the devices will enter the so called Boot protocol (mode for e.g. the BIOS/EFI etc). Thise mode dictates the explicit type of data, the device is supposed to send. Nothing more and nothing less. A minimal common base so to say. For a mouse it looks like this (see p. 61 of the pdf)
    ByteBitsDescription
    00Button 1
    1Button 2
    2Button3
    4 to 7Device-specific
    10 to 7X displacement
    20 to 7Y displacement
    3 to nDevice specific (optional)
  • Since this presents a limited functionality, the USB consortium allows a device to declare Interface Descriptors of the data it will send, when switching modes away from Boot protocol.
  • This is now, where it gets interesting: The corresponding USB/HID driver of the OS will tell the device to switch the mode from Boot Mode to Descriptor Mode when getting bound by usb-hid.
    • Ignoring this fact particularily messed up the data getting parsed by this driver. See the corresponding bugreport.
  • The device stays in this mode, even when we bind to LEETMOUSE.
    • This can cause unforseen consequences to the inputs send from the mouse to the host, since LEETMOUSE interprets them (right now) in a static/fixed way.
    • This is about to change however… Hence this documentation