This is an extension to usb4java and implements javax-usb using the libusb wrapper provided by usb4java as backend.
For more detailed information please visit the usb4java website.
javax.usb extension for usb4java
Home Page: http://usb4java.org/
License: MIT License
This is an extension to usb4java and implements javax-usb using the libusb wrapper provided by usb4java as backend.
For more detailed information please visit the usb4java website.
Hi, using following code:
UsbPort port = usbDevice.getParentUsbPort();
System.out.println("Connected to port: " + port.getPortNumber());
System.out.println("Parent: " + port.getUsbHub());
I can dump some basic info about the device connection. However, I need to know the physical location of the device. I can see it in dmesg:
[ 1415.390194] usb 1-1.2: Manufacturer: SanDisk
Attaching the device to another port prints
[ 1415.390194] usb 1-1.4: Manufacturer: SanDisk
So how do I retrieve the physical address 1-1.4
using usb4java-javax? The code above always prints the same port information, even when switching the ports.
See also this thread on StackOverflow.
What is the problem
We use usb4java-javax in our Java app to receive events and it works.
But sometimes, the app receives events and suddenly not receiving any events at all from usb4java even though device is plugged and unplugged
Environment
Java version: 1.8
usb4java version: 1.3.0
OS: Windows7
Note
Sporadically we run into an issue where usbDevice.getActiveUsbConfiguration();
returns null.
The code was run on a virtual machine. Mostly, this issue occurs when the program is started on a PC without hardware & then the session is switched to a PC with the hardware.
hub.getAttachedUsbDevices()
private UsbConfiguration getUsbConfiguration() {
UsbConfiguration config = null;
if (usbDevice == null) {
LOGGER.warn("The usbDevice is null!");
return null;
}
synchronized (usbDevice) {
config = usbDevice.getActiveUsbConfiguration();
if (config != null) {
return config;
}
List<UsbConfiguration> configs = getUsbDevice().getUsbConfigurations();
if (!configs.isEmpty()) {
for (UsbConfiguration temp : configs) {
LOGGER.debug("UsbConfiguration:: {} \tis active: {} \tdevice: {}",
temp.toString(), temp.isActive(), temp.getUsbDevice());
}
config = configs.get(0);
}
return config;
}
}
This is what we observe, when the above code runs following the issue:
in the first step, we see the device we need to communicate.
once we are in the last step to get a USB Configuration:
getActiveUsbConfiguration()
also returns null.getUsbConfigurations()
we can get hold of a UsbConfiguration
. However, when we try to claim
the usbInterface again, we end up with the following exception: java.util.concurrent.CompletionException: javax.usb.UsbNotActiveException: Pipe is not active.
While running usb4java-javax-example DumpNames
I get an overflow error while reading manufacturer and product name.
The problems happens in LibUsb.getDescriptor()
called by AbstractDevice#getLanguages()
, but when I ignore this overflow (using language 0) a similiar error happens on AbstractDevice#getUsbStringDescriptor().
I tried to increase the ByteBuffer allocation, but this does not help.
C:\ws\github\usb4java-javax-examples>java -cp target\usb4java-javax-examples-1.0.0-SNAPSHOT.jar;c:\users\eckenfel\.m2\repository\org\usb4java\libusb4java\1.2.0\libusb4java-1.2.0-windows-x86_64.jar;c:\Users\eckenfel\.m2\repository\org\usb4java\usb4java-javax\1.2.1-SNAPSHOT\usb4java-javax-1.2.1-SNAPSHOT.jar;c:\users\eckenfel\.m2\repository\javax\usb\usb-api\1.0.2\usb-api-1.0.2.jar;C:\users\eckenfel\.m2\repository\org\usb4java\usb4java\1.2.0\usb4java-1.2.0.jar;C:\users\eckenfel\.m2\repository\org\apache\commons\commons-lang3\3.1\commons-lang3-3.1.jar org.usb4java.javax.examples.DumpNames
USB Service Implementation: usb4java
Implementation version: 1.2.0
Service API version: 1.0.2
Ignoring problematic device: Bus 001 Device 005: ID 1050:0120
javax.usb.UsbPlatformException: USB error 8: Unable to get string descriptor languages: Overflow
at org.usb4java.javax.ExceptionUtils.createPlatformException(ExceptionUtils.java:39)
at org.usb4java.javax.AbstractDevice.getLanguages(AbstractDevice.java:544)
at org.usb4java.javax.AbstractDevice.getUsbStringDescriptor(AbstractDevice.java:507)
at org.usb4java.javax.AbstractDevice.getString(AbstractDevice.java:526)
at org.usb4java.javax.examples.DumpNames.dumpName(DumpNames.java:53)
at org.usb4java.javax.examples.DumpNames.processDevice(DumpNames.java:87)
at org.usb4java.javax.examples.DumpNames.processDevice(DumpNames.java:75)
at org.usb4java.javax.examples.DumpNames.processDevice(DumpNames.java:75)
at org.usb4java.javax.examples.DumpNames.main(DumpNames.java:122)
I can work around this with ignoring the Overflow:
if (result == LibUsb.ERROR_OVERFLOW) return new short[0];
Ignoring problematic device: Bus 001 Device 005: ID 1050:0120
javax.usb.UsbPlatformException: USB error 8: Unable to get string descriptor 1 from device Bus 001 Device 005: ID 1050:0120: Overflow
at org.usb4java.javax.ExceptionUtils.createPlatformException(ExceptionUtils.java:39)
at org.usb4java.javax.AbstractDevice.getUsbStringDescriptor(AbstractDevice.java:515)
at org.usb4java.javax.AbstractDevice.getString(AbstractDevice.java:526)
at org.usb4java.javax.examples.DumpNames.dumpName(DumpNames.java:53)
at org.usb4java.javax.examples.DumpNames.processDevice(DumpNames.java:87)
at org.usb4java.javax.examples.DumpNames.processDevice(DumpNames.java:75)
at org.usb4java.javax.examples.DumpNames.processDevice(DumpNames.java:75)
at org.usb4java.javax.examples.DumpNames.main(DumpNames.java:122)
NB: using DumpDevices if usb4java-examples works with the device (it is using getStringDescriptorAscii
). It looks like:
Device 001/005
Connected to port: 2
Parent: 001/002
Speed: Full
Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 2.00
bDeviceClass 0 Per Interface
bDeviceSubClass 0
bDeviceProtocol 0
bMaxPacketSize0 64
idVendor 0x1050
idProduct 0x0120
bcdDevice 3.32
iManufacturer 1 Yubico
iProduct 2 Security Key by Yubico
iSerial 0
bNumConfigurations 1
...
This is on Win7 (german, 64bit) with the Yubico security-key (HID) and 64bit Java7U72.
I have added property file but still it is showing error that property file not found. Any solution for this?
and in the property file it is showing warning that MISSPELLED WORD
javax.usb.services = org.usb4java.javax.Services (this is what i am writing in property file)
Yes the file is in the same package i am using netbeans on linux
Ignoring problematic device: javax.usb.UsbPlatformException: USB error 5: Can't open device Bus 001 Device 002: ID 0c45:64ce: Entity not found
Ignoring problematic device: javax.usb.UsbPlatformException: USB error 1: Can't open device Bus 002 Device 003: ID 046d:c077: Input/Output Error
Ignoring problematic device: javax.usb.UsbPlatformException: USB error 5: Can't open device Bus 002 Device 004: ID 0a5c:5800: Entity not found
In practice AbstractIrpQueue spawns a new thread whenever an Irp is added. For asyncSubmit this makes a little sense, though reusing the a single thread per pipe would be a lot better. For the syncSubmit usecase it makes no sense to do this. It is very resource intense. By making the following modification I was able to increase performance by a factor of 10x.
public final void add(final T irp)
{
this.irps.add(irp);
// Start the queue processor if not already running.
// if (this.processor == null)
// {
// this.processor = new Thread(new Runnable()
// {
// @Override
// public void run()
// {
process();
// }
// });
// this.processor.setDaemon(true);
// this.processor.setName("usb4java IRP Queue Processor");
// this.processor.start();
// }
}
When using syncSubmit an Irp is added to the queue, and the processor thread is started, when the processor finishes executing the Irp the thread is destroyed again. Meanwhile the syncSubmit thread is waiting. A cleaner solution might be to wait() the processor thread until a new irp is added. That would work for asyncSubmit too. But is not relevant for my usecase.
I'm using usb4java 1.2.0 with a full-speed USB device that I'm developing.
When using the low-level libusb API, I am able to achieve throughput speeds near the theoretical maximum for a full-speed bulk endpoint (1114.112 KB/s).
If I switch to the high-level javax.usb API, my throughput drops by an amount that appears to depend not just on the machine I'm using, but on the port I'm connected to. I always see performance penalties of at least 50%.
I've developed a simple benchmarking tool. The device side reads a 4-byte network-byte-order integer from an OUT endpoint, then transmits that many bytes of garbage on an IN endpoint.
The low-level and high-level usb4java benchmark code is inlined below.
On one port on my development machine, I get the following results:
org.usb4java API benchmark
Writing header
4 bytes sent
Reading 1048576 bytes
1048576 bytes received
1048576 bytes in 1021 ms, 1002.9382957884428 KB/s
javax.usb API benchmark
Writing header
4 bytes sent
Reading 1048576 bytes
1048576 bytes received
1048576 bytes in 2311 ms, 443.09822587624404 KB/s
On another port, I get these results:
org.usb4java API benchmark
Writing header
4 bytes sent
Reading 1048576 bytes
1048576 bytes received
1048576 bytes in 971 ms, 1054.5829042224511 KB/s
javax.usb API benchmark
Writing header
4 bytes sent
Reading 1048576 bytes
1048576 bytes received
1048576 bytes in 16538 ms, 61.91800701414923 KB/s
As you can see, the performance hit is 56% on one port, and 94%(!) on the other.
I have seen this performance penalty on Windows 7 64-bit and Ubuntu Linux 32-bit and 64-bit.
UsbBench.java:
import org.usb4java.*;
import java.nio.*;
import java.io.*;
public class UsbBench
{
public static final short idVendor = (short)0x03eb;
public static final short idProduct = (short)0x2423;
public static final byte ifaceId = (byte)0x00;
public static final byte outEp = (byte)0x02;
public static final byte inEp = (byte)0x81;
public static final int timeout = 60000;
public static void main(String args[])
throws Exception
{
int result;
DeviceHandle handle;
int size = Integer.parseInt(args[0]);
ByteArrayOutputStream headerStream = new ByteArrayOutputStream();
DataOutputStream out = new DataOutputStream(headerStream);
out.writeInt(size);
byte[] header = headerStream.toByteArray();
result = LibUsb.init(null);
if (result != LibUsb.SUCCESS) throw new LibUsbException("Unable to initialize libusb.", result);
handle = findDevice(idVendor, idProduct);
if (handle == null) throw new RuntimeException("Device not found");
try {
result = LibUsb.claimInterface(handle, ifaceId);
if (result != LibUsb.SUCCESS) throw new LibUsbException("Unable to claim interface", result);
ByteBuffer buffer = ByteBuffer.allocateDirect(header.length);
buffer.put(header);
IntBuffer transfered = IntBuffer.allocate(1);
System.out.printf("Writing header\n");
result = LibUsb.bulkTransfer(handle, outEp, buffer, transfered, timeout);
if (result != LibUsb.SUCCESS) throw new LibUsbException("Bulk transfer failed", result);
System.out.printf("%d bytes sent\n", transfered.get());
buffer = ByteBuffer.allocateDirect(size);
transfered = IntBuffer.allocate(1);
System.out.printf("Reading %d bytes\n", size);
long start = System.currentTimeMillis();
result = LibUsb.bulkTransfer(handle, inEp, buffer, transfered, timeout);
long time = System.currentTimeMillis() - start;
if (result != LibUsb.SUCCESS) throw new LibUsbException("Bulk transfer failed", result);
int rx = transfered.get();
System.out.printf("%d bytes received\n", rx);
System.out.printf("%s bytes in %s ms, %s KB/s\n",
rx, time, (rx / (time / 1000.0)) / 1024.0);
}
finally
{
LibUsb.releaseInterface(handle, ifaceId);
LibUsb.close(handle);
LibUsb.exit(null);
}
}
private static DeviceHandle findDevice(short vendorId, short productId)
{
// Read the USB device list
DeviceList list = new DeviceList();
int result = LibUsb.getDeviceList(null, list);
if (result < 0) throw new LibUsbException("Unable to get device list", result);
try
{
// Iterate over all devices and scan for the right one
for (Device device: list)
{
DeviceDescriptor descriptor = new DeviceDescriptor();
result = LibUsb.getDeviceDescriptor(device, descriptor);
if (result != LibUsb.SUCCESS) throw new LibUsbException("Unable to read device descriptor", result);
if (descriptor.idVendor() == vendorId && descriptor.idProduct() == productId)
{
DeviceHandle handle = new DeviceHandle();
result = LibUsb.open(device, handle);
if (result != LibUsb.SUCCESS) throw new LibUsbException("Unable to open USB device", result);
return handle;
}
}
}
finally
{
// Ensure the allocated device list is freed
LibUsb.freeDeviceList(list, true);
}
// Device not found
return null;
}
}
UsbBenchJavax:
import javax.usb.*;
import java.io.*;
import java.util.*;
public class UsbBenchJavax
{
public static final short idVendor = (short)0x03eb;
public static final short idProduct = (short)0x2423;
public static final byte ifaceId = (byte)0x00;
public static final byte outEp = (byte)0x02;
public static final byte inEp = (byte)0x81;
public static void main(String[] args)
throws Exception
{
int size = Integer.parseInt(args[0]);
ByteArrayOutputStream headerStream = new ByteArrayOutputStream();
DataOutputStream out = new DataOutputStream(headerStream);
out.writeInt(size);
byte[] header = headerStream.toByteArray();
UsbServices services = UsbHostManager.getUsbServices();
UsbDevice usbdev = findDevice(services.getRootUsbHub(),
idVendor, idProduct);
UsbConfiguration config = usbdev.getActiveUsbConfiguration();
UsbInterface iface = config.getUsbInterface(ifaceId);
UsbPipe inPipe = iface.getUsbEndpoint(inEp).getUsbPipe();
UsbPipe outPipe = iface.getUsbEndpoint(outEp).getUsbPipe();
iface.claim();
inPipe.open();
outPipe.open();
System.out.printf("Writing header\n");
int tx = outPipe.syncSubmit(header);
System.out.printf("%d bytes sent\n", tx);
byte[] buffer = new byte[size];
System.out.printf("Reading %d bytes\n", size);
long start = System.currentTimeMillis();
int rx = inPipe.syncSubmit(buffer);
long time = System.currentTimeMillis() - start;
System.out.printf("%d bytes received\n", rx);
System.out.printf("%s bytes in %s ms, %s KB/s\n",
rx, time, (rx / (time / 1000.0)) / 1024.0);
}
@SuppressWarnings("unchecked")
private static UsbDevice findDevice(UsbHub hub,
short idVendor, short idProduct)
throws UsbException
{
for (UsbDevice device : (List<UsbDevice>) hub.getAttachedUsbDevices())
{
UsbDeviceDescriptor desc = device.getUsbDeviceDescriptor();
if (desc.idVendor() == idVendor && desc.idProduct() == idProduct)
return device;
if (device.isUsbHub())
{
device = findDevice((UsbHub) device, idVendor, idProduct);
if (device != null) return device;
}
}
return null;
}
}
I tried to run the javax DumpDevices.java example application. I am getting Properties file javax.usb.properties not found error. But I have created the file in the same path. The structure of the directory, content of the file and Java version all are shared below.
mintty> ls -l
total 8
-rw-r--r-- 1 Dinesh Administrators 2739 Apr 29 20:10 DumpDevices.class
-rw-r--r-- 1 Dinesh Administrators 3355 Apr 29 20:10 DumpDevices.java
-rw-r--r-- 1 Dinesh Administrators 49 Apr 29 20:11 javax.usb.properties
mintty>
mintty> cat javax.usb.properties
javax.usb.services = org.usb4java.javax.Services
mintty>
mintty> java DumpDevices
Exception in thread "main" javax.usb.UsbException: Properties file javax.usb.properties not found.
at javax.usb.UsbHostManager.setupProperties(Unknown Source)
at javax.usb.UsbHostManager.getProperties(Unknown Source)
at javax.usb.UsbHostManager.createUsbServices(Unknown Source)
at javax.usb.UsbHostManager.getUsbServices(Unknown Source)
at DumpDevices.main(DumpDevices.java:94)
mintty> java -version
java version "1.8.0_66"
Java(TM) SE Runtime Environment (build 1.8.0_66-b18)
Java HotSpot(TM) Client VM (build 25.66-b18, mixed mode)
mintty> javac -version
javac 1.8.0_66
mintty>
First of all thank you for brilliant wrapper above genius libusb library. But I faced some problems when trying to monitor usb devices - I need physical bus and port on which new device is connected. Something like:
@Override
public void usbDeviceAttached(UsbServicesEvent event) {
DeviceId deviceId = ((AbstractDevice) event.getUsbDevice()).getId();
}
But AbstractDevice
is package local! So are Hub
and NonHub
, so I can not call methods like getId()
or getParentId()
which are public!
Does usb4java support USB isochronous transfer mode ?
If not, is there a plan to include this support ?
I tried to use it but it gave me this error:
javax.usb.UsbException: Unsupported endpoint type: 1
at org.usb4java.javax.IrpQueue.transfer(IrpQueue.java:205)
at org.usb4java.javax.IrpQueue.read(IrpQueue.java:126)
at org.usb4java.javax.IrpQueue.processIrp(IrpQueue.java:76)
at org.usb4java.javax.AbstractIrpQueue.process(AbstractIrpQueue.java:104)
at org.usb4java.javax.AbstractIrpQueue$1.run(AbstractIrpQueue.java:73)
at java.lang.Thread.run(Thread.java:748)
Hi guys,
We use usb4java in our application to detect attached and detached events
It works well except the scenario we have identified recently.
Usb4java does not detect the ATTACHED event for the device that has serial number with more than 100 characters when it is plugged in.
Vendor ID: 0781
Product ID: 5591
Serial No: 0101c14ea1b1ea6e90aa9860523346cf654a93d436044650cdf7c88765d187e9e52300000000000000000000fc1c000e000f2500915581072a2ad2ae
Please help us to solve this problem
First of all thank you for coming back to update this project. API for USB with java is lame.
I'm using the usb4java-javax-examples examples. But the DumpNames class informs me the following errors:
Ignoring problematic device: javax.usb.UsbPlatformException: USB error 12: Can not open device Bus 002 Device 002: ID 045e: 02e6: Operation not supported or unimplemented on this platform
Ignoring problematic device: javax.usb.UsbPlatformException: USB error 8: Unable to get string descriptor languages: Overflow
Ignoring problematic device: javax.usb.UsbPlatformException: USB error 12: Can not open device Bus 002 Device 014: ID 04e8: 6860: Operation not supported or unimplemented on this platform
How to solve or really my platform is not supported?
windows 10 64 bit / java 8
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.