[libhid-discuss] Trying to repair a program using libhid to configure an Ultimarc Joystick

Charles Lepple clepple at ghz.cc
Wed Mar 25 03:32:49 UTC 2015


On Mar 24, 2015, at 11:10 PM, Andrew Silverman <andrewsi at microsoft.com> wrote:

> Hi folks – question from newbie.
>  
> There is a piece of software that was written several years ago to allow Linux users to configure a USB joystick from Ultimarc.  The company has Windows specific tools but no formal support for Linux.
> The tool relies on libhid and the libusb-compat libraries.  A recent firmware change for this joystick seems to have broken the current version of the Linux configuration tool and I am trying to get some help modifying it to work with this latest FW update.

An aside: libhid is not under active development anymore. There is another project called HIDAPI (http://www.signal11.us/oss/hidapi/) which is even more cross-platform than libhid. Also, if you only need the force_open call, that is pretty easy to pull out of libhid so that you only need libusb.
 
> The joystick is VID/PID d209:0511.  It exposes three separate endpoints, EP 2 IN (0x82) which is the two-axis joystick, EP 1 IN which allows the joystick to sometimes behave as a mouse, and then there is EP 3 IN (0x83) which is evidently the endpoint that needs to be written to in order to configure the stick.

The IN/OUT nomenclature is relative to the host. So your application can only write to OUT endpoints (and EP0, which is bidirectional, and uses usb_control_msg())

> The present version of the application is successful at finding and force_opening the device, but I have a suspicion that it may not be writing to the correct endpoint with this latest firmware release.  The stick manufacturer confirms that they used to use libusb under Windows, but with this latest release they use native Windows functionality to write to the HID device.  They also confirm that EP3 is where the data’s supposed to go.  However, they haven’t been entirely forthcoming with complete documentation of the vendor-specific protocol, but they claim no changes have been made in the actual data that needs to be transmitted to the device.

Is there an EP3 OUT (0x03) endpoint? The output of 'lsusb -vvv -d d209:0511' can help here.

> The existing version of the utility seems to rely on making calls to usb_control_msg() to actually send the data, but the behavior I see now with the latest firmware is that the line I’ve marked below with an arrow always fails with EPIPE, saying that the endpoint is stalled.  (I added some debug prints to my copy of the code to inspect the return values, which the original author was ignoring.)  Unfortunately I’m a little new to USB programming (at least at this level of detail) and am having a little difficulty in translating the calls the original author of the application (now unresponsive) is making into the commands in the USB spec, and therefore, what I would need to change in order to make a hopefully simple change to direct the traffic to endpoint EP 3, (if indeed that is the problem.)
>  
> I’ve included a snippet of the app below, please let me know if there’s something reasonably obvious I can change to ensure that the data goes to the correct endpoint, or whether there is potentially some other avenue of investigation I should be looking at.  I can always email the entire single source file (it’s not very long) if you need to see more, but I think this is really the relevant piece.  I don’t want to rewrite the whole app, I just want to get it basically functional again.  Thanks for any/all help!
>  

In the following excerpt, it looks like the data buffer is being broken up into three chunks. Although you are getting the EPIPE error on the second call, the previous line is sending the 32-byte data blocks. If there is an EP3OUT endpoint, the first usb_control_msg() probably needs to be changed to usb_interrupt_write(). The second one might still be needed for synchronization.

If there is no EP3OUT, another possibility is that the destination bits in requesttype and request might be wrong.

>                                                 for(int i=0;i<3;i++){
>                                                                 usbret = usb_control_msg(hid->dev_handle,0x43,0xEB,0x0000, 0 , data+(32*i), sizeof(data)/3,1000);
>                                                                
> This fails---------------->                  usbret = usb_control_msg(hid->dev_handle,0xC3,0xEA,0x0000, 0 , NULL, 0 ,1000);
>                                                                
>                                                 }
>                                                
>                                                 usbret = usb_control_msg(hid->dev_handle,0x43,0xE9,0x0000, 0 , NULL, 0,1000);


-- 
- Charles Lepple
http://ghz.cc/charles/


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.alioth.debian.org/pipermail/libhid-discuss/attachments/20150324/657722dc/attachment.html>


More information about the libhid-discuss mailing list