On Mar 6, 2014, at 3:55 PM, Rob Groner wrote:
> To make this UPS as easy to use as possible for the end-user who chooses
> Linux, I figured I would just completely implement the official USB HID UPS
> spec. That way no subdriver would be needed, or at least very little.
At the moment, we use USB VID and PID to select which HID-to-NUT tables to
consult (since some vendors have "custom" (incorrect) interpretations of
standard HID PDC Usages. So at the very least, you would need a skeleton
usbhid-ups subdriver which matches your VID:PID combination.
>From there, though, if you follow the standard HID PDC Usage IDs, you should
>be able to just map the "HID path" (see below) to the corresponding NUT name.
> However, I am having a terrible time making sense of the pages in the NUT
> guide for writing USB HID drivers, and the USB HID usage table at usb.org.
> Just looking at some of the report ID values that I KNOW are working from the
> UPS example running on the microchip, I can’t seem to find their equivalent
> in either doc. For instance, I know that the UPS code is sending status info
> using a Report ID of 0x40 and two bytes of data…but I cannot find anything in
> the usb.org docs that relates to this. NUT somehow understands it, though,
> since it correctly reports the device’s status.
The report IDs aren't standardized - the HID Usage IDs are. The Report ID is
essentially an opaque, small number to avoid having to send a full list of HID
Usage IDs every time a new report is ready.
If you look up Report ID 0x40 in your HID Report Descriptor, you should see a
few HID Usage Pages and HID Usage IDs. Usage Pages are just the upper 16 bits
of a full Usage ID as seen in the drivers. In the HID Report Descriptor, the
Usage Pages and Usages will most likely be represented as hexadecimal. At the
end of drivers/libhid.c (hid_usage_lkp[]) is a set of tables that map names to
32-bit hex Usage Page/Usage pairs.
Another slightly strange concept in NUT is the way that HID Collections are
represented. Each collection has a Usage Page/Usage associated with it, and for
an UPS, these generally start with Page 0x84 (UPS) or Page 0x85 (Battery). They
are separated with dots, and the whole thing is termed a "HID path" or similar.
Let's use "UPS.PowerConverter.Output.Voltage" from an MGE Evolution as an
example.
>From lsusb -vvv (run as root; with the Linux kernel HID driver detached if
>applicable, and the NUT driver stopped):
Report Descriptor: (length is 1300)
...
Item(Global): Usage Page, data= [ 0x84 ] 132
Power Device Page
Item(Local ): Usage, data= [ 0x04 ] 4
UPS
Item(Main ): Collection, data= [ 0x00 ] 0
Physical
...
Item(Local ): Usage, data= [ 0x16 ] 22
Power Converter
Item(Main ): Collection, data= [ 0x00 ] 0
Physical
...
Item(Local ): Usage, data= [ 0x1c ] 28
Output
Item(Main ): Collection, data= [ 0x00 ] 0
Physical
...
Item(Global): Report ID, data= [ 0x1c ] 28
...
Item(Local ): Usage, data= [ 0x30 ] 48
Voltage
Moving backwards from Voltage, we see that the Report ID is 0x1c.
By summing up the size of the features in that Report (the Report size is
"sticky" in that it is only specified when it changes between fields), we can
find the offset and size of the voltage field. (Sizes are in bits.) I'll let
the usbhid-ups driver do the dirty work:
5.648610 Report[buf]: (10 bytes) => 1c 01 04 57 00 49 00 77 00 3b
5.648687 Path: UPS.PowerConverter.Output.Voltage, Type: Feature,
ReportID: 0x1c, Offset: 48, Size: 16, Value: 119
So an offset of 48 (counting past the report ID 0x1c at the beginning of the
buffer) is 48/8 = 6 bytes in, for a value of "77 00" (0x0077 since USB is
little-endian), or 119.
--
Charles Lepple
clepple@gmail
_______________________________________________
Nut-upsdev mailing list
[email protected]
http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/nut-upsdev