[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