[libhid-discuss] Misunderstanding input and output paths

Charles Lepple clepple at ghz.cc
Fri Apr 23 12:09:25 UTC 2010


On Apr 23, 2010, at 1:17 AM, Gary Briggs wrote:

> On Tue, Apr 20, 2010 at 07:49:50AM -0400, Charles Lepple wrote:
>>> I've written some code [mainly copied outright from the libhid test
>>> example], here:
>>> http://icculus.org/~chunky/stuff/dcdcusb/main.c
>>>
>>> The output from that program is:
>>> http://icculus.org/~chunky/stuff/dcdcusb/ 
>>> set_output_report_output.txt
>>
>> The only thing to note is that there is a bug in the printing  
>> routine,
>> and if you see a "0x00000000" path element, it is just the 2nd or
>> later element of a range. The parser knows what to do internally,
>> though.
>
> I'm still just having a hard time understanding the overall "how to  
> get a
> path out, given a lsusb listing".

You're not the first :-)

Based on a quick read of the Windows source code, I don't know if the  
paths will really matter. Note that the hid_interrupt_read() and  
hid_interrupt_write() calls do not worry about paths - they just take  
an endpoint number, and require you to figure out the packet size  
yourself.

But for completeness, here's how the first element in the dump is  
computed.

> parse tree of HIDInterface 003/015[0]:
>   path: 0x00010080.0x00010081; type: 0x80

The first part of the report descriptor:

>           Report Descriptor: (length is 200)
>             Item(Global): Usage Page, data= [ 0x01 ] 1
>                             Generic Desktop Controls
>             Item(Local ): Usage, data= [ 0x80 ] 128
>                             System Control

"Usage Page...= 0x01" is shorthand, and gets translated to "0x0001 <<  
16", or 0x00010000. "Usage...=0x80" gets OR'd with that, to produce  
"0x00010080". That full 32-bit Usage is the first element of the path  
("root directory", if you will).

The next element in the report descriptor is a collection:

>             Item(Main  ): Collection, data= [ 0x01 ] 1
>                             Application

The notion of a collection is similar to a directory on a filesystem;  
hence, the full Usage calculated above will be the first elements of  
all the paths until the collection ends.

>             Item(Global): Report ID, data= [ 0x01 ] 1

Report IDs are sort of another dimension to the data - they allow the  
information to be broken up into chunks that can be requested  
separately (keyed by the Report ID). They are "sticky" until the next  
Report ID.

>             Item(Local ): Usage, data= [ 0x81 ] 129
>                             System Power Down

This Usage ID is inside the collection, and it inherits the last Usage  
Page which was set (0x0001 => 0x00010000). So its full 32-bit Usage is  
(0x0001 << 16) | 0x0081, or 0x00010081, which is the second element of  
the path (shown in the first line of the dump).

>             Item(Global): Logical Minimum, data= [ 0x00 ] 0
>             Item(Global): Logical Maximum, data= [ 0x01 ] 1
>             Item(Global): Report Size, data= [ 0x01 ] 1
>             Item(Global): Report Count, data= [ 0x01 ] 1
>             Item(Main  ): Input, data= [ 0x06 ] 6
>                             Data Variable Relative No_Wrap Linear
>                             Preferred_State No_Null_Position  
> Non_Volatile Bitfield

This portion from the lsusb listing basically says that the path  
represents one bit of input data. The "0x80" at the end of the libhid  
dump is the internal libhid direction flag (Input, which is Device-to- 
Host).

>             Item(Global): Report Count, data= [ 0x07 ] 7
>             Item(Main  ): Input, data= [ 0x01 ] 1
>                             Constant Array Absolute No_Wrap Linear
>                             Preferred_State No_Null_Position  
> Non_Volatile Bitfield

The single bit of data is padded out with 7 bits of "don't care" (the  
Constant/Absolute flags above).

If we look up the Usage in that Usage Page (which lsusb has done for  
us), it appears as though the PSU is synthesizing a "System Power  
Down" keypress.

After that, the collection is closed, which is sort of like "cd ..":

>             Item(Main  ): End Collection, data=none


So the next Usage Page and Usage pair will specify the first element  
in the path.

> I started reading this:
> http://www.networkupstools.org/doc/2.2.0/hid-subdrivers.html
> Is this actually relevant to me? It seems that if someone else has  
> done
> most of the work for HID power supplies, I'll have more luck beginning
> with that?

Unfortunately, that particular driver is looking for the standard HID  
Power Device Class (PDC) Usage numbers (0x0084 and 0x0085).

Here's a sample libhid dump from the kind of UPS that NUT works with  
out-of-the-box:

http://boxster.ghz.cc/projects/libhid/browser/trunk/ref/test_libhid_output/MGE_Pulsar_Evolution_500

>>> Overall, I'm just confused as to what's going on or how to progress
>>> and
>>> make this work. If anyone has any suggestions as to what I should do
>>> from here, I'd greatly appreciate it.
>>
>> What are your goals? Shutting down the power supply? Monitoring
>> certain parameters? If possible, I would start with something
>> innocuous like changing the state of an LED, but if you can power the
>> test machine from another power source, that would be best.
>
> At least to start, I just want to read the current state of the PSU.
> Saliently, at least to start, I just want to be able to figure out
> whether the ignition is connected or not, and if not, how long until  
> it
> actually shuts the whole system down.

You may be in luck if it's rainy this weekend - I'll have more time to  
look into the Windows code.

> I figure that once I see *something* everything else is in the realm  
> of
> figuring out the device-specific hoojimajiggery. I'm still just at the
> point where I want to see *something*.
>
> Thank-you so much for your time and explanations, they've really been
> helping me.

You're welcome. You have evidently spent a lot of time researching  
this, so I figure it's the least I can do.

Oh, OK - I admit it - I think this device would be cool to support in  
Network UPS Tools :-)



More information about the libhid-discuss mailing list