Code Monkey home page Code Monkey logo

usb4java-javax's Introduction

usb4java-javax

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.

usb4java-javax's People

Contributors

kayahr avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

usb4java-javax's Issues

get device path / port number

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.

usb4java stopped receiving usb events intermittently

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

  1. Th Java app is running as service
  2. We do plug and unplug multiple devices continuously for testing

getActiveUsbConfiguration returns null

The Issue:

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.

tried the following:

  • list the usb devices using hub.getAttachedUsbDevices()
  • If the usb interface is still claimed, then release the usb interface
  • finally:
      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:

    1. getActiveUsbConfiguration() also returns null.
    2. Further down, when we loop through 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.

I have 2 questions:

  • is this a known defect of the library, could it be related to: usb4java/usb4java#51
  • if not, is there a way to get hold of an active UsbConfiguration from here.

Overflow while getting descriptors

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.

Properties File not found

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 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

Threading

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.

High-level API introduces large and unpredictable performance penalty

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;
    }
}

Properties file javax.usb.properties not found error

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>

Make package local classes public

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!

Support for USB Isochronous Transfer mode

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)

Attached event is not received for the device that has lengthy serial number

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

Operation not supported or unimplemented on this platform

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

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.