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

2017-04-26 Thread Charles Lepple
On Mar 19, 2017, at 6:49 PM, Charles Lepple wrote:
> 
> 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.

Drew,

any updates on what to write?

I would still like to try and find the sequence of bytes that we would write 
with libusb, but if that isn't feasible, we can try to build something around 
the hidraw API.

-- 
Charles Lepple
clepple@gmail




___
Nut-upsdev mailing list
Nut-upsdev@lists.alioth.debian.org
http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/nut-upsdev


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

2017-03-20 Thread Drew from Zhrodague

On 3/20/17 9:42 AM, Charles Lepple wrote:

Drew,

Another thing to consider is the NUT driver documentation. This is the 
template, but since it originally predated the USB drivers, feel free to draw 
on the other man pages for inspiration:

https://github.com/networkupstools/nut/blob/master/docs/man/skel.txt



Thanks, Charles, I'll take a look at this tonite.

	I've been using a Windows program on my thin-client to monitor the 
traffic. Still wrapping my head around reports and features.



--

Drew from Zhrodague
d...@zhrodague.net

"Yeah, yeah, yeah!" - Rob Zombie

___
Nut-upsdev mailing list
Nut-upsdev@lists.alioth.debian.org
http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/nut-upsdev


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

2017-03-20 Thread Charles Lepple
Drew,

Another thing to consider is the NUT driver documentation. This is the 
template, but since it originally predated the USB drivers, feel free to draw 
on the other man pages for inspiration:

https://github.com/networkupstools/nut/blob/master/docs/man/skel.txt

- Charles
___
Nut-upsdev mailing list
Nut-upsdev@lists.alioth.debian.org
http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/nut-upsdev


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

2017-03-19 Thread Charles Lepple
On Mar 19, 2017, at 10:56 AM, Drew from Zhrodague  
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
>bmAttributes3
>  Transfer TypeInterrupt
>  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 

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

2017-03-19 Thread Drew from Zhrodague

On 3/11/17 9:15 AM, Charles Lepple wrote:

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


On Mar 9, 2017, at 11:22 AM, Drew from Zhrodague  
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:


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


Couple of updates:

	[] 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.


	[] 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.


	[] 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

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
  Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x81  EP 1 IN
bmAttributes3
  Transfer TypeInterrupt
  Synch Type   None
  Usage Type   Data
wMaxPacketSize 0x0008  1x 8 bytes
bInterval  10



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 welcome any advice or assistance - ideally I'd like to use a proper 
UPS software, rather than my own egregious use of bash. Thanks!



--

Drew from Zhrodague
d...@zhrodague.net

___
Nut-upsdev mailing list
Nut-upsdev@lists.alioth.debian.org
http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/nut-upsdev


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

2017-03-11 Thread Charles Lepple
[moved to nut-upsdev while we figure out the protocol]

> On Mar 9, 2017, at 11:22 AM, Drew from Zhrodague 
>  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  00a7 ffa0 00ff 
> 0002430 00a7 ffa0 00a3  00a7 ffa0 0001 
> 0002440 00a6 ffa0 0080  00a7 ffa0 0011 
> 0002450 00a7 ffa0 00bd  00a7 ffa0 0057 
> 0002460 00a7 ffa0 00ff  00a7 ffa0 00ff 
> 0002470 00a7 ffa0 00a3  00a7 ffa0 0001 
> 
> 
> hidraw:
> 
> 000 1180 59e1  01a3 1180 59e2  01a3
> 010 1180 5ae3  01a3 1180 5ae4  01a3
> 020 1180 5ae5  01a3 1180 5ae6  01a3
> 030 1180 5ae7  01a3 1180 5ae8  01a3
> 040 1180 5ae9  01a3 1180 5aea  01a3
> 050 1180 5aeb  01a3 1180 5aec  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
000 3231 3433 3635 3837
008

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

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

>   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:

https://www.kernel.org/doc/Documentation/hid/hiddev.txt

https://www.kernel.org/doc/Documentation/hid/hidraw.txt

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.
___
Nut-upsdev mailing list
Nut-upsdev@lists.alioth.debian.org
http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/nut-upsdev