[libhid-discuss] help deciphering HID descriptor

Charles Lepple clepple at ghz.cc
Sat Dec 1 14:58:01 UTC 2007


On Nov 28, 2007, at 11:19 PM, Hans-Christoph Steiner wrote:

> On Nov 28, 2007, at 5:17 PM, Peter Stuge wrote:
>
>> Sorry I'm being a bit selective in my answers, but I really can't
>> help at all with the usage stuff. :\
>>
>>
>> On Wed, Nov 28, 2007 at 04:51:15PM -0500, Hans-Christoph Steiner
>> wrote:
>>> My life would be easier if I could find a GNU/Linux box that had a
>>> 'lsusb -vvv' that gave me something other than:
>>>
>>> Report Description:
>>>     ** UNAVAILABLE **
>>
>> This is because the kernel hid driver has claimed the interface.
>> Force detach it or just unload the driver and you should get more
>> output from lsusb.
>
>
> Cool, thanks, that was the first tip I needed, now I got the lsusb -
> vvv output.  It turns out I had to ssh into my machine, stop all the
> services that might be using the USB HID devices (like dbus),  and
> rmmod all of the USB related modules (usbhid, hid, evdev, etc.).
> Then lsusb -vvv gave me the Report Descriptor.

Unfortunately, if running libhid-detach-device doesn't work, then you  
will have to either go through this rmmod sequence every time, or you  
will have to patch the kernel to blacklist the device (as was done  
for the MGE UPS units, which were not accessible through the old  
hiddev kernel API).

> So now I have it, but this one seems to be quite complicated, and I
> am still not following it.  I am trying to trigger any of the output
> usages:

If you modify the example code (~line 42 of test/test_libhid.c) to  
match your device, and run it remotely the way you did for "lsusb - 
vvv" (or run it on OS X without the driver installed), then you  
should get a bunch of printouts with the usage paths already  
assembled (done by hid_dump_tree()). The comments below that function  
call also explain the whole usage path concept.

>
>    idVendor           0x046d Logitech, Inc.
>    idProduct          0xc218
>    bcdDevice            1.00
>    iManufacturer           1 Logitech
>    iProduct                2 Logitech RumblePad 2 USB
>    iSerial                 0
>    bNumConfigurations      1
>    Configuration Descriptor:
>      bLength                 9
>      bDescriptorType         2
>      wTotalLength           41
>      bNumInterfaces          1
>      bConfigurationValue     1
>      iConfiguration          0
>      bmAttributes         0x80
>        (Bus Powered)
>      MaxPower              500mA
>      Interface Descriptor:
>        bLength                 9
>        bDescriptorType         4
>        bInterfaceNumber        0
>        bAlternateSetting       0
>        bNumEndpoints           2
>        bInterfaceClass         3 Human Interface Devices
>        bInterfaceSubClass      0 No Subclass
>        bInterfaceProtocol      0 None
>        iInterface              0
>          HID Device Descriptor:
>            bLength                 9
>            bDescriptorType        33
>            bcdHID               1.10
>            bCountryCode            0 Not supported
>            bNumDescriptors         1
>            bDescriptorType        34 Report
>            wDescriptorLength     119
>            Report Descriptor: (length is 119)
>              Item(Global): Usage Page, data= [ 0x01 ] 1
>                              Generic Desktop Controls
>              Item(Local ): Usage, data= [ 0x04 ] 4
>                              Joystick

The first element of the path would be "0x00010004"

>              Item(Main  ): Collection, data= [ 0x01 ] 1
>                              Application
>              Item(Main  ): Collection, data= [ 0x02 ] 2
>                              Logical
>              Item(Global): Logical Minimum, data= [ 0x00 ] 0
>              Item(Global): Logical Maximum, data= [ 0xff 0x00 ] 255
>              Item(Global): Physical Minimum, data= [ 0x00 ] 0
>              Item(Global): Physical Maximum, data= [ 0xff 0x00 ] 255
>              Item(Global): Report Size, data= [ 0x08 ] 8
>              Item(Global): Report Count, data= [ 0x04 ] 4
>              Item(Local ): Usage, data= [ 0x30 ] 48
>                              Direction-X
>              Item(Local ): Usage, data= [ 0x31 ] 49
>                              Direction-Y
>              Item(Local ): Usage, data= [ 0x32 ] 50
>                              Direction-Z
>              Item(Local ): Usage, data= [ 0x35 ] 53
>                              Rotate-Z
>              Item(Main  ): Input, data= [ 0x02 ] 2
>                              Data Variable Absolute No_Wrap Linear
>                              Preferred_State No_Null_Position
> Non_Volatile Bitfield
>              Item(Global): Logical Maximum, data= [ 0x07 ] 7
>              Item(Global): Physical Maximum, data= [ 0x3b 0x01 ] 315
>              Item(Global): Report Size, data= [ 0x04 ] 4
>              Item(Global): Report Count, data= [ 0x01 ] 1
>              Item(Global): Unit, data= [ 0x14 ] 20
>                              System: English Rotation, Unit: Degrees
>              Item(Local ): Usage, data= [ 0x39 ] 57
>                              Hat Switch
>              Item(Main  ): Input, data= [ 0x42 ] 66
>                              Data Variable Absolute No_Wrap Linear
>                              Preferred_State Null_State Non_Volatile
> Bitfield
>              Item(Global): Unit, data= [ 0x00 ] 0
>                              System: None, Unit: (None)
>              Item(Global): Logical Maximum, data= [ 0x01 ] 1
>              Item(Global): Physical Maximum, data= [ 0x01 ] 1
>              Item(Global): Report Size, data= [ 0x01 ] 1
>              Item(Global): Report Count, data= [ 0x0c ] 12
>              Item(Global): Usage Page, data= [ 0x09 ] 9
>                              Buttons
>              Item(Local ): Usage Minimum, data= [ 0x01 ] 1
>                              Button 1 (Primary)
>              Item(Local ): Usage Maximum, data= [ 0x0c ] 12
>                              (null)
>              Item(Main  ): Input, data= [ 0x02 ] 2
>                              Data Variable Absolute No_Wrap Linear
>                              Preferred_State No_Null_Position
> Non_Volatile Bitfield
>              Item(Global): Usage Page, data= [ 0x00 0xff ] 65280
>                              (null)

the Usage Page here is important.

>              Item(Global): Report Size, data= [ 0x01 ] 1
>              Item(Global): Report Count, data= [ 0x10 ] 16
>              Item(Global): Logical Maximum, data= [ 0x01 ] 1
>              Item(Global): Physical Maximum, data= [ 0x01 ] 1
>              Item(Local ): Usage, data= [ 0x01 ] 1
>                              (null)
>              Item(Main  ): Input, data= [ 0x02 ] 2
>                              Data Variable Absolute No_Wrap Linear
>                              Preferred_State No_Null_Position
> Non_Volatile Bitfield
>              Item(Main  ): End Collection, data=none
>              Item(Main  ): Collection, data= [ 0x02 ] 2
>                              Logical
>              Item(Global): Logical Maximum, data= [ 0xff 0x00 ] 255
>              Item(Global): Physical Maximum, data= [ 0xff 0x00 ] 255
>              Item(Global): Report Size, data= [ 0x08 ] 8
>              Item(Global): Report Count, data= [ 0x07 ] 7
>              Item(Local ): Usage, data= [ 0x02 ] 2
>                              (null)
>              Item(Main  ): Output, data= [ 0x02 ] 2
>                              Data Variable Absolute No_Wrap Linear
>                              Preferred_State No_Null_Position
> Non_Volatile Bitfield

So the path to this output Usage would be { 0x00010004, 0xff000002 }

>              Item(Main  ): End Collection, data=none
>              Item(Main  ): Collection, data= [ 0x02 ] 2
>                              Logical
>              Item(Global): Logical Maximum, data= [ 0xff 0x00 ] 255
>              Item(Global): Physical Maximum, data= [ 0xff 0x00 ] 255
>              Item(Global): Report Size, data= [ 0x08 ] 8
>              Item(Global): Report Count, data= [ 0x05 ] 5
>              Item(Global): Usage Page, data= [ 0x00 0xff ] 65280
>                              (null)
>              Item(Local ): Usage, data= [ 0x01 ] 1
>                              (null)
>              Item(Main  ): Feature, data= [ 0x02 ] 2
>                              Data Variable Absolute No_Wrap Linear
>                              Preferred_State No_Null_Position
> Non_Volatile Bitfield

This feature may also be an output feature as well: {0x00010004,  
0xff000001}

-- 
Charles Lepple





More information about the libhid-discuss mailing list