On Mar 19, 2017, at 10:56 AM, Drew from Zhrodague <drewzhroda...@zhrodague.net> wrote: > > [] I've spoken with one of the developers, and he's offered to share > some technical documentation with me. I'll report here with whatever I can. > He's on vacation in China.
Hopefully this documentation will lead to fewer surprises down the road. > [] I found this hid-example.c program, which fetches the values from > the unit, including a timer, and a current state. However, this example > program pushes data into the unit (to test writing), which sets the timers to > astronomical values. I am not sure the format it wants, I'm unable to > actually set anything, and the timer seems to default to 'a3 minutes'. My C > is rusty, but commenting-out the writing portion makes the data collection > not work. I keep finding the generic hid-example.c from the Linux kernel tree when searching - do you have one specifically for this device? > > [] After unloading the hid modules, I was able to get more details on > the USB format, and I am trying to read documentation to understand what's > going on. From lsusb -vvv: > > Report Descriptor: (length is 34) > Item(Global): Usage Page, data= [ 0xa0 0xff ] 65440 > (null) > Item(Local ): Usage, data= [ 0xa5 ] 165 > (null) > Item(Main ): Collection, data= [ 0x01 ] 1 > Application > Item(Local ): Usage, data= [ 0xa6 ] 166 > (null) > Item(Local ): Usage, data= [ 0xa7 ] 167 > (null) > Item(Global): Logical Minimum, data= [ 0x00 ] 0 > Item(Global): Logical Maximum, data= [ 0xff ] 255 > Item(Global): Report Size, data= [ 0x08 ] 8 > Item(Global): Report Count, data= [ 0x08 ] 8 > Item(Main ): Input, data= [ 0x02 ] 2 > Data Variable Absolute No_Wrap Linear > Preferred_State No_Null_Position Non_Volatile > Bitfield This is the decoded version of roughly the first half of the Report Descriptor bytes below. The HID Report Descriptor has an obscure stack-based approach to organizing data. Both collections and individual Input/Output/Feature items are "named" with Usage numbers, and the Usage Page is a way to set the top 16 bits of the Usage number. The problem here is that the Usage Page is 0xFFA0, and IDs beginning with 0xFF are vendor-specific. (For an UPS, this would be something like 0x84 for the Power Device Page. See /usr/share/misc/usb.ids after the VID/PID section.) I think this one byte (Report Size == 8 bits) for Usage 0xA6, and the other seven bytes (left over from Report Count == 8 x 8 bits) for usage 0xA7. Logical Minimum and Logical Maximum of 0 and 255 tell us that the bytes are unsigned, but that is typical for just passing things through the HID APIs. (A mouse would use signed values for the X and Y axes, for instance.) > Item(Local ): Usage, data= [ 0xa9 ] 169 > (null) > Item(Global): Logical Minimum, data= [ 0x00 ] 0 > Item(Global): Logical Maximum, data= [ 0xff ] 255 > Item(Global): Report Size, data= [ 0x08 ] 8 > Item(Global): Report Count, data= [ 0x08 ] 8 > Item(Main ): Output, data= [ 0x02 ] 2 > Data Variable Absolute No_Wrap Linear > Preferred_State No_Null_Position Non_Volatile > Bitfield > Item(Main ): End Collection, data=none This is the part that is being written to - 0xA9 is an 8-byte output field. As with the Input items earlier, the microcontroller is free to interpret these bytes in any way, so there might be fields within that. > Endpoint Descriptor: > bLength 7 > bDescriptorType 5 > bEndpointAddress 0x81 EP 1 IN > bmAttributes 3 > Transfer Type Interrupt > Synch Type None > Usage Type Data > wMaxPacketSize 0x0008 1x 8 bytes > bInterval 10 Exact values usually don't matter here, but 8 bytes is a typical wMaxPacketSize, especially for lower-speed USB devices. > This is from the hid-example.c: > > Report Descriptor: > 6 a0 ff 9 a5 a1 1 9 a6 9 a7 15 0 25 ff 75 8 95 8 81 2 9 a9 15 0 25 ff 75 8 95 > 8 91 2 c0 > I mistyped earlier: > * 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. should be "Use libusb..." - at one point, there was a libhid that used libusb, but part of that got absorbed into NUT. I started modifying one of the drivers to do the reads, but it may not be of much use until we understand what needs to be written, as you mentioned here: > but commenting-out the writing portion makes the data collection not work. _______________________________________________ Nut-upsdev mailing list Nut-upsdev@lists.alioth.debian.org http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/nut-upsdev