Skip to content

Latest commit

 

History

44 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 

Repository files navigation

USBTransferThread

High performance data exchange via USB for Java, using a thread and the usb4java library.

This is the SensorsINI continuation of Luca Longinotti / iniVation USBTransferThread (BSD-2-Clause). Last upstream tag: 0.9.8 (December 2020). SensorsINI 0.9.9 catches submit failures in run() so they are not uncaught.

jAER uses a frozen jar from this project (jars/USBTransferThread-*.jar). Keep the li.longi.USBTransferThread package name so existing AEReaders keep compiling.

Purpose of this mirror

iniVation stopped at 0.9.8. jAER could not patch the jar, so AEReaders wrapped start/stop around it. The main reason for this GitHub continuation is those uncaught IllegalStateExceptions from failed LibUsb.submitTransfer (missing endpoint after hotplug, gone device, stall, I/O). They killed USBTransferThread without reaching the shutdown callback, so the viewer could show LIVE with a dead reader. 0.9.9 catches that in run(), records getStartFailure(), and exits so join() returns.

Build

Requires JDK 25 (same as jAER javac target 25) and Maven 3.9+.

mvn -DskipTests package

The jar is target/USBTransferThread-0.9.9.jar. Drop that file into jAER jars/ and point NetBeans file.reference.USBTransferThread-*.jar at it. mvn deploy is not required for jAER.

Usage

This library does not replace usb4java. usb4java already does device open, control transfers, and both sync and async I/O. The aim here is high-throughput streaming on bulk and interrupt endpoints: keep several transfers in flight (overlapped / pipelined async I/O) and run libusb’s event loop on a dedicated max-priority thread, so processing and the rest of the JVM do not stall the USB pipe.

usb4java still owns open/claim. USBTransferThread owns the streaming loop: allocate a pool of Transfers, submit them, handleEvents, resubmit after processTransfer, set the IN buffer limit to the bytes received, and cancel/free on interrupt(). A blocking LibUsb.bulkTransfer on the viewer thread cannot do that.

Open the device with usb4java (LibUsb.init, open handle, claim the interface). Implement RestrictedTransferCallback:

  • prepareTransfer — fill the buffer for OUT transfers (no-op for IN).
  • processTransfer — read status(), actualLength(), and buffer() after each completion. Successful IN transfers have the buffer limit set to the bytes received.

Construct USBTransferThread with the DeviceHandle, endpoint address, transfer type (LibUsb.TRANSFER_TYPE_BULK or TRANSFER_TYPE_INTERRUPT), and the callback. Optional arguments: buffer count and size (defaults 16 × 8192 bytes; pass 0 for a default), then optional setup / shutdown / exceptional-shutdown Runnables and a libusb Context. Call start(). If submit fails (LIBUSB_ERROR_NOT_FOUND and similar), the thread exits after deallocateTransfers; join() returns and getStartFailure() holds the IllegalStateException. Change pool size later with setBufferNumber / setBufferSize. Stop with interrupt() then join().

See src/test/java/li/longi/USBTransferThread/USBTransferThreadTest.java for a full IN bulk example. jAER AEReaders follow the same pattern.

About

High-performance Java USB async transfers (usb4java). SensorsINI continuation of Luca Longinotti / iniVation USBTransferThread.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages