Java get usb devices

Java get usb devices

The low-level API of usb4java closely follows the C API of the libusb project. All global functions and constants of libusb are defined as static members of the class org.usb4java.LibUsb. All structures of libusb are defined in separate classes which are named similar to the original struct names but without underscores, with camel-case names and with the libusb prefix removed. For example the struct libusb_device_handle is defined in the class DeviceHandle. Struct members are represented by static methods in the corresponding class.

The following notable differences exists between the libusb 1.0 API and the usb4java API:

  • interface in the configuration descriptor is named iface because interface is a reserved word in Java.
  • MaxPower in the configuration descriptor is named bMaxPower to be compatible to the USB specification and because method names starting with upper-case letters are quite unusual in Java.
  • Whenever libusb expects a byte pointer and a length you have to use a direct Java NIO ByteBuffer instead.
  • Methods which are returning a string through a byte buffer which was passed as argument have additional simplified overloaded method equivalents which are returning a Java String directly.

Initialization/deinitialization

Before using any usb4java functionality you must initialize libusb:

Context context = new Context(); int result = LibUsb.init(context); if (result != LibUsb.SUCCESS) throw new LibUsbException("Unable to initialize libusb.", result);

Specifiying a context is optional. If your application only needs a single libusb context then you can specify null as context.

Before your application terminates you should deinitialize libusb:

Related libusb documentation:

Finding USB devices

Your program most likely wants to communicate with a specific device so first of all you have to find it. You have to get a list of all connected USB devices and then check the vendor/product ids. Here is a method which can be used for this purpose:

public Device 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) return device; >> finally < // Ensure the allocated device list is freed LibUsb.freeDeviceList(list, true); >// Device not found return null; >

In your application it might be a little bit more complicated. Maybe you have more than one device of the same type so you may need a list of devices. Or you have to identify your device by the product or vendor string descriptor instead of just checking the ID (In case you are using a shared vendor/product ID). But this example should bring you on the right track.

Читайте также:  Import static java util collections

Related libusb documentation:

Device handles

For the real USB communication you must open a new device handle and you must close it again when you are finished communicating with the device. Example:

DeviceHandle handle = new DeviceHandle(); int result = LibUsb.open(device, handle); if (result != LibUsb.SUCCESS) throw new LibUsbException(«Unable to open USB device», result); try < // Use device handle here >finally

Interfaces

When you want to communicate with an interface or with endpoints of this interface then you have to claim it before using it and you have to release it when you are finished. Example:

int result = LibUsb.claimInterface(handle, interfaceNumber); if (result != LibUsb.SUCCESS) throw new LibUsbException(«Unable to claim interface», result); try < // Use interface here >finally

It is possible that the interface you want to communicate with is already used by a kernel driver. In this case you have to detach the kernel driver from the interface before claiming it. Example:

// Check if kernel driver must be detached boolean detach = LibUsb.hasCapability(LibUsb.CAP_SUPPORTS_DETACH_KERNEL_DRIVER) && LibUsb.kernelDriverActive(handle, interfaceNumber); // Detach the kernel driver if (detach) < int result = LibUsb.detachKernelDriver(handle, interfaceNumber); if (result != LibUsb.SUCCESS) throw new LibUsbException("Unable to detach kernel driver", result); >// Communicate with the device . // Attach the kernel driver again if needed if (detach)

Please note that detaching kernel drivers is not supported on Windows.

Synchronous I/O

For the actual USB communication you usually have to create a direct byte buffer for the data to send or receive.

This examples sends 8 bytes to a claimed interface using a control transfer:

ByteBuffer buffer = ByteBuffer.allocateDirect(8); buffer.put(new byte[] < 1, 2, 3, 4, 5, 6, 7, 8 >); int transfered = LibUsb.controlTransfer(handle, (byte) (LibUsb.REQUEST_TYPE_CLASS | LibUsb.RECIPIENT_INTERFACE), (byte) 0x09, (short) 2, (short) 1, buffer, timeout); if (transfered < 0) throw new LibUsbException("Control transfer failed", transfered); System.out.println(transfered + " bytes sent");

This example sends 8 bytes to endpoint 0x03 of the claimed interface using a bulk transfer:

