[Nut-upsdev] [nut-upsuser] Copeland Engineering Dockmaster

Charles Lepple clepple at gmail.com
Sat Mar 11 14:15:21 UTC 2017

[moved to nut-upsdev while we figure out the protocol]

> On Mar 9, 2017, at 11:22 AM, Drew from Zhrodague <drewzhrodague at zhrodague.net> wrote:
> I'm able to cat /dev/usb/hiddev0 and /dev/hidraw0 - I pipe this through hexdump and I get different types of data from each:
> hiddev:
> 0002420 00a7 ffa0 00ff 0000 00a7 ffa0 00ff 0000
> 0002430 00a7 ffa0 00a3 0000 00a7 ffa0 0001 0000
> 0002440 00a6 ffa0 0080 0000 00a7 ffa0 0011 0000
> 0002450 00a7 ffa0 00bd 0000 00a7 ffa0 0057 0000
> 0002460 00a7 ffa0 00ff 0000 00a7 ffa0 00ff 0000
> 0002470 00a7 ffa0 00a3 0000 00a7 ffa0 0001 0000
> hidraw:
> 0000000 1180 59e1 ffff 01a3 1180 59e2 ffff 01a3
> 0000010 1180 5ae3 ffff 01a3 1180 5ae4 ffff 01a3
> 0000020 1180 5ae5 ffff 01a3 1180 5ae6 ffff 01a3
> 0000030 1180 5ae7 ffff 01a3 1180 5ae8 ffff 01a3
> 0000040 1180 5ae9 ffff 01a3 1180 5aea ffff 01a3
> 0000050 1180 5aeb ffff 01a3 1180 5aec ffff 01a3

I was trying to reconcile this with your earlier information from usbhid-dump, and it looks like hexdump is swapping bytes:

$ printf 12345678|hexdump
0000000 3231 3433 3635 3837                    

You can do one of the following to get the natural order, plus an ASCII dump:

$ printf 12345678|hexdump -C
00000000  31 32 33 34 35 36 37 38                           |12345678|
$ printf 12345678|hd
00000000  31 32 33 34 35 36 37 38                           |12345678|

> 	I haven't been able to figure out what the differences between hiddev and hidraw are, but the first one has the state (0001), and the second one has the timers (59e2). It also looks like there are two sentences per line.
> 	I have put together a bash script to fetch a few lines from the hiddev, and look for a key/value - sometimes what I'm using as a key changes between boots. It may not be a key/value pair.

Here's the kernel documentation:



In both cases, "cat" is triggering the "read()" operation in each driver.

> In its basic mode, the hiddev will make these individual
> usage changes available to the reader using a struct hiddev_event:
>        struct hiddev_event {
>            unsigned hid;
>            signed int value;
>        };

I think the "hid" value in the hiddev output is one of "ffa000a6" or "ffa000a7", but byte-swapped (still i686, right?) and hexdump-swapped to "00a6 ffa0" and "00a7 ffa0". The next four bytes are the zero-padded version of each byte that shows up in the hidraw output.

I'm not sure what the difference between the ...a6 and ...a7 parts are -- the HID Report Descriptor is not well-formed. It does look like the a6 part comes right before the 80, which seems to be at the beginning of the message.

For hidraw, it looks like we could just read 8 bytes at once, and be done.

>> If you are interested in taking a look at related code, these two drivers are probably good starting points:
>> * https://github.com/networkupstools/nut/blob/libusb-1.0/drivers/nutdrv_atcl_usb.c
>> * https://github.com/networkupstools/nut/blob/libusb-1.0/drivers/richcomm_usb.c

I mention these two drivers because, as I recall, they are also for non-PDC HID devices. For portability, NUT tends to use libusb rather than the Linux-specific hiddev/hidraw APIs. We have a few options:

 * Use hidraw, which is only available on Linux, but is known to work with this device. This would require a bit of autoconf plumbing in order to prevent other platforms from building the new driver.
 * Use HIDAPI, a portability library written by Alan Ott (author of the hidraw.txt kernel documentation). Adds another dependency that we haven't used yet.
 * Use libhid, which involves detaching the hiddev/hidraw driver from the device. We do this all the time with PDC HID devices. It might take a little more experimenting to find the libusb command to send.

NUT developers: anyone else want to weigh in here? I'm leaning towards the third option, but I'm open to suggestions.

More information about the Nut-upsdev mailing list