Giter VIP home page Giter VIP logo

javadoesusb's Introduction

Java Does USB: USB Library for Java

javadoc

Java Does USB is a Java library for working with USB devices. It allows to query the conntected USB devices and to communicate with them using custom / vendor specific protocols. (It is not intended for communication with standard types of USB devices such as mass storage devices, keyboards etc.)

The library uses the Foreign Function and Memory API to access native APIs of the underlying operating system. It is written entirely in Java and does not use JNI or any native third-party library. The Foreign Function and Memory API has been introduced with Java 22. Preview versions were available in several earlier releases.

Features

  • Single API for all operating systems (similar to WebUSB API)
  • Enumeration of USB devices
  • Control, bulk and interrupt transfers (optionally with timeout)
  • Notifications about connected/disconnected devices
  • Descriptive information about interfaces, settings and endpoints
  • High-throughput input/output streams
  • Support for alternate interface settings, composite devices and interface association
  • Published on Maven Central and licensed under the permissive MIT license

Getting Started

The library is available at Maven Central. To use it, just add it to your Maven or Gradle project.

If you are using Maven, add the below dependency to your pom.xml:

<dependency>
      <groupId>net.codecrete.usb</groupId>
      <artifactId>java-does-usb</artifactId>
      <version>1.0.0</version>
</dependency>

If you are using Gradle, add the below dependency to your build.gradle file:

compile group: 'net.codecrete.usb', name: 'java-does-usb', version: '1.0.0'
package net.codecrete.usb.sample;

import net.codecrete.usb.Usb;

public class EnumerateDevices {

    public static void main(String[] args) {
        for (var device : Usb.getDevices()) {
            System.out.println(device);
        }
    }
}

Documentation

Examples

  • Bulk Transfer demonstrates how to find a USB device, open it and communicate using bulk transfer.
  • Enumeration (Java / Kotlin) lists all connected USB devices and displays information about interfaces and endpoints.
  • Monitor (Java / Kotlin) lists the connected USB devices and then monitors for devices being connected and disconnnected.
  • Device Firmware Upload (DFU) for STM32 uploads firmware to STM32 microcontrollers supporting the built-in DFU mode.
  • ePaper Display communicates with an IT8951 controller for e-Paper displays and shows an image on the display.

Prerequisite

  • Java 22 available at jdk.java.net, Azul, Adoptium or with your favorite package manager.
  • Windows (x86 64-bit), macOS (x86 64-bit, ARM 64-bit) or Linux 64 bit (x86 64-bit, ARM 64-bit)

Platform-specific Considerations

macOS

No special considerations apply. Using this library, a Java application can connect to any USB device and claim any interfaces that isn't claimed by an operating system driver or another application. Standard operation system drivers can be unloaded if the application is run with root privileges. It runs both on Macs with Apple Silicon and Intel processors.

Linux

libudev is used to discover and monitor USB devices. It is closely tied to systemd. So the library only runs on Linux distributions with systemd and the related libraries. The majority of Linux distributions suitable for desktop computing (as opposed to distributions optimized for containers) fulfill this requirement. It runs on both Intel and ARM64 processors.

Similar to macOS, a Java application can connect to any USB device and claim any interfaces that isn't claimed by an operating system driver or another application. Standard operation system drivers can be unloaded (without the need for root privileges).

Most Linux distributions set up user accounts without permissions to access USB devices. The udev system daemon is responsible for assigning permissions to USB devices. It can be configured to assign specific permissions or ownership:

Create a file called /etc/udev/rules.d/80-javadoesusb-udev.rules with the below content:

SUBSYSTEM=="usb", ATTRS{idVendor}=="cafe", MODE="0666"

This adds the rule to assign permission mode 0666 to all USB devices with vendor ID 0xCAFE. This unregistered vendor ID is used by the test devices.

Without the udev rule, it is still possible to enumerate and query all USB devices.

Windows

The Windows driver model is rather rigid. It's not possible to open any USB device unless it uses the WinUSB driver. This even applies to devices with no installed driver. Enumerating and querying USB devices is possible independent of the driver.

USB devices can implement special control requests to instruct Windows to automatically install the WinUSB driver (search for WCID or Microsoft OS Compatibility Descriptors). The WinUSB driver can also be manually installed or replaced using a software called Zadig.

The test devices implement the required control requests. So the driver is installed automatically.

