I’ve just released v1.0.1 of libusb. It includes a handful of bug fixes and adds a Darwin backend from Nathan Hjelm, meaning that libusb-1.0 applications can now run on Mac OS X too. Other contributors include David Moore and Hans Ulrich Niedermann, plus Peter Stuge is now hosting git and some other bits – thanks!
I have released libusb-1.0.0. libusb is a library which allows you to write applications that interact with USB devices, without the requirement of writing a kernel device driver.
The new libusb-1.0 branch includes new features and improvements over previous versions of the library. Here is a brief run-down, see the release announcement for more details:
- Support for isochronous endpoints.
- Asynchronous I/O for advanced users.
- A simple, synchronous I/O interface also exists (in the style of libusb-0.1).
- Lightweight with very few dependencies
- Thread safety
- Power saving
- Reduced CPU usage and power drain
- Increased USB throughput
- Detailed API documentation
- Compatibility with libusb-0.1 through the libusb-compat-0.1 compatibility layer
I’ve been making good progress on libusb-1.0, which has now entered beta. Features over libusb-0.1 include:
- Asynchronous transfer capabilities (in addition to the synchronous style presented by v0.1)
- Support for transfers to isochronous endpoints
- Significantly faster bulk transfer performance for large transfers (several kilobytes or more)
- Detailed API documentation
- Power saving: on systems running recent Linux kernels, libusb-1.0 does not wake up all the USB devices plugged into the system during device enumeration
- Greatly reduced CPU usage while waiting for results of bulk/interrupt transfers (libusb-0.1 was waking up every 1ms)
- Thread safety
As noted on the homepage, libusb-1.0 is entirely incompatible with libusb-0.1. However, it is designed to install in parallel, in the same way that you can have GTK+ 1.2 and GTK+ 2.x installed on the same system and in use at the same time.
I have also produced a compatibility layer which replaces libusb-0.1. libusb-compat-0.1 looks and smells exactly the same as libusb-0.1 (same library name, API, header file, etc) but internally it just converts libusb-0.1 calls to libusb-1.0.
This means that existing libusb-0.1 applications can take advantage of some of the new libusb-1.0 hotness mentioned above: improved bulk I/O performance, decreased CPU usage, power saving. These improvements appear without any modification to the original application, provided that the user has uninstalled libusb-0.1, and installed libusb-1.0 plus libusb-compat-0.1.
I’m hoping this release will result in:
- More testing and adoption
- API review and feedback
- Ports to other operating systems. Only Linux is supported at the moment, but the library is structured internally for other ports to be written, and the internal API is documented in the source.
Further API changes may happen as a result of the above. This is not a finished product.
The source code for this project has been available on SourceForge from early on (GPL-2/LGPL-2 licenses). I’ve now completed and submitted a comprehensive project report (similar to a dissertation) for academic assessment, and I’m making this available under a Creative Commons license. You can find the report here.
The academic project is now complete, but I plan to continue development as time permits. There is a lot to be done, and I have already made some good progress on moving libusb-1.0 closer to release.
I’ve been a bit quiet on on the fingerprint scanning front recently, but I’ve been doing a lot of work behind the scenes.
Adopted the libusb project
libfprint has had a design flaw from early on: it only provides a synchronous interface. The technical minded will understand this better in terms that each function call to scan a fingerprint blocks for the duration it takes the user to scan their finger. The library could force its users to do fingerprint scanning in a dedicated thread, but that’s not very nice. It could also create threads internally to avoid this problem, but I don’t agree with that either. I know that things can be done properly by providing an asynchronous interface and not requiring any threads.
The biggest roadblock in offering an asynchronous interface from libfprint (and the reason this was not offered from the start) was due to libfprint’s reliance on libusb and the fact that libusb does not offer asynchronous I/O. The result of this is that it is impossible to offer true asynchronous functionality in anything built on top of libusb.
libusb development had unfortunately stalled, and I could not find any alternatives that I was in agreement with. I started writing my own libusb replacement. The original libusb author, Johannes Erdfelt, liked my ideas and this lead to him handing off the libusb project to me. My new USB library will be released as libusb-1.0 when completed.
Making fprint asynchronous
After producing a working prototype of an asynchronous USB library, I converted most fprint drivers to an asynchronous model and exposed an asynchronous API to library users.
I then ported fprint_demo to use the new asynchronous API, which is working well. Another big plus of an asynchronous model is the opportunity to implement cancellation. fprint_demo now has a working “cancel” button which cancels any ongoing fingerprint scan request.
Exposing fprint over D-Bus
Next task on the table was to work towards handling the complicated scenario of when multiple users and/or applications want to be fingerprint scanning simultaneously. Some kind of central entity is needed to coordinate access.
Enter fprintd, my initial step in this direction. fprintd is a D-Bus daemon which exposes fprint functionality over the D-Bus message bus. There are no fprintd users yet, but this will be the approach we take for desktop integration in future.
Assessed project demo
As I mentioned previously, fprint is actually my final year university project and after reaching the stages described above it was time for an assessed demonstration of my project.
The demonstration went extremely well, and I was impressed with the marker who asked exactly the same kinds of questions that I would have done in that situation – which of course I knew the answers to. He also understood the asynchronous issues perfectly despite me not explaining them in detail due to time constraints.
The above development work was all a little rushed in order to have things to show in time for the project demonstration. Now that the demo is over, I am left with an incomplete libusb-1.0 implementation, an unstable libfprint asynchronous API, a new fprint_demo version relying on the unstable API, and an unstable/incomplete D-Bus daemon. All of these are not released (but code is available from public development repositories) so I have some work to do!
I am going to focus now on stabilising from the ground up, starting with the most low-level component – libusb. I’m working through the TODO list and hope to have an alpha or beta release ready within the next few weeks.