ByteBuffer buffer = ByteBuffer.allocateDirect(8); buffer.put(new byte[] < 1, 2, 3, 4, 5, 6, 7, 8 >); IntBuffer transfered = IntBuffer.allocate(1); int result = LibUsb.bulkTransfer(handle, 0x03, buffer, transfered, timeout); if (result != LibUsb.SUCCESS) throw new LibUsbException("Control transfer failed", transfered); System.out.println(transfered.get() + " bytes sent");

Related libusb documentation:

Asynchronous I/O

Asynchronous I/O is a little bit more complex than synchronous I/O. That's because libusb doesn't start its own thread to handle the actual background tasks. Instead you have to create you own worker thread like this:

class EventHandlingThread extends Thread < /** If thread should abort. */ private volatile boolean abort; /** * Aborts the event handling thread. */ public void abort() < this.abort = true; >@Override public void run() < while (!this.abort) < int result = LibUsb.handleEventsTimeout(null, 250000); if (result != LibUsb.SUCCESS) throw new LibUsbException("Unable to handle events", result); >> >

This simple thread implementation doesn't use a specific libusb context so it specified null as context. If you need contexts then you may want to pass it to the thread somehow.

The thread must be started after you have initialized libusb:

EventHandlingThread thread = new EventHandlingThread(); thread.start();

And it must be stopped before deinitializing libusb:

So now with this thread running in the background you can use the asynchronous functions of libusb. If you don't like this thread and your program already has some kind of application loop then you can also simply call LibUsb.handleEventsTimeout(null, 0) inside the loop. This call returns immediately if there are no events to process.

Читайте также:  Minimum width html css

An actual asynchronous transfer is submitted like this (In this case an outgoing bulk transfer to endpoint 0x03):

ByteBuffer buffer = BufferUtils.allocateByteBuffer(8); buffer.put(new byte[] < 1, 2, 3, 4, 5, 6, 7, 8 >); Transfer transfer = LibUsb.allocTransfer(); LibUsb.fillBulkTransfer(transfer, handle, 0x03, buffer, callback, null, timeout); int result = LibUsb.submitTransfer(transfer); if (result != LibUsb.SUCCESS) throw new LibUsbException("Unable to submit transfer", result);

The callback is an object implementing the TransferCallback interface. Here is an example of such a callback:

TransferCallback callback = new TransferCallback() < @Override public void processTransfer(Transfer transfer) < System.out.println(transfer.actualLength() + " bytes sent"); LibUsb.freeTransfer(transfer); >>;

Related libusb documentation:

See also

Источник

Saved searches

Use saved searches to filter your results more quickly

You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session. You switched accounts on another tab or window. Reload to refresh your session.

A Java library to get a list of all usb storage devices connected to the computer.

License

samuelcampos/usbdrivedetector

This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?

Sign In Required

Please sign in to use Codespaces.

Launching GitHub Desktop

If nothing happens, download GitHub Desktop and try again.

Launching GitHub Desktop

If nothing happens, download GitHub Desktop and try again.

Launching Xcode

If nothing happens, download Xcode and try again.

Launching Visual Studio Code

Your codespace will open once ready.

There was a problem preparing your codespace, please try again.

Latest commit

Git stats

Files

Failed to load latest commit information.

README.md

A Java library to get a list of all usb storage devices connected to the computer and has the capability of unmount them. It works on the three main operating systems (Windows, Linux and OS X).

To include this library in your project, add the following on your pom.xml :

project> dependencies>  New dependency --> dependency> groupId>net.samuelcamposgroupId> artifactId>usbdrivedetectorartifactId> version>2.2.1version> dependency> dependencies> project>
USBDeviceDetectorManager driveDetector = new USBDeviceDetectorManager(); // Display all the USB storage devices currently connected driveDetector.getRemovableDevices().forEach(System.out::println); // Add an event listener to be notified when an USB storage device is connected or removed driveDetector.addDriveListener(System.out::println); // Unmount a device driveDetector.unmountStorageDevice(driveDetector.getRemovableDevices().get(0));

Once you invoke addDriveListener , your application keep running because it will internally create an ScheduledExecutorService . To finish your application, just invoke the close method;