Windows for ARM64 is not yet supported. A port is probably easy, provided you have hardware to test it.

Troubleshooting

32-bit versions

The Foreign Function And Memory API has not been implemented for 32-bit operating systems / JDKs (and likely never will be).

Running on older JDK versions

The Foreign Function And Memory API has been available as a preview feature in JDKs before 22. However, incompatible changes were made from preview to preview to release. Earlier versions can be used with specific versions of this library:

Version Main New Features Compatibility
1.0.x Release for final Java API JDK 22
0.7.x New setter/getter names for improved Kotlin support; Kotlin examples JDK 21
0.6.x Support for JDK 21; better handling of composite devices on Windows JDK 21
0.5.x Support for JDK 20; high-throuput I/O streams JDK 20
0.4.x Early release JDK 19

When using an older JDK, preview features must be enabled using the --enable-preview VM option.

Building from source

To build from source, run the following command:

cd java-does-usb
mvn clean install -DskipTests

The tests are skipped as they require that a special test device is connected to the computer. See the next section for more information.

Testing

In order to run the unit tests, a special test device must be connected to the computer, which can be easily created from very inexpensive microcontroller boards. Two variants exist:

The test device with the loopback-stm32 code supports all tests. If the test device with the composite-stm32 code is connected, some tests are skipped. However, if it is used, the correct handling of composite devices is verified.

Tests can be run from the command line:

cd java-does-usb
mvn clean test

If they are run from an IDE (such as IntelliJ IDEA), you must likely configure VM options to allow native access:

--enable-native-access=net.codecrete.usb

Or (if modules are ignored):

--enable-native-access=ALL-UNNAMED

Code generation

Many bindings for the native APIs have been generated with jextract. See the jextract subdirectory for more information. For functions that need to retain the error state (errno on Linux, GetLastError() on Windows), the bindings have been manually written as jextract does not support it.

Since the code can only be generated for the current operating system, it must be generated on separate computers for Linux, Windows and macOS. Thus, the generated code is included in the repository. The generated code is compilable on all operating systems.

javadoesusb's People

Contributors

manuelbl avatar mpollmeier 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  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

javadoesusb's Issues

Java 19 required

The library is compiled and built with Java 19 which requires that all users of your library must have Java 19 or newer. This is probably not a very good option for many. I strongly recommend you build your library with Java 1.8 or at least Java 11 so more users can be reached. If more users is what you want of course. Anyways thx for your contribution.

Device ignored due to error in descriptor

net.codecrete.usb.windows.WindowsUSBException: Cannot retrieve descriptor 1. L?opération a réussi. (error code: 0)
        at net.codecrete.usb.windows.WindowsUSBException.throwException(WindowsUSBException.java:50)
        at net.codecrete.usb.windows.WindowsUSBException.throwLastError(WindowsUSBException.java:72)
        at net.codecrete.usb.windows.WindowsUSBDeviceRegistry.getDescriptor(WindowsUSBDeviceRegistry.java:317)
        at net.codecrete.usb.windows.WindowsUSBDeviceRegistry.getDescriptor(WindowsUSBDeviceRegistry.java:293)
        at net.codecrete.usb.windows.WindowsUSBDeviceRegistry.getStringDescriptor(WindowsUSBDeviceRegistry.java:347)
        at net.codecrete.usb.windows.WindowsUSBDeviceRegistry.lambda$createDevice$4(WindowsUSBDeviceRegistry.java:285)
        at net.codecrete.usb.common.USBDeviceImpl.setProductString(USBDeviceImpl.java:171)
        at net.codecrete.usb.windows.WindowsUSBDeviceRegistry.createDevice(WindowsUSBDeviceRegistry.java:285)
        at net.codecrete.usb.windows.WindowsUSBDeviceRegistry.createDeviceFromDeviceInfo(WindowsUSBDeviceRegistry.java:249)
        at net.codecrete.usb.windows.WindowsUSBDeviceRegistry.enumeratePresentDevices(WindowsUSBDeviceRegistry.java:149)
        at net.codecrete.usb.windows.WindowsUSBDeviceRegistry.monitorDevices(WindowsUSBDeviceRegistry.java:97)
        at java.base/java.lang.Thread.run(Thread.java:1589)

Due to a error in USB descriptor. Should be fixed by catching the exception, and maybe setting productname to null

