CRI Radio

Apr 23, 2007

jUSB

jUSB: Java USB

http://jusb.sourceforge.net/

About jUSB

This project provides a Free Software (and Open Source) Java API for USB, supporting applications using Java host-side software to drive USB devices. Right now it's of most interest to developers, but some basic tools (including jPhoto) have been developed. Read the API FAQ (and other links at left) for more information.

Although the bulk of this code works on any Java platform, access to USB devices currently requires that they be connected to a GNU/Linux host system. Your clients can be on other systems, if you like. The USB Host implementation works on most recent GNU/Linux distributions, either with the Linux 2.4 kernel support, or a backport of that into 2.2.18 kernel (and later). Of course, the 2.5 kernel works too. As one data point, the RedHat 7 distribution has worked without needing any patches or other upgrades.

The usb.core Applications Programming Interface (API) is supported by a Service Provider Interface (SPI) that abstracts implementation details from applications. Getting this software to work on another operating system should just mean writing new code implementing the SPI. Right now, there are two providers: the Linux one, and a preliminary RMI provider. Portions of a Win32 provider have also been written (but not submitted to the project).


News, 17 September 2003 OK, well the jUSB RPMs still aren't updated -- shoot me! But for all of you wanting jUSB/Windows support, there's software (source + binaries) available from Mike Stahl. (The content here isn't yet updated to use that code.)

News, 3 April 2003 We should be getting some updates soon, like an RH 9 RPM. Meanwhile, take a look at jSyncManager, an application using jUSB to synchronize with Palm PDAs.

News, 24 July 2002 Two interesting CVS updates. Win2K/XP starts; first code from Wayne Westerman (of Fingerworks). Adds usb.windows package; its javadoc is online (see link at left). Makefile now calls "uname -s" instead of relying on predefined symbol du-jour, so it builds on RedHat 7.3 and presumably many other systems (SuSE too).

News, 22 March 2002 Nothing much new to report, except that after a year or so the 2.4.19 prepatches (and 2.5.7 of course :) have the EHCI driver needed to support USB 2.0 device access. And yes, USB 2.0 devices are finally happening!

News, 14 February 2001 New 0.4.4 release from CVS, including initial USB 2.0 support.

News, 3 January 2001 CVS has some bugfixes to the RMI support, and also fixes some bugs in accessing interface descriptors.

Build Notes

If you get the latest (source) release, you should be able to extract it into your working directory and just type "make all", assuming you've got "javac" in your $PATH (from the JDK, Kaffe, etc). (If you're not using JDK 1.2 or later, you might want to move the "apidoc" directory, since you won't be able to recreate it.)

You may need more current code, though. That will call for building from CVS. Go to the project's CVS page and follow the instructions there to get a copy of the jUSB CVS tree; use the module ".". For anonymous CVS, that's something like:

bash$ mkdir jusb
bash$ cd jusb
bash$ cvs -d:pserver:anonymous@cvs.jusb.sourceforge.net:/cvsroot/jusb login
bash$ cvs -z3 -d:pserver:anonymous@cvs.jusb.sourceforge.net:/cvsroot/jusb co .
bash$ make all
...
bash$

Then to test your build, try "make show" (gives an XML dump of your USB bus contents) or "make viewer" (pops up a simple Swing tree viewer that knows about some devices).

C/C++ API

C/C++ developers can use this software if they're working with current (GCC 2.96 or later) versions of GCC, which includes GCJ. GCJ defines "CNI", and maps Java classes to machine code much like the corresponding C++ classes. One snapshot of these APIs is provided below.

These APIs exactly mirror the Java usb.core API, and the Java API specification is definitive. As always, bootstrap using the HostFactory and use only the APIs (not SPIs!) visible from there.

Interfaces in the API include:

Classes in the API include:

Exceptions in the API include:

Note that these particular APIs represent a snapshot for one version of the jUSB core APIs, which may not match the specific version you're using. With CNI, such issues are handled the conventional way, except for classes downloaded at runtime. (Those classes are interpreted.))

Use these headers only for reference about how the Java APIs are exposed to C/C++ programs by CNI, using the GNU Compiler Collection (GCC) runtime environment. You'll notice that the C/C++ compiler will let you call some protected and package-private methods as if they were declared as "public". Don't do that; it violates the API just like if you did a #define private public for any normal C++ program.

API FAQ

Last updated 14 Feb 2002

Background

Who should be interested in this Java USB techology?
Developers and systems designers/implementors who want to use USB, whether from Java or from C/C++. Even some end users, but they'll mostly want the tools that can be built with this software.
Where should I start reading? I want my Java application to use this USB device.
See the device support to learn about support for many common device classes. The usb.core package description (javadoc) shows what you currently would work with if no existing driver works for you from Java.
Where do I browse Javadoc? CVS?
Follow the links to Javadoc or CVS ... the code is most current. Regenerate current javadoc from a CVS child of some kind.

Implementation

How do these Java APIs work, inside?
The API is defined in terms of interactions and descriptors found in the USB specification. Underneath the API is an SPI (Service Provider Interface) that permits most of the code to be shared. There are two SPI implementations: usb.linux is a small JNI wrapper around ioctl()s to usbdevfs; and usb.remote is a remote access mechanism, using RMI. So the API has nothing that's Linux-specific.
Can I use this to talk to devices connected to Win32, Macintosh, or other UNIX?
Not at this time; those would need new SPI implementations. USB itself doesn't change on different operating systems, so the Java APIs (derived from basic USB functionality) won't need to change much if at all. It seems like a FreeBSD port might be quite straightforward in at least some respects.
Can I use this from inside my Pocket Linux, Handheld PC/PDA (iPaq, Sharp, Toshiba, Yopy, ...) or other embedded device?
I encourage smart-enough clients (like PDAs) to offer a TCP/IP network interface instead of proprietary protocols. (The current ARM Linux tree has such support for the SA-1100, as found in some higher end PDAs. Such devices can talk to hosts using the kernel's "usbnet" driver, or similar.) Mainstream Linux doesn't have generic "from USB device" APIs yet, it currently only has "from USB host" APIs. But if you have a particular protocol you need to implement, and the device has USB host functionality, this API supports you. (You'd likely use JVMs such as J9, Kaffe, or KVM for now. GCJ is quickly becoming another option.)

Interfaces

Are there standard APIs (Java, C, ...) for this stuff?
No, which is a good thing in the big picture. USB is early in its adoption curve (look how long a lifespan its predecessor RS-232 has had!) and people are still learning and experimenting. Most API solutions are OS-specific, and are "inside" OS kernels; Linux is ahead of of commercial Unixes in that particular area.
Is this part of Sun's "Java Community Process", for creating a (second) Java USB API?
No; Sun's process requires signing intellectual property over to them, which doesn't work well when that property is covered by the (L)GPL (with its more flexible change control policies). The eventual result of Sun's process "ought to" be usable to make a service provider under this API; this API, as Free Software, can be around for as long as needed. (It was around for about a year before the JSR started its closed-door process.) Because Sun's Java processes and licensing aren't (L)GPL-friendly, the Free Java community (and many parts of the Open Java community) will need a better base -- such as this original software. (See the Apache Group position on some flaws of the Java "Community" Process. Of course, while allowing the Apache license supports Open Source software, it does not facilitate Free Software for Java.)

NEWS FLASH 19-July-2001: The first public review draft of the JSR-80 spec is out. As expected: the code will not be licenced under the (L)GPL, and so doesn't help the Free Java community. The API is unnecessarily large and complex. Not as expected: there's no Win32 code, it's essentially trying to be an alternative to this code, even down to starting a project on an IBM-customized SourceForge. (Eventually to be seeded by code developed behind the JCP process' closed doors.) Curiouser and curiouser ... not something that can ever be taken as supporting the Free Software model of the GNU/Linux community. It's the Microsoft model of development: come in after innovators show the way, then apply market power.
Can I use C/C++?
Yes, you can call this API from C/C++ with GCJ and CNI, which are Free Java technologies. See the CNI binding (not current); use javadoc as the API specification, since those headers expose implementation details. CNI works by calling Java methods like C++ methods. This approach mixes the benefit of a good USB package with the costs of a new (GCC 2.96 or later) compiler and runtime system. If you can't use that recent compiler, try the 'libusb' package (see the links page). Also, see the GCC web site for information about the GCC 3.x releases, which make Free Java GCJ technology much more widely available. At this writing, GCC 3.0 has been released, but has not not yet been incorporated as standard in any GNU/Linux OS releases.

Functionality

Can this be simpler?
Suggestions appreciated; the problem itself is complex. Simple devices can have simple APIs, as layers; see the usb.util.USBSocket class for one example. Many USB devices should automatically work with existing APIs for their types of device; if those aren't simple, it's not a USB issue! Complex devices generally require APIs with layers to mask their complexity. USB devices are no exception; look at the jPhoto work for one such layer, and some tools using it.
Does this API access USB devices across a network?
There's a preview available, supporting RMI access. IIOP should of course be another protocol option (using RMI-IIOP tools); using only JRMP would clearly create interop problems. The preview works for at least pure "client mode" usage. The usb.core.Host is still the bootstrap object; the HostFactory will return a USB Host proxy if one is registered locally. Set up the "USB Daemon" on a host (GNU/Linux for now, using a port of Sun's JVM), to register such a host proxy locally. You'll need to manually look up the proxy for that USB host to use it from another machine, or import its object reference to your local machine's registry.
Can I use this with USB 2.0 devices?
Yes, if you install the EHCI host controller driver. It's included in the 2.5 kernels, and a version is also available for 2.4.17 and later. Information about that "ehci-hcd" host controller driver is at linux-usb.org. From the API perspective, not much changed. USB 2.0 is mostly faster (480 Mbit/s top speed vs 12 Mbit/s), as shown through a "high speed" hub status bit. You can also ask USB 2.0 devices what features they could expose when run at another speed (high speed vs full speed, or the other way around). Root hub port identifiers may behave a bit differently, since the same physical port can be switched between the EHCI controller or a companion (often OHCI) controller.
Can I use a userspace driver (in Java) to talk to a device that some kernel driver has grabbed?
A kernel patch has been posted; if you apply that patch, this driver will claim devices whether or not another driver did so already. Your application should check whether the driver is busy. (That specific security policy is subject to change.)
Can I use this with interrupt transfers?
Not yet. Interrupt transfers are intended to be periodic, but there's no good way to pass periodic IN (device to host) transfers to user mode programs. Unfortunately this is an area where the host controller drivers don't behave consistently either, so even periodic OUT (host to device) transfers have problems. This is likely to be addressed in the 2.5 kernels at some point.