// Shutdown an initialized USBDeviceDetectorManager driveDetector.close();

About

A Java library to get a list of all usb storage devices connected to the computer.

Источник

Java get usb devices

High-level (javax-usb) API

The high-level API implements the javax-usb (JSR-80) standard. This API is object-oriented, event-driven and uses exceptions for error-handling instead of negative return values like the low-level API. Another advantage is that you may switch to a different javax-usb implementation later without changing your code. For example instead of using usb4java you may try out the reference implementation for Linux and Windows.

Читайте также:  Ссылки в виде иконки css

Configuration

To use the usb4java implementation you have to create a file named javax.usb.properties in the root of your class path with the following content:

javax.usb.services = org.usb4java.javax.Services

Finding USB devices

USB devices are managed in a tree. The root of this tree is a virtual USB hub to which all physical root hubs are connected. More hubs can be connected to these root hubs and any hub can have a number of connected USB devices.

Often you need to search for a specific device before working with it. Here is an example how to scan the device tree for the first device with a specific vendor and product id. It can be easily expanded to check for specific device classes or whatever:

public UsbDevice findDevice(UsbHub hub, short vendorId, short productId) < for (UsbDevice device : (List) hub.getAttachedUsbDevices()) < UsbDeviceDescriptor desc = device.getUsbDeviceDescriptor(); if (desc.idVendor() == vendorId && desc.idProduct() == productId) return device; if (device.isUsbHub()) < device = findDevice((UsbHub) device, vendorId, productId); if (device != null) return device; >> return null; >

Control requests

This example reads the current configuration number from a device by using a control request:

UsbControlIrp irp = device.createUsbControlIrp( (byte) (UsbConst.REQUESTTYPE_DIRECTION_IN | UsbConst.REQUESTTYPE_TYPE_STANDARD | UsbConst.REQUESTTYPE_RECIPIENT_DEVICE), UsbConst.REQUEST_GET_CONFIGURATION, (short) 0, (short) 0 ); irp.setData(new byte[1]); device.syncSubmit(irp); System.out.println(irp.getData()[0]);

Interfaces

When you want to communicate with an interface or with endpoints of this interface then you have to claim it before using it and you have to release it when you are finished. Example:

UsbConfiguration configuration = device.getActiveUsbConfiguration(); UsbInterface iface = configuration.getUsbInterface((byte) 1); iface.claim(); try < . Communicate with the interface or endpoints . >finally

It is possible that the interface you want to communicate with is already used by a kernel driver. In this case you can try to force the claiming by passing an interface policy to the claim method:

iface.claim(new UsbInterfacePolicy() < @Override public boolean forceClaim(UsbInterface usbInterface) < return true; >>);

Please note that interface policies are just a hint for the underlying USB implementation. In case of usb4java the policy will be ignored on Windows because libusb doesn't support detaching drivers on Windows.

Synchronous I/O

This example sends 8 bytes to endpoint 0x03:

UsbEndpoint endpoint = iface.getUsbEndpoint(0x03); UsbPipe pipe = endpoint.getUsbPipe(); pipe.open(); try < int sent = pipe.syncSubmit(new byte[] < 1, 2, 3, 4, 5, 6, 7, 8 >); System.out.println(sent + " bytes sent"); > finally

This example reads 8 bytes from endpoint 0x83:

UsbEndpoint endpoint = iface.getUsbEndpoint((byte) 0x83); UsbPipe pipe = endpoint.getUsbPipe(); pipe.open(); try < byte[] data = new byte[8]; int received = pipe.syncSubmit(data); System.out.println(received + " bytes received"); >finally

Asynchronous I/O

Asynchronous I/O works pretty much the same as synchronous I/O. You just use the asyncSubmit methods instead of the syncSubmit methods. While syncSubmit blocks until the request is complete asyncSubmit does not block and return immediately. To receive the response you have to add a listener to the pipe like this:

pipe.addUsbPipeListener(new UsbPipeListener() < @Override public void errorEventOccurred(UsbPipeErrorEvent event) < UsbException error = event.getUsbException(); . Handle error . >@Override public void dataEventOccurred(UsbPipeDataEvent event) < byte[] data = event.getData(); . Process received data . >>);

See also

Источник

Оцените статью