On line 285 of WindowsUsbDeviceRegistry :

device.setProductString(descriptorSegment, (index) -> getStringDescriptor(hubHandle, usbPortNum, index));

Generating wrappers of macOS SDK Foundation framework

@manuelbl I have been advised to explore your work to go further with JExtract/Panama that I use to generate Java bindings to OpenGL.

You seam to be experienced at generating bindings to macOS SDK frameworks so I'd like to ask how you deal with surprising cases such as in Foundation/NSObjCRuntime.h at line 492. The @Class keyword does not seam to be regular C language to me.

#define NSFoundationVersionNumber_iOS_9_x_Max 1299
#endif

@class NSString, Protocol;

typedef NSString * NSExceptionName NS_EXTENSIBLE_STRING_ENUM;
typedef NSString * NSRunLoopMode NS_EXTENSIBLE_STRING_ENUM;

Here is JExtract output:

./panama-gl-bindings-macos/include/Foundation/NSObjCRuntime.h:492:1: error: expected identifier or '('

How did you deal with this kind of line?

Serial number with binary data

Some USB devices, e.g. the ST-Link adapters, return a serial number that isn't a valid Unicode string but rather contains binary data.

A first analysis shows that macOS detects this and treats it differently. This isn't necessarily what we want.

Serial numbers with binary data should be treated consistently across all platforms. And they should retain us much information as possible.

macOS: implement kernel driver detach

I'm trying to use JavaDoesUSB to connect to an IT8951 controlling a Waveshare ePaper Display.
In the end the application will run on Linux but it'd be great for faster dev turn-around if things also ran directly on my development Macbook.

While JavaDoesUSB appears to work in principle it suffers from the same issues that libusb suffers from, namely macOS hogging the device's USB interface with its own kernel drivers.
There are countless discussions around this problem in the libusb tickets, but a key component to get it to work is this PR:
libusb/libusb#911
which add support for macOS's "kernel driver detach" feature.

I'd assume that JavaDoesUSB is pretty much useless for all but the most obscure USB devices under macOS, until this feature is also implemented. I can't really tell how hard it would be to "port" this patch from libusb to JavaDoesUSB.
What's your take, Manuel?

Request: `transferOut` and `transferIn` overloads

Currently JavaDoesUSB provides these two core methods on the USBDevice class:

void transferOut(int endpointNumber, byte[] data, int timeout);
byte[] transferIn(int endpointNumber, int timeout);

While they work fine and do their job I'd like to request the addition of these two overloads:

/**
 * Sends data to this device.
 * <p>
 * This method blocks until the data has been sent, the timeout period has expired
 * or an error has occurred. If the timeout expires, a {@link USBTimeoutException} is thrown.
 * </p>
 * <p>
 * This method can send data to bulk and interrupt endpoints.
 * </p>
 * <p>
 * If the sent data length is a multiple of the packet size, it is often
 * required to send an additional zero-length packet (ZLP) for the device
 * to actually process the data. This method will not do it automatically.
 * </p>
 *
 * @param endpointNumber the endpoint number (in the range between 1 and 127)
 * @param data           the byte array holding the data to send
 * @param offset         the offset into the data array to start sending from
 * @param length         the number of bytes to send
 * @param timeout        the timeout period, in milliseconds (0 for no timeout)
 */
void transferOut(int endpointNumber, byte[] data, int offset, int length, int timeout);


/**
 * Receives data from this device.
 * <p>
 * This method blocks until at least a packet has been received, the timeout period has expired
 * or an error has occurred. If the timeout expired, a {@link USBTimeoutException} is thrown.
 * </p>
 * <p>
 * The method returns the number of bytes that were received as the payload of a packet.
 * If the given buffer is large enough to hold this many bytes at/after the given offset
 * all the received bytes will have been copied into the given buffer array.
 * If the buffer was too small then the returned int will be larger than
 * `buf.length() - offset`.
 * Note that the returned number will be zero if the USB device sends zero-length packets to
 * indicate the end of a data unit.
 * </p>
 * <p>
 * This method can receive data from bulk and interrupt endpoints.
 * </p>
 *
 * @param endpointNumber the endpoint number (in the range between 1 and 127, i.e. without the direction bit)
 * @param buf            the byte array that received bytes are to be copied into
 * @param offset         the offset into `buf` that the received bytes should be copied to
 * @param timeout        the timeout period, in milliseconds (0 for no timeout)
 * @return the number of bytes received (which might be more than the number of bytes placed in `buf`)
 */
