org.bidib.jbidibc.usbhid.UsbManager Maven / Gradle / Ivy
package org.bidib.jbidibc.usbhid;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.usb4java.ConfigDescriptor;
import org.usb4java.DescriptorUtils;
import org.usb4java.Device;
import org.usb4java.DeviceDescriptor;
import org.usb4java.DeviceHandle;
import org.usb4java.DeviceList;
import org.usb4java.EndpointDescriptor;
import org.usb4java.Interface;
import org.usb4java.InterfaceDescriptor;
import org.usb4java.LibUsb;
import org.usb4java.LibUsbException;
public class UsbManager implements AutoCloseable {
private static final Logger LOGGER = LoggerFactory.getLogger(UsbManager.class);
public static final int USB_VENDOR_ID_CP2112 = 0x10C4; // Silicon Laboratories
public static final int USB_DEVICE_ID_CP2112 = 0xEA90;
// tinyusb -->https://github.com/harbaum/I2C-Tiny-USB/tree/master/digispark
public static final int USB_VENDOR_ID_TINYUSB = 0x0403;
public static final int USB_DEVICE_ID_TINYUSB = 0xC631;
private boolean initialized;
public UsbManager() {
}
public void setLibUsbDebugLevel(int logLevel) {
LibUsb.setOption(null, LibUsb.OPTION_LOG_LEVEL, logLevel);
}
public void init(Integer logLevel) {
// context = new Context();
int result = LibUsb.init(null);
if (result != LibUsb.SUCCESS) {
throw new LibUsbException("Unable to initialize libusb.", result);
}
this.initialized = true;
if (logLevel != null) {
LibUsb.setOption(null, LibUsb.OPTION_LOG_LEVEL, logLevel);
}
}
// vendor Silicon Laboratories 10C4
// product CP2112 HID USB-to-SMBus Bridge EA90
public Device findDevice(DeviceVidPid... deviceVidPids) {
Device device = null;
for (DeviceVidPid devVidPid : deviceVidPids) {
device = findDevice(devVidPid.getVid(), devVidPid.getPid());
LOGGER.info("Found supported device: {}", device);
if (device != null) {
break;
}
}
if (device == null) {
throw new RuntimeException("No supported device found!");
}
return device;
}
public Device findDevice(int vendorId, int productId) {
// Read the USB device list
DeviceList list = new DeviceList();
int result = LibUsb.getDeviceList(null, list);
if (result < LibUsb.SUCCESS) {
throw new LibUsbException("Unable to get device list", result);
}
LOGGER.info("Found devices: {}", list);
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);
}
LOGGER.info("Current device: {}", descriptor);
if ((descriptor.idVendor() & 0xFFFF) == vendorId && (descriptor.idProduct() & 0xFFFF) == productId) {
int speed = LibUsb.getDeviceSpeed(device);
LOGGER.info("Current device speed: {}", speed);
return device;
}
}
}
catch (Exception ex) {
LOGGER.warn("Failed to load the device descriptot.", ex);
}
finally {
// Ensure the allocated device list is freed
LibUsb.freeDeviceList(list, true);
}
// Device not found
return null;
}
@Override
public void close() throws Exception {
LOGGER.info("Close the UsbManager instance.");
LibUsb.exit(null);
this.initialized = false;
}
public Map getDeviceList() {
if (!initialized) {
LOGGER.error("Initialize the UsbManager before get the device list.");
return Collections.emptyMap();
}
Map deviceList = new HashMap();
// 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);
}
LOGGER.info("Found devices: {}", list);
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);
}
LOGGER.info("Current device: {}", descriptor);
// prepare the key
String deviceName = String.format("%04x:%04x", descriptor.idVendor(), descriptor.idProduct());
final ConfigDescriptor configDescriptor = new ConfigDescriptor();
// result = LibUsb.getActiveConfigDescriptor(device, configDescriptor);
result = LibUsb.getConfigDescriptor(device, (byte) 0, configDescriptor);
if (result != LibUsb.SUCCESS) {
// TODO
// throw new LibUsbException("Unable to read config descriptor", result);
LOGGER.warn("Unable to read config descriptor");
continue;
}
LOGGER.info("Current configDescriptor: {}", DescriptorUtils.dump(configDescriptor));
int numConfigurations = descriptor.bNumConfigurations() & 0xFF;
int deviceAddress = LibUsb.getDeviceAddress(device);
int attributes = configDescriptor.bmAttributes() & 0xff;
int maxPower = (configDescriptor.bMaxPower() & 0xff) * 2;
String mManufacturerName = null;
String mProductName = null;
String mSerialNumber = null;
final DeviceHandle deviceHandle = new DeviceHandle();
result = LibUsb.open(device, deviceHandle);
if (result != LibUsb.SUCCESS) {
LOGGER.warn("Failed to open the device, result: {}", result);
}
else {
try {
mManufacturerName = LibUsb.getStringDescriptor(deviceHandle, descriptor.iManufacturer());
mProductName = LibUsb.getStringDescriptor(deviceHandle, descriptor.iProduct());
mSerialNumber = LibUsb.getStringDescriptor(deviceHandle, descriptor.iSerialNumber());
LOGGER
.info("Fetched mManufacturerName: {}, mProductName: {}, mSerialNumber: {}",
mManufacturerName, mProductName, mSerialNumber);
}
finally {
LibUsb.close(deviceHandle);
}
}
UsbConfiguration[] configurations = new UsbConfiguration[numConfigurations];
UsbConfiguration config = new UsbConfiguration(deviceAddress, deviceName, attributes, maxPower);
configurations[0] = config;
// TODO get the interfaces
// TODO set the configuration
List interfaces = new ArrayList<>();
List endpoints = new ArrayList<>();
int interfaceId = 0;
int intClass = 0;
int subClass = 0;
int protocol = 0;
for (final Interface iface : configDescriptor.iface()) {
int numAlternateSetting = iface.numAltsetting();
for (final InterfaceDescriptor intDesc : iface.altsetting()) {
interfaceId = intDesc.bInterfaceNumber() & 0xff;
intClass = intDesc.bInterfaceClass() & 0xff;
subClass = intDesc.bInterfaceSubClass() & 0xff;
protocol = intDesc.bInterfaceProtocol() & 0xff;
for (final EndpointDescriptor epDesc : intDesc.endpoint()) {
int endpointAddress = epDesc.bEndpointAddress() & 0xFF;
LOGGER.info("Current endpoint address: {}", endpointAddress);
int epAttributes = epDesc.bmAttributes() & 0xff;
int maxPacketSize = epDesc.wMaxPacketSize() & 0xff;
int interval = epDesc.bInterval() & 0xff;
UsbEndpoint endpoint =
new UsbEndpoint(endpointAddress, epAttributes, maxPacketSize, interval);
endpoints.add(endpoint);
}
}
UsbInterface ifc =
new UsbInterface(interfaceId, numAlternateSetting, null, intClass, subClass, protocol);
ifc.setEndpoints(endpoints.toArray(new UsbEndpoint[0]));
interfaces.add(ifc);
}
config.setInterfaces(interfaces.toArray(new UsbInterface[0]));
final UsbDevice usbDevice =
new UsbDevice(descriptor.idVendor() & 0xFFFF, descriptor.idProduct() & 0xFFFF, deviceName,
configurations, mManufacturerName, mProductName, mSerialNumber);
deviceList.put(deviceName, usbDevice);
LibUsb.freeConfigDescriptor(configDescriptor);
}
}
catch (Exception ex) {
LOGGER.warn("Failed to load the device description.", ex);
}
finally {
// Ensure the allocated device list is freed
LibUsb.freeDeviceList(list, true);
}
return deviceList;
}
public UsbDeviceConnection openDevice(UsbDevice usbDevice) {
LOGGER.info("Create connection for usbDevice: {}", usbDevice);
final UsbDeviceConnection usbDeviceConnection = new UsbDeviceConnection(usbDevice);
usbDeviceConnection.open();
return usbDeviceConnection;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy