Skip to content

Linux Implementation

Manuel Bleichenbacher edited this page Oct 24, 2022 · 4 revisions

The Linux implementation is the simplest of all implementations as the Linux API are the easiest to use.

Also see Linux reference code.

Device enumeration and monitoring

For the device enumeration and monitoring, the libudev functions are used. The library is straight-forward to use, both because it provides the necessary features and because the API is built for use in C and is a good match for Java's Foreign Function & Memory API.

libudev is officially deprecated. The replacement is libsystemd. But it seems that libsystemd isn't as widely available as libudev. A migration to libsystemd is planned and will be straight-forward as the two libraries have a very similar API.

The biggest issue with libudev and libsystemd is the lack of documentation. There are a few man pages. But they are very limited.

Background thread

The background thread on Linux is very simple as well. libudev provides a file descriptor for the monitor. So the background thread can simply use poll() to wait for the next monitor event.

Descriptive information

Linux does not provide any APIs to query any descriptive information about interfaces and endpoints. There are two options. The first option would be to read the pseudo-files in /sys/bus/usb/devices/n-n.n. It is quite cumbersome and would require many file operations.

The second and chosen option is to read all data from the USB device's file path (returned by libudev). It's a concatenation of the device descriptor and configuration descriptor. The descriptors are then parsed by this library (see net.codecrete.usb.common.ConfigurationParser). The configuration parser is needed anyway on Windows to learn about the interface associations and functions.

Device communication

Device communication is straight-forward as well as the API is very similar to the one used by this library. A device needs to be opened. Then ioctl() can be used to claim interfaces and communicate with endpoints. Timeouts is provided out-of-the-box.

The USB ioctl() requests are named like USBDEVFS_xxx and are documented towards the bottom of The Linux-USB Host Side API.

errno

The Linux implementation suffers from a limitation of the current Foreign Function & Memory API: errno can be overwritten by the JVM. It's quite rare but happens nevertheless. Some error handling has been disabled until the API has been enhanced accordingly.

Clone this wiki locally