int transferIn(int endpointNumber, byte[] buf, int offset, int timeout);

Especially the first method would be great to have as it will reduce the amount of intermediate buffer copying that might otherwise be needed.

LinuxUSBDevice.abortTransfers() fails with "Invalid argument (error code: 22)"

LinuxUSBDevice.abortTransfers() can fail with "Invalid argument (error code: 22)".

The reason seems to be a concurrency issue:

  • Thread 1: The first thread calls LinuxUSBDevice.abortTransfers(), which requires the lock on the LinuxAsyncTask instance.
  • Thread 2: At the same time, the transfer has been completed or cancelled by the device. The LinuxAsyncTask just reaped the URB and now wants to acquire the lock on itself.

Since the URB was already reaped (thread 2), discarding it (thread 1) will fail.

Output:

Exception in thread "main" java.util.concurrent.CompletionException: net.codecrete.usb.linux.LinuxUSBException: failed to cancel transfer. Invalid argument (error code: 22)
	at java.base/java.util.concurrent.CompletableFuture.encodeThrowable(CompletableFuture.java:315)
	at java.base/java.util.concurrent.CompletableFuture.completeThrowable(CompletableFuture.java:320)
	at java.base/java.util.concurrent.CompletableFuture$AsyncRun.run$$$capture(CompletableFuture.java:1807)
	at java.base/java.util.concurrent.CompletableFuture$AsyncRun.run(CompletableFuture.java)
	at java.base/java.util.concurrent.CompletableFuture$AsyncRun.exec(CompletableFuture.java:1796)
	at java.base/java.util.concurrent.ForkJoinTask.doExec$$$capture(ForkJoinTask.java:387)
	at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java)
	at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1312)
	at java.base/java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1843)
	at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1808)
	at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:188)
Caused by: net.codecrete.usb.linux.LinuxUSBException: failed to cancel transfer. Invalid argument (error code: 22)
	at net.codecrete.usb.linux.LinuxUSBException.throwException(LinuxUSBException.java:48)
	at net.codecrete.usb.linux.LinuxUSBException.throwLastError(LinuxUSBException.java:74)
	at net.codecrete.usb.linux.LinuxAsyncTask.abortTransfers(LinuxAsyncTask.java:301)
	at net.codecrete.usb.linux.LinuxUSBDevice.abortTransfers(LinuxUSBDevice.java:323)
	at net.codecrete.usb.sample.LogicAnalyzer.stopAcquisition(LogicAnalyzer.java:231)
	at net.codecrete.usb.sample.LogicAnalyzer.detectBufferOverrun(LogicAnalyzer.java:246)
	at java.base/java.util.concurrent.CompletableFuture$AsyncRun.run$$$capture(CompletableFuture.java:1804)
	... 8 more

Consistent string descriptors

USB devices can provide string descriptors such a manufacturer and product name in different languages. On macOS and Linux, the relevant string descriptors are fetched by the operating system. On Windows, this library queries them explicitly with control requests.

It is unclear, which language version is used on the different operating systems, and if they are consistent across all operating systems.

The goal of this issue is to fix investigate it and fix inconsistencies.

Unmount an USB sdcard (soft) do no trigger a disconnected event

  • Running on mac (intel 64)
  • latest lib version: 0.6.1

Event are well received when I plug an sd card.

But when I un-mount (click into the finder on the icon) then no event is received (setOnDeviceDisconnected).

Event (disconnected) is received only when I physically remove the sdcard.

Is it something expected ?

Is this lib suitable for optical mouse configuration ?

Hello , Good day
Im gonna write a program for read/write optical mouse configurations like turning off RGB lights and so on.
Is this library suitable for this kind of programming in JAVA ?
Is there any example for mouse configuration by using this lib ?
Thank You

Cannot open library: CoreFoundation.framework/CoreFoundation

Getting this error on M1 mac.
Using same eclipse and SDK configuration on both an intel based mac and apple silicon.

Config differences

  • Intel: macOS Masonry
  • Apple Silicon: macOS Sonoma

OpenJDK 21
VM args: --enable-preview --enable-native-access=net.codecrete.usb

Exception in thread "main" java.lang.reflect.InvocationTargetException at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:118) at java.base/java.lang.reflect.Method.invoke(Method.java:580) at java.base/sun.launcher.LauncherHelper$FXHelper.main(LauncherHelper.java:1135) Caused by: java.lang.ExceptionInInitializerError at [email protected]/net.codecrete.usb.macos.gen.corefoundation.CoreFoundation.<clinit>(CoreFoundation.java:20) at [email protected]/net.codecrete.usb.macos.CoreFoundationHelper.createCFStringRef(CoreFoundationHelper.java:61) at [email protected]/net.codecrete.usb.macos.MacosUSBDeviceRegistry.<clinit>(MacosUSBDeviceRegistry.java:50) at [email protected]/net.codecrete.usb.USB.createInstance(USB.java:30) at [email protected]/net.codecrete.usb.USB.instance(USB.java:47) at [email protected]/net.codecrete.usb.USB.getAllDevices(USB.java:68) at java.base/jdk.internal.misc.Unsafe.ensureClassInitialized0(Native Method) at java.base/jdk.internal.misc.Unsafe.ensureClassInitialized(Unsafe.java:1160) at java.base/jdk.internal.reflect.MethodHandleAccessorFactory.ensureClassInitialized(MethodHandleAccessorFactory.java:300) at java.base/jdk.internal.reflect.MethodHandleAccessorFactory.newMethodAccessor(MethodHandleAccessorFactory.java:71) at java.base/jdk.internal.reflect.ReflectionFactory.newMethodAccessor(ReflectionFactory.java:159) at java.base/java.lang.reflect.Method.acquireMethodAccessor(Method.java:726) at java.base/java.lang.reflect.Method.invoke(Method.java:577) at javafx.graphics@21/com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(LauncherImpl.java:464) at javafx.graphics@21/com.sun.javafx.application.LauncherImpl.launchApplication(LauncherImpl.java:364) at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103) ... 2 more Caused by: java.lang.IllegalArgumentException: Cannot open library: CoreFoundation.framework/CoreFoundation at java.base/java.lang.foreign.SymbolLookup.libraryLookup(SymbolLookup.java:277) at java.base/java.lang.foreign.SymbolLookup.libraryLookup(SymbolLookup.java:238) at [email protected]/net.codecrete.usb.macos.gen.corefoundation.RuntimeHelper.<clinit>(RuntimeHelper.java:26) ... 20 more

Strange NPE when opening USB device

Hi,

I was hoping you could join me in exploring a strange NPE coming from inside the library.

My program keeps encountering the following error on MacOS.

java.lang.NullPointerException: Cannot invoke "jdk.internal.foreign.AbstractMemorySegmentImpl.isAlignedForElement(long, java.lang.foreign.MemoryLayout)" because "segment" is null
	at java.base/jdk.internal.foreign.LayoutPath.checkAlign(LayoutPath.java:290)
	at net.codecrete.usb.macos.IoKitHelper.getVtable(IoKitHelper.java:96)
	at net.codecrete.usb.macos.IoKitUsb.USBDeviceOpenSeize(IoKitUsb.java:54)
	at net.codecrete.usb.macos.MacosUsbDevice.open(MacosUsbDevice.java:115)

My application code is:

	private fun UsbDevice.openIfNeeded() {
		LOGGER.atDebug().log("USB device is open: {}.", isOpened)
		if (!isOpened) {
			try {
				open()
				try {
					claimInterface(USB_INTERFACE_NUMBER)
				} catch (e: Exception) {
					LOGGER.atWarn().withThrowable(e).log("Failed to claim interface")
				}
			} catch (e: Exception) {
				LOGGER.atWarn().withThrowable(e).log("Failed to open")
			}
		}
	}

I've bee experience this issue since 0.7.0 (first version I used). It happens after several hours of the application running. No USB devices added/removed. Restarting the application immediately makes it work. At no point does my application close the USB device. I added this openIfNeeded function because I found the USB device was releasing endpoints itself. As in, without me explicitly releasing them or closing the device, after several hours, I'd find the device to be unable to transferOut.

I don't know if I'm using the underlying USB library incorrectly (as in, should I not be holding the device open for hours on end without sending traffic), or if there's something else, but from a library perspective, I'd expect the open() call to not fail with an NPE :)

Please let me know if there's more information you'd like or something you'd like me to try out. Thanks for the fun FFM library!

Version: 1.0.0
MacOS Apple Silicon
Java 22

Control requests without opening the device

It looks as if it is possible on all operating systems to send control requests to USB device without opening them. This can be a useful feature if a USB device has already been claimed exclusively by the operating system. It would allow to query detail information about the devices, or control settings of a USB video camera.

This issue's goal is to support sending control requests without opening the device, consistent across all operating systems.

Issues with JavaDoesUSB in Windows 11 with USB 1.1 device

Hi @manuelbl

First of all, great work! The library is amazing and it comes really useful when other USB libraries for Java are almost dead... kudos for that!

I am testing the library for an application which is using a USB 1.1 device on Mac & Windows, and I am finding some issues in the Windows 11 side (in Mac everything works smoothly):

JavaDoesUSB version: 0.5.1

  1. Only a specific version of WinUSB seem to work. When I configure the USB data interface of the device with Zadig, the tool shows the following screen, instructing me to downgrade WinUSB:

image

I guess this is caused because of the device implementing USB 1.1 (that is the reason WCID does not work with the dongle) ... do you think I am right?

  1. Once the USB driver is properly set, the application I am testing can be used. I am sending a command to the device with the following code (kotlin syntax):
companion object {
        const val APP_INTERFACE = 4
        const val IN_ENDPOINT = 4
        const val OUT_ENDPOINT = 5
        const val COMMAND = "COMMAND"
 }
device.get()?.apply {
                try {
                    open()
                    claimInterface(APP_INTERFACE) 
                    transferOut(OUT_ENDPOINT, COMMAND.toByteArray())
                } catch (t: Throwable) {
                    logger.error("Unable to execute USB operation ", t)
                } finally {
                    if (isOpen) {
                        if (getInterface(APP_INTERFACE).isClaimed) {
                            releaseInterface(APP_INTERFACE)
                        }
                        logger.debug { "Closing device..." }
                        close()
                    }
                }
            }

The code is executed inside a process which is continuously running. As you can see it is pretty straightforward, but its behaviour is weird:

  • At first, it does send the command.
  • When I remove the device from the USB connector, and add it again (and I repeat the plug out/plug in process several times), sometimes after plugging the device in, I found the following exception (WinUSB is properly set, as explained above):
net.codecrete.usb.USBException: Interface number 4 cannot be claimed (non WinUSB device?)
at net.codecrete.usb.windows.WindowsUSBException.throwException(WindowsUSBException.java:65)
at net.codecrete.usb.windows.WindowsUSBDevice.claimInterface(WindowsUSBDevice.java:114)
...

If I remove the device and plug it in again, the command works.

  • In all instances, if I run the bulk_transfer example (configured for the device I am testing) from the JavaDoesUSB library, when the long running process fails, the bulk transfer one works properly

Do you think if this is related with the library or with the dongle specification? Would there be any procedure that could help me to debug the issue?

if you think that there is some work that could help with this, just let me know. I would be happy to help.

Again, great work!

Thanks,
Alberto.

Problem claiming USB interface under Linux

I'm trying to use JavaDoesUSB to control an IT8951 attached to a Waveshare ePaper Display and speaking SCSI over USB.
The platform is a Raspberry Pi Zero 2 running Debian GNU/Linux 11 (bullseye).

JavaDoesUSB lets me find and open the IT8951 alright, but attempting to claim the only interface (#0) fails with this exception

net.codecrete.usb.linux.LinuxUSBException: Cannot claim USB interface. Device or resource busy (error code: 16)

My /etc/udev/rules.d/80-javadoesusb-udev.rules files has this content:

SUBSYSTEM=="usb", ATTRS{idVendor}=="048d", MODE="0666"

The vendor should match the device nicely:

~ > sudo lsusb
Bus 001 Device 002: ID 048d:8951 Integrated Technology Express, Inc. ITE T-CON
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

~ > cat /sys/bus/usb/devices/1-1/idVendor
048d

When I force an unbind with this command:

~ > echo '1-1' | sudo tee /sys/bus/usb/drivers/usb/unbind
1-1

The exception changes to:

net.codecrete.usb.linux.LinuxUSBException: Cannot claim USB interface. No such file or directory (error code: 2)

Do you have any ideas as to how I might make progress?
This latter exception looks weird to me.
Finding and opening the device works just as before, but when trying to claim interface #0 the "file" is suddenly gone?

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.