hidapi icon indicating copy to clipboard operation
hidapi copied to clipboard

Invalid usage_page values in Linux

Open tresf opened this issue 6 years ago • 12 comments

I have a Honeywell 1400g barcode scanner which identifies itself as:

Vendor Product Serial
0x0c2e 0x0b87 17338B352C

It has two endpoints:

Endpoint 1 Endpoint 2
UsagePage -116 140

On Windows and MacOS, I can use UsagePage to distinguish between the two. We toss out the -116 and keep the 140 and we have the proper device and can read HID data from it.

Unfortunately, the two endpoints are causing trouble when claiming the device in Linux: both UsagePage values return zero.

The source of hid.c makes this appear intentional:

/* Uncomment to enable the retrieval of Usage and Usage Page in
hid_enumerate(). Warning, on platforms different from FreeBSD
this is very invasive as it requires the detach
and re-attach of the kernel driver. See comments inside hid_enumerate().
libusb HIDAPI programs are encouraged to use the interface number
instead to differentiate between interfaces on a composite HID device. */
/*#define INVASIVE_GET_USAGE*/

Although the documentation recommends to use interface number, for the hardware I'm testing on, interface number is the same between devices. How do other users handle edge-cases where HID returns two device matches on the same physical device on Linux?

tresf avatar Mar 21 '18 05:03 tresf

It sounds like you're using the 'libusb' driver on Linux.
The libusb Linux driver does not have usage and usagePage properties, but the hidraw Linux driver does. You should be able to switch the driver for your app and have it still work.

Note you'll need to change your udev rules if you're using those, swapping KERNEL=="hidraw*" for SUBSYSTEM=="usb".

todbot avatar Mar 21 '18 06:03 todbot

@todbot yes, I believe I am. I'm using it indirectly through a third party, so I'll have to see if switching is an option. Thanks.

tresf avatar Mar 21 '18 20:03 tresf

The hid4java's build process is pretty foreign to me. I can't see how hidapi is even being compiled from the docs for hid4java, making me think he hand-compiles them and then copies them over.

If that's the case, I would try hand-compiling hidapi and copying the file yourself. The README gives how to do that, but in summary, on Linux it would be:

sudo apt-get install libudev-dev autotools-dev autoconf automake libtool build-essential
git clone https://github.com/signal11/hidapi
cd hidapi
./bootstrap
./configure --prefix=${HOME}/hidapi_tmp
make 
make install

And then you'll have a libhidapi_tmp/lib/libhidapi-hidraw.so.0.0.0 file.
Copy that file on top of the file hid4java/src/main/resources/linux-x86/libhidapi.so

todbot avatar Mar 21 '18 21:03 todbot

@todbot thanks kindly for this information! What's not immediately obvious is why the libusb-1.0-0, libusb-1.0-0-dev are left out... or more specifically... how to build without them. How does the build system know to use hidraw, or does the target provide both when done?

tresf avatar Mar 22 '18 01:03 tresf

does the target provide both when done?

Answering my own question, libusb-1.0-0 libusb-1.0-0-dev required and yes, both libraries are built.

@todbot I have to thank you for going out of your way to look into the 3rd party library, that's very kind.

So I've replaced /linux-x86-64/libhidapi.so in hid4java-0.5.0.jar with libhidapi-hidraw.so.0.0.0 and I can confirm that UsagePage is returned, but there's some disparity...

Endpoint 1 Endpoint 2
MacOS UsagePage -116 140
Windows UsagePage -116 140
Linux UsagePage 0 14776

Is there some translation that can be used to map these values to each other? Grabbing at straws here. :)

Note you'll need to change your udev rules if you're using those, swapping KERNEL=="hidraw*" for SUBSYSTEM=="usb"

We've been using SUBSYSTEM=="usb" historically. For some odd reason, this machine works (standard user, not root) without the rules I usually install. It's running VirtualBox VM with Guest Additions, device attached as same user.

ubuntu@ubuntu1404:~$ cat /etc/udev/rules.d/*.rules 
# libusb device access
SUBSYSTEM=="usb_device", ACTION=="add", RUN+="/usr/bin/killall -sUSR1 portcommunicationserviced"
SUBSYSTEM=="usb_device", ACTION=="remove", RUN+="/usr/bin/killall -sUSR2 portcommunicationserviced"
SUBSYSTEM=="usb", ACTION=="add", ENV{DEVTYPE}=="usb_device", RUN+="/usr/bin/killall -sUSR1 portcommunicationserviced"
SUBSYSTEM=="usb", ACTION=="remove", ENV{DEVTYPE}=="usb_device", RUN+="/usr/bin/killall -sUSR2 portcommunicationserviced"
KERNEL=="vboxguest", NAME="vboxguest", OWNER="vboxadd", MODE="0660"
KERNEL=="vboxuser", NAME="vboxuser", OWNER="vboxadd", MODE="0666"

tresf avatar Mar 22 '18 04:03 tresf

Tested UsagePage on physical hardware (identical OS, NOT in a VM) and received different and even less useful results:

Endpoint 1 Endpoint 2
MacOS UsagePage -116 140
Windows UsagePage -116 140
Linux UsagePage (VM) 0 14776
Linux UsagePage (Physical) 18432 18432

tresf avatar Mar 22 '18 04:03 tresf

I could solve the problem of zero values by moving to hidraw. However, I now receive odd/incorrect numbers.

@tresf Could you find a solution to this problem? I have seeing something similar. Actually, same device, same host, different libraries show the following:

If I use https://github.com/flynn/hid path: /dev/hidraw5 VendorID : 0x2c97 UsagePage : 0xffa0

However, when I use a library that is signal11 based:

path: "/dev/hidraw5", vendor_id: 0x2c97, usage_page: 0x0032

jleni avatar Aug 05 '18 12:08 jleni

Unfortunately no. We (my project) simply cannot support this type of hardware on Linux using the hidapi library.

tresf avatar Aug 05 '18 16:08 tresf

it seems to me that the usage_page is not even set and the values we are seeing are some left over.

https://github.com/signal11/hidapi/blob/a6a622ffb680c55da0de787ff93b80280498330f/linux/hid.c#L479-L555

jleni avatar Aug 09 '18 08:08 jleni

Actually, it seems that here is a dead PR with the fix:

https://github.com/signal11/hidapi/pull/6

It is unfortunate that the project has no activity since 2016

jleni avatar Aug 09 '18 08:08 jleni

@tresf would you mind renaming the issue to: "Invalid usage_page values in Linux" ?

jleni avatar Aug 09 '18 08:08 jleni

@tresf would you mind renaming the issue to: "Invalid usage_page values in Linux" ?

Done.

tresf avatar Aug 09 '18 13:08 tresf