From b6102dec750996196c2517819709859bf88d2c49 Mon Sep 17 00:00:00 2001 From: Klaus Reimer Date: Thu, 16 Apr 2015 08:01:36 +0200 Subject: [PATCH 1/5] Toying around with JNA instead of JNI --- pom.xml | 45 +------ .../org/usb4java/jna/ConfigDescriptor.java | 91 +++++++++++++ .../org/usb4java/jna/DeviceDescriptor.java | 56 ++++++++ src/main/java/org/usb4java/jna/Interface.java | 116 +++++++++++++++++ .../java/org/usb4java/jna/LibUsbNative.java | 122 ++++++++++++++++++ src/main/java/org/usb4java/jna/Test.java | 111 ++++++++++++++++ 6 files changed, 500 insertions(+), 41 deletions(-) create mode 100644 src/main/java/org/usb4java/jna/ConfigDescriptor.java create mode 100644 src/main/java/org/usb4java/jna/DeviceDescriptor.java create mode 100644 src/main/java/org/usb4java/jna/Interface.java create mode 100644 src/main/java/org/usb4java/jna/LibUsbNative.java create mode 100644 src/main/java/org/usb4java/jna/Test.java diff --git a/pom.xml b/pom.xml index 63004f7..9df0dc5 100644 --- a/pom.xml +++ b/pom.xml @@ -325,47 +325,10 @@ test - org.usb4java - libusb4java - ${libusb4java.version} - linux-x86 - - - org.usb4java - libusb4java - ${libusb4java.version} - linux-x86_64 - - - org.usb4java - libusb4java - ${libusb4java.version} - linux-arm - - - org.usb4java - libusb4java - ${libusb4java.version} - windows-x86 - - - org.usb4java - libusb4java - ${libusb4java.version} - windows-x86_64 - - - org.usb4java - libusb4java - ${libusb4java.version} - osx-x86 - - - org.usb4java - libusb4java - ${libusb4java.version} - osx-x86_64 - + net.java.dev.jna + jna + 4.1.0 + org.apache.commons commons-lang3 diff --git a/src/main/java/org/usb4java/jna/ConfigDescriptor.java b/src/main/java/org/usb4java/jna/ConfigDescriptor.java new file mode 100644 index 0000000..6c68fbd --- /dev/null +++ b/src/main/java/org/usb4java/jna/ConfigDescriptor.java @@ -0,0 +1,91 @@ +/* + * Copyright 2015 Klaus Reimer + * See LICENSE.md for licensing information. + * + * Based on libusb : + * + * Copyright 2001 Johannes Erdfelt + * Copyright 2007-2009 Daniel Drake + * Copyright 2010-2012 Peter Stuge + * Copyright 2008-2013 Nathan Hjelm + * Copyright 2009-2013 Pete Batard + * Copyright 2009-2013 Ludovic Rousseau + * Copyright 2010-2012 Michael Plante + * Copyright 2011-2013 Hans de Goede + * Copyright 2012-2013 Martin Pieuchot + * Copyright 2012-2013 Toby Gray + */ + +package org.usb4java.jna; + +import java.nio.ByteBuffer; +import java.util.Arrays; +import java.util.List; + +import org.apache.commons.lang3.builder.EqualsBuilder; +import org.apache.commons.lang3.builder.HashCodeBuilder; + +import com.sun.jna.Pointer; +import com.sun.jna.Structure; + +/** + * A structure representing the standard USB configuration descriptor. + * + * This descriptor is documented in section 9.6.3 of the USB 3.0 specification. All multiple-byte fields are represented + * in host-endian format. + * + * @author Klaus Reimer (k@ailis.de) + */ +public class ConfigDescriptor extends Structure { + public ConfigDescriptor(final Pointer pointer) { + super(pointer); + read(); + } + + /** The size of this descriptor (in bytes). */ + public byte bLength; + + /** The descriptor type. */ + public byte bDescriptorType; + + /** The total length of data. */ + public short wTotalLength; + + /** The number of supported interfaces. */ + public byte bNumInterfaces; + + /** The identifier value. */ + public byte bConfigurationValue; + + /** The index of string descriptor describing this configuration. */ + public byte iConfiguration; + + /** The configuration characteristics. */ + public byte bmAttributes; + + /** + * The maximum power consumption of the USB device from this bus in this configuration when the device is fully + * operation. Expressed in units of 2 mA. + */ + public byte bMaxPower; + + /** The array with interfaces supported by this configuration. */ + public Pointer iface; + + /** + * Extra descriptors. + * + * If libusb encounters unknown interface descriptors, it will store them here, should you wish to parse them. + */ + public Pointer extra; + + /** Length of the extra descriptors, in bytes. */ + public int extra_length; + + @Override + protected List getFieldOrder() { + return Arrays.asList(new String[] { "bLength", "bDescriptorType", "wTotalLength", "bNumInterfaces", + "bConfigurationValue", "iConfiguration", "bmAttributes", "bMaxPower", "iface", "extra", "extra_length" }); + } + +} diff --git a/src/main/java/org/usb4java/jna/DeviceDescriptor.java b/src/main/java/org/usb4java/jna/DeviceDescriptor.java new file mode 100644 index 0000000..6d97520 --- /dev/null +++ b/src/main/java/org/usb4java/jna/DeviceDescriptor.java @@ -0,0 +1,56 @@ +/* + * Copyright 2013 Klaus Reimer + * See LICENSE.md for licensing information. + * + * Based on libusb : + * + * Copyright 2001 Johannes Erdfelt + * Copyright 2007-2009 Daniel Drake + * Copyright 2010-2012 Peter Stuge + * Copyright 2008-2013 Nathan Hjelm + * Copyright 2009-2013 Pete Batard + * Copyright 2009-2013 Ludovic Rousseau + * Copyright 2010-2012 Michael Plante + * Copyright 2011-2013 Hans de Goede + * Copyright 2012-2013 Martin Pieuchot + * Copyright 2012-2013 Toby Gray + */ + +package org.usb4java.jna; + +import java.util.Arrays; +import java.util.List; + +import com.sun.jna.Structure; + +/** + * A structure representing the standard USB device descriptor. + * + * This descriptor is documented in section 9.6.1 of the USB 3.0 specification. All multiple-byte fields are represented + * in host-endian format. + * + * @author Klaus Reimer (k@ailis.de) + */ +public class DeviceDescriptor extends Structure { + public byte bLength; + public byte bDescriptorType; + public short bcdUSB; + public byte bDeviceClass; + public byte bDeviceSubClass; + public byte bDeviceProtocol; + public byte bMaxPacketSize0; + public short idVendor; + public short idProduct; + public short bcdDevice; + public byte iManufacturer; + public byte iProduct; + public byte iSerialNumber; + public byte bNumConfigurations; + + @Override + protected List getFieldOrder() { + return Arrays.asList(new String[] { "bLength", "bDescriptorType", "bcdUSB", "bDeviceClass", "bDeviceSubClass", + "bDeviceProtocol", "bMaxPacketSize0", "idVendor", "idProduct", "bcdDevice", "iManufacturer", "iProduct", + "iSerialNumber", "bNumConfigurations" }); + } +} diff --git a/src/main/java/org/usb4java/jna/Interface.java b/src/main/java/org/usb4java/jna/Interface.java new file mode 100644 index 0000000..a56eb91 --- /dev/null +++ b/src/main/java/org/usb4java/jna/Interface.java @@ -0,0 +1,116 @@ +/* + * Copyright 2013 Klaus Reimer + * See LICENSE.md for licensing information. + * + * Based on libusb : + * + * Copyright 2001 Johannes Erdfelt + * Copyright 2007-2009 Daniel Drake + * Copyright 2010-2012 Peter Stuge + * Copyright 2008-2013 Nathan Hjelm + * Copyright 2009-2013 Pete Batard + * Copyright 2009-2013 Ludovic Rousseau + * Copyright 2010-2012 Michael Plante + * Copyright 2011-2013 Hans de Goede + * Copyright 2012-2013 Martin Pieuchot + * Copyright 2012-2013 Toby Gray + */ + +package org.usb4java.jna; + +import java.util.Arrays; +import java.util.List; + +import com.sun.jna.Pointer; +import com.sun.jna.Structure; + +/** + * A collection of alternate settings for a particular USB interface. + * + * @author Klaus Reimer (k@ailis.de) + */ +public final class Interface extends Structure { + public Pointer altsetting; + + public int num_altsetting; +// /** +// * Returns the array with interface descriptors. The length of this array is +// * determined by the {@link #numAltsetting()} field. +// * +// * @return The array with interface descriptors. +// */ +// public native InterfaceDescriptor[] altsetting(); +// +// /** +// * Returns the number of alternate settings that belong to this interface. +// * +// * @return The number of alternate settings. +// */ +// public native int numAltsetting(); +// +// /** +// * Returns a dump of this interface. +// * +// * @return The interface dump. +// */ +// public String dump() +// { +// final StringBuilder builder = new StringBuilder(); +// +// builder.append(String.format( +// "Interface:%n" + +// " numAltsetting %10d", +// this.numAltsetting())); +// +// for (final InterfaceDescriptor intDesc : this.altsetting()) +// { +// builder.append(String.format("%n") + intDesc.dump()); +// } +// +// return builder.toString(); +// } +// +// @Override +// public int hashCode() +// { +// return new HashCodeBuilder() +// .append(this.altsetting()) +// .append(this.numAltsetting()) +// .toHashCode(); +// } +// +// @Override +// public boolean equals(final Object obj) +// { +// if (this == obj) +// { +// return true; +// } +// if (obj == null) +// { +// return false; +// } +// if (this.getClass() != obj.getClass()) +// { +// return false; +// } +// +// final Interface other = (Interface) obj; +// +// return new EqualsBuilder() +// .append(this.altsetting(), other.altsetting()) +// .append(this.numAltsetting(), other.numAltsetting()) +// .isEquals(); +// } +// +// @Override +// public String toString() +// { +// return this.dump(); +// } + + @Override + protected List getFieldOrder() { + return Arrays.asList(new String[] { "altsetting", "num_altsetting" }); + } +} diff --git a/src/main/java/org/usb4java/jna/LibUsbNative.java b/src/main/java/org/usb4java/jna/LibUsbNative.java new file mode 100644 index 0000000..6f698d9 --- /dev/null +++ b/src/main/java/org/usb4java/jna/LibUsbNative.java @@ -0,0 +1,122 @@ +/* + * Copyright (C) 2015 Klaus Reimer + * See LICENSE.md for licensing information. + */ + +package org.usb4java.jna; + +import java.util.Arrays; +import java.util.List; + +import com.sun.jna.Library; +import com.sun.jna.Pointer; +import com.sun.jna.Structure; +import com.sun.jna.ptr.IntByReference; +import com.sun.jna.ptr.PointerByReference; + +/** + * TODO Document me. + * + * @author Klaus Reimer (k@ailis.de) + */ +public interface LibUsbNative extends Library { + + public static class libusb_version extends Structure { + public short major; + + public short minor; + + public short micro; + + public short nano; + + public String rc; + + public String describe; + + @Override + protected List getFieldOrder() { + return Arrays.asList(new String[] { "major", "minor", "micro", "nano", "rc", "describe" }); + } + } + + public String libusb_error_name(int error_code); + + public int libusb_has_capability(int capability); + + public libusb_version libusb_get_version(); + + public int libusb_setlocale(String locale); + + public String libusb_strerror(int errcode); + + public int libusb_init(PointerByReference context); + + public void libusb_set_debug(Pointer context, int level); + + public void libusb_exit(Pointer context); + + public int libusb_get_device_list(Pointer context, PointerByReference list); + + public void libusb_free_device_list(Pointer list, int unref_devices); + + public byte libusb_get_bus_number(Pointer device); + + public byte libusb_get_port_number(Pointer device); + + public int libusb_get_port_numbers(Pointer device, byte[] port_numbers, int port_numbers_len); + + public Pointer libusb_get_parent(Pointer device); + + public byte libusb_get_device_address(Pointer device); + + public int libusb_get_device_speed(Pointer device); + + public int libusb_get_max_packet_size(Pointer device, byte endpoint); + + public int libusb_get_max_iso_packet_size(Pointer device, byte endpoint); + + public Pointer libusb_ref_device(Pointer device); + + public void libusb_unref_device(Pointer device); + + public int libusb_open(Pointer device, PointerByReference handle); + + public Pointer libusb_open_device_with_vid_pid(Pointer context, short vendor_id, short product_id); + + public void libusb_close(Pointer handle); + + public Pointer libusb_get_device(Pointer handle); + + int libusb_get_configuration(Pointer handle, IntByReference config); + + int libusb_set_configuration(Pointer handle, int configuration); + + int libusb_claim_interface(Pointer handle, int interface_number); + + int libusb_release_interface(Pointer handle, int interface_number); + + int libusb_set_interface_alt_setting(Pointer handle, int interface_number, int alternate_setting); + + int libusb_clear_halt(Pointer handle, byte endpoint); + + int libusb_reset_device(Pointer handle); + + int libusb_kernel_driver_active(Pointer handle, int interface_number); + + int libusb_detach_kernel_driver(Pointer handle, int interface_number); + + int libusb_attach_kernel_driver(Pointer handle, int interface_number); + + int libusb_set_auto_detach_kernel_driver(Pointer handle, int enable); + + int libusb_get_device_descriptor(Pointer device, DeviceDescriptor descriptor); + + int libusb_get_active_config_descriptor(Pointer device, PointerByReference config); + + int libusb_get_config_descriptor(Pointer device, byte config_index, PointerByReference config); + + int libusb_get_config_descriptor_by_value(Pointer device, byte bConfigurationValue, PointerByReference config); + + void libusb_free_config_descriptor(ConfigDescriptor config); +} diff --git a/src/main/java/org/usb4java/jna/Test.java b/src/main/java/org/usb4java/jna/Test.java new file mode 100644 index 0000000..abe47ac --- /dev/null +++ b/src/main/java/org/usb4java/jna/Test.java @@ -0,0 +1,111 @@ +/** + * + */ + +package org.usb4java.jna; + +import com.sun.jna.Native; +import com.sun.jna.Pointer; +import com.sun.jna.ptr.IntByReference; +import com.sun.jna.ptr.PointerByReference; + +/** + * @author k + * + */ +public class Test { + + /** + * @param args + */ + public static void main(final String[] args) { + final LibUsbNative lib = (LibUsbNative) Native.loadLibrary("usb-1.0", LibUsbNative.class); + final PointerByReference contextRef = new PointerByReference(); + System.out.println(lib.libusb_init(contextRef)); + final Pointer context = contextRef.getValue(); + lib.libusb_set_debug(context, 4); + + + final PointerByReference listRef = new PointerByReference(); + final int size = lib.libusb_get_device_list(context, listRef); + final Pointer list = listRef.getValue(); + final Pointer[] devices = list.getPointerArray(0, size); + for (final Pointer device: devices) { + System.out.print("bus " + lib.libusb_get_bus_number(device)); + System.out.println(" port " + lib.libusb_get_port_number(device)); + final byte[] ports = new byte[16]; + final int len = lib.libusb_get_port_numbers(device, ports, 16); + System.out.print("Port numbers: "); + for (int i = 0; i < len; ++i) { + System.out.print(ports[i] + " "); + } + final Pointer parent = lib.libusb_get_parent(device); + System.out.println("Parent: " + parent); + System.out.println("Address: " + lib.libusb_get_device_address(device)); + System.out.println("Speed: " + lib.libusb_get_device_speed(device)); + System.out.println("max packet size: " + lib.libusb_get_max_packet_size(device, (byte) 1)); + System.out.println("max iso packet size: " + lib.libusb_get_max_iso_packet_size(device, (byte) 1)); + + final Pointer ref2 = lib.libusb_ref_device(device); + lib.libusb_unref_device(ref2); + + final PointerByReference handleRef = new PointerByReference(); + lib.libusb_open(device, handleRef); + final Pointer handle = handleRef.getValue(); + System.out.println("Handle: " + handle); + if (handle != null) { + System.out.println("Got one!"); + + lib.libusb_close(handle); + System.out.println(lib.libusb_get_device(handle)); + System.out.println(device); + + final IntByReference configRef = new IntByReference(); + // System.out.println(lib.libusb_get_configuration(handle, configRef)); + // System.out.println(configRef.getValue()); + +// System.out.println(lib.libusb_set_configuration(handle, 1)); + // System.out.println(lib.libusb_claim_interface(handle, 1)); + + final DeviceDescriptor descriptor = new DeviceDescriptor(); + System.out.println(lib.libusb_get_device_descriptor(device, descriptor)); + System.out.println(Integer.toHexString(descriptor.idVendor)); + System.out.println(Integer.toHexString(descriptor.idProduct)); + + final PointerByReference configDescriptorRef = new PointerByReference(); + System.out.println(configDescriptorRef.getValue()); + System.out.println(lib.libusb_get_active_config_descriptor(device, configDescriptorRef)); + final ConfigDescriptor configDescriptor = new ConfigDescriptor(configDescriptorRef.getValue()); + System.out.println(configDescriptorRef.getValue()); + System.out.println(configDescriptor.bNumInterfaces); + System.out.println(configDescriptor.bDescriptorType); + System.out.println(configDescriptor.wTotalLength); + lib.libusb_free_config_descriptor(configDescriptor); + + final PointerByReference configDescriptorRef2 = new PointerByReference(); + System.out.println(configDescriptorRef2.getValue()); + System.out.println(lib.libusb_get_config_descriptor(device, (byte) 0, configDescriptorRef2)); + final ConfigDescriptor configDescriptor2 = new ConfigDescriptor(configDescriptorRef2.getValue()); + System.out.println(configDescriptorRef2.getValue()); + System.out.println(configDescriptor2.bNumInterfaces); + System.out.println(configDescriptor2.bDescriptorType); + System.out.println(configDescriptor2.wTotalLength); + System.out.println(configDescriptor2.iface); + lib.libusb_free_config_descriptor(configDescriptor2); + + break; + } + + + System.out.println(); + } + lib.libusb_free_device_list(list, 1); + + +// System.out.println(lib.libusb_open_device_with_vid_pid(context, (short) 0x16c0, (short) 0x05dc)); + + lib.libusb_exit(context); + System.out.println("Exit"); + } + +} From 9748c0cce2dc09664805ca8a990599445b31c344 Mon Sep 17 00:00:00 2001 From: Klaus Reimer Date: Fri, 17 Apr 2015 07:13:45 +0200 Subject: [PATCH 2/5] More JNA implementations --- src/main/java/org/usb4java/Context.java | 78 +- src/main/java/org/usb4java/Device.java | 67 +- src/main/java/org/usb4java/DeviceHandle.java | 68 +- src/main/java/org/usb4java/DeviceList.java | 73 +- src/main/java/org/usb4java/LibUsb.java | 1883 +++++++---------- src/main/java/org/usb4java/Version.java | 89 +- .../org/usb4java/jna/ConfigDescriptor.java | 6 +- .../org/usb4java/jna/EndpointDescriptor.java | 86 + src/main/java/org/usb4java/jna/Interface.java | 86 +- .../org/usb4java/jna/InterfaceDescriptor.java | 85 + .../java/org/usb4java/jna/LibUsbNative.java | 24 +- .../java/org/usb4java/jna/NativeVersion.java | 25 + src/main/java/org/usb4java/jna/Test.java | 61 +- src/test/java/org/usb4java/LibUsbTest.java | 96 +- src/test/java/org/usb4java/VersionTest.java | 20 +- 15 files changed, 1290 insertions(+), 1457 deletions(-) create mode 100644 src/main/java/org/usb4java/jna/EndpointDescriptor.java create mode 100644 src/main/java/org/usb4java/jna/InterfaceDescriptor.java create mode 100644 src/main/java/org/usb4java/jna/NativeVersion.java diff --git a/src/main/java/org/usb4java/Context.java b/src/main/java/org/usb4java/Context.java index eab85ed..348f43c 100644 --- a/src/main/java/org/usb4java/Context.java +++ b/src/main/java/org/usb4java/Context.java @@ -18,34 +18,29 @@ package org.usb4java; +import com.sun.jna.Pointer; + /** - * Structure representing a libusb session. The concept of individual libusb - * sessions allows for your program to use two libraries (or dynamically load - * two modules) which both independently use libusb. This will prevent - * interference between the individual libusb users - for example - * {@link LibUsb#setDebug(Context, int)} will not affect the other user of the - * library, and {@link LibUsb#exit(Context)} will not destroy resources that the - * other user is still using. + * Structure representing a libusb session. The concept of individual libusb sessions allows for your program to use two + * libraries (or dynamically load two modules) which both independently use libusb. This will prevent interference + * between the individual libusb users - for example {@link LibUsb#setDebug(Context, int)} will not affect the other + * user of the library, and {@link LibUsb#exit(Context)} will not destroy resources that the other user is still using. * - * Sessions are created by {@link LibUsb#init(Context)} and destroyed through - * {@link LibUsb#exit(Context)}. If your application is guaranteed to only ever - * include a single libusb user (i.e. you), you do not have to worry about - * contexts: pass NULL in every function call where a context is required. The - * default context will be used. + * Sessions are created by {@link LibUsb#init(Context)} and destroyed through {@link LibUsb#exit(Context)}. If your + * application is guaranteed to only ever include a single libusb user (i.e. you), you do not have to worry about + * contexts: pass NULL in every function call where a context is required. The default context will be used. * * @author Klaus Reimer (k@ailis.de) */ -public final class Context -{ +public final class Context { /** The native pointer to the context structure. */ - private long contextPointer; + private Pointer contextPointer; /** - * Constructs a new libusb context. Must be passed to - * {@link LibUsb#init(Context)} before passing it to any other method. + * Constructs a new libusb context. Must be passed to {@link LibUsb#init(Context)} before passing it to any other + * method. */ - public Context() - { + public Context() { // Empty } @@ -54,47 +49,42 @@ public Context() * * @return The native pointer to the context structure. */ - public long getPointer() - { + public Pointer getPointer() { return this.contextPointer; } + /** + * Sets the context pointer. This must only be called from {@link LibUsb#init(Context)}. + * + * @param pointer + * The pointer to set. + */ + void setPointer(final Pointer pointer) { + this.contextPointer = pointer; + } + @Override - public int hashCode() - { - final int prime = 31; - int result = 1; - result = (prime * result) - + (int) (this.contextPointer ^ (this.contextPointer >>> 32)); - return result; + public int hashCode() { + return this.contextPointer.hashCode(); } @Override - public boolean equals(final Object obj) - { - if (this == obj) - { + public boolean equals(final Object obj) { + if (this == obj) { return true; } - if (obj == null) - { + if (obj == null) { return false; } - if (this.getClass() != obj.getClass()) - { + if (this.getClass() != obj.getClass()) { return false; } final Context other = (Context) obj; - if (this.contextPointer != other.contextPointer) - { - return false; - } - return true; + return (this.contextPointer != null && this.contextPointer.equals(other.contextPointer)); } @Override - public String toString() - { - return String.format("libusb context 0x%x", this.contextPointer); + public String toString() { + return String.format("libusb context " + this.contextPointer); } } diff --git a/src/main/java/org/usb4java/Device.java b/src/main/java/org/usb4java/Device.java index 71f20df..5a74cb0 100644 --- a/src/main/java/org/usb4java/Device.java +++ b/src/main/java/org/usb4java/Device.java @@ -18,39 +18,36 @@ package org.usb4java; +import com.sun.jna.Pointer; + /** * Structure representing a USB device detected on the system. * - * This is an opaque type for which you are only ever provided with a pointer, - * usually originating from {@link LibUsb#getDeviceList(Context, DeviceList)}. + * This is an opaque type for which you are only ever provided with a pointer, usually originating from + * {@link LibUsb#getDeviceList(Context, DeviceList)}. * - * Certain operations can be performed on a device, but in order to do any I/O - * you will have to first obtain a device handle using - * {@link LibUsb#open(Device, DeviceHandle)}. + * Certain operations can be performed on a device, but in order to do any I/O you will have to first obtain a device + * handle using {@link LibUsb#open(Device, DeviceHandle)}. * - * Devices are reference counted with {@link LibUsb#refDevice(Device)} and - * {@link LibUsb#unrefDevice(Device)}, and are freed when the reference count - * reaches 0. New devices presented by - * {@link LibUsb#getDeviceList(Context, DeviceList)} have a reference count of - * 1, and {@link LibUsb#freeDeviceList(DeviceList, boolean)} can optionally - * decrease the reference count on all devices in the list. - * {@link LibUsb#open(Device, DeviceHandle)} adds another reference which is + * Devices are reference counted with {@link LibUsb#refDevice(Device)} and {@link LibUsb#unrefDevice(Device)}, and are + * freed when the reference count reaches 0. New devices presented by {@link LibUsb#getDeviceList(Context, DeviceList)} + * have a reference count of 1, and {@link LibUsb#freeDeviceList(DeviceList, boolean)} can optionally decrease the + * reference count on all devices in the list. {@link LibUsb#open(Device, DeviceHandle)} adds another reference which is * later destroyed by {@link LibUsb#close(DeviceHandle)}. * * @author Klaus Reimer (k@ailis.de) */ -public final class Device -{ +public final class Device { /** The native pointer to the device structure. */ - private long devicePointer; + private final Pointer devicePointer; /** - * Package-private constructor to prevent manual instantiation. Devices are - * always created by JNI. + * Creates a new device. + * + * @param devicePointer The native device pointer. */ - Device() - { - // Empty + Device(final Pointer devicePointer) { + this.devicePointer = devicePointer; } /** @@ -58,47 +55,39 @@ public final class Device * * @return The native pointer to the device structure. */ - public long getPointer() - { + public Pointer getPointer() { return this.devicePointer; } @Override - public int hashCode() - { + public int hashCode() { + final long nativePointer = Pointer.nativeValue(this.devicePointer); final int prime = 31; int result = 1; - result = (prime * result) - + (int) (this.devicePointer ^ (this.devicePointer >>> 32)); + result = (prime * result) + (int) (nativePointer ^ (nativePointer >>> 32)); return result; } @Override - public boolean equals(final Object obj) - { - if (this == obj) - { + public boolean equals(final Object obj) { + if (this == obj) { return true; } - if (obj == null) - { + if (obj == null) { return false; } - if (this.getClass() != obj.getClass()) - { + if (this.getClass() != obj.getClass()) { return false; } final Device other = (Device) obj; - if (this.devicePointer != other.devicePointer) - { + if (Pointer.nativeValue(this.devicePointer) != Pointer.nativeValue(other.devicePointer)) { return false; } return true; } @Override - public String toString() - { - return String.format("libusb device 0x%x", this.devicePointer); + public String toString() { + return String.format("libusb device 0x%x", Pointer.nativeValue(this.devicePointer)); } } diff --git a/src/main/java/org/usb4java/DeviceHandle.java b/src/main/java/org/usb4java/DeviceHandle.java index 47f1130..a0af9e0 100644 --- a/src/main/java/org/usb4java/DeviceHandle.java +++ b/src/main/java/org/usb4java/DeviceHandle.java @@ -18,79 +18,83 @@ package org.usb4java; +import com.sun.jna.Pointer; + /** * Structure representing a handle on a USB device. * - * This is an opaque type for which you are only ever provided with a pointer, - * usually originating from {@link LibUsb#open(Device, DeviceHandle)}. + * This is an opaque type for which you are only ever provided with a pointer, usually originating from + * {@link LibUsb#open(Device, DeviceHandle)}. * - * A device handle is used to perform I/O and other operations. When finished - * with a device handle, you should call {@link LibUsb#close(DeviceHandle)}. + * A device handle is used to perform I/O and other operations. When finished with a device handle, you should call + * {@link LibUsb#close(DeviceHandle)}. * * @author Klaus Reimer (k@ailis.de) */ -public final class DeviceHandle -{ +public final class DeviceHandle { /** The native pointer to the device handle structure. */ - private long deviceHandlePointer; + private Pointer deviceHandlePointer; /** - * Constructs a new device handle. Must be passed to - * {@link LibUsb#open(Device, DeviceHandle)} before passing it to any - * other method. + * Constructs a new device handle. Must be passed to {@link LibUsb#open(Device, DeviceHandle)} before passing it to + * any other method. */ - public DeviceHandle() - { + public DeviceHandle() { // Empty } + /** + * Constructs a new device handle with the specified underlying native handle pointer. + * + * @param deviceHandlePointer + * The native handle pointer. + */ + public DeviceHandle(final Pointer deviceHandlePointer) { + init(deviceHandlePointer); + } + + void init(final Pointer deviceHandlePointer) { + this.deviceHandlePointer = deviceHandlePointer; + } + /** * Returns the native pointer to the device handle structure. * * @return The native pointer to the device handle structure. */ - public long getPointer() - { + public Pointer getPointer() { return this.deviceHandlePointer; } @Override - public int hashCode() - { + public int hashCode() { + final long nativePointer = Pointer.nativeValue(this.deviceHandlePointer); final int prime = 31; int result = 1; - result = (prime * result) + (int) (this.deviceHandlePointer ^ - (this.deviceHandlePointer >>> 32)); + result = (prime * result) + (int) (nativePointer ^ (nativePointer >>> 32)); return result; } @Override - public boolean equals(final Object obj) - { - if (this == obj) - { + public boolean equals(final Object obj) { + if (this == obj) { return true; } - if (obj == null) - { + if (obj == null) { return false; } - if (this.getClass() != obj.getClass()) - { + if (this.getClass() != obj.getClass()) { return false; } final DeviceHandle other = (DeviceHandle) obj; - if (this.deviceHandlePointer != other.deviceHandlePointer) - { + if (Pointer.nativeValue(this.deviceHandlePointer) != Pointer.nativeValue(other.deviceHandlePointer)) { return false; } return true; } @Override - public String toString() - { - return String.format("libusb device handle 0x%x", - this.deviceHandlePointer); + public String toString() { + return String.format("libusb device handle 0x%x", Pointer.nativeValue(this.deviceHandlePointer)); } } diff --git a/src/main/java/org/usb4java/DeviceList.java b/src/main/java/org/usb4java/DeviceList.java index 82f987e..5819045 100644 --- a/src/main/java/org/usb4java/DeviceList.java +++ b/src/main/java/org/usb4java/DeviceList.java @@ -20,36 +20,47 @@ import java.util.Iterator; +import com.sun.jna.Pointer; + /** - * List of devices as returned by - * {@link LibUsb#getDeviceList(Context, DeviceList)}. + * List of devices as returned by {@link LibUsb#getDeviceList(Context, DeviceList)}. * * @author Klaus Reimer (k@ailis.de) */ -public final class DeviceList implements Iterable -{ +public final class DeviceList implements Iterable { /** The native pointer to the devices array. */ - private long deviceListPointer; + private Pointer deviceListPointer; /** The number of devices in the list. */ private int size; /** - * Constructs a new device list. Must be passed to - * {@link LibUsb#getDeviceList(Context, DeviceList)} before using it. + * Constructs a new device list. Must be passed to {@link LibUsb#getDeviceList(Context, DeviceList)} before using + * it. */ - public DeviceList() - { + public DeviceList() { // Empty } + /** + * Initializes the device list. + * + * @param deviceListPointer + * The native pointer to set. + * @param size + * The number of devices. + */ + void init(final Pointer deviceListPointer, final int size) { + this.deviceListPointer = deviceListPointer; + this.size = size; + } + /** * Returns the native pointer. * * @return The native pointer. */ - public long getPointer() - { + public Pointer getPointer() { return this.deviceListPointer; } @@ -58,11 +69,10 @@ public long getPointer() * * @return The number of devices in the list. */ - public int getSize() - { + public int getSize() { return this.size; } - + /** * Returns the device with the specified index. * @@ -70,47 +80,42 @@ public int getSize() * The device index. * @return The device or null when index is out of bounds. */ - public native Device get(final int index); + public Device get(final int index) { + return new Device(this.deviceListPointer.getPointer(index * Pointer.SIZE)); + } @Override - public Iterator iterator() - { + public Iterator iterator() { return new DeviceListIterator(this); } @Override - public int hashCode() - { + public int hashCode() { + final long nativePointer = Pointer.nativeValue(this.deviceListPointer); final int prime = 31; int result = 1; - result = (prime * result) - + (int) (this.deviceListPointer ^ (this.deviceListPointer >>> 32)); + result = (prime * result) + (int) (nativePointer ^ (nativePointer >>> 32)); return result; } @Override - public boolean equals(final Object obj) - { - if (this == obj) - { + public boolean equals(final Object obj) { + if (this == obj) { return true; } - if (obj == null) - { + if (obj == null) { return false; } - if (this.getClass() != obj.getClass()) - { + if (this.getClass() != obj.getClass()) { return false; } final DeviceList other = (DeviceList) obj; - return this.deviceListPointer == other.deviceListPointer; + return Pointer.nativeValue(this.deviceListPointer) == Pointer.nativeValue(other.deviceListPointer); } @Override - public String toString() - { - return String.format("libusb device list 0x%x with size %d", - this.deviceListPointer, this.size); + public String toString() { + return String.format("libusb device list 0x%x with size %d", Pointer.nativeValue(this.deviceListPointer), + this.size); } } diff --git a/src/main/java/org/usb4java/LibUsb.java b/src/main/java/org/usb4java/LibUsb.java index 3d8dbd1..9069f4d 100644 --- a/src/main/java/org/usb4java/LibUsb.java +++ b/src/main/java/org/usb4java/LibUsb.java @@ -27,6 +27,13 @@ import java.util.concurrent.ConcurrentMap; import org.apache.commons.lang3.tuple.ImmutablePair; +import org.usb4java.jna.LibUsbNative; +import org.usb4java.jna.NativeVersion; + +import com.sun.jna.Native; +import com.sun.jna.Pointer; +import com.sun.jna.ptr.IntByReference; +import com.sun.jna.ptr.PointerByReference; /** * Static class providing the constants and functions of libusb. @@ -34,8 +41,7 @@ * @author Klaus Reimer (k@ailis.de) * @author Luca Longinotti (l@longi.li) */ -public final class LibUsb -{ +public final class LibUsb { // Log message levels. /** No messages ever printed by the library (default). */ @@ -48,14 +54,12 @@ public final class LibUsb public static final int LOG_LEVEL_WARNING = 2; /** - * Informational messages are printed to stdout, warning and error messages - * are printed to stderr. + * Informational messages are printed to stdout, warning and error messages are printed to stderr. */ public static final int LOG_LEVEL_INFO = 3; /** - * Debug and informational messages are printed to stdout, warnings and - * errors to stderr. + * Debug and informational messages are printed to stdout, warnings and errors to stderr. */ public static final int LOG_LEVEL_DEBUG = 4; @@ -205,8 +209,7 @@ public final class LibUsb public static final byte REQUEST_SET_SEL = 0x30; /** - * Delay from the time a host transmits a packet to the time it is received - * by the device. + * Delay from the time a host transmits a packet to the time it is received by the device. */ public static final byte SET_ISOCH_DELAY = 0x31; @@ -250,17 +253,15 @@ public final class LibUsb public static final int CAP_HAS_HOTPLUG = 0x0001; /** - * The library can access HID devices without requiring user intervention. - * Note that before being able to actually access an HID device, you may - * still have to call additional libusb functions such as + * The library can access HID devices without requiring user intervention. Note that before being able to actually + * access an HID device, you may still have to call additional libusb functions such as * {@link #detachKernelDriver(DeviceHandle, int)}. */ public static final int CAP_HAS_HID_ACCESS = 0x0100; /** - * The library supports detaching of the default USB driver, using - * {@link #detachKernelDriver(DeviceHandle, int)}, if one is set by the OS - * kernel. + * The library supports detaching of the default USB driver, using {@link #detachKernelDriver(DeviceHandle, int)}, + * if one is set by the OS kernel. */ public static final int CAP_SUPPORTS_DETACH_KERNEL_DRIVER = 0x0101; @@ -270,9 +271,8 @@ public final class LibUsb // Device and/or Interface Class codes. /** - * In the context of a device descriptor, this bDeviceClass value indicates - * that each interface specifies its own class information and all - * interfaces operate independently. + * In the context of a device descriptor, this bDeviceClass value indicates that each interface specifies its own + * class information and all interfaces operate independently. */ public static final byte CLASS_PER_INTERFACE = 0; @@ -440,9 +440,8 @@ public final class LibUsb public static final byte BT_CONTAINER_ID_SIZE = 20; /** We unwrap the BOS => define its maximum size. */ - public static final byte DT_BOS_MAX_SIZE = DT_BOS_SIZE - + BT_USB_2_0_EXTENSION_SIZE + BT_SS_USB_DEVICE_CAPABILITY_SIZE - + BT_CONTAINER_ID_SIZE; + public static final byte DT_BOS_MAX_SIZE = DT_BOS_SIZE + BT_USB_2_0_EXTENSION_SIZE + + BT_SS_USB_DEVICE_CAPABILITY_SIZE + BT_CONTAINER_ID_SIZE; // Endpoint direction. Values for bit 7 of the endpoint address scheme. @@ -523,54 +522,45 @@ public final class LibUsb /** * Automatically free transfer buffer during {@link #freeTransfer(Transfer)} * - * Please note that this flag (which is originally 2) is effectively a no-op - * (set to zero) here in the Java wrapper, since the ByteBuffer that acts as - * a buffer for transfers is allocated by the JVM and is subject to garbage - * collection like any other object at some point. Nulling the reference is - * the only needed action to take, and it is already done by the - * TRANSFER_FREE_TRANSFER flag. + * Please note that this flag (which is originally 2) is effectively a no-op (set to zero) here in the Java wrapper, + * since the ByteBuffer that acts as a buffer for transfers is allocated by the JVM and is subject to garbage + * collection like any other object at some point. Nulling the reference is the only needed action to take, and it + * is already done by the TRANSFER_FREE_TRANSFER flag. */ public static final byte TRANSFER_FREE_BUFFER = 0; /** - * Automatically call {@link #freeTransfer(Transfer)} after callback - * returns. + * Automatically call {@link #freeTransfer(Transfer)} after callback returns. * - * If this flag is set, it is illegal to call - * {@link #freeTransfer(Transfer)} from your transfer callback, as this will - * result in a double-free when this flag is acted upon. + * If this flag is set, it is illegal to call {@link #freeTransfer(Transfer)} from your transfer callback, as this + * will result in a double-free when this flag is acted upon. */ public static final byte TRANSFER_FREE_TRANSFER = 4; /** - * Terminate transfers that are a multiple of the endpoint's wMaxPacketSize - * with an extra zero length packet. + * Terminate transfers that are a multiple of the endpoint's wMaxPacketSize with an extra zero length packet. * - * This is useful when a device protocol mandates that each logical request - * is terminated by an incomplete packet (i.e. the logical requests are not - * separated by other means). + * This is useful when a device protocol mandates that each logical request is terminated by an incomplete packet + * (i.e. the logical requests are not separated by other means). * - * This flag only affects host-to-device transfers to bulk and interrupt - * endpoints. In other situations, it is ignored. + * This flag only affects host-to-device transfers to bulk and interrupt endpoints. In other situations, it is + * ignored. * - * This flag only affects transfers with a length that is a multiple of the - * endpoint's wMaxPacketSize. On transfers of other lengths, this flag has - * no effect. Therefore, if you are working with a device that needs a ZLP - * whenever the end of the logical request falls on a packet boundary, then - * it is sensible to set this flag on every transfer (you do not have to - * worry about only setting it on transfers that end on the boundary). + * This flag only affects transfers with a length that is a multiple of the endpoint's wMaxPacketSize. On transfers + * of other lengths, this flag has no effect. Therefore, if you are working with a device that needs a ZLP whenever + * the end of the logical request falls on a packet boundary, then it is sensible to set this flag on every transfer + * (you do not have to worry about only setting it on transfers that end on the boundary). * - * This flag is currently only supported on Linux. On other systems, - * libusb_submit_transfer() will return {@link #ERROR_NOT_SUPPORTED} for - * every transfer where this flag is set. + * This flag is currently only supported on Linux. On other systems, libusb_submit_transfer() will return + * {@link #ERROR_NOT_SUPPORTED} for every transfer where this flag is set. */ public static final byte TRANSFER_ADD_ZERO_PACKET = 8; // Transfer status codes /** - * Transfer completed without error. Note that this does not indicate that - * the entire amount of requested data was transferred. + * Transfer completed without error. Note that this does not indicate that the entire amount of requested data was + * transferred. */ public static final int TRANSFER_COMPLETED = 0; @@ -584,8 +574,8 @@ public final class LibUsb public static final int TRANSFER_CANCELLED = 3; /** - * For bulk/interrupt endpoints: halt condition detected (endpoint stalled). - * For control endpoints: control request not supported. + * For bulk/interrupt endpoints: halt condition detected (endpoint stalled). For control endpoints: control request + * not supported. */ public static final int TRANSFER_STALL = 4; @@ -613,11 +603,9 @@ public final class LibUsb public static final int HOTPLUG_EVENT_DEVICE_ARRIVED = 0x01; /** - * A device has left and is no longer available. - * It is the user's responsibility to call {@link #close(DeviceHandle)} on - * any handle associated with a disconnected device. - * It is safe to call {@link #getDeviceDescriptor(Device, DeviceDescriptor)} - * on a device that has left. + * A device has left and is no longer available. It is the user's responsibility to call + * {@link #close(DeviceHandle)} on any handle associated with a disconnected device. It is safe to call + * {@link #getDeviceDescriptor(Device, DeviceDescriptor)} on a device that has left. */ public static final int HOTPLUG_EVENT_DEVICE_LEFT = 0x02; @@ -632,141 +620,154 @@ public final class LibUsb /** * Hotplug callbacks (to correctly manage calls and additional data). */ - private static final ConcurrentMap> hotplugCallbacks = + private static final ConcurrentMap> hotplugCallbacks = new ConcurrentHashMap>(); /** * Pollfd listeners (to support different listeners for different contexts). */ - private static final ConcurrentMap> pollfdListeners = + private static final ConcurrentMap> pollfdListeners = new ConcurrentHashMap>(); - static - { - Loader.load(); - } + /** The JNA interface to the libusb library. */ + private static LibUsbNative lib = (LibUsbNative) Native.loadLibrary("usb-1.0", LibUsbNative.class); /** * Private constructor to prevent instantiation. */ - private LibUsb() - { + private LibUsb() { // Empty } /** - * Returns the API version of the underlying libusb library. It is defined - * as follows: (major << 24) | (minor << 16) | (16 bit incremental) + * Returns the API version of the underlying libusb library. It is defined as follows: (major << 24) | (minor << 16) + * | (16 bit incremental) * * @return The API version of the underlying libusb library. + * @deprecated The API version can no longer be read from JNA because it is implemented as a define. Use + * {@link #getVersion()} instead to read the libusb library version. This deprecated method converts + * the library version to an API version which is not really correct but acceptable. */ - public static native int getApiVersion(); + @Deprecated + public static int getApiVersion() { + NativeVersion version = lib.libusb_get_version(); + return version.major << 24 | version.minor << 16 | version.micro; + } /** * Initialize libusb. * * This function must be called before calling any other libusb function. * - * If you do not provide an output location for a {@link Context}, a default - * context will be created. If there was already a default context, it will - * be reused (and nothing will be initialized/reinitialized). + * If you do not provide an output location for a {@link Context}, a default context will be created. If there was + * already a default context, it will be reused (and nothing will be initialized/reinitialized). * * @param context - * Optional output location for context pointer. Null to use - * default context. Only valid on return code 0. + * Optional output location for context pointer. Null to use default context. Only valid on return code + * 0. * @return 0 on success or a error code on failure. */ - public static synchronized native int init(final Context context); + public static int init(final Context context) { + // Quick route for default context + if (context == null) { + return lib.libusb_init(null); + } + + final PointerByReference contextRef = new PointerByReference(); + final int result = lib.libusb_init(contextRef); + context.setPointer(contextRef.getValue()); + return result; + } /** * Deinitialize libusb. * - * Should be called after closing all open devices and before your - * application terminates. + * Should be called after closing all open devices and before your application terminates. * * @param context - * The {@link Context} to deinitialize, or NULL for the default - * context. + * The {@link Context} to deinitialize, or NULL for the default context. */ - public static synchronized native void exit(final Context context); + public static void exit(final Context context) { + lib.libusb_exit(context == null ? null : context.getPointer()); + } /** * Set log message verbosity. * - * The default level is {@link #LOG_LEVEL_NONE}, which means no messages are - * ever printed. If you choose to increase the message verbosity level, - * ensure that your application does not close the stdout/stderr file - * descriptors. + * The default level is {@link #LOG_LEVEL_NONE}, which means no messages are ever printed. If you choose to increase + * the message verbosity level, ensure that your application does not close the stdout/stderr file descriptors. * - * You are advised to use level {@link #LOG_LEVEL_WARNING}. libusb is - * conservative with its message logging and most of the time, will only log - * messages that explain error conditions and other oddities. This will help - * you debug your software. + * You are advised to use level {@link #LOG_LEVEL_WARNING}. libusb is conservative with its message logging and most + * of the time, will only log messages that explain error conditions and other oddities. This will help you debug + * your software. * - * If the {@link #LOG_LEVEL_DEBUG} environment variable was set when libusb - * was initialized, this function does nothing: the message verbosity is - * fixed to the value in the environment variable. + * If the {@link #LOG_LEVEL_DEBUG} environment variable was set when libusb was initialized, this function does + * nothing: the message verbosity is fixed to the value in the environment variable. * - * If libusb was compiled without any message logging, this function does - * nothing: you'll never get any messages. + * If libusb was compiled without any message logging, this function does nothing: you'll never get any messages. * - * If libusb was compiled with verbose debug message logging, this function - * does nothing: you'll always get messages from all levels. + * If libusb was compiled with verbose debug message logging, this function does nothing: you'll always get messages + * from all levels. * * @param context - * The {@link Context} to operate on, or NULL for the default - * context. + * The {@link Context} to operate on, or NULL for the default context. * @param level * The log level to set. */ - public static native void setDebug(final Context context, final int level); + public static void setDebug(final Context context, final int level) { + lib.libusb_set_debug(context == null ? null : context.getPointer(), level); + } /** * Returns the version of the libusb runtime. * * @return The version of the libusb runtime. */ - public static native Version getVersion(); + public static Version getVersion() { + return new Version(lib.libusb_get_version()); + } /** * Returns a list of USB devices currently attached to the system. * * This is your entry point into finding a USB device to operate. * - * You are expected to unreference all the devices when you are done with - * them, and then free the list with - * {@link #freeDeviceList(DeviceList, boolean)}. Note that - * {@link #freeDeviceList(DeviceList, boolean)} can unref all the devices - * for you. Be careful not to unreference a device you are about to open - * until after you have opened it. + * You are expected to unreference all the devices when you are done with them, and then free the list with + * {@link #freeDeviceList(DeviceList, boolean)}. Note that {@link #freeDeviceList(DeviceList, boolean)} can unref + * all the devices for you. Be careful not to unreference a device you are about to open until after you have opened + * it. * * @param context * The context to operate on, or NULL for the default context. * @param list - * Output location for a list of devices. Must be later freed - * with {@link #freeDeviceList(DeviceList, boolean)}. - * @return The number of devices in the outputted list, or any ERROR code - * according to errors encountered by the backend. - */ - public static native int getDeviceList(final Context context, - final DeviceList list); + * Output location for a list of devices. Must be later freed with + * {@link #freeDeviceList(DeviceList, boolean)}. + * @return The number of devices in the outputted list, or any ERROR code according to errors encountered by the + * backend. + */ + public static int getDeviceList(final Context context, final DeviceList list) { + final PointerByReference listRef = new PointerByReference(); + final int size = lib.libusb_get_device_list(context == null ? null : context.getPointer(), listRef); + if (size < 0) { + return size; + } + list.init(listRef.getValue(), size); + return size; + } /** - * Frees a list of devices previously discovered using - * {@link #getDeviceList(Context, DeviceList)}. + * Frees a list of devices previously discovered using {@link #getDeviceList(Context, DeviceList)}. * - * If the unref_devices parameter is set, the reference count of each device - * in the list is decremented by 1. + * If the unref_devices parameter is set, the reference count of each device in the list is decremented by 1. * * @param list * The list to free. * @param unrefDevices * Whether to unref the devices in the list. */ - public static native void freeDeviceList(final DeviceList list, - final boolean unrefDevices); + public static void freeDeviceList(final DeviceList list, final boolean unrefDevices) { + lib.libusb_free_device_list(list.getPointer(), unrefDevices ? 1 : 0); + } /** * Get the number of the bus that a device is connected to. @@ -775,7 +776,9 @@ public static native void freeDeviceList(final DeviceList list, * A device. * @return The bus number */ - public static native int getBusNumber(final Device device); + public static int getBusNumber(final Device device) { + return lib.libusb_get_bus_number(device.getPointer()); + } /** * Get the number of the port that a device is connected to. @@ -784,7 +787,9 @@ public static native void freeDeviceList(final DeviceList list, * A device * @return The port number (0 if not available). */ - public static native int getPortNumber(final Device device); + public static int getPortNumber(final Device device) { + return lib.libusb_get_port_number(device.getPointer()); + } /** * Get the list of all port numbers from root for the specified device. @@ -792,57 +797,51 @@ public static native void freeDeviceList(final DeviceList list, * @param device * A device. * @param path - * The array that should contain the port numbers. As per the USB - * 3.0 specs, the current maximum limit for the depth is 7. - * @return The number of elements filled, {@link #ERROR_OVERFLOW} if the - * array is too small + * The array that should contain the port numbers. As per the USB 3.0 specs, the current maximum limit + * for the depth is 7. + * @return The number of elements filled, {@link #ERROR_OVERFLOW} if the array is too small */ - public static native int getPortNumbers(final Device device, - final ByteBuffer path); + public static int getPortNumbers(final Device device, final ByteBuffer path) { + return lib.libusb_get_port_numbers(device.getPointer(), path, path.capacity()); + } /** * Get the list of all port numbers from root for the specified device. * - * @deprecated Please use {@link #getPortNumbers(Device, ByteBuffer)} - * instead. + * @deprecated Please use {@link #getPortNumbers(Device, ByteBuffer)} instead. * * @param context * The context. * @param device * A device. * @param path - * The array that should contain the port numbers. As per the USB - * 3.0 specs, the current maximum limit for the depth is 7. - * @return The number of elements filled, {@link #ERROR_OVERFLOW} if the - * array is too small + * The array that should contain the port numbers. As per the USB 3.0 specs, the current maximum limit + * for the depth is 7. + * @return The number of elements filled, {@link #ERROR_OVERFLOW} if the array is too small */ @Deprecated - public static int getPortPath(final Context context, final Device device, - final ByteBuffer path) - { + public static int getPortPath(final Context context, final Device device, final ByteBuffer path) { return getPortNumbers(device, path); } /** * Get the the parent from the specified device [EXPERIMENTAL]. * - * Please note that the reference count of the returned device is not - * increased. As such, do not *ever* call {@link #unrefDevice(Device)} - * directly on the returned Device. + * Please note that the reference count of the returned device is not increased. As such, do not *ever* call + * {@link #unrefDevice(Device)} directly on the returned Device. * * @param device * A device * @return The device parent or NULL if not available. You should issue a - * {@link #getDeviceList(Context, DeviceList)} before calling this - * function and make sure that you only access the parent before - * issuing {@link #freeDeviceList(DeviceList, boolean)}. The reason - * is that libusb currently does not maintain a permanent list of - * device instances, and therefore can only guarantee that parents - * are fully instantiated within a - * {@link #getDeviceList(Context, DeviceList)} - + * {@link #getDeviceList(Context, DeviceList)} before calling this function and make sure that you only + * access the parent before issuing {@link #freeDeviceList(DeviceList, boolean)}. The reason is that libusb + * currently does not maintain a permanent list of device instances, and therefore can only guarantee that + * parents are fully instantiated within a {@link #getDeviceList(Context, DeviceList)} - * {@link #freeDeviceList(DeviceList, boolean)} block. */ - public static native Device getParent(final Device device); + public static Device getParent(final Device device) { + return new Device(lib.libusb_get_parent(device.getPointer())); + } /** * Get the address of the device on the bus it is connected to. @@ -851,66 +850,67 @@ public static int getPortPath(final Context context, final Device device, * A device. * @return The device address */ - public static native int getDeviceAddress(final Device device); + public static int getDeviceAddress(final Device device) { + return lib.libusb_get_device_address(device.getPointer()); + } /** * Get the negotiated connection speed for a device. * * @param device * A device. - * @return A SPEED code, where {@link #SPEED_UNKNOWN} means that the OS - * doesn't know or doesn't support returning the negotiated speed. + * @return A SPEED code, where {@link #SPEED_UNKNOWN} means that the OS doesn't know or doesn't support returning + * the negotiated speed. */ - public static native int getDeviceSpeed(final Device device); + public static int getDeviceSpeed(final Device device) { + return lib.libusb_get_device_speed(device.getPointer()); + } /** - * Convenience function to retrieve the wMaxPacketSize value for a - * particular endpoint in the active device configuration. + * Convenience function to retrieve the wMaxPacketSize value for a particular endpoint in the active device + * configuration. * - * This function was originally intended to be of assistance when setting up - * isochronous transfers, but a design mistake resulted in this function - * instead. It simply returns the wMaxPacketSize value without considering - * its contents. If you're dealing with isochronous transfers, you probably - * want {@link #getMaxIsoPacketSize(Device, byte)} instead. + * This function was originally intended to be of assistance when setting up isochronous transfers, but a design + * mistake resulted in this function instead. It simply returns the wMaxPacketSize value without considering its + * contents. If you're dealing with isochronous transfers, you probably want + * {@link #getMaxIsoPacketSize(Device, byte)} instead. * * @param device * A device. * @param endpoint * Address of the endpoint in question. - * @return the wMaxPacketSize value {@link #ERROR_NOT_FOUND} if the endpoint - * does not exist {@link #ERROR_OTHER} on other failure + * @return the wMaxPacketSize value {@link #ERROR_NOT_FOUND} if the endpoint does not exist {@link #ERROR_OTHER} on + * other failure */ - public static native int getMaxPacketSize(final Device device, - final byte endpoint); + public static int getMaxPacketSize(final Device device, final byte endpoint) { + return lib.libusb_get_max_packet_size(device.getPointer(), endpoint); + } /** - * Calculate the maximum packet size which a specific endpoint is capable - * sending or receiving in the duration of 1 microframe. + * Calculate the maximum packet size which a specific endpoint is capable sending or receiving in the duration of 1 + * microframe. * - * Only the active configuration is examined. The calculation is based on - * the wMaxPacketSize field in the endpoint descriptor as described in - * section 9.6.6 in the USB 2.0 specifications. + * Only the active configuration is examined. The calculation is based on the wMaxPacketSize field in the endpoint + * descriptor as described in section 9.6.6 in the USB 2.0 specifications. * - * If acting on an isochronous or interrupt endpoint, this function will - * multiply the value found in bits 0:10 by the number of transactions per - * microframe (determined by bits 11:12). Otherwise, this function just - * returns the numeric value found in bits 0:10. + * If acting on an isochronous or interrupt endpoint, this function will multiply the value found in bits 0:10 by + * the number of transactions per microframe (determined by bits 11:12). Otherwise, this function just returns the + * numeric value found in bits 0:10. * - * This function is useful for setting up isochronous transfers, for example - * you might pass the return value from this function to - * {@link #setIsoPacketLengths(Transfer, int)} in order to set the length - * field of every isochronous packet in a transfer. + * This function is useful for setting up isochronous transfers, for example you might pass the return value from + * this function to {@link #setIsoPacketLengths(Transfer, int)} in order to set the length field of every + * isochronous packet in a transfer. * * @param device * A device. * @param endpoint * Address of the endpoint in question. - * @return The maximum packet size which can be sent/received on this - * endpoint {@link #ERROR_NOT_FOUND} if the endpoint does not exist - * {@link #ERROR_OTHER} on other failure. + * @return The maximum packet size which can be sent/received on this endpoint {@link #ERROR_NOT_FOUND} if the + * endpoint does not exist {@link #ERROR_OTHER} on other failure. */ - public static native int getMaxIsoPacketSize(final Device device, - final byte endpoint); + public static int getMaxIsoPacketSize(final Device device, final byte endpoint) { + return lib.libusb_get_max_iso_packet_size(device.getPointer(), endpoint); + } /** * Increment the reference count of a device. @@ -919,55 +919,58 @@ public static native int getMaxIsoPacketSize(final Device device, * The device to reference. * @return The same device. */ - public static native Device refDevice(final Device device); + public static Device refDevice(final Device device) { + return new Device(lib.libusb_ref_device(device.getPointer())); + } /** * Decrement the reference count of a device. * - * If the decrement operation causes the reference count to reach zero, the - * device shall be destroyed. + * If the decrement operation causes the reference count to reach zero, the device shall be destroyed. * * @param device * the device to unreference. */ - public static native void unrefDevice(final Device device); + public static void unrefDevice(final Device device) { + lib.libusb_unref_device(device.getPointer()); + } /** * Open a device and obtain a device handle. * * A handle allows you to perform I/O on the device in question. * - * Internally, this function adds a reference to the device and makes it - * available to you through {@link #getDevice(DeviceHandle)}. This reference - * is removed during {@link #close(DeviceHandle)}. + * Internally, this function adds a reference to the device and makes it available to you through + * {@link #getDevice(DeviceHandle)}. This reference is removed during {@link #close(DeviceHandle)}. * * This is a non-blocking function; no requests are sent over the bus. * * @param device * The device to open. * @param handle - * Output location for the returned device handle pointer. Only - * populated when the return code is 0. - * @return 0 on success, {@link #ERROR_NO_MEM} on memory allocation failure, - * {@link #ERROR_ACCESS} if the user has insufficient permissions, - * {@link #ERROR_NO_DEVICE} if the device has been disconnected, - * another error on other failure - */ - public static native int open(final Device device, - final DeviceHandle handle); + * Output location for the returned device handle pointer. Only populated when the return code is 0. + * @return 0 on success, {@link #ERROR_NO_MEM} on memory allocation failure, {@link #ERROR_ACCESS} if the user has + * insufficient permissions, {@link #ERROR_NO_DEVICE} if the device has been disconnected, another error on + * other failure + */ + public static int open(final Device device, final DeviceHandle handle) { + final PointerByReference handleRef = new PointerByReference(); + final int result = lib.libusb_open(device.getPointer(), handleRef); + if (result == SUCCESS) { + handle.init(handleRef.getValue()); + } + return result; + } /** - * Convenience function for finding a device with a particular - * idVendor/idProduct combination. + * Convenience function for finding a device with a particular idVendor/idProduct combination. * - * This function is intended for those scenarios where you are using libusb - * to knock up a quick test application - it allows you to avoid calling - * {@link #getDeviceList(Context, DeviceList)} and worrying about - * traversing/freeing the list. + * This function is intended for those scenarios where you are using libusb to knock up a quick test application - + * it allows you to avoid calling {@link #getDeviceList(Context, DeviceList)} and worrying about traversing/freeing + * the list. * - * This function has limitations and is hence not intended for use in real - * applications: if multiple devices have the same IDs it will only give you - * the first one, etc. + * This function has limitations and is hence not intended for use in real applications: if multiple devices have + * the same IDs it will only give you the first one, etc. * * @param context * The context to operate on, or NULL for the default context. @@ -975,121 +978,120 @@ public static native int open(final Device device, * The idVendor value to search for. * @param productId * The idProduct value to search for. - * @return A handle for the first found device or NULL on error or if the - * device could not be found. + * @return A handle for the first found device or NULL on error or if the device could not be found. */ - public static native DeviceHandle openDeviceWithVidPid( - final Context context, final short vendorId, final short productId); + public static DeviceHandle openDeviceWithVidPid(final Context context, final short vendorId, + final short productId) { + return new DeviceHandle(lib.libusb_open_device_with_vid_pid(context == null ? null : context.getPointer(), + vendorId, productId)); + } /** * Close a device handle. * * Should be called on all open handles before your application exits. * - * Internally, this function destroys the reference that was added by - * {@link #open(Device, DeviceHandle)} on the given device. + * Internally, this function destroys the reference that was added by {@link #open(Device, DeviceHandle)} on the + * given device. * * This is a non-blocking function; no requests are sent over the bus. * * @param handle * The handle to close. */ - public static native void close(final DeviceHandle handle); - -/** + public static void close(final DeviceHandle handle) { + lib.libusb_close(handle.getPointer()); + } + + /** * Get the underlying device for a handle. * - * Please note that the reference count of the returned device is not - * increased. As such, do not *ever* call {@link #unrefDevice(Device)} - * directly on the returned Device. + * Please note that the reference count of the returned device is not increased. As such, do not *ever* call + * {@link #unrefDevice(Device)} directly on the returned Device. * * @param handle * a device handle. * @return The underlying device. */ - public static native Device getDevice(final DeviceHandle handle); + public static Device getDevice(final DeviceHandle handle) { + return new Device(lib.libusb_get_device(handle.getPointer())); + } /** * Determine the bConfigurationValue of the currently active configuration. * - * You could formulate your own control request to obtain this information, - * but this function has the advantage that it may be able to retrieve the - * information from operating system caches (no I/O involved). + * You could formulate your own control request to obtain this information, but this function has the advantage that + * it may be able to retrieve the information from operating system caches (no I/O involved). * - * If the OS does not cache this information, then this function will block - * while a control transfer is submitted to retrieve the information. + * If the OS does not cache this information, then this function will block while a control transfer is submitted to + * retrieve the information. * - * This function will return a value of 0 in the config output parameter if - * the device is in unconfigured state. + * This function will return a value of 0 in the config output parameter if the device is in unconfigured state. * * @param handle * a device handle. * @param config - * output location for the bConfigurationValue of the active - * configuration (only valid for return code 0) - * @return 0 on success {@link #ERROR_NO_DEVICE} if the device has been - * disconnected another error code on other failure + * output location for the bConfigurationValue of the active configuration (only valid for return code 0) + * @return 0 on success {@link #ERROR_NO_DEVICE} if the device has been disconnected another error code on other + * failure */ - public static native int getConfiguration(final DeviceHandle handle, - final IntBuffer config); + public static int getConfiguration(final DeviceHandle handle, final IntBuffer config) { + final IntByReference configRef = new IntByReference(); + final int result = lib.libusb_get_configuration(handle.getPointer(), configRef); + if (result == SUCCESS) { + config.put(0, configRef.getValue()); + } + return result; + } /** * Set the active configuration for a device. * - * The operating system may or may not have already set an active - * configuration on the device. It is up to your application to ensure the - * correct configuration is selected before you attempt to claim interfaces - * and perform other operations. + * The operating system may or may not have already set an active configuration on the device. It is up to your + * application to ensure the correct configuration is selected before you attempt to claim interfaces and perform + * other operations. * - * If you call this function on a device already configured with the - * selected configuration, then this function will act as a lightweight - * device reset: it will issue a SET_CONFIGURATION request using the current - * configuration, causing most USB-related device state to be reset - * (altsetting reset to zero, endpoint halts cleared, toggles reset). + * If you call this function on a device already configured with the selected configuration, then this function will + * act as a lightweight device reset: it will issue a SET_CONFIGURATION request using the current configuration, + * causing most USB-related device state to be reset (altsetting reset to zero, endpoint halts cleared, toggles + * reset). * - * You cannot change/reset configuration if your application has claimed - * interfaces - you should free them with - * {@link #releaseInterface(DeviceHandle, int)} first. You cannot - * change/reset configuration if other applications or drivers have claimed - * interfaces. + * You cannot change/reset configuration if your application has claimed interfaces - you should free them with + * {@link #releaseInterface(DeviceHandle, int)} first. You cannot change/reset configuration if other applications + * or drivers have claimed interfaces. * - * A configuration value of -1 will put the device in unconfigured state. - * The USB specifications state that a configuration value of 0 does this, - * however buggy devices exist which actually have a configuration 0. + * A configuration value of -1 will put the device in unconfigured state. The USB specifications state that a + * configuration value of 0 does this, however buggy devices exist which actually have a configuration 0. * - * You should always use this function rather than formulating your own - * SET_CONFIGURATION control request. This is because the underlying - * operating system needs to know when such changes happen. + * You should always use this function rather than formulating your own SET_CONFIGURATION control request. This is + * because the underlying operating system needs to know when such changes happen. * * This is a blocking function. * * @param handle * a device handle. * @param config - * the bConfigurationValue of the configuration you wish to - * activate, or -1 if you wish to put the device in unconfigured - * state - * @return 0 on success, {@link #ERROR_NOT_FOUND} if the requested - * configuration does not exist, {@link #ERROR_BUSY} if interfaces - * are currently claimed, {@link #ERROR_NO_DEVICE} if the device has - * been disconnected, another error code on other failure - */ - public static native int setConfiguration(final DeviceHandle handle, - final int config); + * the bConfigurationValue of the configuration you wish to activate, or -1 if you wish to put the device + * in unconfigured state + * @return 0 on success, {@link #ERROR_NOT_FOUND} if the requested configuration does not exist, {@link #ERROR_BUSY} + * if interfaces are currently claimed, {@link #ERROR_NO_DEVICE} if the device has been disconnected, + * another error code on other failure + */ + public static int setConfiguration(final DeviceHandle handle, final int config) { + return lib.libusb_set_configuration(handle.getPointer(), config); + } /** * Claim an interface on a given device handle. * - * You must claim the interface you wish to use before you can perform I/O - * on any of its endpoints. + * You must claim the interface you wish to use before you can perform I/O on any of its endpoints. * - * It is legal to attempt to claim an already-claimed interface, in which - * case libusb just returns 0 without doing anything. + * It is legal to attempt to claim an already-claimed interface, in which case libusb just returns 0 without doing + * anything. * - * Claiming of interfaces is a purely logical operation; it does not cause - * any requests to be sent over the bus. Interface claiming is used to - * instruct the underlying operating system that your application wishes to - * take ownership of the interface. + * Claiming of interfaces is a purely logical operation; it does not cause any requests to be sent over the bus. + * Interface claiming is used to instruct the underlying operating system that your application wishes to take + * ownership of the interface. * * This is a non-blocking function. * @@ -1097,43 +1099,40 @@ public static native int setConfiguration(final DeviceHandle handle, * A device handle. * @param iface * The bInterfaceNumber of the interface you wish to claim. - * @return 0 on success, {@link #ERROR_NOT_FOUND} if the requested interface - * does not exist, {@link #ERROR_BUSY} if another program or driver - * has claimed the interface, {@link #ERROR_NO_DEVICE} if the device - * has been disconnected, another error code on other failure + * @return 0 on success, {@link #ERROR_NOT_FOUND} if the requested interface does not exist, {@link #ERROR_BUSY} if + * another program or driver has claimed the interface, {@link #ERROR_NO_DEVICE} if the device has been + * disconnected, another error code on other failure */ - public static native int claimInterface(final DeviceHandle handle, - final int iface); + public static int claimInterface(final DeviceHandle handle, final int iface) { + return lib.libusb_claim_interface(handle.getPointer(), iface); + } /** - * Release an interface previously claimed with - * {@link #claimInterface(DeviceHandle, int)}. + * Release an interface previously claimed with {@link #claimInterface(DeviceHandle, int)}. * * You should release all claimed interfaces before closing a device handle. * - * This is a blocking function. A SET_INTERFACE control request will be sent - * to the device, resetting interface state to the first alternate setting. + * This is a blocking function. A SET_INTERFACE control request will be sent to the device, resetting interface + * state to the first alternate setting. * * @param handle * a device handle. * @param iface * The bInterfaceNumber of the previously-claimed interface - * @return 0 on success, {@link #ERROR_NOT_FOUND} if the interface was not - * claimed, {@link #ERROR_NO_DEVICE} if the device has been - * disconnected, another ERROR code on other failure + * @return 0 on success, {@link #ERROR_NOT_FOUND} if the interface was not claimed, {@link #ERROR_NO_DEVICE} if the + * device has been disconnected, another ERROR code on other failure */ - public static native int releaseInterface(final DeviceHandle handle, - final int iface); + public static int releaseInterface(final DeviceHandle handle, final int iface) { + return lib.libusb_release_interface(handle.getPointer(), iface); + } /** * Activate an alternate setting for an interface. * - * The interface must have been previously claimed with - * {@link #claimInterface(DeviceHandle, int)}. + * The interface must have been previously claimed with {@link #claimInterface(DeviceHandle, int)}. * - * You should always use this function rather than formulating your own - * SET_INTERFACE control request. This is because the underlying operating - * system needs to know when such changes happen. + * You should always use this function rather than formulating your own SET_INTERFACE control request. This is + * because the underlying operating system needs to know when such changes happen. * * This is a blocking function. * @@ -1143,22 +1142,21 @@ public static native int releaseInterface(final DeviceHandle handle, * The bInterfaceNumber of the previously-claimed interface * @param alternateSetting * The bAlternateSetting of the alternate setting to activate - * @return 0 on success, {@link #ERROR_NOT_FOUND} if the interface was not - * claimed, or the requested alternate setting does not exist - * {@link #ERROR_NO_DEVICE} if the device has been disconnected, - * another ERROR code on other failure + * @return 0 on success, {@link #ERROR_NOT_FOUND} if the interface was not claimed, or the requested alternate + * setting does not exist {@link #ERROR_NO_DEVICE} if the device has been disconnected, another ERROR code + * on other failure */ - public static native int setInterfaceAltSetting(final DeviceHandle handle, - final int interfaceNumber, final int alternateSetting); + public static int setInterfaceAltSetting(final DeviceHandle handle, final int interfaceNumber, + final int alternateSetting) { + return lib.libusb_set_interface_alt_setting(handle.getPointer(), interfaceNumber, alternateSetting); + } /** * Clear the halt/stall condition for an endpoint. * - * Endpoints with halt status are unable to receive or transmit data until - * the halt condition is stalled. + * Endpoints with halt status are unable to receive or transmit data until the halt condition is stalled. * - * You should cancel all pending transfers before attempting to clear the - * halt condition. + * You should cancel all pending transfers before attempting to clear the halt condition. * * This is a blocking function. * @@ -1166,46 +1164,43 @@ public static native int setInterfaceAltSetting(final DeviceHandle handle, * A device handle. * @param endpoint * The endpoint to clear halt status - * @return 0 on success, {@link #ERROR_NOT_FOUND} if the endpoint does not - * exist, {@link #ERROR_NO_DEVICE} if the device has been - * disconnected, another ERROR code on other failure. + * @return 0 on success, {@link #ERROR_NOT_FOUND} if the endpoint does not exist, {@link #ERROR_NO_DEVICE} if the + * device has been disconnected, another ERROR code on other failure. */ - public static native int clearHalt(final DeviceHandle handle, - final byte endpoint); - + public static int clearHalt(final DeviceHandle handle, final byte endpoint) { + return lib.libusb_clear_halt(handle.getPointer(), endpoint); + } + /** * Perform a USB port reset to reinitialize a device. * - * The system will attempt to restore the previous configuration and - * alternate settings after the reset has completed. + * The system will attempt to restore the previous configuration and alternate settings after the reset has + * completed. * - * If the reset fails, the descriptors change, or the previous state cannot - * be restored, the device will appear to be disconnected and reconnected. - * This means that the device handle is no longer valid (you should close - * it) and rediscover the device. A return code of {@link #ERROR_NOT_FOUND} - * indicates when this is the case. + * If the reset fails, the descriptors change, or the previous state cannot be restored, the device will appear to + * be disconnected and reconnected. This means that the device handle is no longer valid (you should close it) and + * rediscover the device. A return code of {@link #ERROR_NOT_FOUND} indicates when this is the case. * * This is a blocking function which usually incurs a noticeable delay. * * @param handle * a handle of the device to reset - * @return 0 on success, {@link #ERROR_NOT_FOUND} if re-enumeration is - * required, or if the device has been disconnected another ERROR - * code on other failure + * @return 0 on success, {@link #ERROR_NOT_FOUND} if re-enumeration is required, or if the device has been + * disconnected another ERROR code on other failure */ - public static native int resetDevice(final DeviceHandle handle); + public static int resetDevice(final DeviceHandle handle) { + return lib.libusb_reset_device(handle.getPointer()); + } /** - * Allocate up to numStreams USB bulk streams on the specified endpoints. - * This function takes an array of endpoints rather then a single endpoint - * because some protocols require that endpoints are setup with similar - * stream ids. All endpoints passed in must belong to the same interface. + * Allocate up to numStreams USB bulk streams on the specified endpoints. This function takes an array of endpoints + * rather then a single endpoint because some protocols require that endpoints are setup with similar stream ids. + * All endpoints passed in must belong to the same interface. * * Note that this function may return less streams then requested. * - * Stream id 0 is reserved, and should not be used to communicate with - * devices. If LibUsb.allocStreams() returns with a value of N, you may - * use stream ids 1 to N. + * Stream id 0 is reserved, and should not be used to communicate with devices. If LibUsb.allocStreams() returns + * with a value of N, you may use stream ids 1 to N. * * @param handle * a device handle @@ -1213,11 +1208,9 @@ public static native int clearHalt(final DeviceHandle handle, * number of streams to try to allocate * @param endpoints * array of endpoints to allocate streams on - * @return The number of streams allocated, or a LIBUSB_ERROR code - * on failure. + * @return The number of streams allocated, or a LIBUSB_ERROR code on failure. */ - public static native int allocStreams(final DeviceHandle handle, - final int numStreams, final byte[] endpoints); + public static native int allocStreams(final DeviceHandle handle, final int numStreams, final byte[] endpoints); /** * Free USB bulk streams allocated with LibUsb.allocStreams(). @@ -1230,14 +1223,12 @@ public static native int allocStreams(final DeviceHandle handle, * array of endpoints to allocate streams on * @return 0 on success, or a LIBUSB_ERROR code on failure. */ - public static native int freeStreams(final DeviceHandle handle, - final byte[] endpoints); + public static native int freeStreams(final DeviceHandle handle, final byte[] endpoints); /** * Determine if a kernel driver is active on an interface. * - * If a kernel driver is active, you cannot claim the interface, and libusb - * will be unable to perform I/O. + * If a kernel driver is active, you cannot claim the interface, and libusb will be unable to perform I/O. * * This functionality is not available on Windows. * @@ -1245,50 +1236,46 @@ public static native int freeStreams(final DeviceHandle handle, * A device handle. * @param interfaceNumber * The interface to check. - * @return 0 if no kernel driver is active, 1 if a kernel driver is active, - * {@link #ERROR_NO_DEVICE} if the device has been disconnected, - * {@link #ERROR_NOT_SUPPORTED} on platforms where the functionality - * is not available, another ERROR code on other failure + * @return 0 if no kernel driver is active, 1 if a kernel driver is active, {@link #ERROR_NO_DEVICE} if the device + * has been disconnected, {@link #ERROR_NOT_SUPPORTED} on platforms where the functionality is not + * available, another ERROR code on other failure * * @see #detachKernelDriver(DeviceHandle, int) */ - public static native int kernelDriverActive(final DeviceHandle handle, - final int interfaceNumber); + public static int kernelDriverActive(final DeviceHandle handle, final int interfaceNumber) { + return lib.libusb_kernel_driver_active(handle.getPointer(), interfaceNumber); + } /** * Detach a kernel driver from an interface. * - * If successful, you will then be able to claim the interface and perform - * I/O. + * If successful, you will then be able to claim the interface and perform I/O. * * This functionality is not available on Darwin or Windows. * - * Note that libusb itself also talks to the device through a special - * kernel driver, if this driver is already attached to the device, this - * call will not detach it and return {@link #ERROR_NOT_FOUND}. + * Note that libusb itself also talks to the device through a special kernel driver, if this driver is already + * attached to the device, this call will not detach it and return {@link #ERROR_NOT_FOUND}. * * @param handle * a device handle * @param interfaceNumber * the interface to detach the driver from - * @return 0 on success, {@link #ERROR_NOT_FOUND} if no kernel driver was - * active, {@link #ERROR_INVALID_PARAM} if the interface does not - * exist, {@link #ERROR_NO_DEVICE} if the device has been - * disconnected, {@link #ERROR_NOT_SUPPORTED} on platforms where the - * functionality is not available, another ERROR code on other - * failure + * @return 0 on success, {@link #ERROR_NOT_FOUND} if no kernel driver was active, {@link #ERROR_INVALID_PARAM} if + * the interface does not exist, {@link #ERROR_NO_DEVICE} if the device has been disconnected, + * {@link #ERROR_NOT_SUPPORTED} on platforms where the functionality is not available, another ERROR code on + * other failure * * @see #kernelDriverActive(DeviceHandle, int) */ - public static native int detachKernelDriver(final DeviceHandle handle, - final int interfaceNumber); + public static int detachKernelDriver(final DeviceHandle handle, final int interfaceNumber) { + return lib.libusb_detach_kernel_driver(handle.getPointer(), interfaceNumber); + } /** - * Re-attach an interface's kernel driver, which was previously detached - * using {@link #detachKernelDriver(DeviceHandle, int)}. + * Re-attach an interface's kernel driver, which was previously detached using + * {@link #detachKernelDriver(DeviceHandle, int)}. * - * This call is only effective on Linux and returns - * {@link #ERROR_NOT_SUPPORTED} on all other platforms. + * This call is only effective on Linux and returns {@link #ERROR_NOT_SUPPORTED} on all other platforms. * * This functionality is not available on Darwin or Windows. * @@ -1296,42 +1283,39 @@ public static native int detachKernelDriver(final DeviceHandle handle, * A device handle * @param interfaceNumber * the interface to attach the driver from - * @return 0 on success, {@link #ERROR_NOT_FOUND} if no kernel driver was - * active, {@link #ERROR_INVALID_PARAM} if the interface does not - * exist, {@link #ERROR_NO_DEVICE} if the device has been - * disconnected, {@link #ERROR_NOT_SUPPORTED} on platforms where the - * functionality is not available, {@link #ERROR_BUSY} if the driver - * cannot be attached because the interface is claimed by a program - * or driver, anotherERROR code on other failure + * @return 0 on success, {@link #ERROR_NOT_FOUND} if no kernel driver was active, {@link #ERROR_INVALID_PARAM} if + * the interface does not exist, {@link #ERROR_NO_DEVICE} if the device has been disconnected, + * {@link #ERROR_NOT_SUPPORTED} on platforms where the functionality is not available, {@link #ERROR_BUSY} + * if the driver cannot be attached because the interface is claimed by a program or driver, anotherERROR + * code on other failure * * @see #kernelDriverActive(DeviceHandle, int) */ - public static native int attachKernelDriver(final DeviceHandle handle, - final int interfaceNumber); + public static int attachKernelDriver(final DeviceHandle handle, final int interfaceNumber) { + return lib.libusb_attach_kernel_driver(handle.getPointer(), interfaceNumber); + } /** * Enable/disable libusb's automatic kernel driver detachment. * - * When this is enabled libusb will automatically detach the kernel driver - * on an interface when claiming the interface, and attach it when releasing - * the interface. + * When this is enabled libusb will automatically detach the kernel driver on an interface when claiming the + * interface, and attach it when releasing the interface. * - * Automatic kernel driver detachment is disabled on newly opened device - * handles by default. + * Automatic kernel driver detachment is disabled on newly opened device handles by default. * - * On platforms which do not have {@link #CAP_SUPPORTS_DETACH_KERNEL_DRIVER} - * this function will return {@link #ERROR_NOT_SUPPORTED}, and libusb will - * continue as if this function was never called. + * On platforms which do not have {@link #CAP_SUPPORTS_DETACH_KERNEL_DRIVER} this function will return + * {@link #ERROR_NOT_SUPPORTED}, and libusb will continue as if this function was never called. * * @param handle * A device handle. * @param enable * Whether to enable or disable auto kernel driver detachment - * @return {@link #SUCCESS} on success, {@link #ERROR_NOT_SUPPORTED} on - * platforms where the functionality is not available. + * @return {@link #SUCCESS} on success, {@link #ERROR_NOT_SUPPORTED} on platforms where the functionality is not + * available. */ - public static native int setAutoDetachKernelDriver( - final DeviceHandle handle, final boolean enable); + public static int setAutoDetachKernelDriver(final DeviceHandle handle, final boolean enable) { + return lib.libusb_set_auto_detach_kernel_driver(handle.getPointer(), enable ? 1 : 0); + } /** * Check at runtime if the loaded library has a given capability. @@ -1340,54 +1324,47 @@ public static native int setAutoDetachKernelDriver( * The capability to check for. * @return True if the running library has the capability, false otherwise. */ - public static native boolean hasCapability(final int capability); + public static boolean hasCapability(final int capability) { + return lib.libusb_has_capability(capability) != 0; + } /** - * Returns a string with the ASCII name of a libusb error or transfer status - * code. + * Returns a string with the ASCII name of a libusb error or transfer status code. * * @param errorCode - * The libusb error or libusb transfer status code to return the - * name of. - * @return The error name, or the string **UNKNOWN** if the value of - * errorCode is not a known error / status code. + * The libusb error or libusb transfer status code to return the name of. + * @return The error name, or the string **UNKNOWN** if the value of errorCode is not a known error / status code. */ - public static native String errorName(final int errorCode); + public static String errorName(final int errorCode) { + return lib.libusb_error_name(errorCode); + } /** - * Set the language, and only the language, not the encoding! used for - * translatable libusb messages. + * Set the language, and only the language, not the encoding! used for translatable libusb messages. * - * This takes a locale string in the default setlocale format: lang[-region] - * or lang[_country_region][.codeset]. Only the lang part of the string is - * used, and only 2 letter ISO 639-1 codes are accepted for it, such as - * "de". The optional region, country_region or codeset parts are ignored. - * This means that functions which return translatable strings will NOT - * honor the specified encoding. All strings returned are encoded as UTF-8 - * strings. + * This takes a locale string in the default setlocale format: lang[-region] or lang[_country_region][.codeset]. + * Only the lang part of the string is used, and only 2 letter ISO 639-1 codes are accepted for it, such as "de". + * The optional region, country_region or codeset parts are ignored. This means that functions which return + * translatable strings will NOT honor the specified encoding. All strings returned are encoded as UTF-8 strings. * - * If {@link #setLocale(String)} is not called, all messages will be in - * English. + * If {@link #setLocale(String)} is not called, all messages will be in English. * - * The following functions return translatable strings: libusb_strerror(). - * Note that the libusb log messages controlled through - * {@link #setDebug(Context, int)} are not translated, they are always in - * English. + * The following functions return translatable strings: libusb_strerror(). Note that the libusb log messages + * controlled through {@link #setDebug(Context, int)} are not translated, they are always in English. * * @param locale - * locale-string in the form of lang[_country_region][.codeset] - * or lang[-region], where lang is a 2 letter ISO 639-1 code. - * @return {@link #SUCCESS} on success, {@link #ERROR_INVALID_PARAM} if the - * locale doesn't meet the requirements, {@link #ERROR_NOT_FOUND} if - * the requested language is not supported, a error code on other - * errors. + * locale-string in the form of lang[_country_region][.codeset] or lang[-region], where lang is a 2 + * letter ISO 639-1 code. + * @return {@link #SUCCESS} on success, {@link #ERROR_INVALID_PARAM} if the locale doesn't meet the requirements, + * {@link #ERROR_NOT_FOUND} if the requested language is not supported, a error code on other errors. */ - public static native int setLocale(final String locale); + public static int setLocale(final String locale) { + return lib.libusb_setlocale(locale); + } /** - * Returns a string with a short description of the given error code, this - * description is intended for displaying to the end user and will be in the - * language set by {@link #setLocale(String)}. + * Returns a string with a short description of the given error code, this description is intended for displaying to + * the end user and will be in the language set by {@link #setLocale(String)}. * * The messages always start with a capital letter and end without any dot. * @@ -1395,13 +1372,14 @@ public static native int setAutoDetachKernelDriver( * The error code whose description is desired. * @return A short description of the error code. */ - public static native String strError(final int errcode); + public static String strError(final int errcode) { + return lib.libusb_strerror(errcode); + } /** * Convert a 16-bit value from little-endian to host-endian format. * - * On little endian systems, this function does nothing. On big endian - * systems, the bytes are swapped. + * On little endian systems, this function does nothing. On big endian systems, the bytes are swapped. * * @param x * The little-endian value to convert @@ -1412,8 +1390,7 @@ public static native int setAutoDetachKernelDriver( /** * Convert a 16-bit value from host-endian to little-endian format. * - * On little endian systems, this function does nothing. On big endian - * systems, the bytes are swapped. + * On little endian systems, this function does nothing. On big endian systems, the bytes are swapped. * * @param x * The host-endian value to convert @@ -1424,8 +1401,7 @@ public static native int setAutoDetachKernelDriver( /** * Get the USB device descriptor for a given device. * - * This is a non-blocking function; the device descriptor is cached in - * memory. + * This is a non-blocking function; the device descriptor is cached in memory. * * @param device * the device @@ -1433,12 +1409,10 @@ public static native int setAutoDetachKernelDriver( * output location for the descriptor data * @return 0 on success or a ERROR code on failure */ - public static native int getDeviceDescriptor(final Device device, - final DeviceDescriptor descriptor); + public static native int getDeviceDescriptor(final Device device, final DeviceDescriptor descriptor); /** - * Returns the size in bytes of the buffer that's required to hold all - * of a device descriptor's data. + * Returns the size in bytes of the buffer that's required to hold all of a device descriptor's data. * * @return buffer size in bytes */ @@ -1455,15 +1429,13 @@ public static native int getDeviceDescriptor(final Device device, * Output buffer for ASCII string descriptor. * @return Number of bytes returned in data, or ERROR code on failure. */ - public static native int getStringDescriptorAscii( - final DeviceHandle handle, final byte index, final StringBuffer string); + public static native int getStringDescriptorAscii(final DeviceHandle handle, final byte index, + final StringBuffer string); /** - * A simple wrapper around - * {@link #getStringDescriptorAscii(DeviceHandle, byte, StringBuffer)}. - * It simply returns the string (maximum length of 127) if possible. If not - * possible (NULL handle or 0-index specified or error occured) then null is - * returned. + * A simple wrapper around {@link #getStringDescriptorAscii(DeviceHandle, byte, StringBuffer)}. It simply returns + * the string (maximum length of 127) if possible. If not possible (NULL handle or 0-index specified or error + * occured) then null is returned. * * This method is not part of libusb. * @@ -1473,18 +1445,14 @@ public static native int getStringDescriptorAscii( * The string descriptor index. * @return The string or null if it could not be read. */ - public static String getStringDescriptor(final DeviceHandle handle, - final byte index) - { - if ((handle == null) || (index == 0)) - { + public static String getStringDescriptor(final DeviceHandle handle, final byte index) { + if ((handle == null) || (index == 0)) { return null; } final StringBuffer buffer = new StringBuffer(); - if (getStringDescriptorAscii(handle, index, buffer) >= 0) - { + if (getStringDescriptorAscii(handle, index, buffer) >= 0) { return buffer.toString(); } @@ -1492,86 +1460,72 @@ public static String getStringDescriptor(final DeviceHandle handle, } /** - * Get the USB configuration descriptor for the currently active - * configuration. + * Get the USB configuration descriptor for the currently active configuration. * - * This is a non-blocking function which does not involve any requests being - * sent to the device. + * This is a non-blocking function which does not involve any requests being sent to the device. * * @param device * A device. * @param descriptor - * Output location for the USB configuration descriptor. Only - * valid if 0 was returned. Must be freed with + * Output location for the USB configuration descriptor. Only valid if 0 was returned. Must be freed with * {@link #freeConfigDescriptor(ConfigDescriptor)} after use. - * @return 0 on success, {@link #ERROR_NOT_FOUND} if the device is in - * unconfigured state another ERROR code on error + * @return 0 on success, {@link #ERROR_NOT_FOUND} if the device is in unconfigured state another ERROR code on error * * @see #getConfigDescriptor(Device, byte, ConfigDescriptor) */ - public static native int getActiveConfigDescriptor(final Device device, - final ConfigDescriptor descriptor); + public static native int getActiveConfigDescriptor(final Device device, final ConfigDescriptor descriptor); /** * Get a USB configuration descriptor based on its index. * - * This is a non-blocking function which does not involve any requests being - * sent to the device. + * This is a non-blocking function which does not involve any requests being sent to the device. * * @param device * A device. * @param index * The index of the configuration you wish to retrieve * @param descriptor - * Output location for the USB configuration descriptor. Only - * valid if 0 was returned. Must be freed with + * Output location for the USB configuration descriptor. Only valid if 0 was returned. Must be freed with * {@link #freeConfigDescriptor(ConfigDescriptor)} after use. - * @return 0 on success {@link #ERROR_NOT_FOUND} if the configuration does - * not exist another ERROR code on error. + * @return 0 on success {@link #ERROR_NOT_FOUND} if the configuration does not exist another ERROR code on error. * * @see #getActiveConfigDescriptor(Device, ConfigDescriptor) * @see #getConfigDescriptorByValue(Device, byte, ConfigDescriptor) */ - public static native int getConfigDescriptor(final Device device, - final byte index, final ConfigDescriptor descriptor); + public static native int getConfigDescriptor(final Device device, final byte index, + final ConfigDescriptor descriptor); /** * Get a USB configuration descriptor with a specific bConfigurationValue. * - * This is a non-blocking function which does not involve any requests being - * sent to the device. + * This is a non-blocking function which does not involve any requests being sent to the device. * * @param device * A device. * @param value - * The bConfigurationValue of the configuration you wish to - * retrieve. + * The bConfigurationValue of the configuration you wish to retrieve. * @param descriptor - * Output location for the USB configuration descriptor. Only - * valid if 0 was returned. Must be freed with + * Output location for the USB configuration descriptor. Only valid if 0 was returned. Must be freed with * {@link #freeConfigDescriptor(ConfigDescriptor)} after use. - * @return 0 on success {@link #ERROR_NOT_FOUND} if the configuration does - * not exist another ERROR code on error See also: + * @return 0 on success {@link #ERROR_NOT_FOUND} if the configuration does not exist another ERROR code on error See + * also: * * @see #getActiveConfigDescriptor(Device, ConfigDescriptor) * @see #getConfigDescriptor(Device, byte, ConfigDescriptor) */ - public static native int getConfigDescriptorByValue(final Device device, - final byte value, final ConfigDescriptor descriptor); + public static native int getConfigDescriptorByValue(final Device device, final byte value, + final ConfigDescriptor descriptor); /** - * Free a configuration descriptor obtained from - * {@link #getConfigDescriptor(Device, byte, ConfigDescriptor)} or + * Free a configuration descriptor obtained from {@link #getConfigDescriptor(Device, byte, ConfigDescriptor)} or * {@link #getActiveConfigDescriptor(Device, ConfigDescriptor)}. * - * It is safe to call this function with a NULL config parameter, in which - * case the function simply returns. + * It is safe to call this function with a NULL config parameter, in which case the function simply returns. * * @param descriptor * The configuration descriptor to free */ - public static native void freeConfigDescriptor( - final ConfigDescriptor descriptor); + public static native void freeConfigDescriptor(final ConfigDescriptor descriptor); /** * Get an endpoints superspeed endpoint companion descriptor (if any). @@ -1579,57 +1533,44 @@ public static native void freeConfigDescriptor( * @param context * The context to operate on, or NULL for the default context. * @param endpointDescriptor - * Endpoint descriptor from which to get the superspeed endpoint - * companion descriptor. + * Endpoint descriptor from which to get the superspeed endpoint companion descriptor. * @param companionDescriptor - * Output location for the superspeed endpoint companion - * descriptor. Only valid if 0 was returned. Must be freed with - * {@link #freeSsEndpointCompanionDescriptor - * (SsEndpointCompanionDescriptor)} - * after use. - * @return {@link #SUCCESS} on success, {@link #ERROR_NOT_FOUND} if the - * descriptor does not exist, another error code on error + * Output location for the superspeed endpoint companion descriptor. Only valid if 0 was returned. Must + * be freed with {@link #freeSsEndpointCompanionDescriptor (SsEndpointCompanionDescriptor)} after use. + * @return {@link #SUCCESS} on success, {@link #ERROR_NOT_FOUND} if the descriptor does not exist, another error + * code on error */ - public static native int getSsEndpointCompanionDescriptor( - final Context context, final EndpointDescriptor endpointDescriptor, - final SsEndpointCompanionDescriptor companionDescriptor); + public static native int getSsEndpointCompanionDescriptor(final Context context, + final EndpointDescriptor endpointDescriptor, final SsEndpointCompanionDescriptor companionDescriptor); /** * Free a superspeed endpoint companion descriptor obtained from - * {@link #getSsEndpointCompanionDescriptor(Context, EndpointDescriptor, - * SsEndpointCompanionDescriptor)}. + * {@link #getSsEndpointCompanionDescriptor(Context, EndpointDescriptor, SsEndpointCompanionDescriptor)}. * - * It is safe to call this function with a NULL parameter, in which case the - * function simply returns. + * It is safe to call this function with a NULL parameter, in which case the function simply returns. * * @param companionDescriptor * The superspeed endpoint companion descriptor to free */ - public static native void freeSsEndpointCompanionDescriptor( - final SsEndpointCompanionDescriptor companionDescriptor); + public static native void freeSsEndpointCompanionDescriptor(final SsEndpointCompanionDescriptor companionDescriptor); /** - * Get a Binary Object Store (BOS) descriptor. This is a BLOCKING function, - * which will send requests to the device. + * Get a Binary Object Store (BOS) descriptor. This is a BLOCKING function, which will send requests to the device. * * @param handle * The handle of an open libusb device. * @param descriptor - * Output location for the BOS descriptor. Only valid if 0 was - * returned. Must be freed with + * Output location for the BOS descriptor. Only valid if 0 was returned. Must be freed with * {@link #freeBosDescriptor(BosDescriptor)} after use. - * @return {@link #SUCCESS} on success, {@link #ERROR_NOT_FOUND} if the - * device doesn't have a BOS descriptor, another error code on error + * @return {@link #SUCCESS} on success, {@link #ERROR_NOT_FOUND} if the device doesn't have a BOS descriptor, + * another error code on error */ - public static native int getBosDescriptor(final DeviceHandle handle, - final BosDescriptor descriptor); + public static native int getBosDescriptor(final DeviceHandle handle, final BosDescriptor descriptor); /** - * Free a BOS descriptor obtained from - * {@link #getBosDescriptor(DeviceHandle, BosDescriptor)}. + * Free a BOS descriptor obtained from {@link #getBosDescriptor(DeviceHandle, BosDescriptor)}. * - * It is safe to call this function with a NULL parameter, in which case the - * function simply returns. + * It is safe to call this function with a NULL parameter, in which case the function simply returns. * * @param descriptor * The BOS descriptor to free. @@ -1642,32 +1583,25 @@ public static native int getBosDescriptor(final DeviceHandle handle, * @param context * The context to operate on, or NULL for the default context. * @param devCapDescriptor - * Device Capability descriptor with a bDevCapabilityType of - * {@link #BT_USB_2_0_EXTENSION}. + * Device Capability descriptor with a bDevCapabilityType of {@link #BT_USB_2_0_EXTENSION}. * @param extensionDescriptor - * Output location for the USB 2.0 Extension descriptor. Only - * valid if 0 was returned. Must be freed with - * {@link #freeUsb20ExtensionDescriptor( - * Usb20ExtensionDescriptor)} after use. + * Output location for the USB 2.0 Extension descriptor. Only valid if 0 was returned. Must be freed with + * {@link #freeUsb20ExtensionDescriptor(Usb20ExtensionDescriptor)} after use. * @return 0 on success a LIBUSB_ERROR code on error */ public static native int getUsb20ExtensionDescriptor(final Context context, - final BosDevCapabilityDescriptor devCapDescriptor, - final Usb20ExtensionDescriptor extensionDescriptor); + final BosDevCapabilityDescriptor devCapDescriptor, final Usb20ExtensionDescriptor extensionDescriptor); /** * Free a USB 2.0 Extension descriptor obtained from - * {@link #getUsb20ExtensionDescriptor(Context, BosDevCapabilityDescriptor, - * Usb20ExtensionDescriptor)}. + * {@link #getUsb20ExtensionDescriptor(Context, BosDevCapabilityDescriptor, Usb20ExtensionDescriptor)}. * - * It is safe to call this function with a NULL parameter, in which case - * the function simply returns. + * It is safe to call this function with a NULL parameter, in which case the function simply returns. * * @param extensionDescriptor * The USB 2.0 Extension descriptor to free. */ - public static native void freeUsb20ExtensionDescriptor( - final Usb20ExtensionDescriptor extensionDescriptor); + public static native void freeUsb20ExtensionDescriptor(final Usb20ExtensionDescriptor extensionDescriptor); /** * Get a SuperSpeed USB Device Capability descriptor. @@ -1675,28 +1609,23 @@ public static native void freeUsb20ExtensionDescriptor( * @param context * The context to operate on, or NULL for the default context. * @param devCapDescriptor - * Device Capability descriptor with a bDevCapabilityType of - * {@link #BT_SS_USB_DEVICE_CAPABILITY}. + * Device Capability descriptor with a bDevCapabilityType of {@link #BT_SS_USB_DEVICE_CAPABILITY}. * @param ssUsbDeviceCapabilityDescriptor - * Output location for the SuperSpeed USB Device Capability - * descriptor. Only valid if {@link #SUCCESS} was returned. - * Must be freed with - * {@link #freeSsUsbDeviceCapabilityDescriptor( - * SsUsbDeviceCapabilityDescriptor)} after use. + * Output location for the SuperSpeed USB Device Capability descriptor. Only valid if {@link #SUCCESS} + * was returned. Must be freed with + * {@link #freeSsUsbDeviceCapabilityDescriptor(SsUsbDeviceCapabilityDescriptor)} after use. * @return {@link #SUCCESS} on success, an error code on error. */ - public static native int getSsUsbDeviceCapabilityDescriptor( - final Context context, + public static native int getSsUsbDeviceCapabilityDescriptor(final Context context, final BosDevCapabilityDescriptor devCapDescriptor, final SsUsbDeviceCapabilityDescriptor ssUsbDeviceCapabilityDescriptor); /** * Free a SuperSpeed USB Device Capability descriptor obtained from - * {@link #getSsUsbDeviceCapabilityDescriptor(Context, - * BosDevCapabilityDescriptor, SsUsbDeviceCapabilityDescriptor)}. + * {@link #getSsUsbDeviceCapabilityDescriptor(Context, BosDevCapabilityDescriptor, SsUsbDeviceCapabilityDescriptor)} + * . * - * It is safe to call this function with a NULL parameter, - * in which case the function simply returns. + * It is safe to call this function with a NULL parameter, in which case the function simply returns. * * @param ssUsbDeviceCapabilityDescriptor * The descriptor to free. @@ -1710,38 +1639,30 @@ public static native void freeSsUsbDeviceCapabilityDescriptor( * @param context * The context to operate on, or NULL for the default context. * @param devCapDescriptor - * Device Capability descriptor with a bDevCapabilityType of - * {@link #BT_CONTAINER_ID}. + * Device Capability descriptor with a bDevCapabilityType of {@link #BT_CONTAINER_ID}. * @param containerIdDescriptor - * Output location for the Container ID descriptor. Only valid if - * {@link #SUCCESS} was returned. Must be freed with - * {@link #freeContainerIdDescriptor(ContainerIdDescriptor)} - * after use. + * Output location for the Container ID descriptor. Only valid if {@link #SUCCESS} was returned. Must be + * freed with {@link #freeContainerIdDescriptor(ContainerIdDescriptor)} after use. * @return {@link #SUCCESS} on success or an error code on error */ public static native int getContainerIdDescriptor(final Context context, - final BosDevCapabilityDescriptor devCapDescriptor, - final ContainerIdDescriptor containerIdDescriptor); + final BosDevCapabilityDescriptor devCapDescriptor, final ContainerIdDescriptor containerIdDescriptor); /** * Free a Container ID descriptor obtained from - * {@link #getContainerIdDescriptor(Context, BosDevCapabilityDescriptor, - * ContainerIdDescriptor)}. + * {@link #getContainerIdDescriptor(Context, BosDevCapabilityDescriptor, ContainerIdDescriptor)}. * - * It is safe to call this function with a NULL parameter, in which case - * the function simply returns. + * It is safe to call this function with a NULL parameter, in which case the function simply returns. * * @param containerIdDescriptor * The descriptor to free. */ - public static native void freeContainerIdDescriptor( - final ContainerIdDescriptor containerIdDescriptor); + public static native void freeContainerIdDescriptor(final ContainerIdDescriptor containerIdDescriptor); /** * Retrieve a descriptor from the default control pipe. * - * This is a convenience function which formulates the appropriate control - * message to retrieve the descriptor. + * This is a convenience function which formulates the appropriate control message to retrieve the descriptor. * * @param handle * A device handle. @@ -1754,20 +1675,16 @@ public static native void freeContainerIdDescriptor( * @return number of bytes returned in data, or ERROR code on failure * */ - public static int getDescriptor(final DeviceHandle handle, final byte type, - final byte index, final ByteBuffer data) - { + public static int getDescriptor(final DeviceHandle handle, final byte type, final byte index, final ByteBuffer data) { return controlTransfer(handle, ENDPOINT_IN, REQUEST_GET_DESCRIPTOR, - (short) (((type & 0xff) << 8) | (index & 0xff)), (short) 0, - data, 1000); + (short) (((type & 0xff) << 8) | (index & 0xff)), (short) 0, data, 1000); } /** * Retrieve a descriptor from a device. * - * This is a convenience function which formulates the appropriate control - * message to retrieve the descriptor. The string returned is Unicode, as - * detailed in the USB specifications. + * This is a convenience function which formulates the appropriate control message to retrieve the descriptor. The + * string returned is Unicode, as detailed in the USB specifications. * * @param handle * A device handle. @@ -1780,9 +1697,8 @@ public static int getDescriptor(final DeviceHandle handle, final byte type, * @return number of bytes returned in data, or LIBUSB_ERROR code on failure * @see #getStringDescriptorAscii(DeviceHandle, byte, StringBuffer) */ - public static int getStringDescriptor(final DeviceHandle handle, - final byte index, final short langId, final ByteBuffer data) - { + public static int getStringDescriptor(final DeviceHandle handle, final byte index, final short langId, + final ByteBuffer data) { return controlTransfer(handle, ENDPOINT_IN, REQUEST_GET_DESCRIPTOR, (short) ((DT_STRING << 8) | (index & 0xff)), langId, data, 1000); } @@ -1790,11 +1706,9 @@ public static int getStringDescriptor(final DeviceHandle handle, /** * Perform a USB control transfer. * - * The direction of the transfer is inferred from the bmRequestType field of - * the setup packet. + * The direction of the transfer is inferred from the bmRequestType field of the setup packet. * - * The wValue, wIndex and wLength fields values should be given in - * host-endian byte order. + * The wValue, wIndex and wLength fields values should be given in host-endian byte order. * * @param handle * A handle for the device to communicate with. @@ -1807,87 +1721,67 @@ public static int getStringDescriptor(final DeviceHandle handle, * @param wIndex * The index field for the setup packet. * @param data - * A suitably-sized data buffer for either input or output - * (depending on direction bits within bmRequestType). + * A suitably-sized data buffer for either input or output (depending on direction bits within + * bmRequestType). * @param timeout - * Timeout (in millseconds) that this function should wait before - * giving up due to no response being received. For an unlimited - * timeout, use value 0. - * @return on success the number of bytes actually transferred, - * {@link #ERROR_TIMEOUT} if the transfer timed out, - * {@link #ERROR_PIPE} if the control request was not supported by - * the device, {@link #ERROR_NO_DEVICE} if the device has been - * disconnected, another ERROR code on other failures + * Timeout (in millseconds) that this function should wait before giving up due to no response being + * received. For an unlimited timeout, use value 0. + * @return on success the number of bytes actually transferred, {@link #ERROR_TIMEOUT} if the transfer timed out, + * {@link #ERROR_PIPE} if the control request was not supported by the device, {@link #ERROR_NO_DEVICE} if + * the device has been disconnected, another ERROR code on other failures */ - public static native int controlTransfer(final DeviceHandle handle, - final byte bmRequestType, final byte bRequest, final short wValue, - final short wIndex, final ByteBuffer data, final long timeout); + public static native int controlTransfer(final DeviceHandle handle, final byte bmRequestType, final byte bRequest, + final short wValue, final short wIndex, final ByteBuffer data, final long timeout); /** * Perform a USB bulk transfer. * - * The direction of the transfer is inferred from the direction bits of the - * endpoint address. + * The direction of the transfer is inferred from the direction bits of the endpoint address. * - * For bulk reads, the length field indicates the maximum length of data you - * are expecting to receive. If less data arrives than expected, this - * function will return that data, so be sure to check the transferred - * output parameter. + * For bulk reads, the length field indicates the maximum length of data you are expecting to receive. If less data + * arrives than expected, this function will return that data, so be sure to check the transferred output parameter. * - * You should also check the transferred parameter for bulk writes. Not all - * of the data may have been written. + * You should also check the transferred parameter for bulk writes. Not all of the data may have been written. * - * Also check transferred when dealing with a timeout error code. libusb - * may have to split your transfer into a number of chunks to satisfy - * underlying O/S requirements, meaning that the timeout may expire after - * the first few chunks have completed. libusb is careful not to lose any - * data that may have been transferred; do not assume that timeout - * conditions indicate a complete lack of I/O. + * Also check transferred when dealing with a timeout error code. libusb may have to split your transfer into a + * number of chunks to satisfy underlying O/S requirements, meaning that the timeout may expire after the first few + * chunks have completed. libusb is careful not to lose any data that may have been transferred; do not assume that + * timeout conditions indicate a complete lack of I/O. * * @param handle * A handle for the device to communicate with. * @param endpoint * The address of a valid endpoint to communicate with. * @param data - * A suitably-sized data buffer for either input or output - * (depending on endpoint). + * A suitably-sized data buffer for either input or output (depending on endpoint). * @param transferred * Output location for the number of bytes actually transferred. * @param timeout - * timeout (in millseconds) that this function should wait before - * giving up due to no response being received. For an unlimited - * timeout, use value 0. - * @return 0 on success (and populates transferred), {@link #ERROR_TIMEOUT} - * if the transfer timed out (and populates transferred), - * {@link #ERROR_PIPE} if the endpoint halted, - * {@link #ERROR_OVERFLOW} if the device offered more data, see - * Packets and overflows, {@link #ERROR_NO_DEVICE} if the device has - * been disconnected, another ERROR code on other failures. - */ - public static native int bulkTransfer(final DeviceHandle handle, - final byte endpoint, final ByteBuffer data, + * timeout (in millseconds) that this function should wait before giving up due to no response being + * received. For an unlimited timeout, use value 0. + * @return 0 on success (and populates transferred), {@link #ERROR_TIMEOUT} if the transfer timed out (and populates + * transferred), {@link #ERROR_PIPE} if the endpoint halted, {@link #ERROR_OVERFLOW} if the device offered + * more data, see Packets and overflows, {@link #ERROR_NO_DEVICE} if the device has been disconnected, + * another ERROR code on other failures. + */ + public static native int bulkTransfer(final DeviceHandle handle, final byte endpoint, final ByteBuffer data, final IntBuffer transferred, final long timeout); /** * Perform a USB interrupt transfer. * - * The direction of the transfer is inferred from the direction bits of the - * endpoint address. + * The direction of the transfer is inferred from the direction bits of the endpoint address. * - * For interrupt reads, the length field indicates the maximum length of - * data you are expecting to receive. If less data arrives than expected, - * this function will return that data, so be sure to check the transferred - * output parameter. + * For interrupt reads, the length field indicates the maximum length of data you are expecting to receive. If less + * data arrives than expected, this function will return that data, so be sure to check the transferred output + * parameter. * - * You should also check the transferred parameter for interrupt writes. Not - * all of the data may have been written. + * You should also check the transferred parameter for interrupt writes. Not all of the data may have been written. * - * Also check transferred when dealing with a timeout error code. libusb - * may have to split your transfer into a number of chunks to satisfy - * underlying O/S requirements, meaning that the timeout may expire after - * the first few chunks have completed. libusb is careful not to lose any - * data that may have been transferred; do not assume that timeout - * conditions indicate a complete lack of I/O. + * Also check transferred when dealing with a timeout error code. libusb may have to split your transfer into a + * number of chunks to satisfy underlying O/S requirements, meaning that the timeout may expire after the first few + * chunks have completed. libusb is careful not to lose any data that may have been transferred; do not assume that + * timeout conditions indicate a complete lack of I/O. * * The default endpoint bInterval value is used as the polling interval. * @@ -1896,63 +1790,50 @@ public static native int bulkTransfer(final DeviceHandle handle, * @param endpoint * The address of a valid endpoint to communicate with. * @param data - * A suitably-sized data buffer for either input or output - * (depending on endpoint). + * A suitably-sized data buffer for either input or output (depending on endpoint). * @param transferred * Output location for the number of bytes actually transferred. * @param timeout - * Timeout (in millseconds) that this function should wait before - * giving up due to no response being received. For an unlimited - * timeout, use value 0. - * @return 0 on success (and populates transferred), {@link #ERROR_TIMEOUT} - * if the transfer timed out, {@link #ERROR_PIPE} if the endpoint - * halted, {@link #ERROR_OVERFLOW} if the device offered more data, - * see Packets and overflows, {@link #ERROR_NO_DEVICE} if the device - * has been disconnected, another ERROR code on other error - */ - public static native int interruptTransfer(final DeviceHandle handle, - final byte endpoint, final ByteBuffer data, + * Timeout (in millseconds) that this function should wait before giving up due to no response being + * received. For an unlimited timeout, use value 0. + * @return 0 on success (and populates transferred), {@link #ERROR_TIMEOUT} if the transfer timed out, + * {@link #ERROR_PIPE} if the endpoint halted, {@link #ERROR_OVERFLOW} if the device offered more data, see + * Packets and overflows, {@link #ERROR_NO_DEVICE} if the device has been disconnected, another ERROR code + * on other error + */ + public static native int interruptTransfer(final DeviceHandle handle, final byte endpoint, final ByteBuffer data, final IntBuffer transferred, final long timeout); /** * Attempt to acquire the event handling lock. * - * This lock is used to ensure that only one thread is monitoring libusb - * event sources at any one time. + * This lock is used to ensure that only one thread is monitoring libusb event sources at any one time. * - * You only need to use this lock if you are developing an application which - * calls poll() or select() on libusb's file descriptors directly. If you - * stick to libusb's event handling loop functions (e.g. - * {@link #handleEvents(Context)}) then you do not need to be concerned with - * this locking. + * You only need to use this lock if you are developing an application which calls poll() or select() on libusb's + * file descriptors directly. If you stick to libusb's event handling loop functions (e.g. + * {@link #handleEvents(Context)}) then you do not need to be concerned with this locking. * - * While holding this lock, you are trusted to actually be handling events. - * If you are no longer handling events, you must call - * {@link #unlockEvents(Context)} as soon as possible. + * While holding this lock, you are trusted to actually be handling events. If you are no longer handling events, + * you must call {@link #unlockEvents(Context)} as soon as possible. * * @param context * The context to operate on, or NULL for the default context. - * @return 0 if the lock was obtained successfully, 1 if the lock was not - * obtained (i.e. another thread holds the lock) + * @return 0 if the lock was obtained successfully, 1 if the lock was not obtained (i.e. another thread holds the + * lock) */ public static native int tryLockEvents(final Context context); /** - * Acquire the event handling lock, blocking until successful acquisition if - * it is contended. + * Acquire the event handling lock, blocking until successful acquisition if it is contended. * - * This lock is used to ensure that only one thread is monitoring libusb - * event sources at any one time. + * This lock is used to ensure that only one thread is monitoring libusb event sources at any one time. * - * You only need to use this lock if you are developing an application which - * calls poll() or select() on libusb's file descriptors directly. If you - * stick to libusb's event handling loop functions (e.g. - * {@link #handleEvents(Context)}) then you do not need to be concerned with - * this locking. + * You only need to use this lock if you are developing an application which calls poll() or select() on libusb's + * file descriptors directly. If you stick to libusb's event handling loop functions (e.g. + * {@link #handleEvents(Context)}) then you do not need to be concerned with this locking. * - * While holding this lock, you are trusted to actually be handling events. - * If you are no longer handling events, you must call - * {@link #unlockEvents(Context)} as soon as possible. + * While holding this lock, you are trusted to actually be handling events. If you are no longer handling events, + * you must call {@link #unlockEvents(Context)} as soon as possible. * * @param context * The context to operate on, or NULL for the default context. @@ -1960,11 +1841,9 @@ public static native int interruptTransfer(final DeviceHandle handle, public static native void lockEvents(final Context context); /** - * Release the lock previously acquired with {@link #tryLockEvents(Context)} - * or {@link #lockEvents(Context)}. + * Release the lock previously acquired with {@link #tryLockEvents(Context)} or {@link #lockEvents(Context)}. * - * Releasing this lock will wake up any threads blocked on - * {@link #waitForEvent(Context, long)}. + * Releasing this lock will wake up any threads blocked on {@link #waitForEvent(Context, long)}. * * @param context * The context to operate on, or NULL for the default context @@ -1974,54 +1853,44 @@ public static native int interruptTransfer(final DeviceHandle handle, /** * Determine if it is still OK for this thread to be doing event handling. * - * Sometimes, libusb needs to temporarily pause all event handlers, and - * this is the function you should use before polling file descriptors to - * see if this is the case. + * Sometimes, libusb needs to temporarily pause all event handlers, and this is the function you should use before + * polling file descriptors to see if this is the case. * - * If this function instructs your thread to give up the events lock, you - * should just continue the usual logic that is documented in Multi-threaded - * applications and asynchronous I/O. On the next iteration, your thread - * will fail to obtain the events lock, and will hence become an event - * waiter. + * If this function instructs your thread to give up the events lock, you should just continue the usual logic that + * is documented in Multi-threaded applications and asynchronous I/O. On the next iteration, your thread will fail + * to obtain the events lock, and will hence become an event waiter. * - * This function should be called while the events lock is held: you don't - * need to worry about the results of this function if your thread is not - * the current event handler. + * This function should be called while the events lock is held: you don't need to worry about the results of this + * function if your thread is not the current event handler. * * @param context * The context to operate on, or NULL for the default context. - * @return 1 if event handling can start or continue, 0 if this thread must - * give up the events lock + * @return 1 if event handling can start or continue, 0 if this thread must give up the events lock */ public static native int eventHandlingOk(final Context context); /** - * Determine if an active thread is handling events (i.e. if anyone is - * holding the event handling lock). + * Determine if an active thread is handling events (i.e. if anyone is holding the event handling lock). * * @param context * The context to operate on, or NULL for the default context. - * @return 1 if a thread is handling events, 0 if there are no threads - * currently handling events. + * @return 1 if a thread is handling events, 0 if there are no threads currently handling events. */ public static native int eventHandlerActive(final Context context); /** * Acquire the event waiters lock. * - * This lock is designed to be obtained under the situation where you want - * to be aware when events are completed, but some other thread is event - * handling so calling {@link #handleEvents(Context)} is not allowed. + * This lock is designed to be obtained under the situation where you want to be aware when events are completed, + * but some other thread is event handling so calling {@link #handleEvents(Context)} is not allowed. * - * You then obtain this lock, re-check that another thread is still handling - * events, then call {@link #waitForEvent(Context, long)}. + * You then obtain this lock, re-check that another thread is still handling events, then call + * {@link #waitForEvent(Context, long)}. * - * You only need to use this lock if you are developing an application which - * calls poll() or select() on libusb's file descriptors directly, and may - * potentially be handling events from 2 threads simultaenously. If you - * stick to libusb's event handling loop functions (e.g. - * {@link #handleEvents(Context)}) then you do not need to be concerned with - * this locking. + * You only need to use this lock if you are developing an application which calls poll() or select() on libusb's + * file descriptors directly, and may potentially be handling events from 2 threads simultaenously. If you stick to + * libusb's event handling loop functions (e.g. {@link #handleEvents(Context)}) then you do not need to be concerned + * with this locking. * * @param context * The context to operate on, or NULL for the default context. @@ -2039,105 +1908,90 @@ public static native int interruptTransfer(final DeviceHandle handle, /** * Wait for another thread to signal completion of an event. * - * Must be called with the event waiters lock held, see - * {@link #lockEventWaiters(Context)}. + * Must be called with the event waiters lock held, see {@link #lockEventWaiters(Context)}. * * This function will block until any of the following conditions are met: * - * The timeout expires A transfer completes A thread releases the event - * handling lock through {@link #unlockEvents(Context)} Condition 1 is - * obvious. Condition 2 unblocks your thread after the callback for the - * transfer has completed. Condition 3 is important because it means that - * the thread that was previously handling events is no longer doing so, so - * if any events are to complete, another thread needs to step up and start - * event handling. + * The timeout expires A transfer completes A thread releases the event handling lock through + * {@link #unlockEvents(Context)} Condition 1 is obvious. Condition 2 unblocks your thread after the callback for + * the transfer has completed. Condition 3 is important because it means that the thread that was previously + * handling events is no longer doing so, so if any events are to complete, another thread needs to step up and + * start event handling. * - * This function releases the event waiters lock before putting your thread - * to sleep, and reacquires the lock as it is being woken up. + * This function releases the event waiters lock before putting your thread to sleep, and reacquires the lock as it + * is being woken up. * * @param context * The context to operate on, or NULL for the default context. * @param timeout - * Maximum timeout for this blocking function. A 0 value - * indicates unlimited timeout. + * Maximum timeout for this blocking function. A 0 value indicates unlimited timeout. * - * @return 0 after a transfer completes or another thread stops event - * handling, 1 if the timeout expired + * @return 0 after a transfer completes or another thread stops event handling, 1 if the timeout expired */ - public static native int waitForEvent(final Context context, - final long timeout); + public static native int waitForEvent(final Context context, final long timeout); /** * Handle any pending events. * - * libusb determines "pending events" by checking if any timeouts have - * expired and by checking the set of file descriptors for activity. + * libusb determines "pending events" by checking if any timeouts have expired and by checking the set of file + * descriptors for activity. * - * If a zero timeval is passed, this function will handle any - * already-pending events and then immediately return in non-blocking style. + * If a zero timeval is passed, this function will handle any already-pending events and then immediately return in + * non-blocking style. * - * If a non-zero timeval is passed and no events are currently pending, this - * function will block waiting for events to handle up until the specified - * timeout. If an event arrives or a signal is raised, this function will - * return early. + * If a non-zero timeval is passed and no events are currently pending, this function will block waiting for events + * to handle up until the specified timeout. If an event arrives or a signal is raised, this function will return + * early. * - * If the parameter completed is not NULL then after obtaining the event - * handling lock this function will return immediately if the integer - * pointed to is not 0. This allows for race free waiting for the completion - * of a specific transfer. + * If the parameter completed is not NULL then after obtaining the event handling lock this function will return + * immediately if the integer pointed to is not 0. This allows for race free waiting for the completion of a + * specific transfer. * - * The only way to implement this in Java is by passing a direct buffer, and - * then accessing memory directly. IntBuffers can be direct, if they are - * created as a view of a direct ByteBuffer, by using BufferUtils: + * The only way to implement this in Java is by passing a direct buffer, and then accessing memory directly. + * IntBuffers can be direct, if they are created as a view of a direct ByteBuffer, by using BufferUtils: * {@link BufferUtils#allocateIntBuffer()} * * @param context * the context to operate on, or NULL for the default context * @param timeout - * the maximum time to block waiting for events, or 0 for - * non-blocking mode. + * the maximum time to block waiting for events, or 0 for non-blocking mode. * @param completed * Buffer for completion integer to check, or NULL. * @return 0 on success, or a ERROR code on failure */ - public static native int handleEventsTimeoutCompleted( - final Context context, final long timeout, final IntBuffer completed); + public static native int handleEventsTimeoutCompleted(final Context context, final long timeout, + final IntBuffer completed); /** * Handle any pending events. * - * Like {@link #handleEventsTimeoutCompleted(Context, long, IntBuffer)}, but - * without the completed parameter, calling this function is equivalent to - * calling {@link #handleEventsTimeoutCompleted(Context, long, IntBuffer)} + * Like {@link #handleEventsTimeoutCompleted(Context, long, IntBuffer)}, but without the completed parameter, + * calling this function is equivalent to calling {@link #handleEventsTimeoutCompleted(Context, long, IntBuffer)} * with a NULL completed parameter. * - * This function is kept primarily for backwards compatibility. All new code - * should call {@link #handleEventsCompleted(Context, IntBuffer)} or - * {@link #handleEventsTimeoutCompleted(Context, long, IntBuffer)} to avoid - * race conditions. + * This function is kept primarily for backwards compatibility. All new code should call + * {@link #handleEventsCompleted(Context, IntBuffer)} or + * {@link #handleEventsTimeoutCompleted(Context, long, IntBuffer)} to avoid race conditions. * * @param context * The context to operate on, or NULL for the default context * @param timeout - * The maximum time (In microseconds) to block waiting for - * events, or an all zero timeval struct for non-blocking mode + * The maximum time (In microseconds) to block waiting for events, or an all zero timeval struct for + * non-blocking mode * @return 0 on success, or a ERROR code on failure */ - public static native int handleEventsTimeout(final Context context, - final long timeout); + public static native int handleEventsTimeout(final Context context, final long timeout); /** * Handle any pending events in blocking mode. * - * There is currently a timeout hardcoded at 60 seconds but we plan to make - * it unlimited in future. For finer control over whether this function is - * blocking or non-blocking, or for control over the timeout, use + * There is currently a timeout hardcoded at 60 seconds but we plan to make it unlimited in future. For finer + * control over whether this function is blocking or non-blocking, or for control over the timeout, use * {@link #handleEventsTimeoutCompleted(Context, long, IntBuffer)} instead. * - * This function is kept primarily for backwards compatibility. All new code - * should call {@link #handleEventsCompleted(Context, IntBuffer)} or - * {@link #handleEventsTimeoutCompleted(Context, long, IntBuffer)} to avoid - * race conditions. + * This function is kept primarily for backwards compatibility. All new code should call + * {@link #handleEventsCompleted(Context, IntBuffer)} or + * {@link #handleEventsTimeoutCompleted(Context, long, IntBuffer)} to avoid race conditions. * * @param context * The context to operate on, or NULL for the default context. @@ -2148,12 +2002,10 @@ public static native int handleEventsTimeout(final Context context, /** * Handle any pending events in blocking mode. * - * Like {@link #handleEvents(Context)}, with the addition of a completed - * parameter to allow for race free waiting for the completion of a specific - * transfer. + * Like {@link #handleEvents(Context)}, with the addition of a completed parameter to allow for race free waiting + * for the completion of a specific transfer. * - * See {@link #handleEventsTimeoutCompleted(Context, long, IntBuffer)} for - * details on the completed parameter. + * See {@link #handleEventsTimeoutCompleted(Context, long, IntBuffer)} for details on the completed parameter. * * @param context * The context to operate on, or NULL for the default context. @@ -2161,159 +2013,132 @@ public static native int handleEventsTimeout(final Context context, * Buffer for completion integer to check, or NULL. * @return 0 on success, or a ERROR code on failure. */ - public static native int handleEventsCompleted(final Context context, - final IntBuffer completed); + public static native int handleEventsCompleted(final Context context, final IntBuffer completed); /** - * Handle any pending events by polling file descriptors, without checking - * if any other threads are already doing so. + * Handle any pending events by polling file descriptors, without checking if any other threads are already doing + * so. * - * Must be called with the event lock held, see {@link #lockEvents(Context)} - * . + * Must be called with the event lock held, see {@link #lockEvents(Context)} . * - * This function is designed to be called under the situation where you have - * taken the event lock and are calling poll()/select() directly on libusb's - * file descriptors (as opposed to using {@link #handleEvents(Context)} or - * similar). You detect events on libusb's descriptors, so you then call - * this function with a zero timeout value (while still holding the event - * lock). + * This function is designed to be called under the situation where you have taken the event lock and are calling + * poll()/select() directly on libusb's file descriptors (as opposed to using {@link #handleEvents(Context)} or + * similar). You detect events on libusb's descriptors, so you then call this function with a zero timeout value + * (while still holding the event lock). * * @param context * The context to operate on, or NULL for the default context. * @param timeout - * The maximum time (In microseconds) to block waiting for - * events, or zero for non-blocking mode + * The maximum time (In microseconds) to block waiting for events, or zero for non-blocking mode * @return 0 on success, or a ERROR code on failure. */ - public static native int handleEventsLocked(final Context context, - final long timeout); + public static native int handleEventsLocked(final Context context, final long timeout); /** - * Determines whether your application must apply special timing - * considerations when monitoring libusb's file descriptors. + * Determines whether your application must apply special timing considerations when monitoring libusb's file + * descriptors. * - * This function is only useful for applications which retrieve and poll - * libusb's file descriptors in their own main loop (The more advanced - * option). + * This function is only useful for applications which retrieve and poll libusb's file descriptors in their own main + * loop (The more advanced option). * - * Ordinarily, libusb's event handler needs to be called into at specific - * moments in time (in addition to times when there is activity on the file - * descriptor set). The usual approach is to use - * {@link #getNextTimeout(Context, LongBuffer)} to learn about when the next - * timeout occurs, and to adjust your poll()/select() timeout accordingly so - * that you can make a call into the library at that time. + * Ordinarily, libusb's event handler needs to be called into at specific moments in time (in addition to times when + * there is activity on the file descriptor set). The usual approach is to use + * {@link #getNextTimeout(Context, LongBuffer)} to learn about when the next timeout occurs, and to adjust your + * poll()/select() timeout accordingly so that you can make a call into the library at that time. * - * Some platforms supported by libusb do not come with this baggage - any - * events relevant to timing will be represented by activity on the file - * descriptor set, and {@link #getNextTimeout(Context, LongBuffer)} will - * always return 0. This function allows you to detect whether you are - * running on such a platform. + * Some platforms supported by libusb do not come with this baggage - any events relevant to timing will be + * represented by activity on the file descriptor set, and {@link #getNextTimeout(Context, LongBuffer)} will always + * return 0. This function allows you to detect whether you are running on such a platform. * * @param context * The context to operate on, or NULL for the default context - * @return 0 if you must call into libusb at times determined by - * {@link #getNextTimeout(Context, LongBuffer)}, or 1 if all timeout - * events are handled internally or through regular activity on the - * file descriptors. + * @return 0 if you must call into libusb at times determined by {@link #getNextTimeout(Context, LongBuffer)}, or 1 + * if all timeout events are handled internally or through regular activity on the file descriptors. */ public static native int pollfdsHandleTimeouts(final Context context); /** * Determine the next internal timeout that libusb needs to handle. * - * You only need to use this function if you are calling poll() or select() - * or similar on libusb's file descriptors yourself - you do not need to - * use it if you are calling {@link #handleEvents(Context)} or a variant - * directly. + * You only need to use this function if you are calling poll() or select() or similar on libusb's file descriptors + * yourself - you do not need to use it if you are calling {@link #handleEvents(Context)} or a variant directly. * - * You should call this function in your main loop in order to determine how - * long to wait for select() or poll() to return results. libusb needs to - * be called into at this timeout, so you should use it as an upper bound on - * your select() or poll() call. + * You should call this function in your main loop in order to determine how long to wait for select() or poll() to + * return results. libusb needs to be called into at this timeout, so you should use it as an upper bound on your + * select() or poll() call. * - * When the timeout has expired, call into - * {@link #handleEventsTimeout(Context, long)} (perhaps in non-blocking + * When the timeout has expired, call into {@link #handleEventsTimeout(Context, long)} (perhaps in non-blocking * mode) so that libusb can handle the timeout. * - * This function may return 1 (success) and an all-zero timeval. If this is - * the case, it indicates that libusb has a timeout that has already - * expired so you should call {@link #handleEventsTimeout(Context, long)} or - * similar immediately. A return code of 0 indicates that there are no - * pending timeouts. + * This function may return 1 (success) and an all-zero timeval. If this is the case, it indicates that libusb has a + * timeout that has already expired so you should call {@link #handleEventsTimeout(Context, long)} or similar + * immediately. A return code of 0 indicates that there are no pending timeouts. * - * On some platforms, this function will always returns 0 (no pending - * timeouts). See Notes on time-based events. + * On some platforms, this function will always returns 0 (no pending timeouts). See Notes on time-based events. * * @param context * The context to operate on, or NULL for the default context * @param timeout - * Output location for a relative time against the current clock - * in which libusb must be called into in order to process - * timeout events - * @return 0 if there are no pending timeouts, 1 if a timeout was returned, - * or {@link #ERROR_OTHER} failure + * Output location for a relative time against the current clock in which libusb must be called into in + * order to process timeout events + * @return 0 if there are no pending timeouts, 1 if a timeout was returned, or {@link #ERROR_OTHER} failure */ - public static native int getNextTimeout(final Context context, - final LongBuffer timeout); + public static native int getNextTimeout(final Context context, final LongBuffer timeout); /** * Register notification functions for file descriptor additions/removals. * - * These functions will be invoked for every new or removed file descriptor - * that libusb uses as an event source. + * These functions will be invoked for every new or removed file descriptor that libusb uses as an event source. * * To remove notifiers, pass NULL values for the function pointers. * - * Note that file descriptors may have been added even before you register - * these notifiers (e.g. at {@link #init(Context)} time). + * Note that file descriptors may have been added even before you register these notifiers (e.g. at + * {@link #init(Context)} time). * - * Additionally, note that the removal notifier may be called during - * {@link #exit(Context)} (e.g. when it is closing file descriptors that - * were opened and added to the poll set at {@link #init(Context)} time). If - * you don't want this, remove the notifiers immediately before calling - * {@link #exit(Context)}. + * Additionally, note that the removal notifier may be called during {@link #exit(Context)} (e.g. when it is closing + * file descriptors that were opened and added to the poll set at {@link #init(Context)} time). If you don't want + * this, remove the notifiers immediately before calling {@link #exit(Context)}. * * @param context * The context to operate on, or NULL for the default context. * @param listener * The listener for addition and removal notifications. * @param userData - * User data to be passed back to callbacks (useful for passing - * context information). - */ - public static synchronized void setPollfdNotifiers(final Context context, - final PollfdListener listener, final Object userData) - { - long contextId; - - if (context == null) - { - // NULL pointer has value 0 - contextId = 0; - } - else - { - contextId = context.getPointer(); - } - - if (listener == null) - { - unsetPollfdNotifiersNative(context); - - pollfdListeners.remove(contextId); - } - else - { - setPollfdNotifiersNative(context, contextId); - - pollfdListeners.put(contextId, - new ImmutablePair(listener, userData)); - } + * User data to be passed back to callbacks (useful for passing context information). + */ + public static synchronized void setPollfdNotifiers(final Context context, final PollfdListener listener, + final Object userData) { + // TODO + // long contextId; + // + // if (context == null) + // { + // // NULL pointer has value 0 + // contextId = 0; + // } + // else + // { + // contextId = context.getPointer(); + // } + // + // if (listener == null) + // { + // unsetPollfdNotifiersNative(context); + // + // pollfdListeners.remove(contextId); + // } + // else + // { + // setPollfdNotifiersNative(context, contextId); + // + // pollfdListeners.put(contextId, + // new ImmutablePair(listener, userData)); + // } } /** - * Callback function, invoked when a new file descriptor should be added to - * the set of file descriptors monitored for events. + * Callback function, invoked when a new file descriptor should be added to the set of file descriptors monitored + * for events. * * @param fd * The new file descriptor, @@ -2322,14 +2147,10 @@ public static synchronized void setPollfdNotifiers(final Context context, * @param contextId * A unique identifier for the originating context. */ - static void triggerPollfdAdded(final FileDescriptor fd, final int events, - final long contextId) - { - final ImmutablePair listener = pollfdListeners - .get(contextId); + static void triggerPollfdAdded(final FileDescriptor fd, final int events, final long contextId) { + final ImmutablePair listener = pollfdListeners.get(contextId); - if (listener != null) - { + if (listener != null) { listener.left.pollfdAdded(fd, events, listener.right); } } @@ -2342,33 +2163,26 @@ static void triggerPollfdAdded(final FileDescriptor fd, final int events, * @param contextId * A unique identifier for the originating context. */ - static void triggerPollfdRemoved(final FileDescriptor fd, - final long contextId) - { - final ImmutablePair listener = pollfdListeners - .get(contextId); + static void triggerPollfdRemoved(final FileDescriptor fd, final long contextId) { + final ImmutablePair listener = pollfdListeners.get(contextId); - if (listener != null) - { + if (listener != null) { listener.left.pollfdRemoved(fd, listener.right); } } /** - * Configures libusb to inform this class about pollfd additions and - * removals. + * Configures libusb to inform this class about pollfd additions and removals. * * @param context * The context to operate on, or NULL for the default context * @param contextId * A unique identifier for the given context. */ - static native void setPollfdNotifiersNative(final Context context, - final long contextId); + static native void setPollfdNotifiersNative(final Context context, final long contextId); /** - * Tells libusb to stop informing this class about pollfd additions and - * removals. + * Tells libusb to stop informing this class about pollfd additions and removals. * * @param context * The context to operate on, or NULL for the default context @@ -2378,37 +2192,31 @@ static native void setPollfdNotifiersNative(final Context context, /** * Allocate a libusb transfer without support for isochronous transfers. * - * The returned transfer is pre-initialized for you. When the new transfer - * is no longer needed, it should be freed with - * {@link #freeTransfer(Transfer)}. + * The returned transfer is pre-initialized for you. When the new transfer is no longer needed, it should be freed + * with {@link #freeTransfer(Transfer)}. * * @return A newly allocated transfer, or NULL on error */ - public static Transfer allocTransfer() - { + public static Transfer allocTransfer() { return allocTransfer(0); } /** - * Allocate a libusb transfer with a specified number of isochronous packet - * descriptors. + * Allocate a libusb transfer with a specified number of isochronous packet descriptors. * - * The returned transfer is pre-initialized for you. When the new transfer - * is no longer needed, it should be freed with - * {@link #freeTransfer(Transfer)}. + * The returned transfer is pre-initialized for you. When the new transfer is no longer needed, it should be freed + * with {@link #freeTransfer(Transfer)}. * - * Transfers intended for non-isochronous endpoints (e.g. control, bulk, - * interrupt) should specify an iso_packets count of zero. + * Transfers intended for non-isochronous endpoints (e.g. control, bulk, interrupt) should specify an iso_packets + * count of zero. * - * For transfers intended for isochronous endpoints, specify an appropriate - * number of packet descriptors to be allocated as part of the transfer. The - * returned transfer is not specially initialized for isochronous I/O; you - * are still required to call the {@link Transfer#setNumIsoPackets(int)} a - * {@link Transfer#setType(byte)} methods accordingly. + * For transfers intended for isochronous endpoints, specify an appropriate number of packet descriptors to be + * allocated as part of the transfer. The returned transfer is not specially initialized for isochronous I/O; you + * are still required to call the {@link Transfer#setNumIsoPackets(int)} a {@link Transfer#setType(byte)} methods + * accordingly. * - * It is safe to allocate a transfer with some isochronous packets and then - * use it on a non-isochronous endpoint. If you do this, ensure that at time - * of submission, numIsoPackets is 0 and that type is set appropriately. + * It is safe to allocate a transfer with some isochronous packets and then use it on a non-isochronous endpoint. If + * you do this, ensure that at time of submission, numIsoPackets is 0 and that type is set appropriately. * * @param isoPackets * Number of isochronous packet descriptors to allocate. @@ -2419,17 +2227,13 @@ public static Transfer allocTransfer() /** * Free a transfer structure. * - * This should be called for all transfers allocated with - * {@link #allocTransfer(int)}. + * This should be called for all transfers allocated with {@link #allocTransfer(int)}. * - * Please refer to {@link #TRANSFER_FREE_BUFFER} for an explanation - * of how buffers are freed. + * Please refer to {@link #TRANSFER_FREE_BUFFER} for an explanation of how buffers are freed. * - * It is legal to call this function with a NULL transfer. In this case, the - * function will simply return safely. + * It is legal to call this function with a NULL transfer. In this case, the function will simply return safely. * - * It is not legal to free an active transfer (one which has been submitted - * and has not yet completed). + * It is not legal to free an active transfer (one which has been submitted and has not yet completed). * * @param transfer * The transfer to free @@ -2443,79 +2247,63 @@ public static Transfer allocTransfer() * * @param transfer * The transfer to submit - * @return 0 on success, {@link #ERROR_NO_DEVICE} if the device has - * been - * disconnected, {@link #ERROR_BUSY} if the transfer has - * already been - * submitted. {@link #ERROR_NOT_SUPPORTED} if the transfer - * flags are - * not supported by the operating system. Another LIBUSB_ERROR code - * on failure. + * @return 0 on success, {@link #ERROR_NO_DEVICE} if the device has been disconnected, {@link #ERROR_BUSY} if the + * transfer has already been submitted. {@link #ERROR_NOT_SUPPORTED} if the transfer flags are not supported + * by the operating system. Another LIBUSB_ERROR code on failure. */ public static native int submitTransfer(final Transfer transfer); /** * Asynchronously cancel a previously submitted transfer. * - * This function returns immediately, but this does not indicate - * cancellation - * is complete. Your callback function will be invoked at some later time - * with a transfer status of {@link #TRANSFER_CANCELLED}. + * This function returns immediately, but this does not indicate cancellation is complete. Your callback function + * will be invoked at some later time with a transfer status of {@link #TRANSFER_CANCELLED}. * * @param transfer * The transfer to cancel - * @return 0 on success, {@link #ERROR_NOT_FOUND} if the transfer is - * already complete or cancelled. Another LIBUSB_ERROR code on - * failure. + * @return 0 on success, {@link #ERROR_NOT_FOUND} if the transfer is already complete or cancelled. Another + * LIBUSB_ERROR code on failure. */ public static native int cancelTransfer(final Transfer transfer); /** * Get the data section of a control transfer. * - * This convenience function is here to remind you that the data does not - * start until 8 bytes into the actual buffer, as the setup packet comes - * first. + * This convenience function is here to remind you that the data does not start until 8 bytes into the actual + * buffer, as the setup packet comes first. * - * Calling this function only makes sense from a transfer callback function, - * or situations where you have already allocated a suitably sized buffer at - * {@link Transfer#buffer()}. + * Calling this function only makes sense from a transfer callback function, or situations where you have already + * allocated a suitably sized buffer at {@link Transfer#buffer()}. * * @param transfer * A transfer. * @return The data section. */ - public static ByteBuffer controlTransferGetData(final Transfer transfer) - { - return BufferUtils.slice(transfer.buffer(), CONTROL_SETUP_SIZE, - transfer.buffer().limit() - CONTROL_SETUP_SIZE); + public static ByteBuffer controlTransferGetData(final Transfer transfer) { + return BufferUtils.slice(transfer.buffer(), CONTROL_SETUP_SIZE, transfer.buffer().limit() - CONTROL_SETUP_SIZE); } /** * Get the control setup packet of a control transfer. * - * This convenience function is here to remind you that the control setup - * occupies the first 8 bytes of the transfer data buffer. + * This convenience function is here to remind you that the control setup occupies the first 8 bytes of the transfer + * data buffer. * - * Calling this function only makes sense from a transfer callback function, - * or situations where you have already allocated a suitably sized buffer at - * {@link Transfer#buffer()}. + * Calling this function only makes sense from a transfer callback function, or situations where you have already + * allocated a suitably sized buffer at {@link Transfer#buffer()}. * * @param transfer * A transfer. * @return The setup section. */ - public static ControlSetup controlTransferGetSetup(final Transfer transfer) - { + public static ControlSetup controlTransferGetSetup(final Transfer transfer) { return new ControlSetup(transfer.buffer()); } /** - * Helper function to populate the setup packet (first 8 bytes of the data - * buffer) for a control transfer. + * Helper function to populate the setup packet (first 8 bytes of the data buffer) for a control transfer. * - * The wIndex, wValue and wLength values should be given in host-endian byte - * order. + * The wIndex, wValue and wLength values should be given in host-endian byte order. * * @param buffer * Buffer to output the setup packet into. @@ -2530,10 +2318,8 @@ public static ControlSetup controlTransferGetSetup(final Transfer transfer) * @param wLength * See {@link ControlSetup#wLength()}. */ - public static void fillControlSetup(final ByteBuffer buffer, - final byte bmRequestType, final byte bRequest, final short wValue, - final short wIndex, final short wLength) - { + public static void fillControlSetup(final ByteBuffer buffer, final byte bmRequestType, final byte bRequest, + final short wValue, final short wIndex, final short wLength) { final ControlSetup setup = new ControlSetup(buffer); setup.setBmRequestType(bmRequestType); setup.setBRequest(bRequest); @@ -2543,39 +2329,32 @@ public static void fillControlSetup(final ByteBuffer buffer, } /** - * Helper function to populate the required {@link Transfer} fields for a - * control transfer. + * Helper function to populate the required {@link Transfer} fields for a control transfer. * - * If you pass a transfer buffer to this function, the first 8 bytes will be - * interpreted as a control setup packet, and the wLength field will be used - * to automatically populate the length field of the transfer. Therefore the + * If you pass a transfer buffer to this function, the first 8 bytes will be interpreted as a control setup packet, + * and the wLength field will be used to automatically populate the length field of the transfer. Therefore the * recommended approach is: * - * 1. Allocate a suitably sized data buffer (including space for control - * setup). + * 1. Allocate a suitably sized data buffer (including space for control setup). * - * 2. Call - * {@link #fillControlSetup(ByteBuffer, byte, byte, short, short, short)}. + * 2. Call {@link #fillControlSetup(ByteBuffer, byte, byte, short, short, short)}. * - * 3. If this is a host-to-device transfer with a data stage, put the data - * in place after the setup packet. + * 3. If this is a host-to-device transfer with a data stage, put the data in place after the setup packet. * * 4. Call this function. * * 5. Call {@link #submitTransfer(Transfer)}. * - * It is also legal to pass a NULL buffer to this function, in which case - * this function will not attempt to populate the length field. Remember - * that you must then populate the buffer and length fields later. + * It is also legal to pass a NULL buffer to this function, in which case this function will not attempt to populate + * the length field. Remember that you must then populate the buffer and length fields later. * * @param transfer * The transfer to populate. * @param handle * Handle of the device that will handle the transfer. * @param buffer - * Data buffer. If provided, this function will interpret the - * first 8 bytes as a setup packet and infer the transfer length - * from that. + * Data buffer. If provided, this function will interpret the first 8 bytes as a setup packet and infer + * the transfer length from that. * @param callback * callback function to be invoked on transfer completion. * @param userData @@ -2583,11 +2362,8 @@ public static void fillControlSetup(final ByteBuffer buffer, * @param timeout * Timeout for the transfer in milliseconds. */ - public static void fillControlTransfer(final Transfer transfer, - final DeviceHandle handle, final ByteBuffer buffer, - final TransferCallback callback, final Object userData, - final long timeout) - { + public static void fillControlTransfer(final Transfer transfer, final DeviceHandle handle, final ByteBuffer buffer, + final TransferCallback callback, final Object userData, final long timeout) { transfer.setDevHandle(handle); transfer.setEndpoint((byte) 0); transfer.setType(TRANSFER_TYPE_CONTROL); @@ -2602,8 +2378,7 @@ public static void fillControlTransfer(final Transfer transfer, } /** - * Helper function to populate the required {@link Transfer} fields for a - * bulk transfer. + * Helper function to populate the required {@link Transfer} fields for a bulk transfer. * * @param transfer * The transfer to populate. @@ -2620,11 +2395,8 @@ public static void fillControlTransfer(final Transfer transfer, * @param timeout * Timeout for the transfer in milliseconds. */ - public static void fillBulkTransfer(final Transfer transfer, - final DeviceHandle handle, final byte endpoint, - final ByteBuffer buffer, final TransferCallback callback, - final Object userData, final long timeout) - { + public static void fillBulkTransfer(final Transfer transfer, final DeviceHandle handle, final byte endpoint, + final ByteBuffer buffer, final TransferCallback callback, final Object userData, final long timeout) { transfer.setDevHandle(handle); transfer.setEndpoint(endpoint); transfer.setType(TRANSFER_TYPE_BULK); @@ -2635,8 +2407,7 @@ public static void fillBulkTransfer(final Transfer transfer, } /** - * Helper function to populate the required {@link Transfer} fields - * for a bulk transfer using bulk streams. + * Helper function to populate the required {@link Transfer} fields for a bulk transfer using bulk streams. * * @param transfer * The transfer to populate. @@ -2655,19 +2426,16 @@ public static void fillBulkTransfer(final Transfer transfer, * @param timeout * Timeout for the transfer in milliseconds. */ - public static void fillBulkStreamTransfer(final Transfer transfer, - final DeviceHandle handle, final byte endpoint, final int streamId, - final ByteBuffer buffer, final TransferCallback callback, - final Object userData, final long timeout) - { + public static void fillBulkStreamTransfer(final Transfer transfer, final DeviceHandle handle, final byte endpoint, + final int streamId, final ByteBuffer buffer, final TransferCallback callback, final Object userData, + final long timeout) { fillBulkTransfer(transfer, handle, endpoint, buffer, callback, userData, timeout); transfer.setType(TRANSFER_TYPE_BULK_STREAM); transfer.setStreamId(streamId); } /** - * Helper function to populate the required {@link Transfer} fields for an - * interrupt transfer. + * Helper function to populate the required {@link Transfer} fields for an interrupt transfer. * * @param transfer * The transfer to populate. @@ -2684,11 +2452,8 @@ public static void fillBulkStreamTransfer(final Transfer transfer, * @param timeout * Timeout for the transfer in milliseconds. */ - public static void fillInterruptTransfer(final Transfer transfer, - final DeviceHandle handle, final byte endpoint, - final ByteBuffer buffer, final TransferCallback callback, - final Object userData, final long timeout) - { + public static void fillInterruptTransfer(final Transfer transfer, final DeviceHandle handle, final byte endpoint, + final ByteBuffer buffer, final TransferCallback callback, final Object userData, final long timeout) { transfer.setDevHandle(handle); transfer.setEndpoint(endpoint); transfer.setType(TRANSFER_TYPE_INTERRUPT); @@ -2699,8 +2464,7 @@ public static void fillInterruptTransfer(final Transfer transfer, } /** - * Helper function to populate the required {@link Transfer} fields for an - * isochronous transfer. + * Helper function to populate the required {@link Transfer} fields for an isochronous transfer. * * @param transfer * The transfer to populate. @@ -2719,12 +2483,9 @@ public static void fillInterruptTransfer(final Transfer transfer, * @param timeout * Timeout for the transfer in milliseconds. */ - public static void fillIsoTransfer(final Transfer transfer, - final DeviceHandle handle, final byte endpoint, - final ByteBuffer buffer, final int numIsoPackets, - final TransferCallback callback, final Object userData, - final long timeout) - { + public static void fillIsoTransfer(final Transfer transfer, final DeviceHandle handle, final byte endpoint, + final ByteBuffer buffer, final int numIsoPackets, final TransferCallback callback, final Object userData, + final long timeout) { transfer.setDevHandle(handle); transfer.setEndpoint(endpoint); transfer.setType(TRANSFER_TYPE_ISOCHRONOUS); @@ -2736,8 +2497,8 @@ public static void fillIsoTransfer(final Transfer transfer, } /** - * Convenience function to set the length of all packets in an isochronous - * transfer, based on the {@link Transfer#numIsoPackets()} field. + * Convenience function to set the length of all packets in an isochronous transfer, based on the + * {@link Transfer#numIsoPackets()} field. * * @param transfer * A transfer. @@ -2745,87 +2506,69 @@ public static void fillIsoTransfer(final Transfer transfer, * The length to set in each isochronous packet descriptor. * @see #getMaxPacketSize(Device, byte) */ - public static void setIsoPacketLengths(final Transfer transfer, - final int length) - { - for (final IsoPacketDescriptor isoDesc : transfer.isoPacketDesc()) - { + public static void setIsoPacketLengths(final Transfer transfer, final int length) { + for (final IsoPacketDescriptor isoDesc: transfer.isoPacketDesc()) { isoDesc.setLength(length); } } /** - * Convenience function to locate the position of an isochronous packet - * within the buffer of an isochronous transfer. + * Convenience function to locate the position of an isochronous packet within the buffer of an isochronous + * transfer. * - * This is a thorough function which loops through all preceding packets, - * accumulating their lengths to find the position of the specified packet. - * Typically you will assign equal lengths to each packet in the transfer, - * and hence the above method is sub-optimal. You may wish to use - * {@link #getIsoPacketBufferSimple(Transfer, int)} instead. + * This is a thorough function which loops through all preceding packets, accumulating their lengths to find the + * position of the specified packet. Typically you will assign equal lengths to each packet in the transfer, and + * hence the above method is sub-optimal. You may wish to use {@link #getIsoPacketBufferSimple(Transfer, int)} + * instead. * * @param transfer * A transfer. * @param packet * The packet to return the address of. - * @return The base address of the packet buffer inside the transfer buffer, - * or NULL if the packet does not exist. + * @return The base address of the packet buffer inside the transfer buffer, or NULL if the packet does not exist. * @see #getIsoPacketBufferSimple(Transfer, int) */ - public static ByteBuffer getIsoPacketBuffer(final Transfer transfer, - final int packet) - { - if (packet >= transfer.numIsoPackets()) - { + public static ByteBuffer getIsoPacketBuffer(final Transfer transfer, final int packet) { + if (packet >= transfer.numIsoPackets()) { return null; } final IsoPacketDescriptor[] isoDescriptors = transfer.isoPacketDesc(); int offset = 0; - for (int i = 0; i < packet; i++) - { + for (int i = 0; i < packet; i++) { offset += isoDescriptors[i].length(); } - return BufferUtils.slice(transfer.buffer(), offset, - isoDescriptors[packet].length()); + return BufferUtils.slice(transfer.buffer(), offset, isoDescriptors[packet].length()); } /** - * Convenience function to locate the position of an isochronous packet - * within the buffer of an isochronous transfer, for transfers where each - * packet is of identical size. + * Convenience function to locate the position of an isochronous packet within the buffer of an isochronous + * transfer, for transfers where each packet is of identical size. * - * This function relies on the assumption that every packet within the - * transfer is of identical size to the first packet. Calculating the - * location of the packet buffer is then just a simple calculation: buffer + - * (packet_size * packet) + * This function relies on the assumption that every packet within the transfer is of identical size to the first + * packet. Calculating the location of the packet buffer is then just a simple calculation: buffer + (packet_size * + * packet) * - * Do not use this function on transfers other than those that have - * identical packet lengths for each packet. + * Do not use this function on transfers other than those that have identical packet lengths for each packet. * * @param transfer * A transfer. * @param packet * The packet to return the address of. - * @return The base address of the packet buffer inside the transfer buffer, - * or NULL if the packet does not exist. + * @return The base address of the packet buffer inside the transfer buffer, or NULL if the packet does not exist. * @see #getIsoPacketBuffer(Transfer, int) */ - public static ByteBuffer getIsoPacketBufferSimple(final Transfer transfer, - final int packet) - { - if (packet >= transfer.numIsoPackets()) - { + public static ByteBuffer getIsoPacketBufferSimple(final Transfer transfer, final int packet) { + if (packet >= transfer.numIsoPackets()) { return null; } final IsoPacketDescriptor[] isoDescriptors = transfer.isoPacketDesc(); final int offset = isoDescriptors[0].length() * packet; - return BufferUtils.slice(transfer.buffer(), offset, - isoDescriptors[packet].length()); + return BufferUtils.slice(transfer.buffer(), offset, isoDescriptors[packet].length()); } /** @@ -2839,28 +2582,22 @@ public static ByteBuffer getIsoPacketBufferSimple(final Transfer transfer, * Event that occurred * @param hotplugId * The hotplug ID. - * @return Whether this callback is finished processing events. Returning 1 - * will cause this callback to be deregistered. + * @return Whether this callback is finished processing events. Returning 1 will cause this callback to be + * deregistered. */ - static int hotplugCallback(final Context context, final Device device, - final int event, final long hotplugId) - { - final ImmutablePair callback = hotplugCallbacks - .get(hotplugId); + static int hotplugCallback(final Context context, final Device device, final int event, final long hotplugId) { + final ImmutablePair callback = hotplugCallbacks.get(hotplugId); int result = 0; - if (callback != null) - { - result = callback.left.processEvent(context, device, event, - callback.right); + if (callback != null) { + result = callback.left.processEvent(context, device, event, callback.right); } // If callback indicates it is finished, it will get deregistered // automatically. As such, we have to remove it from the Java // map, like when deregistering manually. - if (result == 1) - { + if (result == 1) { hotplugCallbacks.remove(hotplugId); } @@ -2870,12 +2607,10 @@ static int hotplugCallback(final Context context, final Device device, /** * Register a hotplug callback function. * - * Register a callback with the {@link Context}. The callback will fire - * when a matching event occurs on a matching device. The callback is - * armed until either it is deregistered with - * {@link #hotplugDeregisterCallback(Context, HotplugCallbackHandle)} or the - * supplied callback returns 1 to indicate it is finished processing - * events. + * Register a callback with the {@link Context}. The callback will fire when a matching event occurs on a matching + * device. The callback is armed until either it is deregistered with + * {@link #hotplugDeregisterCallback(Context, HotplugCallbackHandle)} or the supplied callback returns 1 to indicate + * it is finished processing events. * * @param context * Context to register this callback with. @@ -2894,44 +2629,33 @@ static int hotplugCallback(final Context context, final Device device, * @param userData * User data to pass to the callback function. * @param callbackHandle - * Hotplug callback handle of the allocated callback. Only needed - * if you later want to deregister this callback, can be NULL. + * Hotplug callback handle of the allocated callback. Only needed if you later want to deregister this + * callback, can be NULL. * @return {@link #SUCCESS} on success, some ERROR code on failure. */ - public static synchronized int hotplugRegisterCallback( - final Context context, final int events, final int flags, - final int vendorId, final int productId, final int deviceClass, - final HotplugCallback callback, final Object userData, - final HotplugCallbackHandle callbackHandle) - { - if (callback == null) - { + public static synchronized int hotplugRegisterCallback(final Context context, final int events, final int flags, + final int vendorId, final int productId, final int deviceClass, final HotplugCallback callback, + final Object userData, final HotplugCallbackHandle callbackHandle) { + if (callback == null) { throw new IllegalArgumentException("callback must not be null"); } // Callback must be added to our own list before registering it in // libusb because otherwise we won't get the enumeration events - hotplugCallbacks.put(globalHotplugId, - new ImmutablePair(callback, userData)); + hotplugCallbacks.put(globalHotplugId, new ImmutablePair(callback, userData)); // Mask the values for conversion to int in libusb API. - final int result = hotplugRegisterCallbackNative( - context, events, flags, - (vendorId == LibUsb.HOTPLUG_MATCH_ANY) ? (LibUsb.HOTPLUG_MATCH_ANY) - : (vendorId & 0xFFFF), - (productId == LibUsb.HOTPLUG_MATCH_ANY) ? (LibUsb.HOTPLUG_MATCH_ANY) - : (productId & 0xFFFF), - (deviceClass == LibUsb.HOTPLUG_MATCH_ANY) ? - (LibUsb.HOTPLUG_MATCH_ANY) : (deviceClass & 0xFF), - callbackHandle, globalHotplugId); - - if (result == LibUsb.SUCCESS) - { + final int result = + hotplugRegisterCallbackNative(context, events, flags, (vendorId == LibUsb.HOTPLUG_MATCH_ANY) + ? (LibUsb.HOTPLUG_MATCH_ANY) : (vendorId & 0xFFFF), (productId == LibUsb.HOTPLUG_MATCH_ANY) + ? (LibUsb.HOTPLUG_MATCH_ANY) : (productId & 0xFFFF), (deviceClass == LibUsb.HOTPLUG_MATCH_ANY) + ? (LibUsb.HOTPLUG_MATCH_ANY) : (deviceClass & 0xFF), callbackHandle, globalHotplugId); + + if (result == LibUsb.SUCCESS) { // Increment globalHotplugId by one, like the libusb handle. globalHotplugId++; } - else - { + else { // When registration failed then remove the hotplug callback from // our list. hotplugCallbacks.remove(globalHotplugId); @@ -2956,33 +2680,28 @@ public static synchronized int hotplugRegisterCallback( * @param deviceClass * The device class to match or {@link #HOTPLUG_MATCH_ANY}. * @param callbackHandle - * Hotplug callback handle of the allocated callback. Only needed - * if you later want to deregister this callback, can be NULL. + * Hotplug callback handle of the allocated callback. Only needed if you later want to deregister this + * callback, can be NULL. * @param hotplugId * The hotplug callback ID. * @return {@link #SUCCESS} on success, some ERROR code on failure. */ - static native int hotplugRegisterCallbackNative(final Context context, - final int events, final int flags, final int vendorId, - final int productId, final int deviceClass, - final HotplugCallbackHandle callbackHandle, final long hotplugId); + static native int hotplugRegisterCallbackNative(final Context context, final int events, final int flags, + final int vendorId, final int productId, final int deviceClass, final HotplugCallbackHandle callbackHandle, + final long hotplugId); /** * Deregisters a hotplug callback. * - * Deregister a callback from a {@link Context}. This function is safe to - * call from within a hotplug callback. + * Deregister a callback from a {@link Context}. This function is safe to call from within a hotplug callback. * * @param context * context this callback is registered with * @param callbackHandle * the handle of the callback to deregister */ - public static void hotplugDeregisterCallback(final Context context, - final HotplugCallbackHandle callbackHandle) - { - final long handle = hotplugDeregisterCallbackNative(context, - callbackHandle); + public static void hotplugDeregisterCallback(final Context context, final HotplugCallbackHandle callbackHandle) { + final long handle = hotplugDeregisterCallbackNative(context, callbackHandle); // When a handle is assigned by a register call, its value is the same // as the one of globalHotplugId at that moment, which is what's used @@ -2999,8 +2718,7 @@ public static void hotplugDeregisterCallback(final Context context, /** * Internally called native method for unregistering a hotplug callback. * - * Deregister a callback from a {@link Context}. This function is safe to - * call from within a hotplug callback. + * Deregister a callback from a {@link Context}. This function is safe to call from within a hotplug callback. * * @param context * context this callback is registered with @@ -3008,6 +2726,5 @@ public static void hotplugDeregisterCallback(final Context context, * the handle of the callback to deregister * @return The hotplug callback ID. */ - static native long hotplugDeregisterCallbackNative(final Context context, - final HotplugCallbackHandle callbackHandle); + static native long hotplugDeregisterCallbackNative(final Context context, final HotplugCallbackHandle callbackHandle); } diff --git a/src/main/java/org/usb4java/Version.java b/src/main/java/org/usb4java/Version.java index 910888f..7546563 100644 --- a/src/main/java/org/usb4java/Version.java +++ b/src/main/java/org/usb4java/Version.java @@ -20,34 +20,25 @@ import org.apache.commons.lang3.builder.EqualsBuilder; import org.apache.commons.lang3.builder.HashCodeBuilder; +import org.usb4java.jna.NativeVersion; /** * Structure providing the version of the libusb runtime. * * @author Klaus Reimer (k@ailis.de) */ -public final class Version -{ - /** The native pointer to the version structure. */ - private long versionPointer; +public final class Version { + /** The native version structure. */ + private final NativeVersion version; /** - * Package-private constructor to prevent manual instantiation. An instance - * is only returned by the JNI method {@link LibUsb#getVersion()}. + * Creates a new version container from the specified native version structure. + * + * @param version + * The native version structure. */ - Version() - { - // Empty - } - - /** - * Returns the native pointer. - * - * @return The native pointer. - */ - public long getPointer() - { - return this.versionPointer; + public Version(final NativeVersion version) { + this.version = version; } /** @@ -55,79 +46,73 @@ public long getPointer() * * @return The library major version. */ - public native int major(); + public int major() { + return this.version.major & 0xff; + } /** * Returns the library minor version. * * @return The library minor version. */ - public native int minor(); + public int minor() { + return this.version.minor & 0xff; + } /** * Returns the library micro version. * * @return The library micro version. */ - public native int micro(); + public int micro() { + return this.version.micro & 0xffff; + } /** * Returns the library nano version. * * @return The library nano version. */ - public native int nano(); + public int nano() { + return this.version.nano & 0xffff; + } /** * Returns the release candidate suffix string, e.g. "-rc4". * * @return The release candidate suffix string. */ - public native String rc(); - + public String rc() { + return this.version.rc; + } + @Override - public int hashCode() - { - return new HashCodeBuilder() - .append(this.major()) - .append(this.minor()) - .append(this.micro()) - .append(this.nano()) - .append(this.rc()) - .toHashCode(); + public int hashCode() { + return new HashCodeBuilder().append(this.major()).append(this.minor()).append(this.micro()).append(this.nano()) + .append(this.rc()).toHashCode(); } @Override - public boolean equals(final Object obj) - { - if (this == obj) - { + public boolean equals(final Object obj) { + if (this == obj) { return true; } - if (obj == null) - { + if (obj == null) { return false; } - if (this.getClass() != obj.getClass()) - { + if (this.getClass() != obj.getClass()) { return false; } final Version other = (Version) obj; - return new EqualsBuilder() - .append(this.major(), other.major()) - .append(this.minor(), other.minor()) - .append(this.micro(), other.micro()) - .append(this.nano(), other.nano()) - .append(this.rc(), other.rc()) + return new EqualsBuilder().append(this.major(), other.major()).append(this.minor(), other.minor()) + .append(this.micro(), other.micro()).append(this.nano(), other.nano()).append(this.rc(), other.rc()) .isEquals(); } @Override - public String toString() - { - return this.major() + "." + this.minor() + "." + this.micro() + "." - + this.nano() + this.rc(); + public String toString() { + return this.major() + "." + this.minor() + "." + this.micro() + "." + this.nano() + this.rc(); } } diff --git a/src/main/java/org/usb4java/jna/ConfigDescriptor.java b/src/main/java/org/usb4java/jna/ConfigDescriptor.java index 6c68fbd..c823d09 100644 --- a/src/main/java/org/usb4java/jna/ConfigDescriptor.java +++ b/src/main/java/org/usb4java/jna/ConfigDescriptor.java @@ -18,13 +18,9 @@ package org.usb4java.jna; -import java.nio.ByteBuffer; import java.util.Arrays; import java.util.List; -import org.apache.commons.lang3.builder.EqualsBuilder; -import org.apache.commons.lang3.builder.HashCodeBuilder; - import com.sun.jna.Pointer; import com.sun.jna.Structure; @@ -70,7 +66,7 @@ public ConfigDescriptor(final Pointer pointer) { public byte bMaxPower; /** The array with interfaces supported by this configuration. */ - public Pointer iface; + public Interface iface; /** * Extra descriptors. diff --git a/src/main/java/org/usb4java/jna/EndpointDescriptor.java b/src/main/java/org/usb4java/jna/EndpointDescriptor.java new file mode 100644 index 0000000..ca044fa --- /dev/null +++ b/src/main/java/org/usb4java/jna/EndpointDescriptor.java @@ -0,0 +1,86 @@ +/* + * Copyright 2013 Klaus Reimer + * See LICENSE.md for licensing information. + * + * Based on libusb : + * + * Copyright 2001 Johannes Erdfelt + * Copyright 2007-2009 Daniel Drake + * Copyright 2010-2012 Peter Stuge + * Copyright 2008-2013 Nathan Hjelm + * Copyright 2009-2013 Pete Batard + * Copyright 2009-2013 Ludovic Rousseau + * Copyright 2010-2012 Michael Plante + * Copyright 2011-2013 Hans de Goede + * Copyright 2012-2013 Martin Pieuchot + * Copyright 2012-2013 Toby Gray + */ + +package org.usb4java.jna; + +import java.util.Arrays; +import java.util.List; + +import org.usb4java.LibUsb; + +import com.sun.jna.Pointer; +import com.sun.jna.Structure; +import com.sun.jna.Structure.ByReference; + +/** + * A structure representing the standard USB endpoint descriptor. + * + * This descriptor is documented in section 9.6.6 of the USB 3.0 specification. All multiple-byte fields are represented + * in host-endian format. + * + * @author Klaus Reimer (k@ailis.de) + */ +public final class EndpointDescriptor extends Structure implements ByReference { + /** The size of this descriptor (in bytes). */ + public byte bLength; + + /** The descriptor type. Will have value {@link LibUsb#DT_ENDPOINT} in this context. */ + public byte bDescriptorType; + + /** + * The address of the endpoint described by this descriptor. Bits 0:3 are the endpoint number. Bits 4:6 are + * reserved. Bit 7 indicates direction (Either {@link LibUsb#ENDPOINT_IN} or {@link LibUsb#ENDPOINT_OUT}). + */ + public byte bEndpointAddress; + + /** + * Attributes which apply to the endpoint when it is configured using the bConfigurationValue. Bits 0:1 determine + * the transfer type and correspond to the LibUsb.TRANSFER_TYPE_* constants. Bits 2:3 are only used for isochronous + * endpoints and correspond to the LibUsb.ISO_SYNC_TYPE_* constants. Bits 4:5 are also only used for isochronous + * endpoints and correspond to the LibUsb.ISO_USAGE_TYPE_* constants. Bits 6:7 are reserved. + */ + public byte bmAttributes; + + /** The maximum packet size this endpoint is capable of sending/receiving. */ + public short wMaxPacketSize; + + /** The interval for polling endpoint for data transfers. */ + public byte bInterval; + + /** For audio devices only: the rate at which synchronization feedback is provided. */ + public byte bRefresh; + + /** For audio devices only: the address of the synch endpoint. */ + public byte bSynchAddress; + + /** + * Extra descriptors. If libusb encounters unknown endpoint descriptors, it will store them here, should you wish to + * parse them. + */ + public Pointer extra; + + /** Length of the extra descriptors, in bytes. */ + public int extra_length; + + + @Override + protected List getFieldOrder() { + return Arrays.asList(new String[] { "bLength", "bDescriptorType", "bEndpointAddress", "bmAttributes", + "wMaxPacketSize", "bInterval", "bRefresh", "bSynchAddress", "extra", "extra_length" }); + } +} diff --git a/src/main/java/org/usb4java/jna/Interface.java b/src/main/java/org/usb4java/jna/Interface.java index a56eb91..45480e0 100644 --- a/src/main/java/org/usb4java/jna/Interface.java +++ b/src/main/java/org/usb4java/jna/Interface.java @@ -21,93 +21,23 @@ import java.util.Arrays; import java.util.List; -import com.sun.jna.Pointer; import com.sun.jna.Structure; +import com.sun.jna.Structure.ByReference; /** * A collection of alternate settings for a particular USB interface. * * @author Klaus Reimer (k@ailis.de) */ -public final class Interface extends Structure { - public Pointer altsetting; +public final class Interface extends Structure implements ByReference { + /** + * The array with interface descriptors. The length of this array is determined by the {@link #num_altsetting} + * field. + */ + public InterfaceDescriptor altsetting; + /** the number of alternate settings that belong to this interface. */ public int num_altsetting; -// /** -// * Returns the array with interface descriptors. The length of this array is -// * determined by the {@link #numAltsetting()} field. -// * -// * @return The array with interface descriptors. -// */ -// public native InterfaceDescriptor[] altsetting(); -// -// /** -// * Returns the number of alternate settings that belong to this interface. -// * -// * @return The number of alternate settings. -// */ -// public native int numAltsetting(); -// -// /** -// * Returns a dump of this interface. -// * -// * @return The interface dump. -// */ -// public String dump() -// { -// final StringBuilder builder = new StringBuilder(); -// -// builder.append(String.format( -// "Interface:%n" + -// " numAltsetting %10d", -// this.numAltsetting())); -// -// for (final InterfaceDescriptor intDesc : this.altsetting()) -// { -// builder.append(String.format("%n") + intDesc.dump()); -// } -// -// return builder.toString(); -// } -// -// @Override -// public int hashCode() -// { -// return new HashCodeBuilder() -// .append(this.altsetting()) -// .append(this.numAltsetting()) -// .toHashCode(); -// } -// -// @Override -// public boolean equals(final Object obj) -// { -// if (this == obj) -// { -// return true; -// } -// if (obj == null) -// { -// return false; -// } -// if (this.getClass() != obj.getClass()) -// { -// return false; -// } -// -// final Interface other = (Interface) obj; -// -// return new EqualsBuilder() -// .append(this.altsetting(), other.altsetting()) -// .append(this.numAltsetting(), other.numAltsetting()) -// .isEquals(); -// } -// -// @Override -// public String toString() -// { -// return this.dump(); -// } @Override protected List getFieldOrder() { diff --git a/src/main/java/org/usb4java/jna/InterfaceDescriptor.java b/src/main/java/org/usb4java/jna/InterfaceDescriptor.java new file mode 100644 index 0000000..0b7b153 --- /dev/null +++ b/src/main/java/org/usb4java/jna/InterfaceDescriptor.java @@ -0,0 +1,85 @@ +/* + * Copyright 2013 Klaus Reimer + * See LICENSE.md for licensing information. + * + * Based on libusb : + * + * Copyright 2001 Johannes Erdfelt + * Copyright 2007-2009 Daniel Drake + * Copyright 2010-2012 Peter Stuge + * Copyright 2008-2013 Nathan Hjelm + * Copyright 2009-2013 Pete Batard + * Copyright 2009-2013 Ludovic Rousseau + * Copyright 2010-2012 Michael Plante + * Copyright 2011-2013 Hans de Goede + * Copyright 2012-2013 Martin Pieuchot + * Copyright 2012-2013 Toby Gray + */ + +package org.usb4java.jna; + +import java.util.Arrays; +import java.util.List; + +import org.usb4java.LibUsb; + +import com.sun.jna.Pointer; +import com.sun.jna.Structure; +import com.sun.jna.Structure.ByReference; + +/** + * A structure representing the standard USB interface descriptor. + * + * This descriptor is documented in section 9.6.5 of the USB 3.0 specification. All multiple-byte fields are represented + * in host-endian format. + * + * @author Klaus Reimer (k@ailis.de) + */ +public final class InterfaceDescriptor extends Structure implements ByReference { + + /** The size of this descriptor (in bytes). */ + public byte bLength; + + /** The descriptor type. Will have value {@link LibUsb#DT_INTERFACE}. */ + public byte bDescriptorType; + + /** The number of this interface. */ + public byte bInterfaceNumber; + + /** The value used to select this alternate setting for this interface. */ + public byte bAlternateSetting; + + /** The number of endpoints used by this interface (excluding the control endpoint). */ + public byte bNumEndpoints; + + /** The USB-IF class code for this interface. See LibUSB.CLASS_* constants. */ + public byte bInterfaceClass; + + /** The USB-IF subclass code for this interface, qualified by the bInterfaceClass value. */ + public byte bInterfaceSubClass; + + /** The USB-IF protocol code for this interface, qualified by thebInterfaceClass and bInterfaceSubClass values. */ + public byte bInterfaceProtocol; + + /** The index of string descriptor describing this interface. */ + public byte iInterface; + + /** The array with endpoints. */ + public EndpointDescriptor endpoint; + + /** + * Extra descriptors. If libusb encounters unknown interface descriptors, it will store them here, should you wish + * to parse them. + */ + public Pointer extra; + + /** Length of the extra descriptors, in bytes. */ + public int extra_length; + + @Override + protected List getFieldOrder() { + return Arrays.asList(new String[] { "bLength", "bDescriptorType", "bInterfaceNumber", "bAlternateSetting", + "bNumEndpoints", "bInterfaceClass", "bInterfaceSubClass", "bInterfaceProtocol", "iInterface", "endpoint", + "extra", "extra_length" }); + } +} diff --git a/src/main/java/org/usb4java/jna/LibUsbNative.java b/src/main/java/org/usb4java/jna/LibUsbNative.java index 6f698d9..021776b 100644 --- a/src/main/java/org/usb4java/jna/LibUsbNative.java +++ b/src/main/java/org/usb4java/jna/LibUsbNative.java @@ -5,6 +5,7 @@ package org.usb4java.jna; +import java.nio.ByteBuffer; import java.util.Arrays; import java.util.List; @@ -21,30 +22,11 @@ */ public interface LibUsbNative extends Library { - public static class libusb_version extends Structure { - public short major; - - public short minor; - - public short micro; - - public short nano; - - public String rc; - - public String describe; - - @Override - protected List getFieldOrder() { - return Arrays.asList(new String[] { "major", "minor", "micro", "nano", "rc", "describe" }); - } - } - public String libusb_error_name(int error_code); public int libusb_has_capability(int capability); - public libusb_version libusb_get_version(); + public NativeVersion libusb_get_version(); public int libusb_setlocale(String locale); @@ -64,7 +46,7 @@ protected List getFieldOrder() { public byte libusb_get_port_number(Pointer device); - public int libusb_get_port_numbers(Pointer device, byte[] port_numbers, int port_numbers_len); + public int libusb_get_port_numbers(Pointer device, ByteBuffer port_numbers, int port_numbers_len); public Pointer libusb_get_parent(Pointer device); diff --git a/src/main/java/org/usb4java/jna/NativeVersion.java b/src/main/java/org/usb4java/jna/NativeVersion.java new file mode 100644 index 0000000..0ec7eb2 --- /dev/null +++ b/src/main/java/org/usb4java/jna/NativeVersion.java @@ -0,0 +1,25 @@ +package org.usb4java.jna; + +import java.util.Arrays; +import java.util.List; + +import com.sun.jna.Structure; + +public final class NativeVersion extends Structure { + public short major; + + public short minor; + + public short micro; + + public short nano; + + public String rc; + + public String describe; + + @Override + protected List getFieldOrder() { + return Arrays.asList(new String[] { "major", "minor", "micro", "nano", "rc", "describe" }); + } +} \ No newline at end of file diff --git a/src/main/java/org/usb4java/jna/Test.java b/src/main/java/org/usb4java/jna/Test.java index abe47ac..7a9d966 100644 --- a/src/main/java/org/usb4java/jna/Test.java +++ b/src/main/java/org/usb4java/jna/Test.java @@ -4,6 +4,12 @@ package org.usb4java.jna; +import java.nio.ByteBuffer; + +import org.usb4java.Device; +import org.usb4java.DeviceList; +import org.usb4java.LibUsb; + import com.sun.jna.Native; import com.sun.jna.Pointer; import com.sun.jna.ptr.IntByReference; @@ -34,11 +40,11 @@ public static void main(final String[] args) { System.out.print("bus " + lib.libusb_get_bus_number(device)); System.out.println(" port " + lib.libusb_get_port_number(device)); final byte[] ports = new byte[16]; - final int len = lib.libusb_get_port_numbers(device, ports, 16); - System.out.print("Port numbers: "); - for (int i = 0; i < len; ++i) { - System.out.print(ports[i] + " "); - } +// final int len = lib.libusb_get_port_numbers(device, ports, 16); +// System.out.print("Port numbers: "); +// for (int i = 0; i < len; ++i) { +// System.out.print(ports[i] + " "); +// } final Pointer parent = lib.libusb_get_parent(device); System.out.println("Parent: " + parent); System.out.println("Address: " + lib.libusb_get_device_address(device)); @@ -87,10 +93,34 @@ public static void main(final String[] args) { System.out.println(lib.libusb_get_config_descriptor(device, (byte) 0, configDescriptorRef2)); final ConfigDescriptor configDescriptor2 = new ConfigDescriptor(configDescriptorRef2.getValue()); System.out.println(configDescriptorRef2.getValue()); - System.out.println(configDescriptor2.bNumInterfaces); System.out.println(configDescriptor2.bDescriptorType); System.out.println(configDescriptor2.wTotalLength); - System.out.println(configDescriptor2.iface); + System.out.println("Num Interfaces: " + configDescriptor2.bNumInterfaces); + System.out.println("Extra: " + configDescriptor2.extra); + System.out.println("Extra len: " + configDescriptor2.extra_length); +// for (int i = 0; i < configDescriptor2.bNumInterfaces; ++i) { +// Pointer ifacePointer = configDescriptor2.iface.get +// System.out.println(ifacePointer); +// System.out.println(configDescriptor.iface); +// } + Interface[] ifaces = (Interface[]) configDescriptor2.iface.toArray(configDescriptor2.bNumInterfaces); + for (Interface iface: ifaces) { + System.out.println("============================================================"); + System.out.println(iface); + System.out.println("============================================================"); + InterfaceDescriptor[] ifaceDescriptors = (InterfaceDescriptor[]) iface.altsetting.toArray(iface.num_altsetting); + for (InterfaceDescriptor ifaceDescriptor: ifaceDescriptors) { + System.out.println("---------------------------------------"); + System.out.println(ifaceDescriptor); + System.out.println("---------------------------------------"); + if (ifaceDescriptor.bNumEndpoints != 0) { + EndpointDescriptor[] endpointDescriptors = (EndpointDescriptor[]) ifaceDescriptor.endpoint.toArray(ifaceDescriptor.bNumEndpoints); + for (EndpointDescriptor endpointDescriptor: endpointDescriptors) { + System.out.println(endpointDescriptor); + } + } + } + } lib.libusb_free_config_descriptor(configDescriptor2); break; @@ -106,6 +136,23 @@ public static void main(final String[] args) { lib.libusb_exit(context); System.out.println("Exit"); + + LibUsb.init(null); + System.out.println(LibUsb.getVersion()); + DeviceList list2 = new DeviceList(); + System.out.println(LibUsb.getDeviceList(null, list2)); + System.out.println(list2); + for (Device device: list2) { + System.out.println(device); + ByteBuffer path = ByteBuffer.allocateDirect(7); + System.out.println(LibUsb.getPortNumbers(device, path)); + for (int i = 0; i < 7; ++i) { + System.out.print(path.get(i) + " "); + } + System.out.println(); + } + LibUsb.freeDeviceList(list2, true); + LibUsb.exit(null); } } diff --git a/src/test/java/org/usb4java/LibUsbTest.java b/src/test/java/org/usb4java/LibUsbTest.java index 34cd154..5ed69c1 100644 --- a/src/test/java/org/usb4java/LibUsbTest.java +++ b/src/test/java/org/usb4java/LibUsbTest.java @@ -1181,9 +1181,10 @@ public void testGetNextTimeoutWithUninitializedContext() @Test(expected = IllegalStateException.class) public void testSetPollfdNotifiersWithUninitializedContext() { - assumeUsbTestsEnabled(); - final Context context = new Context(); - LibUsb.setPollfdNotifiersNative(context, context.getPointer()); + // TODO +// assumeUsbTestsEnabled(); +// final Context context = new Context(); +// LibUsb.setPollfdNotifiersNative(context, context.getPointer()); } /** @@ -1206,49 +1207,50 @@ public void testUnsetPollfdNotifiersWithUninitializedContext() @Test public void testPollFdNotifiers() { - assumeUsbTestsEnabled(); - final PollfdListenerMock listener = new PollfdListenerMock(); - final Context context = new Context(); - LibUsb.init(context); - LibUsb.setPollfdNotifiers(context, listener, "test"); - - FileDescriptor fd = new FileDescriptor(); - LibUsb.triggerPollfdAdded(fd, 53, context.getPointer()); - assertEquals(53, listener.addedEvents); - assertSame(fd, listener.addedFd); - assertSame("test", listener.addedUserData); - assertNull(listener.removedFd); - assertNull(listener.removedUserData); - - listener.reset(); - - fd = new FileDescriptor(); - LibUsb.triggerPollfdRemoved(fd, context.getPointer()); - assertEquals(0, listener.addedEvents); - assertNull(listener.addedFd); - assertNull(listener.addedUserData); - assertSame(fd, listener.removedFd); - assertSame("test", listener.removedUserData); - - LibUsb.setPollfdNotifiers(context, null, null); - listener.reset(); - - fd = new FileDescriptor(); - LibUsb.triggerPollfdAdded(fd, 53, context.getPointer()); - assertEquals(0, listener.addedEvents); - assertNull(listener.addedFd); - assertNull(listener.addedUserData); - assertNull(listener.removedFd); - assertNull(listener.removedUserData); - - listener.reset(); - - fd = new FileDescriptor(); - LibUsb.triggerPollfdRemoved(fd, context.getPointer()); - assertEquals(0, listener.addedEvents); - assertNull(listener.addedFd); - assertNull(listener.addedUserData); - assertNull(listener.removedFd); - assertNull(listener.removedUserData); + // TODO +// assumeUsbTestsEnabled(); +// final PollfdListenerMock listener = new PollfdListenerMock(); +// final Context context = new Context(); +// LibUsb.init(context); +// LibUsb.setPollfdNotifiers(context, listener, "test"); +// +// FileDescriptor fd = new FileDescriptor(); +// LibUsb.triggerPollfdAdded(fd, 53, context.getPointer()); +// assertEquals(53, listener.addedEvents); +// assertSame(fd, listener.addedFd); +// assertSame("test", listener.addedUserData); +// assertNull(listener.removedFd); +// assertNull(listener.removedUserData); +// +// listener.reset(); +// +// fd = new FileDescriptor(); +// LibUsb.triggerPollfdRemoved(fd, context.getPointer()); +// assertEquals(0, listener.addedEvents); +// assertNull(listener.addedFd); +// assertNull(listener.addedUserData); +// assertSame(fd, listener.removedFd); +// assertSame("test", listener.removedUserData); +// +// LibUsb.setPollfdNotifiers(context, null, null); +// listener.reset(); +// +// fd = new FileDescriptor(); +// LibUsb.triggerPollfdAdded(fd, 53, context.getPointer()); +// assertEquals(0, listener.addedEvents); +// assertNull(listener.addedFd); +// assertNull(listener.addedUserData); +// assertNull(listener.removedFd); +// assertNull(listener.removedUserData); +// +// listener.reset(); +// +// fd = new FileDescriptor(); +// LibUsb.triggerPollfdRemoved(fd, context.getPointer()); +// assertEquals(0, listener.addedEvents); +// assertNull(listener.addedFd); +// assertNull(listener.addedUserData); +// assertNull(listener.removedFd); +// assertNull(listener.removedUserData); } } diff --git a/src/test/java/org/usb4java/VersionTest.java b/src/test/java/org/usb4java/VersionTest.java index 3c2b8df..3ec0376 100644 --- a/src/test/java/org/usb4java/VersionTest.java +++ b/src/test/java/org/usb4java/VersionTest.java @@ -16,6 +16,7 @@ import org.junit.After; import org.junit.Before; import org.junit.Test; +import org.usb4java.jna.NativeVersion; /** * Tests the {@link Version} class. @@ -65,7 +66,7 @@ public void testMajor() public void testUninitializedMajor() { assumeUsbTestsEnabled(); - new Version().major(); + new Version(new NativeVersion()).major(); } /** @@ -85,7 +86,7 @@ public void testMinor() public void testUninitializedMinor() { assumeUsbTestsEnabled(); - new Version().minor(); + new Version(new NativeVersion()).minor(); } /** @@ -105,7 +106,7 @@ public void testMicro() public void testUninitializedMicro() { assumeUsbTestsEnabled(); - new Version().micro(); + new Version(new NativeVersion()).micro(); } /** @@ -125,7 +126,7 @@ public void testRc() public void testUninitializedRc() { assumeUsbTestsEnabled(); - new Version().rc(); + new Version(new NativeVersion()).rc(); } /** @@ -166,15 +167,4 @@ public void testToString() assertNotNull(version.toString()); assertTrue(version.toString().length() > 0); } - - /** - * Tests the {@link Version#getPointer()} method - */ - @Test - public void testGetPointer() - { - assumeUsbTestsEnabled(); - assertEquals(0, new Version().getPointer()); - assertNotEquals(0, LibUsb.getVersion().getPointer()); - } } From 1f59801b54f55dfdb2d49650f42b64c82dbc58ce Mon Sep 17 00:00:00 2001 From: Klaus Reimer Date: Sat, 18 Apr 2015 10:39:56 +0200 Subject: [PATCH 3/5] Converting some basic libusb stuff from JNI to JNA. DumpDevices demo already working with it. --- pom.xml | 2 +- src/main/java/org/usb4java/BosDescriptor.java | 25 +- .../usb4java/BosDevCapabilityDescriptor.java | 20 +- .../java/org/usb4java/ConfigDescriptor.java | 180 ++++----- .../org/usb4java/ContainerIdDescriptor.java | 25 +- .../java/org/usb4java/DescriptorUtils.java | 33 +- src/main/java/org/usb4java/Device.java | 18 +- .../java/org/usb4java/DeviceDescriptor.java | 212 +++++------ .../java/org/usb4java/EndpointDescriptor.java | 170 ++++----- src/main/java/org/usb4java/Interface.java | 89 ++--- .../org/usb4java/InterfaceDescriptor.java | 190 +++++---- .../org/usb4java/IsoPacketDescriptor.java | 20 +- src/main/java/org/usb4java/LibUsb.java | 329 +++++++++++----- src/main/java/org/usb4java/Loader.java | 360 ------------------ .../SsEndpointCompanionDescriptor.java | 25 +- .../SsUsbDeviceCapabilityDescriptor.java | 40 +- src/main/java/org/usb4java/Transfer.java | 122 ++++-- .../usb4java/Usb20ExtensionDescriptor.java | 20 +- ...iptor.java => NativeConfigDescriptor.java} | 7 +- ...iptor.java => NativeDeviceDescriptor.java} | 2 +- ...tor.java => NativeEndpointDescriptor.java} | 2 +- .../{Interface.java => NativeInterface.java} | 4 +- ...or.java => NativeInterfaceDescriptor.java} | 5 +- .../{LibUsbNative.java => NativeLibUsb.java} | 13 +- src/main/java/org/usb4java/jna/Test.java | 247 ++++++------ 25 files changed, 1030 insertions(+), 1130 deletions(-) delete mode 100644 src/main/java/org/usb4java/Loader.java rename src/main/java/org/usb4java/jna/{ConfigDescriptor.java => NativeConfigDescriptor.java} (93%) rename src/main/java/org/usb4java/jna/{DeviceDescriptor.java => NativeDeviceDescriptor.java} (97%) rename src/main/java/org/usb4java/jna/{EndpointDescriptor.java => NativeEndpointDescriptor.java} (97%) rename src/main/java/org/usb4java/jna/{Interface.java => NativeInterface.java} (91%) rename src/main/java/org/usb4java/jna/{InterfaceDescriptor.java => NativeInterfaceDescriptor.java} (94%) rename src/main/java/org/usb4java/jna/{LibUsbNative.java => NativeLibUsb.java} (89%) diff --git a/pom.xml b/pom.xml index 9df0dc5..516aa7c 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ usb4java jar usb4java - 1.2.1-SNAPSHOT + 1.3.0-SNAPSHOT http://usb4java.org/ USB library for Java based on libusb and implementing javax-usb (JSR-80). diff --git a/src/main/java/org/usb4java/BosDescriptor.java b/src/main/java/org/usb4java/BosDescriptor.java index e1828cd..9712fe8 100644 --- a/src/main/java/org/usb4java/BosDescriptor.java +++ b/src/main/java/org/usb4java/BosDescriptor.java @@ -58,35 +58,50 @@ public long getPointer() * * @return The descriptor size in bytes; */ - public native byte bLength(); + public byte bLength() { + // TODO + throw new RuntimeException("Not implemented yet"); + } /** * Returns the descriptor type. * * @return The descriptor type. */ - public native byte bDescriptorType(); + public byte bDescriptorType() { + // TODO + throw new RuntimeException("Not implemented yet"); + } /** * Returns the length of this descriptor and all of its sub descriptors. * * @return The total descriptor length. */ - public native short wTotalLength(); + public short wTotalLength() { + // TODO + throw new RuntimeException("Not implemented yet"); + } /** * Returns the number of separate device capability descriptors in the BOS. * * @return The number of device capability descriptors. */ - public native byte bNumDeviceCaps(); + public byte bNumDeviceCaps() { + // TODO + throw new RuntimeException("Not implemented yet"); + } /** * Returns the array with the device capability descriptors. * * @return The array with device capability descriptors. */ - public native BosDevCapabilityDescriptor[] devCapability(); + public BosDevCapabilityDescriptor[] devCapability() { + // TODO + throw new RuntimeException("Not implemented yet"); + } /** * Returns a dump of this descriptor. diff --git a/src/main/java/org/usb4java/BosDevCapabilityDescriptor.java b/src/main/java/org/usb4java/BosDevCapabilityDescriptor.java index 822be7d..c9a917c 100644 --- a/src/main/java/org/usb4java/BosDevCapabilityDescriptor.java +++ b/src/main/java/org/usb4java/BosDevCapabilityDescriptor.java @@ -60,28 +60,40 @@ public long getPointer() * * @return The descriptor size in bytes; */ - public native byte bLength(); + public byte bLength() { + // TODO + throw new RuntimeException("Not implemented yet"); + } /** * Returns the descriptor type. * * @return The descriptor type. */ - public native byte bDescriptorType(); + public byte bDescriptorType() { + // TODO + throw new RuntimeException("Not implemented yet"); + } /** * Returns the device capability type. * * @return The device capability type. */ - public native byte bDevCapabilityType(); + public byte bDevCapabilityType() { + // TODO + throw new RuntimeException("Not implemented yet"); + } /** * Returns the device capability data (bLength - 3 bytes). * * @return The device capability data. */ - public native ByteBuffer devCapabilityData(); + public ByteBuffer devCapabilityData() { + // TODO + throw new RuntimeException("Not implemented yet"); + } /** * Returns a dump of this descriptor. diff --git a/src/main/java/org/usb4java/ConfigDescriptor.java b/src/main/java/org/usb4java/ConfigDescriptor.java index b741391..9f24000 100644 --- a/src/main/java/org/usb4java/ConfigDescriptor.java +++ b/src/main/java/org/usb4java/ConfigDescriptor.java @@ -22,143 +22,170 @@ import org.apache.commons.lang3.builder.EqualsBuilder; import org.apache.commons.lang3.builder.HashCodeBuilder; +import org.usb4java.jna.NativeConfigDescriptor; +import org.usb4java.jna.NativeInterface; + +import com.sun.jna.Pointer; /** * A structure representing the standard USB configuration descriptor. * - * This descriptor is documented in section 9.6.3 of the USB 3.0 specification. - * All multiple-byte fields are represented in host-endian format. + * This descriptor is documented in section 9.6.3 of the USB 3.0 specification. All multiple-byte fields are represented + * in host-endian format. * * @author Klaus Reimer (k@ailis.de) */ -public final class ConfigDescriptor -{ - /** The native pointer to the descriptor structure. */ - private long configDescriptorPointer; - +public final class ConfigDescriptor { + /** The config descriptor structure. */ + private NativeConfigDescriptor nativeConfigDescriptor; + /** * Constructs a new config descriptor which can be passed to the - * {@link LibUsb#getConfigDescriptor(Device, byte, ConfigDescriptor)} - * method. + * {@link LibUsb#getConfigDescriptor(Device, byte, ConfigDescriptor)} method. */ - public ConfigDescriptor() - { - // Empty + public ConfigDescriptor() { } + void init(final NativeConfigDescriptor nativeConfigDescriptor) { + this.nativeConfigDescriptor = nativeConfigDescriptor; + } + /** - * Returns the native pointer. + * Returns the config descriptor structure. * - * @return The native pointer. + * @return The config descriptor structure. */ - public long getPointer() - { - return this.configDescriptorPointer; + NativeConfigDescriptor getNative() { + return this.nativeConfigDescriptor; } /** * Returns the size of this descriptor (in bytes). * - * @return The size of this descriptor (in bytes). + * @return The size of this descriptor (in bytes). */ - public native byte bLength(); + public byte bLength() { + return this.nativeConfigDescriptor.bLength; + } /** - * Returns the descriptor type. Will have value {@link LibUsb#DT_CONFIG} - * in this context. + * Returns the descriptor type. Will have value {@link LibUsb#DT_CONFIG} in this context. * * @return The descriptor type. */ - public native byte bDescriptorType(); + public byte bDescriptorType() { + return this.nativeConfigDescriptor.bDescriptorType; + } /** * Returns the total length of data returned for this configuration. * * @return The total length of data. */ - public native short wTotalLength(); + public short wTotalLength() { + return this.nativeConfigDescriptor.wTotalLength; + } /** * Returns the number of interfaces supported by this configuration. * * @return The number of supported interfaces. - */ - public native byte bNumInterfaces(); + */ + public byte bNumInterfaces() { + return this.nativeConfigDescriptor.bNumInterfaces; + } /** * Returns the identifier value for this configuration. * * @return The identifier value. */ - public native byte bConfigurationValue(); + public byte bConfigurationValue() { + return this.nativeConfigDescriptor.bConfigurationValue; + } /** * Returns the index of string descriptor describing this configuration. * * @return The string descriptor index. */ - public native byte iConfiguration(); + public byte iConfiguration() { + return this.nativeConfigDescriptor.iConfiguration; + } /** * Returns the configuration characteristics. * * @return The configuration characteristics. */ - public native byte bmAttributes(); + public byte bmAttributes() { + return this.nativeConfigDescriptor.bmAttributes; + } /** - * Returns the maximum power consumption of the USB device from this bus - * in this configuration when the device is fully operation. Expressed in - * units of 2 mA. + * Returns the maximum power consumption of the USB device from this bus in this configuration when the device is + * fully operation. Expressed in units of 2 mA. * * @return The maximum power consumption. */ - public native byte bMaxPower(); + public byte bMaxPower() { + return this.nativeConfigDescriptor.bMaxPower; + } /** * Returns the array with interfaces supported by this configuration. * * @return The array with interfaces. */ - public native Interface[] iface(); + public Interface[] iface() { + final int numInterfaces = bNumInterfaces() & 0xff; + final Interface[] ifaces = new Interface[numInterfaces]; + if (numInterfaces > 0) { + final NativeInterface[] nativeInterfaces = (NativeInterface[]) this.nativeConfigDescriptor.iface.toArray(numInterfaces); + for (int i = 0; i != numInterfaces; ++i) { + ifaces[i] = new Interface(nativeInterfaces[i]); + } + } + return ifaces; + } /** * Extra descriptors. * - * If libusb encounters unknown interface descriptors, it will store them - * here, should you wish to parse them. + * If libusb encounters unknown interface descriptors, it will store them here, should you wish to parse them. * * @return The extra descriptors. */ - public native ByteBuffer extra(); + public ByteBuffer extra() { + Pointer pointer = this.nativeConfigDescriptor.extra; + if (pointer == null) { + return ByteBuffer.allocate(0); + } else { + return pointer.getByteBuffer(0, extraLength()); + } + } /** * Length of the extra descriptors, in bytes. * * @return The extra descriptors length. */ - public native int extraLength(); - + public int extraLength() { + return this.nativeConfigDescriptor.extra_length; + } + /** * Returns a dump of this descriptor. * * @return The descriptor dump. */ - public String dump() - { + public String dump() { final StringBuilder builder = new StringBuilder(); - builder.append(String.format( - "%s" + - " extralen %17d%n" + - " extra:%n" + - "%s", - DescriptorUtils.dump(this), - this.extraLength(), - DescriptorUtils.dump(this.extra()).replaceAll("(?m)^", " "))); - - for (final Interface iface : this.iface()) - { + builder.append(String.format("%s" + " extralen %17d%n" + " extra:%n" + "%s", DescriptorUtils.dump(this), + this.extraLength(), DescriptorUtils.dump(this.extra()).replaceAll("(?m)^", " "))); + + for (final Interface iface: this.iface()) { builder.append(String.format("%n") + iface.dump()); } @@ -166,59 +193,38 @@ public String dump() } @Override - public int hashCode() - { - return new HashCodeBuilder() - .append(this.bLength()) - .append(this.bDescriptorType()) - .append(this.wTotalLength()) - .append(this.bNumInterfaces()) - .append(this.bConfigurationValue()) - .append(this.iConfiguration()) - .append(this.bmAttributes()) - .append(this.bMaxPower()) - .append(this.iface()) - .append(this.extra()) - .append(this.extraLength()) - .toHashCode(); + public int hashCode() { + return new HashCodeBuilder().append(this.bLength()).append(this.bDescriptorType()).append(this.wTotalLength()) + .append(this.bNumInterfaces()).append(this.bConfigurationValue()).append(this.iConfiguration()) + .append(this.bmAttributes()).append(this.bMaxPower()).append(this.iface()).append(this.extra()) + .append(this.extraLength()).toHashCode(); } @Override - public boolean equals(final Object obj) - { - if (this == obj) - { + public boolean equals(final Object obj) { + if (this == obj) { return true; } - if (obj == null) - { + if (obj == null) { return false; } - if (this.getClass() != obj.getClass()) - { + if (this.getClass() != obj.getClass()) { return false; } final ConfigDescriptor other = (ConfigDescriptor) obj; - return new EqualsBuilder() - .append(this.bLength(), other.bLength()) - .append(this.bDescriptorType(), other.bDescriptorType()) - .append(this.wTotalLength(), other.wTotalLength()) + return new EqualsBuilder().append(this.bLength(), other.bLength()) + .append(this.bDescriptorType(), other.bDescriptorType()).append(this.wTotalLength(), other.wTotalLength()) .append(this.bNumInterfaces(), other.bNumInterfaces()) .append(this.bConfigurationValue(), other.bConfigurationValue()) - .append(this.iConfiguration(), other.iConfiguration()) - .append(this.bmAttributes(), other.bmAttributes()) - .append(this.bMaxPower(), other.bMaxPower()) - .append(this.iface(), other.iface()) - .append(this.extra(), other.extra()) - .append(this.extraLength(), other.extraLength()) - .isEquals(); + .append(this.iConfiguration(), other.iConfiguration()).append(this.bmAttributes(), other.bmAttributes()) + .append(this.bMaxPower(), other.bMaxPower()).append(this.iface(), other.iface()) + .append(this.extra(), other.extra()).append(this.extraLength(), other.extraLength()).isEquals(); } @Override - public String toString() - { + public String toString() { return this.dump(); } } diff --git a/src/main/java/org/usb4java/ContainerIdDescriptor.java b/src/main/java/org/usb4java/ContainerIdDescriptor.java index 08d0ec4..254b474 100644 --- a/src/main/java/org/usb4java/ContainerIdDescriptor.java +++ b/src/main/java/org/usb4java/ContainerIdDescriptor.java @@ -63,35 +63,50 @@ public long getPointer() * * @return The descriptor size in bytes; */ - public native byte bLength(); + public byte bLength() { + // TODO + throw new RuntimeException("Not implemented yet"); + } /** * Returns the descriptor type. * * @return The descriptor type. */ - public native byte bDescriptorType(); + public byte bDescriptorType() { + // TODO + throw new RuntimeException("Not implemented yet"); + } /** * Returns the device capability type. * * @return The device capability type. */ - public native byte bDevCapabilityType(); + public byte bDevCapabilityType() { + // TODO + throw new RuntimeException("Not implemented yet"); + } /** * Returns the reserved field. * * @return The reserved field. */ - public native byte bReserved(); + public byte bReserved() { + // TODO + throw new RuntimeException("Not implemented yet"); + } /** * Returns the 128 bit UUID. * * @return The 128 bit UUID. */ - public native ByteBuffer containerId(); + public ByteBuffer containerId() { + // TODO + throw new RuntimeException("Not implemented yet"); + } /** * Returns a dump of this descriptor. diff --git a/src/main/java/org/usb4java/DescriptorUtils.java b/src/main/java/org/usb4java/DescriptorUtils.java index a30d1b6..677cabd 100644 --- a/src/main/java/org/usb4java/DescriptorUtils.java +++ b/src/main/java/org/usb4java/DescriptorUtils.java @@ -92,26 +92,27 @@ public static String decodeBCD(final short bcd) */ public static String dump(final ByteBuffer bytes) { - bytes.rewind(); - final int columns = 16; final StringBuilder builder = new StringBuilder(); - - int i = 0; - while (bytes.hasRemaining()) - { - if ((i % columns) != 0) - { - builder.append(' '); - } - else if (i >= columns) + if (bytes != null) { + bytes.rewind(); + final int columns = 16; + + int i = 0; + while (bytes.hasRemaining()) { - builder.append(String.format("%n")); + if ((i % columns) != 0) + { + builder.append(' '); + } + else if (i >= columns) + { + builder.append(String.format("%n")); + } + + builder.append(String.format("%02x", bytes.get())); + i++; } - - builder.append(String.format("%02x", bytes.get())); - i++; } - return builder.toString(); } diff --git a/src/main/java/org/usb4java/Device.java b/src/main/java/org/usb4java/Device.java index 5a74cb0..ec168c4 100644 --- a/src/main/java/org/usb4java/Device.java +++ b/src/main/java/org/usb4java/Device.java @@ -39,15 +39,15 @@ */ public final class Device { /** The native pointer to the device structure. */ - private final Pointer devicePointer; + private final Pointer nativeDevicePointer; /** * Creates a new device. * - * @param devicePointer The native device pointer. + * @param nativeDevicePointer The native device pointer. */ - Device(final Pointer devicePointer) { - this.devicePointer = devicePointer; + Device(final Pointer nativeDevicePointer) { + this.nativeDevicePointer = nativeDevicePointer; } /** @@ -55,13 +55,13 @@ public final class Device { * * @return The native pointer to the device structure. */ - public Pointer getPointer() { - return this.devicePointer; + Pointer getNative() { + return this.nativeDevicePointer; } @Override public int hashCode() { - final long nativePointer = Pointer.nativeValue(this.devicePointer); + final long nativePointer = Pointer.nativeValue(this.nativeDevicePointer); final int prime = 31; int result = 1; result = (prime * result) + (int) (nativePointer ^ (nativePointer >>> 32)); @@ -80,7 +80,7 @@ public boolean equals(final Object obj) { return false; } final Device other = (Device) obj; - if (Pointer.nativeValue(this.devicePointer) != Pointer.nativeValue(other.devicePointer)) { + if (Pointer.nativeValue(this.nativeDevicePointer) != Pointer.nativeValue(other.nativeDevicePointer)) { return false; } return true; @@ -88,6 +88,6 @@ public boolean equals(final Object obj) { @Override public String toString() { - return String.format("libusb device 0x%x", Pointer.nativeValue(this.devicePointer)); + return String.format("libusb device 0x%x", Pointer.nativeValue(this.nativeDevicePointer)); } } diff --git a/src/main/java/org/usb4java/DeviceDescriptor.java b/src/main/java/org/usb4java/DeviceDescriptor.java index a79244d..e1585be 100644 --- a/src/main/java/org/usb4java/DeviceDescriptor.java +++ b/src/main/java/org/usb4java/DeviceDescriptor.java @@ -18,169 +18,163 @@ package org.usb4java; -import java.nio.ByteBuffer; - import org.apache.commons.lang3.builder.EqualsBuilder; import org.apache.commons.lang3.builder.HashCodeBuilder; +import org.usb4java.jna.NativeDeviceDescriptor; /** * A structure representing the standard USB device descriptor. * - * This descriptor is documented in section 9.6.1 of the USB 3.0 specification. - * All multiple-byte fields are represented in host-endian format. + * This descriptor is documented in section 9.6.1 of the USB 3.0 specification. All multiple-byte fields are represented + * in host-endian format. * * @author Klaus Reimer (k@ailis.de) */ -public final class DeviceDescriptor -{ - /** The native pointer to the descriptor structure. */ - private long deviceDescriptorPointer; - - /** The Java ByteBuffer which contains the descriptor structure. */ - private final ByteBuffer deviceDescriptorBuffer; - - /** - * Constructs a new device descriptor which can be passed to the - * {@link LibUsb#getDeviceDescriptor(Device, DeviceDescriptor)} method. - */ - public DeviceDescriptor() - { - // Assign new buffer. - this.deviceDescriptorBuffer = BufferUtils.allocateByteBuffer( - LibUsb.deviceDescriptorStructSize()); - } - - /** - * Returns the native pointer. - * - * @return The native pointer. - */ - public long getPointer() - { - return this.deviceDescriptorPointer; +public final class DeviceDescriptor { + /** The libusb device descriptor. */ + private final NativeDeviceDescriptor nativeDeviceDescriptor; + + public DeviceDescriptor() { + this.nativeDeviceDescriptor = new NativeDeviceDescriptor(); } - /** - * Returns the Java byte buffer which contains the descriptor structure. - * - * @return The descriptor structur buffer. - */ - public ByteBuffer getBuffer() - { - return this.deviceDescriptorBuffer; + NativeDeviceDescriptor getNative() { + return this.nativeDeviceDescriptor; } /** * Returns the size of this descriptor (in bytes). * - * @return The size of this descriptor (in bytes). + * @return The size of this descriptor (in bytes). */ - public native byte bLength(); + public byte bLength() { + return this.nativeDeviceDescriptor.bLength; + } /** - * Returns the descriptor type. Will have value {@link LibUsb#DT_DEVICE} - * in this context. + * Returns the descriptor type. Will have value {@link LibUsb#DT_DEVICE} in this context. * * @return The descriptor type. */ - public native byte bDescriptorType(); + public byte bDescriptorType() { + return this.nativeDeviceDescriptor.bDescriptorType; + } /** - * Returns the USB specification release number in binary-coded decimal. - * A value of 0x0200 indicates USB 2.0, 0x0110 indicates USB 1.1, etc. + * Returns the USB specification release number in binary-coded decimal. A value of 0x0200 indicates USB 2.0, 0x0110 + * indicates USB 1.1, etc. * * @return The USB specification release number. - */ - public native short bcdUSB(); + */ + public short bcdUSB() { + return this.nativeDeviceDescriptor.bcdUSB; + } /** - * Returns the USB-IF class code for the device. See LibUSB.CLASS_* - * constants. + * Returns the USB-IF class code for the device. See LibUSB.CLASS_* constants. * * @return The USB-IF class code. */ - public native byte bDeviceClass(); + public byte bDeviceClass() { + return this.nativeDeviceDescriptor.bDeviceClass; + } /** - * Returns the USB-IF subclass code for the device, qualified by the - * bDeviceClass value. + * Returns the USB-IF subclass code for the device, qualified by the bDeviceClass value. * * @return The USB-IF subclass code. - */ - public native byte bDeviceSubClass(); + */ + public byte bDeviceSubClass() { + return this.nativeDeviceDescriptor.bDeviceSubClass; + } /** - * Returns the USB-IF protocol code for the device, qualified by the - * bDeviceClass and bDeviceSubClass values. + * Returns the USB-IF protocol code for the device, qualified by the bDeviceClass and bDeviceSubClass values. * * @return The USB-IF protocol code. */ - public native byte bDeviceProtocol(); + public byte bDeviceProtocol() { + return this.nativeDeviceDescriptor.bDeviceProtocol; + } /** * Returns the maximum packet size for endpoint 0. * * @return The maximum packet site for endpoint 0. */ - public native byte bMaxPacketSize0(); + public byte bMaxPacketSize0() { + return this.nativeDeviceDescriptor.bMaxPacketSize0; + } /** * Returns the USB-IF vendor ID. * * @return The vendor ID */ - public native short idVendor(); + public short idVendor() { + return this.nativeDeviceDescriptor.idVendor; + } /** * Returns the USB-IF product ID. * * @return The product ID. */ - public native short idProduct(); + public short idProduct() { + return this.nativeDeviceDescriptor.idProduct; + } /** * Returns the device release number in binary-coded decimal. * * @return The device release number. */ - public native short bcdDevice(); + public short bcdDevice() { + return this.nativeDeviceDescriptor.bcdDevice; + } /** * Returns the index of the string descriptor describing manufacturer. * * @return The manufacturer string descriptor index. */ - public native byte iManufacturer(); + public byte iManufacturer() { + return this.nativeDeviceDescriptor.iManufacturer; + } /** * Returns the index of the string descriptor describing product. * * @return The product string descriptor index. */ - public native byte iProduct(); + public byte iProduct() { + return this.nativeDeviceDescriptor.iProduct; + } /** - * Returns the index of the string descriptor containing device serial - * number. + * Returns the index of the string descriptor containing device serial number. * * @return The serial number string descriptor index. */ - public native byte iSerialNumber(); + public byte iSerialNumber() { + return this.nativeDeviceDescriptor.iSerialNumber; + } /** * Returns the number of possible configurations. * * @return The number of possible configurations. */ - public native byte bNumConfigurations(); + public byte bNumConfigurations() { + return this.nativeDeviceDescriptor.bNumConfigurations; + } /** * Returns a dump of this descriptor. * * @return The descriptor dump. */ - public String dump() - { + public String dump() { return this.dump(null); } @@ -188,82 +182,52 @@ public String dump() * Returns a dump of this descriptor. * * @param handle - * The USB device handle for resolving string descriptors. If - * null then no strings are resolved. + * The USB device handle for resolving string descriptors. If null then no strings are resolved. * @return The descriptor dump. */ - public String dump(final DeviceHandle handle) - { - final String sManufacturer = LibUsb.getStringDescriptor(handle, - this.iManufacturer()); - final String sProduct = LibUsb.getStringDescriptor(handle, - this.iProduct()); - final String sSerialNumber = LibUsb.getStringDescriptor(handle, - this.iSerialNumber()); - return DescriptorUtils.dump(this, sManufacturer, sProduct, - sSerialNumber); + public String dump(final DeviceHandle handle) { + final String sManufacturer = LibUsb.getStringDescriptor(handle, this.iManufacturer()); + final String sProduct = LibUsb.getStringDescriptor(handle, this.iProduct()); + final String sSerialNumber = LibUsb.getStringDescriptor(handle, this.iSerialNumber()); + return DescriptorUtils.dump(this, sManufacturer, sProduct, sSerialNumber); } @Override - public int hashCode() - { - return new HashCodeBuilder() - .append(this.bLength()) - .append(this.bDescriptorType()) - .append(this.bcdUSB()) - .append(this.bDeviceClass()) - .append(this.bDeviceSubClass()) - .append(this.bDeviceProtocol()) - .append(this.bMaxPacketSize0()) - .append(this.idVendor()) - .append(this.idProduct()) - .append(this.bcdDevice()) - .append(this.iManufacturer()) - .append(this.iProduct()) - .append(this.iSerialNumber()) - .append(this.bNumConfigurations()) - .toHashCode(); + public int hashCode() { + return new HashCodeBuilder().append(this.bLength()).append(this.bDescriptorType()).append(this.bcdUSB()) + .append(this.bDeviceClass()).append(this.bDeviceSubClass()).append(this.bDeviceProtocol()) + .append(this.bMaxPacketSize0()).append(this.idVendor()).append(this.idProduct()).append(this.bcdDevice()) + .append(this.iManufacturer()).append(this.iProduct()).append(this.iSerialNumber()) + .append(this.bNumConfigurations()).toHashCode(); } @Override - public boolean equals(final Object obj) - { - if (this == obj) - { + public boolean equals(final Object obj) { + if (this == obj) { return true; } - if (obj == null) - { + if (obj == null) { return false; } - if (this.getClass() != obj.getClass()) - { + if (this.getClass() != obj.getClass()) { return false; } final DeviceDescriptor other = (DeviceDescriptor) obj; - return new EqualsBuilder() - .append(this.bLength(), other.bLength()) - .append(this.bDescriptorType(), other.bDescriptorType()) - .append(this.bcdUSB(), other.bcdUSB()) - .append(this.bDeviceClass(), other.bDeviceClass()) - .append(this.bDeviceSubClass(), other.bDeviceSubClass()) + return new EqualsBuilder().append(this.bLength(), other.bLength()) + .append(this.bDescriptorType(), other.bDescriptorType()).append(this.bcdUSB(), other.bcdUSB()) + .append(this.bDeviceClass(), other.bDeviceClass()).append(this.bDeviceSubClass(), other.bDeviceSubClass()) .append(this.bDeviceProtocol(), other.bDeviceProtocol()) - .append(this.bMaxPacketSize0(), other.bMaxPacketSize0()) - .append(this.idVendor(), other.idVendor()) - .append(this.idProduct(), other.idProduct()) - .append(this.bcdDevice(), other.bcdDevice()) - .append(this.iManufacturer(), other.iManufacturer()) - .append(this.iProduct(), other.iProduct()) + .append(this.bMaxPacketSize0(), other.bMaxPacketSize0()).append(this.idVendor(), other.idVendor()) + .append(this.idProduct(), other.idProduct()).append(this.bcdDevice(), other.bcdDevice()) + .append(this.iManufacturer(), other.iManufacturer()).append(this.iProduct(), other.iProduct()) .append(this.iSerialNumber(), other.iSerialNumber()) - .append(this.bNumConfigurations(), other.bNumConfigurations()) - .isEquals(); + .append(this.bNumConfigurations(), other.bNumConfigurations()).isEquals(); } @Override - public String toString() - { + public String toString() { return this.dump(); } } diff --git a/src/main/java/org/usb4java/EndpointDescriptor.java b/src/main/java/org/usb4java/EndpointDescriptor.java index 999116d..b4e42c3 100644 --- a/src/main/java/org/usb4java/EndpointDescriptor.java +++ b/src/main/java/org/usb4java/EndpointDescriptor.java @@ -22,192 +22,170 @@ import org.apache.commons.lang3.builder.EqualsBuilder; import org.apache.commons.lang3.builder.HashCodeBuilder; +import org.usb4java.jna.NativeEndpointDescriptor; + +import com.sun.jna.Pointer; /** * A structure representing the standard USB endpoint descriptor. * - * This descriptor is documented in section 9.6.6 of the USB 3.0 specification. - * All multiple-byte fields are represented in host-endian format. + * This descriptor is documented in section 9.6.6 of the USB 3.0 specification. All multiple-byte fields are represented + * in host-endian format. * * @author Klaus Reimer (k@ailis.de) */ -public final class EndpointDescriptor -{ - /** The native pointer to the descriptor structure. */ - private long endpointDescriptorPointer; - - /** - * Package-private constructor to prevent manual instantiation. Endpoint - * descriptors are always created by JNI. - */ - EndpointDescriptor() - { - // Empty - } +public final class EndpointDescriptor { + /** The native endpoint descriptor structure. */ + private final NativeEndpointDescriptor nativeEndpointDescriptor; - /** - * Returns the native pointer. - * - * @return The native pointer. - */ - public long getPointer() - { - return this.endpointDescriptorPointer; + EndpointDescriptor(final NativeEndpointDescriptor nativeEndpointDescriptor) { + this.nativeEndpointDescriptor = nativeEndpointDescriptor; } /** * Returns the size of this descriptor (in bytes). * - * @return The size of this descriptor (in bytes). + * @return The size of this descriptor (in bytes). */ - public native byte bLength(); + public byte bLength() { + return this.nativeEndpointDescriptor.bLength; + } /** - * Returns the descriptor type. Will have value {@link LibUsb#DT_ENDPOINT} - * in this context. + * Returns the descriptor type. Will have value {@link LibUsb#DT_ENDPOINT} in this context. * * @return The descriptor type. */ - public native byte bDescriptorType(); + public byte bDescriptorType() { + return this.nativeEndpointDescriptor.bDescriptorType; + } /** - * The address of the endpoint described by this descriptor. Bits 0:3 are - * the endpoint number. Bits 4:6 are reserved. Bit 7 indicates direction - * (Either {@link LibUsb#ENDPOINT_IN} or {@link LibUsb#ENDPOINT_OUT}). + * The address of the endpoint described by this descriptor. Bits 0:3 are the endpoint number. Bits 4:6 are + * reserved. Bit 7 indicates direction (Either {@link LibUsb#ENDPOINT_IN} or {@link LibUsb#ENDPOINT_OUT}). * * @return The endpoint address. */ - public native byte bEndpointAddress(); + public byte bEndpointAddress() { + return this.nativeEndpointDescriptor.bEndpointAddress; + } /** - * Attributes which apply to the endpoint when it is configured using the - * bConfigurationValue. Bits 0:1 determine the transfer type and correspond - * to the LibUsb.TRANSFER_TYPE_* constants. Bits 2:3 are only used for - * isochronous endpoints and correspond to the LibUsb.ISO_SYNC_TYPE_* - * constants. Bits 4:5 are also only used for isochronous endpoints and - * correspond to the LibUsb.ISO_USAGE_TYPE_* constants. Bits 6:7 are - * reserved. + * Attributes which apply to the endpoint when it is configured using the bConfigurationValue. Bits 0:1 determine + * the transfer type and correspond to the LibUsb.TRANSFER_TYPE_* constants. Bits 2:3 are only used for isochronous + * endpoints and correspond to the LibUsb.ISO_SYNC_TYPE_* constants. Bits 4:5 are also only used for isochronous + * endpoints and correspond to the LibUsb.ISO_USAGE_TYPE_* constants. Bits 6:7 are reserved. * * @return The attributes. */ - public native byte bmAttributes(); + public byte bmAttributes() { + return this.nativeEndpointDescriptor.bmAttributes; + } /** - * Returns the maximum packet size this endpoint is capable of - * sending/receiving. + * Returns the maximum packet size this endpoint is capable of sending/receiving. * * @return The maximum packet size. */ - public native short wMaxPacketSize(); + public short wMaxPacketSize() { + return this.nativeEndpointDescriptor.wMaxPacketSize; + } /** * Returns the interval for polling endpoint for data transfers. * * @return The polling interval. */ - public native byte bInterval(); + public byte bInterval() { + return this.nativeEndpointDescriptor.bLength; + } /** - * For audio devices only: the rate at which synchronization feedback is - * provided. + * For audio devices only: the rate at which synchronization feedback is provided. * * @return The synchronization feedback rate. */ - public native byte bRefresh(); + public byte bRefresh() { + return this.nativeEndpointDescriptor.bRefresh; + } /** * For audio devices only: the address of the synch endpoint. * * @return The synch endpoint address. */ - public native byte bSynchAddress(); + public byte bSynchAddress() { + return this.nativeEndpointDescriptor.bSynchAddress; + } /** * Extra descriptors. * - * If libusb encounters unknown endpoint descriptors, it will store them - * here, should you wish to parse them. + * If libusb encounters unknown endpoint descriptors, it will store them here, should you wish to parse them. * * @return The extra descriptors. */ - public native ByteBuffer extra(); + public ByteBuffer extra() { + Pointer pointer = this.nativeEndpointDescriptor.extra; + if (pointer == null) { + return ByteBuffer.allocate(0); + } else { + return pointer.getByteBuffer(0, extraLength()); + } + } /** * Length of the extra descriptors, in bytes. * * @return The extra descriptors length. */ - public native int extraLength(); + public int extraLength() { + return this.nativeEndpointDescriptor.extra_length; + } /** * Returns a dump of this descriptor. * * @return The descriptor dump. */ - public String dump() - { - return String.format( - "%s" + - " extralen %17d%n" + - " extra:%n" + - "%s", - DescriptorUtils.dump(this), - this.extraLength(), - DescriptorUtils.dump(this.extra()).replaceAll("(?m)^", " ")); + public String dump() { + return String.format("%s" + " extralen %17d%n" + " extra:%n" + "%s", DescriptorUtils.dump(this), + this.extraLength(), DescriptorUtils.dump(this.extra()).replaceAll("(?m)^", " ")); } @Override - public int hashCode() - { - return new HashCodeBuilder() - .append(this.bLength()) - .append(this.bDescriptorType()) - .append(this.bEndpointAddress()) - .append(this.bmAttributes()) - .append(this.wMaxPacketSize()) - .append(this.bInterval()) - .append(this.bRefresh()) - .append(this.bSynchAddress()) - .append(this.extra()) - .append(this.extraLength()) - .toHashCode(); + public int hashCode() { + return new HashCodeBuilder().append(this.bLength()).append(this.bDescriptorType()) + .append(this.bEndpointAddress()).append(this.bmAttributes()).append(this.wMaxPacketSize()) + .append(this.bInterval()).append(this.bRefresh()).append(this.bSynchAddress()).append(this.extra()) + .append(this.extraLength()).toHashCode(); } @Override - public boolean equals(final Object obj) - { - if (this == obj) - { + public boolean equals(final Object obj) { + if (this == obj) { return true; } - if (obj == null) - { + if (obj == null) { return false; } - if (this.getClass() != obj.getClass()) - { + if (this.getClass() != obj.getClass()) { return false; } final EndpointDescriptor other = (EndpointDescriptor) obj; - return new EqualsBuilder() - .append(this.bLength(), other.bLength()) + return new EqualsBuilder().append(this.bLength(), other.bLength()) .append(this.bDescriptorType(), other.bDescriptorType()) .append(this.bEndpointAddress(), other.bEndpointAddress()) - .append(this.bmAttributes(), other.bmAttributes()) - .append(this.wMaxPacketSize(), other.wMaxPacketSize()) - .append(this.bInterval(), other.bInterval()) - .append(this.bRefresh(), other.bRefresh()) - .append(this.bSynchAddress(), other.bSynchAddress()) - .append(this.extra(), other.extra()) - .append(this.extraLength(), other.extraLength()) - .isEquals(); + .append(this.bmAttributes(), other.bmAttributes()).append(this.wMaxPacketSize(), other.wMaxPacketSize()) + .append(this.bInterval(), other.bInterval()).append(this.bRefresh(), other.bRefresh()) + .append(this.bSynchAddress(), other.bSynchAddress()).append(this.extra(), other.extra()) + .append(this.extraLength(), other.extraLength()).isEquals(); } @Override - public String toString() - { + public String toString() { return this.dump(); } } diff --git a/src/main/java/org/usb4java/Interface.java b/src/main/java/org/usb4java/Interface.java index 717de1c..5d5c268 100644 --- a/src/main/java/org/usb4java/Interface.java +++ b/src/main/java/org/usb4java/Interface.java @@ -20,67 +20,61 @@ import org.apache.commons.lang3.builder.EqualsBuilder; import org.apache.commons.lang3.builder.HashCodeBuilder; +import org.usb4java.jna.NativeInterface; +import org.usb4java.jna.NativeInterfaceDescriptor; /** * A collection of alternate settings for a particular USB interface. * * @author Klaus Reimer (k@ailis.de) */ -public final class Interface -{ - /** The native pointer to the descriptor structure. */ - private long interfacePointer; +public final class Interface { + /** The native interface structure. */ + private final NativeInterface nativeInterface; - /** - * Package-private constructor to prevent manual instantiation. Interfaces - * are always created by JNI. - */ - Interface() - { - // Empty - } - - /** - * Returns the native pointer. - * - * @return The native pointer. - */ - public long getPointer() - { - return this.interfacePointer; + Interface(final NativeInterface nativeInterface) { + this.nativeInterface = nativeInterface; } /** - * Returns the array with interface descriptors. The length of this array is - * determined by the {@link #numAltsetting()} field. + * Returns the array with interface descriptors. The length of this array is determined by the + * {@link #numAltsetting()} field. * * @return The array with interface descriptors. */ - public native InterfaceDescriptor[] altsetting(); + public InterfaceDescriptor[] altsetting() { + final int numAltsetting = numAltsetting(); + final InterfaceDescriptor[] descriptors = new InterfaceDescriptor[numAltsetting]; + if (numAltsetting > 0) { + final NativeInterfaceDescriptor[] nativeDescriptors = + (NativeInterfaceDescriptor[]) this.nativeInterface.altsetting.toArray(numAltsetting); + for (int i = 0; i != numAltsetting; ++i) { + descriptors[i] = new InterfaceDescriptor(nativeDescriptors[i]); + } + } + return descriptors; + } /** * Returns the number of alternate settings that belong to this interface. * * @return The number of alternate settings. */ - public native int numAltsetting(); + public int numAltsetting() { + return this.nativeInterface.num_altsetting; + } /** * Returns a dump of this interface. * * @return The interface dump. */ - public String dump() - { + public String dump() { final StringBuilder builder = new StringBuilder(); - builder.append(String.format( - "Interface:%n" + - " numAltsetting %10d", - this.numAltsetting())); + builder.append(String.format("Interface:%n" + " numAltsetting %10d", this.numAltsetting())); - for (final InterfaceDescriptor intDesc : this.altsetting()) - { + for (final InterfaceDescriptor intDesc: this.altsetting()) { builder.append(String.format("%n") + intDesc.dump()); } @@ -88,41 +82,30 @@ public String dump() } @Override - public int hashCode() - { - return new HashCodeBuilder() - .append(this.altsetting()) - .append(this.numAltsetting()) - .toHashCode(); + public int hashCode() { + return new HashCodeBuilder().append(this.altsetting()).append(this.numAltsetting()).toHashCode(); } @Override - public boolean equals(final Object obj) - { - if (this == obj) - { + public boolean equals(final Object obj) { + if (this == obj) { return true; } - if (obj == null) - { + if (obj == null) { return false; } - if (this.getClass() != obj.getClass()) - { + if (this.getClass() != obj.getClass()) { return false; } final Interface other = (Interface) obj; - return new EqualsBuilder() - .append(this.altsetting(), other.altsetting()) - .append(this.numAltsetting(), other.numAltsetting()) - .isEquals(); + return new EqualsBuilder().append(this.altsetting(), other.altsetting()) + .append(this.numAltsetting(), other.numAltsetting()).isEquals(); } @Override - public String toString() - { + public String toString() { return this.dump(); } } diff --git a/src/main/java/org/usb4java/InterfaceDescriptor.java b/src/main/java/org/usb4java/InterfaceDescriptor.java index bac28b6..8c9f08e 100644 --- a/src/main/java/org/usb4java/InterfaceDescriptor.java +++ b/src/main/java/org/usb4java/InterfaceDescriptor.java @@ -22,152 +22,163 @@ import org.apache.commons.lang3.builder.EqualsBuilder; import org.apache.commons.lang3.builder.HashCodeBuilder; +import org.usb4java.jna.NativeEndpointDescriptor; +import org.usb4java.jna.NativeInterfaceDescriptor; + +import com.sun.jna.Pointer; /** * A structure representing the standard USB interface descriptor. * - * This descriptor is documented in section 9.6.5 of the USB 3.0 specification. - * All multiple-byte fields are represented in host-endian format. + * This descriptor is documented in section 9.6.5 of the USB 3.0 specification. All multiple-byte fields are represented + * in host-endian format. * * @author Klaus Reimer (k@ailis.de) */ -public final class InterfaceDescriptor -{ - /** The native pointer to the descriptor structure. */ - private long interfaceDescriptorPointer; - - /** - * Package-private constructor to prevent manual instantiation. Interface - * descriptors are always created by JNI. - */ - InterfaceDescriptor() - { - // Empty - } +public final class InterfaceDescriptor { + private final NativeInterfaceDescriptor nativeInterfaceDescriptor; - /** - * Returns the native pointer. - * - * @return The native pointer. - */ - public long getPointer() - { - return this.interfaceDescriptorPointer; + InterfaceDescriptor(final NativeInterfaceDescriptor nativeInterfaceDescriptor) { + this.nativeInterfaceDescriptor = nativeInterfaceDescriptor; } - + /** * Returns the size of this descriptor (in bytes). * - * @return The size of this descriptor (in bytes). + * @return The size of this descriptor (in bytes). */ - public native byte bLength(); + public byte bLength() { + return this.nativeInterfaceDescriptor.bLength; + } /** - * Returns the descriptor type. Will have value {@link LibUsb#DT_INTERFACE} - * in this context. + * Returns the descriptor type. Will have value {@link LibUsb#DT_INTERFACE} in this context. * * @return The descriptor type. */ - public native byte bDescriptorType(); + public byte bDescriptorType() { + return this.nativeInterfaceDescriptor.bDescriptorType; + } /** - * Returns the number of this interface. + * Returns the number of this interface. * * @return The interface number. */ - public native byte bInterfaceNumber(); + public byte bInterfaceNumber() { + return this.nativeInterfaceDescriptor.bInterfaceNumber; + } /** - * Returns the value used to select this alternate setting for this - * interface. + * Returns the value used to select this alternate setting for this interface. * * @return The alternate setting value. */ - public native byte bAlternateSetting(); + public byte bAlternateSetting() { + return this.nativeInterfaceDescriptor.bAlternateSetting; + } /** - * Returns the number of endpoints used by this interface (excluding the - * control endpoint). + * Returns the number of endpoints used by this interface (excluding the control endpoint). * * @return The number of endpoints. */ - public native byte bNumEndpoints(); + public byte bNumEndpoints() { + return this.nativeInterfaceDescriptor.bNumEndpoints; + } /** - * Returns the USB-IF class code for this interface. See LibUSB.CLASS_* - * constants. + * Returns the USB-IF class code for this interface. See LibUSB.CLASS_* constants. * * @return The USB-IF class code. */ - public native byte bInterfaceClass(); + public byte bInterfaceClass() { + return this.nativeInterfaceDescriptor.bInterfaceClass; + } /** - * Returns the USB-IF subclass code for this interface, qualified by the - * bInterfaceClass value. + * Returns the USB-IF subclass code for this interface, qualified by the bInterfaceClass value. * * @return The USB-IF subclass code. */ - public native byte bInterfaceSubClass(); + public byte bInterfaceSubClass() { + return this.nativeInterfaceDescriptor.bInterfaceSubClass; + } /** - * Returns the USB-IF protocol code for this interface, qualified by the - * bInterfaceClass and bInterfaceSubClass values. + * Returns the USB-IF protocol code for this interface, qualified by the bInterfaceClass and bInterfaceSubClass + * values. * - * @return The USB-IF protocol code. + * @return The USB-IF protocol code. */ - public native byte bInterfaceProtocol(); + public byte bInterfaceProtocol() { + return this.nativeInterfaceDescriptor.bInterfaceProtocol; + } /** * Returns the index of string descriptor describing this interface. * - * @return The string descriptor index. + * @return The string descriptor index. */ - public native byte iInterface(); + public byte iInterface() { + return this.nativeInterfaceDescriptor.iInterface; + } /** * Returns the array with endpoints. * * @return The array with endpoints. */ - public native EndpointDescriptor[] endpoint(); + public EndpointDescriptor[] endpoint() { + final int numEndpoints = bNumEndpoints() & 0xff; + final EndpointDescriptor[] descriptors = new EndpointDescriptor[numEndpoints]; + if (numEndpoints > 0) { + final NativeEndpointDescriptor[] nativeDescriptors = + (NativeEndpointDescriptor[]) this.nativeInterfaceDescriptor.endpoint.toArray(numEndpoints); + for (int i = 0; i != numEndpoints; ++i) { + descriptors[i] = new EndpointDescriptor(nativeDescriptors[i]); + } + } + return descriptors; + } /** * Extra descriptors. * - * If libusb encounters unknown interface descriptors, it will store them - * here, should you wish to parse them. + * If libusb encounters unknown interface descriptors, it will store them here, should you wish to parse them. * * @return The extra descriptors. */ - public native ByteBuffer extra(); + public ByteBuffer extra() { + Pointer pointer = this.nativeInterfaceDescriptor.extra; + if (pointer == null) { + return ByteBuffer.allocate(0); + } else { + return pointer.getByteBuffer(0, extraLength()); + } + } /** * Length of the extra descriptors, in bytes. * * @return The extra descriptors length. */ - public native int extraLength(); + public int extraLength() { + return this.nativeInterfaceDescriptor.extra_length; + } /** * Returns a dump of this descriptor. * * @return The descriptor dump. */ - public String dump() - { + public String dump() { final StringBuilder builder = new StringBuilder(); - builder.append(String.format( - "%s" + - " extralen %17d%n" + - " extra:%n" + - "%s", - DescriptorUtils.dump(this), - this.extraLength(), - DescriptorUtils.dump(this.extra()).replaceAll("(?m)^", " "))); - - for (final EndpointDescriptor epDesc : this.endpoint()) - { + builder.append(String.format("%s" + " extralen %17d%n" + " extra:%n" + "%s", DescriptorUtils.dump(this), + this.extraLength(), DescriptorUtils.dump(this.extra()).replaceAll("(?m)^", " "))); + + for (final EndpointDescriptor epDesc: this.endpoint()) { builder.append(String.format("%n") + epDesc.dump()); } @@ -175,44 +186,29 @@ public String dump() } @Override - public int hashCode() - { - return new HashCodeBuilder() - .append(this.bLength()) - .append(this.bDescriptorType()) - .append(this.bInterfaceNumber()) - .append(this.bAlternateSetting()) - .append(this.bNumEndpoints()) - .append(this.bInterfaceClass()) - .append(this.bInterfaceSubClass()) - .append(this.bInterfaceProtocol()) - .append(this.iInterface()) - .append(this.endpoint()) - .append(this.extra()) - .append(this.extraLength()) + public int hashCode() { + return new HashCodeBuilder().append(this.bLength()).append(this.bDescriptorType()) + .append(this.bInterfaceNumber()).append(this.bAlternateSetting()).append(this.bNumEndpoints()) + .append(this.bInterfaceClass()).append(this.bInterfaceSubClass()).append(this.bInterfaceProtocol()) + .append(this.iInterface()).append(this.endpoint()).append(this.extra()).append(this.extraLength()) .toHashCode(); } @Override - public boolean equals(final Object obj) - { - if (this == obj) - { + public boolean equals(final Object obj) { + if (this == obj) { return true; } - if (obj == null) - { + if (obj == null) { return false; } - if (this.getClass() != obj.getClass()) - { + if (this.getClass() != obj.getClass()) { return false; } final InterfaceDescriptor other = (InterfaceDescriptor) obj; - return new EqualsBuilder() - .append(this.bLength(), other.bLength()) + return new EqualsBuilder().append(this.bLength(), other.bLength()) .append(this.bDescriptorType(), other.bDescriptorType()) .append(this.bInterfaceNumber(), other.bInterfaceNumber()) .append(this.bAlternateSetting(), other.bAlternateSetting()) @@ -220,16 +216,12 @@ public boolean equals(final Object obj) .append(this.bInterfaceClass(), other.bInterfaceClass()) .append(this.bInterfaceSubClass(), other.bInterfaceSubClass()) .append(this.bInterfaceProtocol(), other.bInterfaceProtocol()) - .append(this.iInterface(), other.iInterface()) - .append(this.endpoint(), other.endpoint()) - .append(this.extra(), other.extra()) - .append(this.extraLength(), other.extraLength()) - .isEquals(); + .append(this.iInterface(), other.iInterface()).append(this.endpoint(), other.endpoint()) + .append(this.extra(), other.extra()).append(this.extraLength(), other.extraLength()).isEquals(); } @Override - public String toString() - { + public String toString() { return this.dump(); } } diff --git a/src/main/java/org/usb4java/IsoPacketDescriptor.java b/src/main/java/org/usb4java/IsoPacketDescriptor.java index ac952ed..e3072f0 100644 --- a/src/main/java/org/usb4java/IsoPacketDescriptor.java +++ b/src/main/java/org/usb4java/IsoPacketDescriptor.java @@ -52,7 +52,10 @@ public long getPointer() * * @return The length of data to request in this packet. */ - public native int length(); + public int length() { + // TODO + throw new RuntimeException("Not implemented yet"); + } /** * Sets the length of data to request in this packet. @@ -63,21 +66,30 @@ public long getPointer() // Theoretically the right representation for a C unsigned int would be a // Java long, but the maximum length for ISO Packets is 1024 bytes, so an // int more than suffices to hold any possible valid values here. - public native void setLength(final int length); + public void setLength(final int length) { + // TODO + throw new RuntimeException("Not implemented yet"); + } /** * Returns the amount of data that was actually transferred. * * @return The amount of data that was actually transferred. */ - public native int actualLength(); + public int actualLength() { + // TODO + throw new RuntimeException("Not implemented yet"); + } /** * Returns the status code for this packet. * * @return The status code for this packet. */ - public native int status(); + public int status() { + // TODO + throw new RuntimeException("Not implemented yet"); + } @Override public int hashCode() diff --git a/src/main/java/org/usb4java/LibUsb.java b/src/main/java/org/usb4java/LibUsb.java index 9069f4d..7da5153 100644 --- a/src/main/java/org/usb4java/LibUsb.java +++ b/src/main/java/org/usb4java/LibUsb.java @@ -20,14 +20,19 @@ package org.usb4java; import java.io.FileDescriptor; +import java.nio.Buffer; import java.nio.ByteBuffer; import java.nio.IntBuffer; import java.nio.LongBuffer; +import java.nio.charset.CharacterCodingException; +import java.nio.charset.Charset; +import java.nio.charset.CharsetDecoder; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import org.apache.commons.lang3.tuple.ImmutablePair; -import org.usb4java.jna.LibUsbNative; +import org.usb4java.jna.NativeConfigDescriptor; +import org.usb4java.jna.NativeLibUsb; import org.usb4java.jna.NativeVersion; import com.sun.jna.Native; @@ -630,7 +635,7 @@ public final class LibUsb { new ConcurrentHashMap>(); /** The JNA interface to the libusb library. */ - private static LibUsbNative lib = (LibUsbNative) Native.loadLibrary("usb-1.0", LibUsbNative.class); + private static NativeLibUsb lib = (NativeLibUsb) Native.loadLibrary("usb-1.0", NativeLibUsb.class); /** * Private constructor to prevent instantiation. @@ -747,12 +752,11 @@ public static Version getVersion() { */ public static int getDeviceList(final Context context, final DeviceList list) { final PointerByReference listRef = new PointerByReference(); - final int size = lib.libusb_get_device_list(context == null ? null : context.getPointer(), listRef); - if (size < 0) { - return size; + final int result = lib.libusb_get_device_list(context == null ? null : context.getPointer(), listRef); + if (result >= 0) { + list.init(listRef.getValue(), result); } - list.init(listRef.getValue(), size); - return size; + return result; } /** @@ -777,7 +781,7 @@ public static void freeDeviceList(final DeviceList list, final boolean unrefDevi * @return The bus number */ public static int getBusNumber(final Device device) { - return lib.libusb_get_bus_number(device.getPointer()); + return lib.libusb_get_bus_number(device.getNative()); } /** @@ -788,7 +792,7 @@ public static int getBusNumber(final Device device) { * @return The port number (0 if not available). */ public static int getPortNumber(final Device device) { - return lib.libusb_get_port_number(device.getPointer()); + return lib.libusb_get_port_number(device.getNative()); } /** @@ -802,7 +806,7 @@ public static int getPortNumber(final Device device) { * @return The number of elements filled, {@link #ERROR_OVERFLOW} if the array is too small */ public static int getPortNumbers(final Device device, final ByteBuffer path) { - return lib.libusb_get_port_numbers(device.getPointer(), path, path.capacity()); + return lib.libusb_get_port_numbers(device.getNative(), path, path.capacity()); } /** @@ -840,7 +844,8 @@ public static int getPortPath(final Context context, final Device device, final * {@link #freeDeviceList(DeviceList, boolean)} block. */ public static Device getParent(final Device device) { - return new Device(lib.libusb_get_parent(device.getPointer())); + final Pointer pointer = lib.libusb_get_parent(device.getNative()); + return pointer == null ? null : new Device(pointer); } /** @@ -851,7 +856,7 @@ public static Device getParent(final Device device) { * @return The device address */ public static int getDeviceAddress(final Device device) { - return lib.libusb_get_device_address(device.getPointer()); + return lib.libusb_get_device_address(device.getNative()); } /** @@ -863,7 +868,7 @@ public static int getDeviceAddress(final Device device) { * the negotiated speed. */ public static int getDeviceSpeed(final Device device) { - return lib.libusb_get_device_speed(device.getPointer()); + return lib.libusb_get_device_speed(device.getNative()); } /** @@ -883,7 +888,7 @@ public static int getDeviceSpeed(final Device device) { * other failure */ public static int getMaxPacketSize(final Device device, final byte endpoint) { - return lib.libusb_get_max_packet_size(device.getPointer(), endpoint); + return lib.libusb_get_max_packet_size(device.getNative(), endpoint); } /** @@ -909,7 +914,7 @@ public static int getMaxPacketSize(final Device device, final byte endpoint) { * endpoint does not exist {@link #ERROR_OTHER} on other failure. */ public static int getMaxIsoPacketSize(final Device device, final byte endpoint) { - return lib.libusb_get_max_iso_packet_size(device.getPointer(), endpoint); + return lib.libusb_get_max_iso_packet_size(device.getNative(), endpoint); } /** @@ -920,7 +925,7 @@ public static int getMaxIsoPacketSize(final Device device, final byte endpoint) * @return The same device. */ public static Device refDevice(final Device device) { - return new Device(lib.libusb_ref_device(device.getPointer())); + return new Device(lib.libusb_ref_device(device.getNative())); } /** @@ -932,7 +937,7 @@ public static Device refDevice(final Device device) { * the device to unreference. */ public static void unrefDevice(final Device device) { - lib.libusb_unref_device(device.getPointer()); + lib.libusb_unref_device(device.getNative()); } /** @@ -955,7 +960,7 @@ public static void unrefDevice(final Device device) { */ public static int open(final Device device, final DeviceHandle handle) { final PointerByReference handleRef = new PointerByReference(); - final int result = lib.libusb_open(device.getPointer(), handleRef); + final int result = lib.libusb_open(device.getNative(), handleRef); if (result == SUCCESS) { handle.init(handleRef.getValue()); } @@ -1210,7 +1215,10 @@ public static int resetDevice(final DeviceHandle handle) { * array of endpoints to allocate streams on * @return The number of streams allocated, or a LIBUSB_ERROR code on failure. */ - public static native int allocStreams(final DeviceHandle handle, final int numStreams, final byte[] endpoints); + public static int allocStreams(final DeviceHandle handle, final int numStreams, final byte[] endpoints) { + // TODO + throw new RuntimeException("Not implemented yet"); + } /** * Free USB bulk streams allocated with LibUsb.allocStreams(). @@ -1223,7 +1231,10 @@ public static int resetDevice(final DeviceHandle handle) { * array of endpoints to allocate streams on * @return 0 on success, or a LIBUSB_ERROR code on failure. */ - public static native int freeStreams(final DeviceHandle handle, final byte[] endpoints); + public static int freeStreams(final DeviceHandle handle, final byte[] endpoints) { + // TODO + throw new RuntimeException("Not implemented yet"); + } /** * Determine if a kernel driver is active on an interface. @@ -1385,7 +1396,10 @@ public static String strError(final int errcode) { * The little-endian value to convert * @return the value in host-endian byte order */ - public static native short le16ToCpu(final short x); + public static short le16ToCpu(final short x) { + // TODO + throw new RuntimeException("Not implemented yet"); + } /** * Convert a 16-bit value from host-endian to little-endian format. @@ -1396,7 +1410,10 @@ public static String strError(final int errcode) { * The host-endian value to convert * @return the value in little-endian byte order */ - public static native short cpuToLe16(final short x); + public static short cpuToLe16(final short x) { + // TODO + throw new RuntimeException("Not implemented yet"); + } /** * Get the USB device descriptor for a given device. @@ -1409,14 +1426,10 @@ public static String strError(final int errcode) { * output location for the descriptor data * @return 0 on success or a ERROR code on failure */ - public static native int getDeviceDescriptor(final Device device, final DeviceDescriptor descriptor); - - /** - * Returns the size in bytes of the buffer that's required to hold all of a device descriptor's data. - * - * @return buffer size in bytes - */ - static native int deviceDescriptorStructSize(); + public static int getDeviceDescriptor(final Device device, final DeviceDescriptor descriptor) { + return lib.libusb_get_device_descriptor(device.getNative(), descriptor.getNative()); + + } /** * Retrieve a string descriptor in C style ASCII. @@ -1429,8 +1442,22 @@ public static String strError(final int errcode) { * Output buffer for ASCII string descriptor. * @return Number of bytes returned in data, or ERROR code on failure. */ - public static native int getStringDescriptorAscii(final DeviceHandle handle, final byte index, - final StringBuffer string); + public static int getStringDescriptorAscii(final DeviceHandle handle, final byte index, + final StringBuffer string) { + final ByteBuffer buffer = ByteBuffer.allocateDirect(128); + final int result = lib.libusb_get_string_descriptor_ascii(handle.getPointer(), index, buffer, 128); + if (result >= 0) { + try { + string.append(Charset.forName("ASCII").newDecoder().decode(buffer)); + } + catch (CharacterCodingException e) { + // Should not happen because libusb returns ASCII and we decode ASCII. But just in case we forward + // the exception + throw new RuntimeException(e.toString(), e); + } + } + return result; + } /** * A simple wrapper around {@link #getStringDescriptorAscii(DeviceHandle, byte, StringBuffer)}. It simply returns @@ -1473,7 +1500,14 @@ public static String getStringDescriptor(final DeviceHandle handle, final byte i * * @see #getConfigDescriptor(Device, byte, ConfigDescriptor) */ - public static native int getActiveConfigDescriptor(final Device device, final ConfigDescriptor descriptor); + public static int getActiveConfigDescriptor(final Device device, final ConfigDescriptor descriptor) { + PointerByReference descriptorRef = new PointerByReference(); + int result = lib.libusb_get_active_config_descriptor(device.getNative(), descriptorRef); + if (result == SUCCESS) { + descriptor.init(new NativeConfigDescriptor(descriptorRef.getValue())); + } + return result; + } /** * Get a USB configuration descriptor based on its index. @@ -1492,8 +1526,14 @@ public static String getStringDescriptor(final DeviceHandle handle, final byte i * @see #getActiveConfigDescriptor(Device, ConfigDescriptor) * @see #getConfigDescriptorByValue(Device, byte, ConfigDescriptor) */ - public static native int getConfigDescriptor(final Device device, final byte index, - final ConfigDescriptor descriptor); + public static int getConfigDescriptor(final Device device, final byte index, final ConfigDescriptor descriptor) { + PointerByReference descriptorRef = new PointerByReference(); + int result = lib.libusb_get_config_descriptor(device.getNative(), index, descriptorRef); + if (result == SUCCESS) { + descriptor.init(new NativeConfigDescriptor(descriptorRef.getValue())); + } + return result; + } /** * Get a USB configuration descriptor with a specific bConfigurationValue. @@ -1513,8 +1553,15 @@ public static native int getConfigDescriptor(final Device device, final byte ind * @see #getActiveConfigDescriptor(Device, ConfigDescriptor) * @see #getConfigDescriptor(Device, byte, ConfigDescriptor) */ - public static native int getConfigDescriptorByValue(final Device device, final byte value, - final ConfigDescriptor descriptor); + public static int getConfigDescriptorByValue(final Device device, final byte value, + final ConfigDescriptor descriptor) { + final PointerByReference descriptorRef = new PointerByReference(); + final int result = lib.libusb_get_config_descriptor_by_value(device.getNative(), value, descriptorRef); + if (result == SUCCESS) { + descriptor.init(new NativeConfigDescriptor(descriptorRef.getValue())); + } + return result; + } /** * Free a configuration descriptor obtained from {@link #getConfigDescriptor(Device, byte, ConfigDescriptor)} or @@ -1525,7 +1572,9 @@ public static native int getConfigDescriptorByValue(final Device device, final b * @param descriptor * The configuration descriptor to free */ - public static native void freeConfigDescriptor(final ConfigDescriptor descriptor); + public static void freeConfigDescriptor(final ConfigDescriptor descriptor) { + lib.libusb_free_config_descriptor(descriptor.getNative()); + } /** * Get an endpoints superspeed endpoint companion descriptor (if any). @@ -1540,8 +1589,11 @@ public static native int getConfigDescriptorByValue(final Device device, final b * @return {@link #SUCCESS} on success, {@link #ERROR_NOT_FOUND} if the descriptor does not exist, another error * code on error */ - public static native int getSsEndpointCompanionDescriptor(final Context context, - final EndpointDescriptor endpointDescriptor, final SsEndpointCompanionDescriptor companionDescriptor); + public static int getSsEndpointCompanionDescriptor(final Context context, + final EndpointDescriptor endpointDescriptor, final SsEndpointCompanionDescriptor companionDescriptor) { + // TODO + throw new RuntimeException("Not implemented yet"); + } /** * Free a superspeed endpoint companion descriptor obtained from @@ -1552,7 +1604,10 @@ public static native int getSsEndpointCompanionDescriptor(final Context context, * @param companionDescriptor * The superspeed endpoint companion descriptor to free */ - public static native void freeSsEndpointCompanionDescriptor(final SsEndpointCompanionDescriptor companionDescriptor); + public static void freeSsEndpointCompanionDescriptor(final SsEndpointCompanionDescriptor companionDescriptor) { + // TODO + throw new RuntimeException("Not implemented yet"); + } /** * Get a Binary Object Store (BOS) descriptor. This is a BLOCKING function, which will send requests to the device. @@ -1565,7 +1620,10 @@ public static native int getSsEndpointCompanionDescriptor(final Context context, * @return {@link #SUCCESS} on success, {@link #ERROR_NOT_FOUND} if the device doesn't have a BOS descriptor, * another error code on error */ - public static native int getBosDescriptor(final DeviceHandle handle, final BosDescriptor descriptor); + public static int getBosDescriptor(final DeviceHandle handle, final BosDescriptor descriptor) { + // TODO + throw new RuntimeException("Not implemented yet"); + } /** * Free a BOS descriptor obtained from {@link #getBosDescriptor(DeviceHandle, BosDescriptor)}. @@ -1575,7 +1633,10 @@ public static native int getSsEndpointCompanionDescriptor(final Context context, * @param descriptor * The BOS descriptor to free. */ - public static native void freeBosDescriptor(final BosDescriptor descriptor); + public static void freeBosDescriptor(final BosDescriptor descriptor) { + // TODO + throw new RuntimeException("Not implemented yet"); + } /** * Get an USB 2.0 Extension descriptor. @@ -1589,8 +1650,11 @@ public static native int getSsEndpointCompanionDescriptor(final Context context, * {@link #freeUsb20ExtensionDescriptor(Usb20ExtensionDescriptor)} after use. * @return 0 on success a LIBUSB_ERROR code on error */ - public static native int getUsb20ExtensionDescriptor(final Context context, - final BosDevCapabilityDescriptor devCapDescriptor, final Usb20ExtensionDescriptor extensionDescriptor); + public static int getUsb20ExtensionDescriptor(final Context context, + final BosDevCapabilityDescriptor devCapDescriptor, final Usb20ExtensionDescriptor extensionDescriptor) { + // TODO + throw new RuntimeException("Not implemented yet"); + } /** * Free a USB 2.0 Extension descriptor obtained from @@ -1601,7 +1665,10 @@ public static native int getUsb20ExtensionDescriptor(final Context context, * @param extensionDescriptor * The USB 2.0 Extension descriptor to free. */ - public static native void freeUsb20ExtensionDescriptor(final Usb20ExtensionDescriptor extensionDescriptor); + public static void freeUsb20ExtensionDescriptor(final Usb20ExtensionDescriptor extensionDescriptor) { + // TODO + throw new RuntimeException("Not implemented yet"); + } /** * Get a SuperSpeed USB Device Capability descriptor. @@ -1616,9 +1683,12 @@ public static native int getUsb20ExtensionDescriptor(final Context context, * {@link #freeSsUsbDeviceCapabilityDescriptor(SsUsbDeviceCapabilityDescriptor)} after use. * @return {@link #SUCCESS} on success, an error code on error. */ - public static native int getSsUsbDeviceCapabilityDescriptor(final Context context, + public static int getSsUsbDeviceCapabilityDescriptor(final Context context, final BosDevCapabilityDescriptor devCapDescriptor, - final SsUsbDeviceCapabilityDescriptor ssUsbDeviceCapabilityDescriptor); + final SsUsbDeviceCapabilityDescriptor ssUsbDeviceCapabilityDescriptor) { + // TODO + throw new RuntimeException("Not implemented yet"); + } /** * Free a SuperSpeed USB Device Capability descriptor obtained from @@ -1630,8 +1700,11 @@ public static native int getSsUsbDeviceCapabilityDescriptor(final Context contex * @param ssUsbDeviceCapabilityDescriptor * The descriptor to free. */ - public static native void freeSsUsbDeviceCapabilityDescriptor( - final SsUsbDeviceCapabilityDescriptor ssUsbDeviceCapabilityDescriptor); + public static void freeSsUsbDeviceCapabilityDescriptor( + final SsUsbDeviceCapabilityDescriptor ssUsbDeviceCapabilityDescriptor) { + // TODO + throw new RuntimeException("Not implemented yet"); + } /** * Get a Container ID descriptor. @@ -1645,8 +1718,11 @@ public static native void freeSsUsbDeviceCapabilityDescriptor( * freed with {@link #freeContainerIdDescriptor(ContainerIdDescriptor)} after use. * @return {@link #SUCCESS} on success or an error code on error */ - public static native int getContainerIdDescriptor(final Context context, - final BosDevCapabilityDescriptor devCapDescriptor, final ContainerIdDescriptor containerIdDescriptor); + public static int getContainerIdDescriptor(final Context context, + final BosDevCapabilityDescriptor devCapDescriptor, final ContainerIdDescriptor containerIdDescriptor) { + // TODO + throw new RuntimeException("Not implemented yet"); + } /** * Free a Container ID descriptor obtained from @@ -1657,7 +1733,10 @@ public static native int getContainerIdDescriptor(final Context context, * @param containerIdDescriptor * The descriptor to free. */ - public static native void freeContainerIdDescriptor(final ContainerIdDescriptor containerIdDescriptor); + public static void freeContainerIdDescriptor(final ContainerIdDescriptor containerIdDescriptor) { + // TODO + throw new RuntimeException("Not implemented yet"); + } /** * Retrieve a descriptor from the default control pipe. @@ -1730,8 +1809,11 @@ public static int getStringDescriptor(final DeviceHandle handle, final byte inde * {@link #ERROR_PIPE} if the control request was not supported by the device, {@link #ERROR_NO_DEVICE} if * the device has been disconnected, another ERROR code on other failures */ - public static native int controlTransfer(final DeviceHandle handle, final byte bmRequestType, final byte bRequest, - final short wValue, final short wIndex, final ByteBuffer data, final long timeout); + public static int controlTransfer(final DeviceHandle handle, final byte bmRequestType, final byte bRequest, + final short wValue, final short wIndex, final ByteBuffer data, final long timeout) { + // TODO + throw new RuntimeException("Not implemented yet"); + } /** * Perform a USB bulk transfer. @@ -1764,8 +1846,11 @@ public static native int controlTransfer(final DeviceHandle handle, final byte b * more data, see Packets and overflows, {@link #ERROR_NO_DEVICE} if the device has been disconnected, * another ERROR code on other failures. */ - public static native int bulkTransfer(final DeviceHandle handle, final byte endpoint, final ByteBuffer data, - final IntBuffer transferred, final long timeout); + public static int bulkTransfer(final DeviceHandle handle, final byte endpoint, final ByteBuffer data, + final IntBuffer transferred, final long timeout) { + // TODO + throw new RuntimeException("Not implemented yet"); + } /** * Perform a USB interrupt transfer. @@ -1801,8 +1886,11 @@ public static native int bulkTransfer(final DeviceHandle handle, final byte endp * Packets and overflows, {@link #ERROR_NO_DEVICE} if the device has been disconnected, another ERROR code * on other error */ - public static native int interruptTransfer(final DeviceHandle handle, final byte endpoint, final ByteBuffer data, - final IntBuffer transferred, final long timeout); + public static int interruptTransfer(final DeviceHandle handle, final byte endpoint, final ByteBuffer data, + final IntBuffer transferred, final long timeout) { + // TODO + throw new RuntimeException("Not implemented yet"); + } /** * Attempt to acquire the event handling lock. @@ -1821,7 +1909,10 @@ public static native int interruptTransfer(final DeviceHandle handle, final byte * @return 0 if the lock was obtained successfully, 1 if the lock was not obtained (i.e. another thread holds the * lock) */ - public static native int tryLockEvents(final Context context); + public static int tryLockEvents(final Context context) { + // TODO + throw new RuntimeException("Not implemented yet"); + } /** * Acquire the event handling lock, blocking until successful acquisition if it is contended. @@ -1838,7 +1929,10 @@ public static native int interruptTransfer(final DeviceHandle handle, final byte * @param context * The context to operate on, or NULL for the default context. */ - public static native void lockEvents(final Context context); + public static void lockEvents(final Context context) { + // TODO + throw new RuntimeException("Not implemented yet"); + } /** * Release the lock previously acquired with {@link #tryLockEvents(Context)} or {@link #lockEvents(Context)}. @@ -1848,7 +1942,10 @@ public static native int interruptTransfer(final DeviceHandle handle, final byte * @param context * The context to operate on, or NULL for the default context */ - public static native void unlockEvents(final Context context); + public static void unlockEvents(final Context context) { + // TODO + throw new RuntimeException("Not implemented yet"); + } /** * Determine if it is still OK for this thread to be doing event handling. @@ -1867,7 +1964,10 @@ public static native int interruptTransfer(final DeviceHandle handle, final byte * The context to operate on, or NULL for the default context. * @return 1 if event handling can start or continue, 0 if this thread must give up the events lock */ - public static native int eventHandlingOk(final Context context); + public static int eventHandlingOk(final Context context) { + // TODO + throw new RuntimeException("Not implemented yet"); + } /** * Determine if an active thread is handling events (i.e. if anyone is holding the event handling lock). @@ -1876,7 +1976,10 @@ public static native int interruptTransfer(final DeviceHandle handle, final byte * The context to operate on, or NULL for the default context. * @return 1 if a thread is handling events, 0 if there are no threads currently handling events. */ - public static native int eventHandlerActive(final Context context); + public static int eventHandlerActive(final Context context) { + // TODO + throw new RuntimeException("Not implemented yet"); + } /** * Acquire the event waiters lock. @@ -1895,7 +1998,10 @@ public static native int interruptTransfer(final DeviceHandle handle, final byte * @param context * The context to operate on, or NULL for the default context. */ - public static native void lockEventWaiters(final Context context); + public static void lockEventWaiters(final Context context) { + // TODO + throw new RuntimeException("Not implemented yet"); + } /** * Release the event waiters lock. @@ -1903,7 +2009,10 @@ public static native int interruptTransfer(final DeviceHandle handle, final byte * @param context * The context to operate on, or NULL for the default context. */ - public static native void unlockEventWaiters(final Context context); + public static void unlockEventWaiters(final Context context) { + // TODO + throw new RuntimeException("Not implemented yet"); + } /** * Wait for another thread to signal completion of an event. @@ -1928,7 +2037,10 @@ public static native int interruptTransfer(final DeviceHandle handle, final byte * * @return 0 after a transfer completes or another thread stops event handling, 1 if the timeout expired */ - public static native int waitForEvent(final Context context, final long timeout); + public static int waitForEvent(final Context context, final long timeout) { + // TODO + throw new RuntimeException("Not implemented yet"); + } /** * Handle any pending events. @@ -1959,8 +2071,11 @@ public static native int interruptTransfer(final DeviceHandle handle, final byte * Buffer for completion integer to check, or NULL. * @return 0 on success, or a ERROR code on failure */ - public static native int handleEventsTimeoutCompleted(final Context context, final long timeout, - final IntBuffer completed); + public static int handleEventsTimeoutCompleted(final Context context, final long timeout, + final IntBuffer completed) { + // TODO + throw new RuntimeException("Not implemented yet"); + } /** * Handle any pending events. @@ -1980,7 +2095,10 @@ public static native int handleEventsTimeoutCompleted(final Context context, fin * non-blocking mode * @return 0 on success, or a ERROR code on failure */ - public static native int handleEventsTimeout(final Context context, final long timeout); + public static int handleEventsTimeout(final Context context, final long timeout) { + // TODO + throw new RuntimeException("Not implemented yet"); + } /** * Handle any pending events in blocking mode. @@ -1997,7 +2115,10 @@ public static native int handleEventsTimeoutCompleted(final Context context, fin * The context to operate on, or NULL for the default context. * @return 0 on success, or a ERROR code on failure. */ - public static native int handleEvents(final Context context); + public static int handleEvents(final Context context) { + // TODO + throw new RuntimeException("Not implemented yet"); + } /** * Handle any pending events in blocking mode. @@ -2013,7 +2134,10 @@ public static native int handleEventsTimeoutCompleted(final Context context, fin * Buffer for completion integer to check, or NULL. * @return 0 on success, or a ERROR code on failure. */ - public static native int handleEventsCompleted(final Context context, final IntBuffer completed); + public static int handleEventsCompleted(final Context context, final IntBuffer completed) { + // TODO + throw new RuntimeException("Not implemented yet"); + } /** * Handle any pending events by polling file descriptors, without checking if any other threads are already doing @@ -2032,7 +2156,10 @@ public static native int handleEventsTimeoutCompleted(final Context context, fin * The maximum time (In microseconds) to block waiting for events, or zero for non-blocking mode * @return 0 on success, or a ERROR code on failure. */ - public static native int handleEventsLocked(final Context context, final long timeout); + public static int handleEventsLocked(final Context context, final long timeout) { + // TODO + throw new RuntimeException("Not implemented yet"); + } /** * Determines whether your application must apply special timing considerations when monitoring libusb's file @@ -2055,7 +2182,10 @@ public static native int handleEventsTimeoutCompleted(final Context context, fin * @return 0 if you must call into libusb at times determined by {@link #getNextTimeout(Context, LongBuffer)}, or 1 * if all timeout events are handled internally or through regular activity on the file descriptors. */ - public static native int pollfdsHandleTimeouts(final Context context); + public static int pollfdsHandleTimeouts(final Context context) { + // TODO + throw new RuntimeException("Not implemented yet"); + } /** * Determine the next internal timeout that libusb needs to handle. @@ -2083,7 +2213,10 @@ public static native int handleEventsTimeoutCompleted(final Context context, fin * order to process timeout events * @return 0 if there are no pending timeouts, 1 if a timeout was returned, or {@link #ERROR_OTHER} failure */ - public static native int getNextTimeout(final Context context, final LongBuffer timeout); + public static int getNextTimeout(final Context context, final LongBuffer timeout) { + // TODO + throw new RuntimeException("Not implemented yet"); + } /** * Register notification functions for file descriptor additions/removals. @@ -2179,7 +2312,10 @@ static void triggerPollfdRemoved(final FileDescriptor fd, final long contextId) * @param contextId * A unique identifier for the given context. */ - static native void setPollfdNotifiersNative(final Context context, final long contextId); + static void setPollfdNotifiersNative(final Context context, final long contextId) { + // TODO + throw new RuntimeException("Not implemented yet"); + } /** * Tells libusb to stop informing this class about pollfd additions and removals. @@ -2187,7 +2323,10 @@ static void triggerPollfdRemoved(final FileDescriptor fd, final long contextId) * @param context * The context to operate on, or NULL for the default context */ - static native void unsetPollfdNotifiersNative(final Context context); + static void unsetPollfdNotifiersNative(final Context context) { + // TODO + throw new RuntimeException("Not implemented yet"); + } /** * Allocate a libusb transfer without support for isochronous transfers. @@ -2222,7 +2361,10 @@ public static Transfer allocTransfer() { * Number of isochronous packet descriptors to allocate. * @return A newly allocated transfer, or NULL on error */ - public static native Transfer allocTransfer(final int isoPackets); + public static Transfer allocTransfer(final int isoPackets) { + // TODO + throw new RuntimeException("Not implemented yet"); + } /** * Free a transfer structure. @@ -2238,7 +2380,10 @@ public static Transfer allocTransfer() { * @param transfer * The transfer to free */ - public static native void freeTransfer(final Transfer transfer); + public static void freeTransfer(final Transfer transfer) { + // TODO + throw new RuntimeException("Not implemented yet"); + } /** * Submit a transfer. @@ -2251,7 +2396,10 @@ public static Transfer allocTransfer() { * transfer has already been submitted. {@link #ERROR_NOT_SUPPORTED} if the transfer flags are not supported * by the operating system. Another LIBUSB_ERROR code on failure. */ - public static native int submitTransfer(final Transfer transfer); + public static int submitTransfer(final Transfer transfer) { + // TODO + throw new RuntimeException("Not implemented yet"); + } /** * Asynchronously cancel a previously submitted transfer. @@ -2264,7 +2412,10 @@ public static Transfer allocTransfer() { * @return 0 on success, {@link #ERROR_NOT_FOUND} if the transfer is already complete or cancelled. Another * LIBUSB_ERROR code on failure. */ - public static native int cancelTransfer(final Transfer transfer); + public static int cancelTransfer(final Transfer transfer) { + // TODO + throw new RuntimeException("Not implemented yet"); + } /** * Get the data section of a control transfer. @@ -2665,7 +2816,7 @@ public static synchronized int hotplugRegisterCallback(final Context context, fi } /** - * Internally called native method for registering a hotplug callback. + * Internally called method for registering a hotplug callback. * * @param context * Context to register this callback with. @@ -2686,9 +2837,12 @@ public static synchronized int hotplugRegisterCallback(final Context context, fi * The hotplug callback ID. * @return {@link #SUCCESS} on success, some ERROR code on failure. */ - static native int hotplugRegisterCallbackNative(final Context context, final int events, final int flags, + static int hotplugRegisterCallbackNative(final Context context, final int events, final int flags, final int vendorId, final int productId, final int deviceClass, final HotplugCallbackHandle callbackHandle, - final long hotplugId); + final long hotplugId) { + // TODO + throw new RuntimeException("Not implemented yet"); + } /** * Deregisters a hotplug callback. @@ -2716,7 +2870,7 @@ public static void hotplugDeregisterCallback(final Context context, final Hotplu } /** - * Internally called native method for unregistering a hotplug callback. + * Internally called method for unregistering a hotplug callback. * * Deregister a callback from a {@link Context}. This function is safe to call from within a hotplug callback. * @@ -2726,5 +2880,8 @@ public static void hotplugDeregisterCallback(final Context context, final Hotplu * the handle of the callback to deregister * @return The hotplug callback ID. */ - static native long hotplugDeregisterCallbackNative(final Context context, final HotplugCallbackHandle callbackHandle); + static long hotplugDeregisterCallbackNative(final Context context, final HotplugCallbackHandle callbackHandle) { + // TODO + throw new RuntimeException("Not implemented yet"); + } } diff --git a/src/main/java/org/usb4java/Loader.java b/src/main/java/org/usb4java/Loader.java deleted file mode 100644 index bbf6f0e..0000000 --- a/src/main/java/org/usb4java/Loader.java +++ /dev/null @@ -1,360 +0,0 @@ -/* - * Copyright (C) 2011 Klaus Reimer - * See LICENSE.md for licensing information. - */ - -package org.usb4java; - -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.net.URISyntaxException; -import java.net.URL; - -/** - * Utility class to load native libraries from classpath. - * - * @author Klaus Reimer (k@ailis.de) - */ -public final class Loader -{ - /** Buffer size used for copying data. */ - private static final int BUFFER_SIZE = 8192; - - /** Constant for OS X operating system. */ - private static final String OS_OSX = "osx"; - - /** Constant for OS X operating system. */ - private static final String OS_MACOSX = "macosx"; - - /** Constant for Linux operating system. */ - private static final String OS_LINUX = "linux"; - - /** Constant for Windows operating system. */ - private static final String OS_WINDOWS = "windows"; - - /** Constant for FreeBSD operating system. */ - private static final String OS_FREEBSD = "freebsd"; - - /** Constant for SunOS operating system. */ - private static final String OS_SUNOS = "sunos"; - - /** Constant for i386 architecture. */ - private static final String ARCH_I386 = "i386"; - - /** Constant for x86 architecture. */ - private static final String ARCH_X86 = "x86"; - - /** Constant for x86_64 architecture. */ - private static final String ARCH_X86_64 = "x86_64"; - - /** Constant for amd64 architecture. */ - private static final String ARCH_AMD64 = "amd64"; - - /** Constant for so file extension. */ - private static final String EXT_SO = "so"; - - /** Constant for dll file extension. */ - private static final String EXT_DLL = "dll"; - - /** Constant for dylib file extension. */ - private static final String EXT_DYLIB = "dylib"; - - /** The temporary directory for native libraries. */ - private static File tmp; - - /** If library is already loaded. */ - private static boolean loaded = false; - - /** - * Private constructor to prevent instantiation. - */ - private Loader() - { - // Nothing to do here - } - - /** - * Returns the operating system name. This could be "linux", "windows" or - * "osx" or (for any other non-supported platform) the value of the - * "os.name" property converted to lower case and with removed space - * characters. - * - * @return The operating system name. - */ - private static String getOS() - { - final String os = System.getProperty("os.name").toLowerCase() - .replace(" ", ""); - if (os.contains(OS_WINDOWS)) - { - return OS_WINDOWS; - } - if (os.equals(OS_MACOSX)) - { - return OS_OSX; - } - return os; - } - - /** - * Returns the CPU architecture. This will be "x86" or "x86_64" (Platform - * names i386 und amd64 are converted accordingly) or (when platform is - * unsupported) the value of os.arch converted to lower-case and with - * removed space characters. - * - * @return The CPU architecture - */ - private static String getArch() - { - final String arch = System.getProperty("os.arch").toLowerCase() - .replace(" ", ""); - if (arch.equals(ARCH_I386)) - { - return ARCH_X86; - } - if (arch.equals(ARCH_AMD64)) - { - return ARCH_X86_64; - } - return arch; - } - - /** - * Returns the shared library extension name. - * - * @return The shared library extension name. - */ - private static String getExt() - { - final String os = getOS(); - final String key = "usb4java.libext." + getOS(); - final String ext = System.getProperty(key); - if (ext != null) - { - return ext; - } - if (os.equals(OS_LINUX) || os.equals(OS_FREEBSD) || os.equals(OS_SUNOS)) - { - return EXT_SO; - } - if (os.equals(OS_WINDOWS)) - { - return EXT_DLL; - } - if (os.equals(OS_OSX)) - { - return EXT_DYLIB; - } - throw new LoaderException("Unable to determine the shared library " - + "file extension for operating system '" + os - + "'. Please specify Java parameter -D" + key - + "="); - } - - /** - * Creates the temporary directory used for unpacking the native libraries. - * This directory is marked for deletion on exit. - * - * @return The temporary directory for native libraries. - */ - private static File createTempDirectory() - { - // Return cached tmp directory when already created - if (tmp != null) - { - return tmp; - } - - try - { - tmp = File.createTempFile("usb4java", null); - if (!tmp.delete()) - { - throw new IOException("Unable to delete temporary file " + tmp); - } - if (!tmp.mkdirs()) - { - throw new IOException("Unable to create temporary directory " - + tmp); - } - tmp.deleteOnExit(); - return tmp; - } - catch (final IOException e) - { - throw new LoaderException("Unable to create temporary directory " - + "for usb4java natives: " + e, e); - } - } - - /** - * Returns the platform name. This could be for example "linux-x86" or - * "windows-x86_64". - * - * @return The architecture name. Never null. - */ - private static String getPlatform() - { - return getOS() + "-" + getArch(); - } - - /** - * Returns the name of the usb4java native library. This could be - * "libusb4java.dll" for example. - * - * @return The usb4java native library name. Never null. - */ - private static String getLibName() - { - return "libusb4java." + getExt(); - } - - /** - * Returns the name of the libusb native library. This could be - * "libusb0.dll" for example or null if this library is not needed on the - * current platform (Because it is provided by the operating system). - * - * @return The libusb native library name or null if not needed. - */ - private static String getExtraLibName() - { - final String os = getOS(); - if (os.equals(OS_WINDOWS)) - { - return "libusb-1.0." + EXT_DLL; - } - return null; - } - - /** - * Copies the specified input stream to the specified output file. - * - * @param input - * The input stream. - * @param output - * The output file. - * @throws IOException - * If copying failed. - */ - private static void copy(final InputStream input, final File output) - throws IOException - { - final byte[] buffer = new byte[BUFFER_SIZE]; - final FileOutputStream stream = new FileOutputStream(output); - try - { - int read; - while ((read = input.read(buffer)) != -1) - { - stream.write(buffer, 0, read); - } - } - finally - { - stream.close(); - } - } - - /** - * Extracts a single library. - * - * @param platform - * The platform name (For example "linux-x86") - * @param lib - * The library name to extract (For example "libusb0.dll") - * @return The absolute path to the extracted library. - */ - private static String extractLibrary(final String platform, - final String lib) - { - // Extract the usb4java library - final String source = '/' - + Loader.class.getPackage().getName().replace('.', '/') + '/' - + platform + "/" + lib; - - // Check if native library is present - final URL url = Loader.class.getResource(source); - if (url == null) - { - throw new LoaderException("Native library not found in classpath: " - + source); - } - - // If native library was found in an already extracted form then - // return this one without extracting it - if ("file".equals(url.getProtocol())) - { - try - { - return new File(url.toURI()).getAbsolutePath(); - } - catch (final URISyntaxException e) - { - // Can't happen because we are not constructing the URI - // manually. But even when it happens then we fall back to - // extracting the library. - throw new LoaderException(e.toString(), e); - } - } - - // Extract the library and return the path to the extracted file. - final File dest = new File(createTempDirectory(), lib); - try - { - final InputStream stream = Loader.class.getResourceAsStream(source); - if (stream == null) - { - throw new LoaderException("Unable to find " + source - + " in the classpath"); - } - try - { - copy(stream, dest); - } - finally - { - stream.close(); - } - } - catch (final IOException e) - { - throw new LoaderException("Unable to extract native library " - + source + " to " + dest + ": " + e, e); - } - - // Mark usb4java library for deletion - dest.deleteOnExit(); - - return dest.getAbsolutePath(); - } - - /** - * Loads the libusb native wrapper library. Can be safely called multiple - * times. Duplicate calls are ignored. This method is automatically called - * when the {@link LibUsb} class is loaded. When you need to do it earlier - * (To catch exceptions for example) then simply call this method manually. - * - * @throws LoaderException - * When loading the native wrapper libraries failed. - */ - public static synchronized void load() - { - // Do nothing if already loaded (or still loading) - if (loaded) - { - return; - } - - loaded = true; - final String platform = getPlatform(); - final String lib = getLibName(); - final String extraLib = getExtraLibName(); - if (extraLib != null) - { - System.load(extractLibrary(platform, extraLib)); - } - System.load(extractLibrary(platform, lib)); - } -} diff --git a/src/main/java/org/usb4java/SsEndpointCompanionDescriptor.java b/src/main/java/org/usb4java/SsEndpointCompanionDescriptor.java index 9a63d3a..01e279a 100644 --- a/src/main/java/org/usb4java/SsEndpointCompanionDescriptor.java +++ b/src/main/java/org/usb4java/SsEndpointCompanionDescriptor.java @@ -60,14 +60,20 @@ public long getPointer() * * @return The descriptor size in bytes; */ - public native byte bLength(); + public byte bLength() { + // TODO + throw new RuntimeException("Not implemented yet"); + } /** * Returns the descriptor type. * * @return The descriptor type. */ - public native byte bDescriptorType(); + public byte bDescriptorType() { + // TODO + throw new RuntimeException("Not implemented yet"); + } /** * Returns the maximum number of packets the endpoint can send or receive as @@ -75,7 +81,10 @@ public long getPointer() * * @return The maximum number of packets as part of a burst. */ - public native byte bMaxBurst(); + public byte bMaxBurst() { + // TODO + throw new RuntimeException("Not implemented yet"); + } /** * Returns the attributes. In bulk endpoint: bits 4:0 represents the @@ -85,7 +94,10 @@ public long getPointer() * * @return The attributes. */ - public native byte bmAttributes(); + public byte bmAttributes() { + // TODO + throw new RuntimeException("Not implemented yet"); + } /** * Returns the total number of bytes this endpoint will transfer every @@ -93,7 +105,10 @@ public long getPointer() * * @return The total number of bytes per service interval. */ - public native short wBytesPerInterval(); + public short wBytesPerInterval() { + // TODO + throw new RuntimeException("Not implemented yet"); + } /** * Returns a dump of this descriptor. diff --git a/src/main/java/org/usb4java/SsUsbDeviceCapabilityDescriptor.java b/src/main/java/org/usb4java/SsUsbDeviceCapabilityDescriptor.java index fef65f1..27455ac 100644 --- a/src/main/java/org/usb4java/SsUsbDeviceCapabilityDescriptor.java +++ b/src/main/java/org/usb4java/SsUsbDeviceCapabilityDescriptor.java @@ -62,28 +62,40 @@ public long getPointer() * * @return The descriptor size in bytes; */ - public native byte bLength(); + public byte bLength() { + // TODO + throw new RuntimeException("Not implemented yet"); + } /** * Returns the descriptor type. * * @return The descriptor type. */ - public native byte bDescriptorType(); + public byte bDescriptorType() { + // TODO + throw new RuntimeException("Not implemented yet"); + } /** * Returns the device capability type. * * @return The device capability type. */ - public native byte bDevCapabilityType(); + public byte bDevCapabilityType() { + // TODO + throw new RuntimeException("Not implemented yet"); + } /** * Returns the bitmap of supported device level features. * * @return The supported device level features. */ - public native byte bmAttributes(); + public byte bmAttributes() { + // TODO + throw new RuntimeException("Not implemented yet"); + } /** * Returns the bitmap encoding of the speed supported by this device when @@ -91,7 +103,10 @@ public long getPointer() * * @return The supported speed. */ - public native short wSpeedSupported(); + public short wSpeedSupported() { + // TODO + throw new RuntimeException("Not implemented yet"); + } /** * Returns the lowest speed at which all the functionality supported by the @@ -99,21 +114,30 @@ public long getPointer() * * @return The lowest speed. */ - public native byte bFunctionalitySupport(); + public byte bFunctionalitySupport() { + // TODO + throw new RuntimeException("Not implemented yet"); + } /** * Returns the U1 Device Exit Latency. * * @return The U1 Device Exit Latency. */ - public native byte bU1DevExitLat(); + public byte bU1DevExitLat() { + // TODO + throw new RuntimeException("Not implemented yet"); + } /** * Returns the U2 Device Exit Latency. * * @return The U2 Device Exit Latency. */ - public native short bU2DevExitLat(); + public short bU2DevExitLat() { + // TODO + throw new RuntimeException("Not implemented yet"); + } /** * Returns a dump of this descriptor. diff --git a/src/main/java/org/usb4java/Transfer.java b/src/main/java/org/usb4java/Transfer.java index 828975b..c98fc4c 100644 --- a/src/main/java/org/usb4java/Transfer.java +++ b/src/main/java/org/usb4java/Transfer.java @@ -66,7 +66,10 @@ public long getPointer() * * @return The handle of the device. */ - public native DeviceHandle devHandle(); + public DeviceHandle devHandle() { + // TODO + throw new RuntimeException("Not implemented yet"); + } /** * Sets the handle of the device that this transfer will be submitted to. @@ -74,14 +77,20 @@ public long getPointer() * @param handle * The handle of the device. */ - public native void setDevHandle(final DeviceHandle handle); + public void setDevHandle(final DeviceHandle handle) { + // TODO + throw new RuntimeException("Not implemented yet"); + } /** * Returns the bitwise OR combination of libusb transfer flags. * * @return The transfer flags. */ - public native byte flags(); + public byte flags() { + // TODO + throw new RuntimeException("Not implemented yet"); + } /** * Sets the bitwise OR combination of libusb transfer flags. @@ -89,14 +98,20 @@ public long getPointer() * @param flags * The transfer flags to set. */ - public native void setFlags(final byte flags); + public void setFlags(final byte flags) { + // TODO + throw new RuntimeException("Not implemented yet"); + } /** * Returns the address of the endpoint where this transfer will be sent. * * @return The endpoint address. */ - public native byte endpoint(); + public byte endpoint() { + // TODO + throw new RuntimeException("Not implemented yet"); + } /** * Sets the address of the endpoint where this transfer will be sent. @@ -104,14 +119,20 @@ public long getPointer() * @param endpoint * The endpoint address to set */ - public native void setEndpoint(final byte endpoint); + public void setEndpoint(final byte endpoint) { + // TODO + throw new RuntimeException("Not implemented yet"); + } /** * Returns the type of the endpoint. * * @return The endpoint type. */ - public native byte type(); + public byte type() { + // TODO + throw new RuntimeException("Not implemented yet"); + } /** * Sets the type of the endpoint. @@ -119,7 +140,10 @@ public long getPointer() * @param type * The endpoint type to set. */ - public native void setType(final byte type); + public void setType(final byte type) { + // TODO + throw new RuntimeException("Not implemented yet"); + } /** * Returns the timeout for this transfer in milliseconds. A value of 0 @@ -127,7 +151,10 @@ public long getPointer() * * @return The timeout. */ - public native long timeout(); + public long timeout() { + // TODO + throw new RuntimeException("Not implemented yet"); + } /** * Sets the timeout for this transfer in milliseconds. A value of 0 @@ -136,7 +163,10 @@ public long getPointer() * @param timeout * The timeout to set. */ - public native void setTimeout(final long timeout); + public void setTimeout(final long timeout) { + // TODO + throw new RuntimeException("Not implemented yet"); + } /** * Returns the status of the transfer. Read-only, and only for use within @@ -149,14 +179,20 @@ public long getPointer() * * @return The transfer status. */ - public native int status(); + public int status() { + // TODO + throw new RuntimeException("Not implemented yet"); + } /** * Returns the length of the data buffer. * * @return The data buffer length. */ - public native int length(); + public int length() { + // TODO + throw new RuntimeException("Not implemented yet"); + } /** * Sets the length of the data buffer. @@ -195,7 +231,10 @@ public void setLength(final int length) * @param length * The length to set. */ - native void setLengthNative(final int length); + void setLengthNative(final int length) { + // TODO + throw new RuntimeException("Not implemented yet"); + } /** * Returns the actual length of data that was transferred. Read-only, and @@ -204,14 +243,20 @@ public void setLength(final int length) * * @return The actual length of the transferred data. */ - public native int actualLength(); + public int actualLength() { + // TODO + throw new RuntimeException("Not implemented yet"); + } /** * Returns the current callback object. * * @return The current callback object. */ - public native TransferCallback callback(); + public TransferCallback callback() { + // TODO + throw new RuntimeException("Not implemented yet"); + } /** * Sets the callback object. @@ -221,14 +266,20 @@ public void setLength(final int length) * @param callback * The callback object to use. */ - public native void setCallback(final TransferCallback callback); + public void setCallback(final TransferCallback callback) { + // TODO + throw new RuntimeException("Not implemented yet"); + } /** * Returns the current user data object. * * @return The current user data object. */ - public native Object userData(); + public Object userData() { + // TODO + throw new RuntimeException("Not implemented yet"); + } /** * Sets the user data object, representing user context data to pass to @@ -237,7 +288,10 @@ public void setLength(final int length) * @param userData * The user data object to set. */ - public native void setUserData(final Object userData); + public void setUserData(final Object userData) { + // TODO + throw new RuntimeException("Not implemented yet"); + } /** * Returns the data buffer. @@ -270,7 +324,7 @@ public void setBuffer(final ByteBuffer buffer) this.setLengthNative(0); } - // Once we know the native calls have gone through, update the + // Once we know the calls have gone through, update the // reference. this.transferBuffer = buffer; } @@ -281,7 +335,10 @@ public void setBuffer(final ByteBuffer buffer) * @param buffer * The data buffer to set. */ - native void setBufferNative(final ByteBuffer buffer); + void setBufferNative(final ByteBuffer buffer) { + // TODO + throw new RuntimeException("Not implemented yet"); + } /** * Returns the number of isochronous packets. Only used for I/O with @@ -289,7 +346,10 @@ public void setBuffer(final ByteBuffer buffer) * * @return The number of isochronous packets. */ - public native int numIsoPackets(); + public int numIsoPackets() { + // TODO + throw new RuntimeException("Not implemented yet"); + } /** * Sets the number of isochronous packets. @@ -297,21 +357,30 @@ public void setBuffer(final ByteBuffer buffer) * @param numIsoPackets * The number of isochronous packets to set. */ - public native void setNumIsoPackets(final int numIsoPackets); + public void setNumIsoPackets(final int numIsoPackets) { + // TODO + throw new RuntimeException("Not implemented yet"); + } /** * Array of isochronous packet descriptors, for isochronous transfers only. * * @return The array of isochronous packet descriptors. */ - public native IsoPacketDescriptor[] isoPacketDesc(); + public IsoPacketDescriptor[] isoPacketDesc() { + // TODO + throw new RuntimeException("Not implemented yet"); + } /** * Get a transfer's bulk stream id. * * @return The stream id for the transfer. */ - public native int streamId(); + public int streamId() { + // TODO + throw new RuntimeException("Not implemented yet"); + } /** * Set a transfer's bulk stream id. @@ -322,7 +391,10 @@ public void setBuffer(final ByteBuffer buffer) * @param streamId * The stream id to set. */ - public native void setStreamId(final int streamId); + public void setStreamId(final int streamId) { + // TODO + throw new RuntimeException("Not implemented yet"); + } @Override public int hashCode() diff --git a/src/main/java/org/usb4java/Usb20ExtensionDescriptor.java b/src/main/java/org/usb4java/Usb20ExtensionDescriptor.java index ee4fb38..8fafb36 100644 --- a/src/main/java/org/usb4java/Usb20ExtensionDescriptor.java +++ b/src/main/java/org/usb4java/Usb20ExtensionDescriptor.java @@ -60,28 +60,40 @@ public long getPointer() * * @return The descriptor size in bytes; */ - public native byte bLength(); + public byte bLength() { + // TODO + throw new RuntimeException("Not implemented yet"); + } /** * Returns the descriptor type. * * @return The descriptor type. */ - public native byte bDescriptorType(); + public byte bDescriptorType() { + // TODO + throw new RuntimeException("Not implemented yet"); + } /** * Returns the device capability type. * * @return The device capability type. */ - public native byte bDevCapabilityType(); + public byte bDevCapabilityType() { + // TODO + throw new RuntimeException("Not implemented yet"); + } /** * Returns the bitmap of supported device level features. * * @return The supported device level features. */ - public native int bmAttributes(); + public int bmAttributes() { + // TODO + throw new RuntimeException("Not implemented yet"); + } /** * Returns a dump of this descriptor. diff --git a/src/main/java/org/usb4java/jna/ConfigDescriptor.java b/src/main/java/org/usb4java/jna/NativeConfigDescriptor.java similarity index 93% rename from src/main/java/org/usb4java/jna/ConfigDescriptor.java rename to src/main/java/org/usb4java/jna/NativeConfigDescriptor.java index c823d09..b14af8b 100644 --- a/src/main/java/org/usb4java/jna/ConfigDescriptor.java +++ b/src/main/java/org/usb4java/jna/NativeConfigDescriptor.java @@ -18,6 +18,7 @@ package org.usb4java.jna; +import java.nio.ByteBuffer; import java.util.Arrays; import java.util.List; @@ -32,8 +33,8 @@ * * @author Klaus Reimer (k@ailis.de) */ -public class ConfigDescriptor extends Structure { - public ConfigDescriptor(final Pointer pointer) { +public class NativeConfigDescriptor extends Structure { + public NativeConfigDescriptor(final Pointer pointer) { super(pointer); read(); } @@ -66,7 +67,7 @@ public ConfigDescriptor(final Pointer pointer) { public byte bMaxPower; /** The array with interfaces supported by this configuration. */ - public Interface iface; + public NativeInterface iface; /** * Extra descriptors. diff --git a/src/main/java/org/usb4java/jna/DeviceDescriptor.java b/src/main/java/org/usb4java/jna/NativeDeviceDescriptor.java similarity index 97% rename from src/main/java/org/usb4java/jna/DeviceDescriptor.java rename to src/main/java/org/usb4java/jna/NativeDeviceDescriptor.java index 6d97520..f68500c 100644 --- a/src/main/java/org/usb4java/jna/DeviceDescriptor.java +++ b/src/main/java/org/usb4java/jna/NativeDeviceDescriptor.java @@ -31,7 +31,7 @@ * * @author Klaus Reimer (k@ailis.de) */ -public class DeviceDescriptor extends Structure { +public class NativeDeviceDescriptor extends Structure { public byte bLength; public byte bDescriptorType; public short bcdUSB; diff --git a/src/main/java/org/usb4java/jna/EndpointDescriptor.java b/src/main/java/org/usb4java/jna/NativeEndpointDescriptor.java similarity index 97% rename from src/main/java/org/usb4java/jna/EndpointDescriptor.java rename to src/main/java/org/usb4java/jna/NativeEndpointDescriptor.java index ca044fa..0dd2160 100644 --- a/src/main/java/org/usb4java/jna/EndpointDescriptor.java +++ b/src/main/java/org/usb4java/jna/NativeEndpointDescriptor.java @@ -35,7 +35,7 @@ * * @author Klaus Reimer (k@ailis.de) */ -public final class EndpointDescriptor extends Structure implements ByReference { +public final class NativeEndpointDescriptor extends Structure implements ByReference { /** The size of this descriptor (in bytes). */ public byte bLength; diff --git a/src/main/java/org/usb4java/jna/Interface.java b/src/main/java/org/usb4java/jna/NativeInterface.java similarity index 91% rename from src/main/java/org/usb4java/jna/Interface.java rename to src/main/java/org/usb4java/jna/NativeInterface.java index 45480e0..cc998bc 100644 --- a/src/main/java/org/usb4java/jna/Interface.java +++ b/src/main/java/org/usb4java/jna/NativeInterface.java @@ -29,12 +29,12 @@ * * @author Klaus Reimer (k@ailis.de) */ -public final class Interface extends Structure implements ByReference { +public final class NativeInterface extends Structure implements ByReference { /** * The array with interface descriptors. The length of this array is determined by the {@link #num_altsetting} * field. */ - public InterfaceDescriptor altsetting; + public NativeInterfaceDescriptor altsetting; /** the number of alternate settings that belong to this interface. */ public int num_altsetting; diff --git a/src/main/java/org/usb4java/jna/InterfaceDescriptor.java b/src/main/java/org/usb4java/jna/NativeInterfaceDescriptor.java similarity index 94% rename from src/main/java/org/usb4java/jna/InterfaceDescriptor.java rename to src/main/java/org/usb4java/jna/NativeInterfaceDescriptor.java index 0b7b153..597d513 100644 --- a/src/main/java/org/usb4java/jna/InterfaceDescriptor.java +++ b/src/main/java/org/usb4java/jna/NativeInterfaceDescriptor.java @@ -18,6 +18,7 @@ package org.usb4java.jna; +import java.nio.ByteBuffer; import java.util.Arrays; import java.util.List; @@ -35,7 +36,7 @@ * * @author Klaus Reimer (k@ailis.de) */ -public final class InterfaceDescriptor extends Structure implements ByReference { +public final class NativeInterfaceDescriptor extends Structure implements ByReference { /** The size of this descriptor (in bytes). */ public byte bLength; @@ -65,7 +66,7 @@ public final class InterfaceDescriptor extends Structure implements ByReference public byte iInterface; /** The array with endpoints. */ - public EndpointDescriptor endpoint; + public NativeEndpointDescriptor endpoint; /** * Extra descriptors. If libusb encounters unknown interface descriptors, it will store them here, should you wish diff --git a/src/main/java/org/usb4java/jna/LibUsbNative.java b/src/main/java/org/usb4java/jna/NativeLibUsb.java similarity index 89% rename from src/main/java/org/usb4java/jna/LibUsbNative.java rename to src/main/java/org/usb4java/jna/NativeLibUsb.java index 021776b..3cd2b31 100644 --- a/src/main/java/org/usb4java/jna/LibUsbNative.java +++ b/src/main/java/org/usb4java/jna/NativeLibUsb.java @@ -6,12 +6,9 @@ package org.usb4java.jna; import java.nio.ByteBuffer; -import java.util.Arrays; -import java.util.List; import com.sun.jna.Library; import com.sun.jna.Pointer; -import com.sun.jna.Structure; import com.sun.jna.ptr.IntByReference; import com.sun.jna.ptr.PointerByReference; @@ -20,7 +17,7 @@ * * @author Klaus Reimer (k@ailis.de) */ -public interface LibUsbNative extends Library { +public interface NativeLibUsb extends Library { public String libusb_error_name(int error_code); @@ -92,7 +89,7 @@ public interface LibUsbNative extends Library { int libusb_set_auto_detach_kernel_driver(Pointer handle, int enable); - int libusb_get_device_descriptor(Pointer device, DeviceDescriptor descriptor); + int libusb_get_device_descriptor(Pointer device, NativeDeviceDescriptor descriptor); int libusb_get_active_config_descriptor(Pointer device, PointerByReference config); @@ -100,5 +97,9 @@ public interface LibUsbNative extends Library { int libusb_get_config_descriptor_by_value(Pointer device, byte bConfigurationValue, PointerByReference config); - void libusb_free_config_descriptor(ConfigDescriptor config); + void libusb_free_config_descriptor(NativeConfigDescriptor config); + + /* ... */ + + int libusb_get_string_descriptor_ascii(Pointer handle, byte desc_index, ByteBuffer data, int length); } diff --git a/src/main/java/org/usb4java/jna/Test.java b/src/main/java/org/usb4java/jna/Test.java index 7a9d966..53ea884 100644 --- a/src/main/java/org/usb4java/jna/Test.java +++ b/src/main/java/org/usb4java/jna/Test.java @@ -6,6 +6,7 @@ import java.nio.ByteBuffer; +import org.usb4java.Context; import org.usb4java.Device; import org.usb4java.DeviceList; import org.usb4java.LibUsb; @@ -25,134 +26,132 @@ public class Test { * @param args */ public static void main(final String[] args) { - final LibUsbNative lib = (LibUsbNative) Native.loadLibrary("usb-1.0", LibUsbNative.class); - final PointerByReference contextRef = new PointerByReference(); - System.out.println(lib.libusb_init(contextRef)); - final Pointer context = contextRef.getValue(); - lib.libusb_set_debug(context, 4); - - - final PointerByReference listRef = new PointerByReference(); - final int size = lib.libusb_get_device_list(context, listRef); - final Pointer list = listRef.getValue(); - final Pointer[] devices = list.getPointerArray(0, size); - for (final Pointer device: devices) { - System.out.print("bus " + lib.libusb_get_bus_number(device)); - System.out.println(" port " + lib.libusb_get_port_number(device)); - final byte[] ports = new byte[16]; -// final int len = lib.libusb_get_port_numbers(device, ports, 16); -// System.out.print("Port numbers: "); -// for (int i = 0; i < len; ++i) { -// System.out.print(ports[i] + " "); -// } - final Pointer parent = lib.libusb_get_parent(device); - System.out.println("Parent: " + parent); - System.out.println("Address: " + lib.libusb_get_device_address(device)); - System.out.println("Speed: " + lib.libusb_get_device_speed(device)); - System.out.println("max packet size: " + lib.libusb_get_max_packet_size(device, (byte) 1)); - System.out.println("max iso packet size: " + lib.libusb_get_max_iso_packet_size(device, (byte) 1)); - - final Pointer ref2 = lib.libusb_ref_device(device); - lib.libusb_unref_device(ref2); - - final PointerByReference handleRef = new PointerByReference(); - lib.libusb_open(device, handleRef); - final Pointer handle = handleRef.getValue(); - System.out.println("Handle: " + handle); - if (handle != null) { - System.out.println("Got one!"); - - lib.libusb_close(handle); - System.out.println(lib.libusb_get_device(handle)); - System.out.println(device); - - final IntByReference configRef = new IntByReference(); - // System.out.println(lib.libusb_get_configuration(handle, configRef)); - // System.out.println(configRef.getValue()); - -// System.out.println(lib.libusb_set_configuration(handle, 1)); - // System.out.println(lib.libusb_claim_interface(handle, 1)); - - final DeviceDescriptor descriptor = new DeviceDescriptor(); - System.out.println(lib.libusb_get_device_descriptor(device, descriptor)); - System.out.println(Integer.toHexString(descriptor.idVendor)); - System.out.println(Integer.toHexString(descriptor.idProduct)); - - final PointerByReference configDescriptorRef = new PointerByReference(); - System.out.println(configDescriptorRef.getValue()); - System.out.println(lib.libusb_get_active_config_descriptor(device, configDescriptorRef)); - final ConfigDescriptor configDescriptor = new ConfigDescriptor(configDescriptorRef.getValue()); - System.out.println(configDescriptorRef.getValue()); - System.out.println(configDescriptor.bNumInterfaces); - System.out.println(configDescriptor.bDescriptorType); - System.out.println(configDescriptor.wTotalLength); - lib.libusb_free_config_descriptor(configDescriptor); - - final PointerByReference configDescriptorRef2 = new PointerByReference(); - System.out.println(configDescriptorRef2.getValue()); - System.out.println(lib.libusb_get_config_descriptor(device, (byte) 0, configDescriptorRef2)); - final ConfigDescriptor configDescriptor2 = new ConfigDescriptor(configDescriptorRef2.getValue()); - System.out.println(configDescriptorRef2.getValue()); - System.out.println(configDescriptor2.bDescriptorType); - System.out.println(configDescriptor2.wTotalLength); - System.out.println("Num Interfaces: " + configDescriptor2.bNumInterfaces); - System.out.println("Extra: " + configDescriptor2.extra); - System.out.println("Extra len: " + configDescriptor2.extra_length); -// for (int i = 0; i < configDescriptor2.bNumInterfaces; ++i) { -// Pointer ifacePointer = configDescriptor2.iface.get -// System.out.println(ifacePointer); -// System.out.println(configDescriptor.iface); +// final NativeLibUsb lib = (NativeLibUsb) Native.loadLibrary("usb-1.0", NativeLibUsb.class); +// final PointerByReference contextRef = new PointerByReference(); +// System.out.println(lib.libusb_init(contextRef)); +// final Pointer context = contextRef.getValue(); +// lib.libusb_set_debug(context, 4); +// +// +// final PointerByReference listRef = new PointerByReference(); +// final int size = lib.libusb_get_device_list(context, listRef); +// final Pointer list = listRef.getValue(); +// final Pointer[] devices = list.getPointerArray(0, size); +// for (final Pointer device: devices) { +// System.out.print("bus " + lib.libusb_get_bus_number(device)); +// System.out.println(" port " + lib.libusb_get_port_number(device)); +// final byte[] ports = new byte[16]; +//// final int len = lib.libusb_get_port_numbers(device, ports, 16); +//// System.out.print("Port numbers: "); +//// for (int i = 0; i < len; ++i) { +//// System.out.print(ports[i] + " "); +//// } +// final Pointer parent = lib.libusb_get_parent(device); +// System.out.println("Parent: " + parent); +// System.out.println("Address: " + lib.libusb_get_device_address(device)); +// System.out.println("Speed: " + lib.libusb_get_device_speed(device)); +// System.out.println("max packet size: " + lib.libusb_get_max_packet_size(device, (byte) 1)); +// System.out.println("max iso packet size: " + lib.libusb_get_max_iso_packet_size(device, (byte) 1)); +// +// final Pointer ref2 = lib.libusb_ref_device(device); +// lib.libusb_unref_device(ref2); +// +// final PointerByReference handleRef = new PointerByReference(); +// lib.libusb_open(device, handleRef); +// final Pointer handle = handleRef.getValue(); +// System.out.println("Handle: " + handle); +// if (handle != null) { +// System.out.println("Got one!"); +// +// lib.libusb_close(handle); +// System.out.println(lib.libusb_get_device(handle)); +// System.out.println(device); +// +// final IntByReference configRef = new IntByReference(); +// // System.out.println(lib.libusb_get_configuration(handle, configRef)); +// // System.out.println(configRef.getValue()); +// +//// System.out.println(lib.libusb_set_configuration(handle, 1)); +// // System.out.println(lib.libusb_claim_interface(handle, 1)); +// +// final NativeDeviceDescriptor descriptor = new NativeDeviceDescriptor(); +// System.out.println(lib.libusb_get_device_descriptor(device, descriptor)); +// System.out.println(Integer.toHexString(descriptor.idVendor)); +// System.out.println(Integer.toHexString(descriptor.idProduct)); +// +// final PointerByReference configDescriptorRef = new PointerByReference(); +// System.out.println(configDescriptorRef.getValue()); +// System.out.println(lib.libusb_get_active_config_descriptor(device, configDescriptorRef)); +// final NativeConfigDescriptor configDescriptor = new NativeConfigDescriptor(configDescriptorRef.getValue()); +// System.out.println(configDescriptorRef.getValue()); +// System.out.println(configDescriptor.bNumInterfaces); +// System.out.println(configDescriptor.bDescriptorType); +// System.out.println(configDescriptor.wTotalLength); +// lib.libusb_free_config_descriptor(configDescriptor); +// +// final PointerByReference configDescriptorRef2 = new PointerByReference(); +// System.out.println(configDescriptorRef2.getValue()); +// System.out.println(lib.libusb_get_config_descriptor(device, (byte) 0, configDescriptorRef2)); +// final NativeConfigDescriptor configDescriptor2 = new NativeConfigDescriptor(configDescriptorRef2.getValue()); +// System.out.println(configDescriptorRef2.getValue()); +// System.out.println(configDescriptor2.bDescriptorType); +// System.out.println(configDescriptor2.wTotalLength); +// System.out.println("Num Interfaces: " + configDescriptor2.bNumInterfaces); +// System.out.println("Extra: " + configDescriptor2.extra); +// System.out.println("Extra len: " + configDescriptor2.extra_length); +//// for (int i = 0; i < configDescriptor2.bNumInterfaces; ++i) { +//// Pointer ifacePointer = configDescriptor2.iface.get +//// System.out.println(ifacePointer); +//// System.out.println(configDescriptor.iface); +//// } +// NativeInterface[] ifaces = (NativeInterface[]) configDescriptor2.iface.toArray(configDescriptor2.bNumInterfaces); +// for (NativeInterface iface: ifaces) { +// System.out.println("============================================================"); +// System.out.println(iface); +// System.out.println("============================================================"); +// NativeInterfaceDescriptor[] ifaceDescriptors = (NativeInterfaceDescriptor[]) iface.altsetting.toArray(iface.num_altsetting); +// for (NativeInterfaceDescriptor ifaceDescriptor: ifaceDescriptors) { +// System.out.println("---------------------------------------"); +// System.out.println(ifaceDescriptor); +// System.out.println("---------------------------------------"); +//// if (ifaceDescriptor.bNumEndpoints != 0) { +//// NativeEndpointDescriptor[] endpointDescriptors = (NativeEndpointDescriptor[]) ifaceDescriptor.endpoint.toArray(ifaceDescriptor.bNumEndpoints); +//// for (NativeEndpointDescriptor endpointDescriptor: endpointDescriptors) { +//// System.out.println(endpointDescriptor); +//// } +//// } +// } // } - Interface[] ifaces = (Interface[]) configDescriptor2.iface.toArray(configDescriptor2.bNumInterfaces); - for (Interface iface: ifaces) { - System.out.println("============================================================"); - System.out.println(iface); - System.out.println("============================================================"); - InterfaceDescriptor[] ifaceDescriptors = (InterfaceDescriptor[]) iface.altsetting.toArray(iface.num_altsetting); - for (InterfaceDescriptor ifaceDescriptor: ifaceDescriptors) { - System.out.println("---------------------------------------"); - System.out.println(ifaceDescriptor); - System.out.println("---------------------------------------"); - if (ifaceDescriptor.bNumEndpoints != 0) { - EndpointDescriptor[] endpointDescriptors = (EndpointDescriptor[]) ifaceDescriptor.endpoint.toArray(ifaceDescriptor.bNumEndpoints); - for (EndpointDescriptor endpointDescriptor: endpointDescriptors) { - System.out.println(endpointDescriptor); - } - } - } - } - lib.libusb_free_config_descriptor(configDescriptor2); - - break; - } - - - System.out.println(); - } - lib.libusb_free_device_list(list, 1); - - -// System.out.println(lib.libusb_open_device_with_vid_pid(context, (short) 0x16c0, (short) 0x05dc)); - - lib.libusb_exit(context); - System.out.println("Exit"); - - LibUsb.init(null); - System.out.println(LibUsb.getVersion()); +// lib.libusb_free_config_descriptor(configDescriptor2); +// +// // break; +// } +// +// +// System.out.println(); +// } +// lib.libusb_free_device_list(list, 1); +// +// +//// System.out.println(lib.libusb_open_device_with_vid_pid(context, (short) 0x16c0, (short) 0x05dc)); +// +// lib.libusb_exit(context); +// System.out.println("Exit"); +// + final Context context = new Context(); + LibUsb.init(context); DeviceList list2 = new DeviceList(); - System.out.println(LibUsb.getDeviceList(null, list2)); - System.out.println(list2); - for (Device device: list2) { - System.out.println(device); - ByteBuffer path = ByteBuffer.allocateDirect(7); - System.out.println(LibUsb.getPortNumbers(device, path)); - for (int i = 0; i < 7; ++i) { - System.out.print(path.get(i) + " "); + if (LibUsb.getDeviceList(context, list2) >= 0) { + try { + for (Device device: list2) { + System.out.println(LibUsb.getBusNumber(device)); + System.out.println(LibUsb.getDeviceAddress(device)); + } + } finally { + LibUsb.freeDeviceList(list2, true); } - System.out.println(); } - LibUsb.freeDeviceList(list2, true); - LibUsb.exit(null); + LibUsb.exit(context); } } From 646277088983363d87c485534045b9f441db24d7 Mon Sep 17 00:00:00 2001 From: Klaus Reimer Date: Sat, 18 Apr 2015 13:43:40 +0200 Subject: [PATCH 4/5] Add more native descriptor implementations, add custom armhf search path and free context descriptor by pointer instead of reference --- .../java/org/usb4java/ConfigDescriptor.java | 75 ++++++---- src/main/java/org/usb4java/Context.java | 48 +++--- src/main/java/org/usb4java/LibUsb.java | 139 +++++++++--------- .../org/usb4java/jna/NativeBosDescriptor.java | 61 ++++++++ .../jna/NativeBosDevCapabilityDescriptor.java | 53 +++++++ .../usb4java/jna/NativeConfigDescriptor.java | 13 ++ .../jna/NativeContainerIdDescriptor.java | 62 ++++++++ .../java/org/usb4java/jna/NativeLibUsb.java | 32 +++- .../NativeSsEndpointCompanionDescriptor.java | 68 +++++++++ ...NativeSsUsbDeviceCapabilityDescriptor.java | 69 +++++++++ .../jna/NativeUsb20ExtensionDescriptor.java | 58 ++++++++ 11 files changed, 551 insertions(+), 127 deletions(-) create mode 100644 src/main/java/org/usb4java/jna/NativeBosDescriptor.java create mode 100644 src/main/java/org/usb4java/jna/NativeBosDevCapabilityDescriptor.java create mode 100644 src/main/java/org/usb4java/jna/NativeContainerIdDescriptor.java create mode 100644 src/main/java/org/usb4java/jna/NativeSsEndpointCompanionDescriptor.java create mode 100644 src/main/java/org/usb4java/jna/NativeSsUsbDeviceCapabilityDescriptor.java create mode 100644 src/main/java/org/usb4java/jna/NativeUsb20ExtensionDescriptor.java diff --git a/src/main/java/org/usb4java/ConfigDescriptor.java b/src/main/java/org/usb4java/ConfigDescriptor.java index 9f24000..42d4d4e 100644 --- a/src/main/java/org/usb4java/ConfigDescriptor.java +++ b/src/main/java/org/usb4java/ConfigDescriptor.java @@ -38,30 +38,38 @@ public final class ConfigDescriptor { /** The config descriptor structure. */ private NativeConfigDescriptor nativeConfigDescriptor; - + /** - * Constructs a new config descriptor which can be passed to the - * {@link LibUsb#getConfigDescriptor(Device, byte, ConfigDescriptor)} method. + * Initializes the config descriptor. + * + * @param nativeConfigDescriptor + * The native config descriptor to initialize this one with. */ - public ConfigDescriptor() { - } - void init(final NativeConfigDescriptor nativeConfigDescriptor) { + if (nativeConfigDescriptor == null) { + throw new IllegalArgumentException("Native config descriptor must not be null"); + } + if (this.nativeConfigDescriptor != null) { + throw new IllegalStateException("Config descriptor already initialized"); + } this.nativeConfigDescriptor = nativeConfigDescriptor; } - + /** * Returns the config descriptor structure. * * @return The config descriptor structure. */ NativeConfigDescriptor getNative() { + if (this.nativeConfigDescriptor == null) { + throw new IllegalStateException("Config descriptor not initialized"); + } return this.nativeConfigDescriptor; } /** * Returns the size of this descriptor (in bytes). - * + * * @return The size of this descriptor (in bytes). */ public byte bLength() { @@ -70,7 +78,7 @@ public byte bLength() { /** * Returns the descriptor type. Will have value {@link LibUsb#DT_CONFIG} in this context. - * + * * @return The descriptor type. */ public byte bDescriptorType() { @@ -79,7 +87,7 @@ public byte bDescriptorType() { /** * Returns the total length of data returned for this configuration. - * + * * @return The total length of data. */ public short wTotalLength() { @@ -88,7 +96,7 @@ public short wTotalLength() { /** * Returns the number of interfaces supported by this configuration. - * + * * @return The number of supported interfaces. */ public byte bNumInterfaces() { @@ -97,7 +105,7 @@ public byte bNumInterfaces() { /** * Returns the identifier value for this configuration. - * + * * @return The identifier value. */ public byte bConfigurationValue() { @@ -106,7 +114,7 @@ public byte bConfigurationValue() { /** * Returns the index of string descriptor describing this configuration. - * + * * @return The string descriptor index. */ public byte iConfiguration() { @@ -115,7 +123,7 @@ public byte iConfiguration() { /** * Returns the configuration characteristics. - * + * * @return The configuration characteristics. */ public byte bmAttributes() { @@ -125,7 +133,7 @@ public byte bmAttributes() { /** * Returns the maximum power consumption of the USB device from this bus in this configuration when the device is * fully operation. Expressed in units of 2 mA. - * + * * @return The maximum power consumption. */ public byte bMaxPower() { @@ -141,7 +149,8 @@ public Interface[] iface() { final int numInterfaces = bNumInterfaces() & 0xff; final Interface[] ifaces = new Interface[numInterfaces]; if (numInterfaces > 0) { - final NativeInterface[] nativeInterfaces = (NativeInterface[]) this.nativeConfigDescriptor.iface.toArray(numInterfaces); + final NativeInterface[] nativeInterfaces = (NativeInterface[]) this.nativeConfigDescriptor.iface + .toArray(numInterfaces); for (int i = 0; i != numInterfaces; ++i) { ifaces[i] = new Interface(nativeInterfaces[i]); } @@ -157,7 +166,7 @@ public Interface[] iface() { * @return The extra descriptors. */ public ByteBuffer extra() { - Pointer pointer = this.nativeConfigDescriptor.extra; + final Pointer pointer = this.nativeConfigDescriptor.extra; if (pointer == null) { return ByteBuffer.allocate(0); } else { @@ -173,7 +182,7 @@ public ByteBuffer extra() { public int extraLength() { return this.nativeConfigDescriptor.extra_length; } - + /** * Returns a dump of this descriptor. * @@ -183,9 +192,9 @@ public String dump() { final StringBuilder builder = new StringBuilder(); builder.append(String.format("%s" + " extralen %17d%n" + " extra:%n" + "%s", DescriptorUtils.dump(this), - this.extraLength(), DescriptorUtils.dump(this.extra()).replaceAll("(?m)^", " "))); + extraLength(), DescriptorUtils.dump(extra()).replaceAll("(?m)^", " "))); - for (final Interface iface: this.iface()) { + for (final Interface iface : iface()) { builder.append(String.format("%n") + iface.dump()); } @@ -194,10 +203,10 @@ public String dump() { @Override public int hashCode() { - return new HashCodeBuilder().append(this.bLength()).append(this.bDescriptorType()).append(this.wTotalLength()) - .append(this.bNumInterfaces()).append(this.bConfigurationValue()).append(this.iConfiguration()) - .append(this.bmAttributes()).append(this.bMaxPower()).append(this.iface()).append(this.extra()) - .append(this.extraLength()).toHashCode(); + return new HashCodeBuilder().append(bLength()).append(bDescriptorType()).append(wTotalLength()) + .append(bNumInterfaces()).append(bConfigurationValue()).append(iConfiguration()) + .append(bmAttributes()).append(bMaxPower()).append(iface()).append(extra()) + .append(extraLength()).toHashCode(); } @Override @@ -214,17 +223,19 @@ public boolean equals(final Object obj) { final ConfigDescriptor other = (ConfigDescriptor) obj; - return new EqualsBuilder().append(this.bLength(), other.bLength()) - .append(this.bDescriptorType(), other.bDescriptorType()).append(this.wTotalLength(), other.wTotalLength()) - .append(this.bNumInterfaces(), other.bNumInterfaces()) - .append(this.bConfigurationValue(), other.bConfigurationValue()) - .append(this.iConfiguration(), other.iConfiguration()).append(this.bmAttributes(), other.bmAttributes()) - .append(this.bMaxPower(), other.bMaxPower()).append(this.iface(), other.iface()) - .append(this.extra(), other.extra()).append(this.extraLength(), other.extraLength()).isEquals(); + return new EqualsBuilder().append(bLength(), other.bLength()) + .append(bDescriptorType(), other.bDescriptorType()) + .append(wTotalLength(), other.wTotalLength()) + .append(bNumInterfaces(), other.bNumInterfaces()) + .append(bConfigurationValue(), other.bConfigurationValue()) + .append(iConfiguration(), other.iConfiguration()) + .append(bmAttributes(), other.bmAttributes()).append(bMaxPower(), other.bMaxPower()) + .append(iface(), other.iface()).append(extra(), other.extra()) + .append(extraLength(), other.extraLength()).isEquals(); } @Override public String toString() { - return this.dump(); + return dump(); } } diff --git a/src/main/java/org/usb4java/Context.java b/src/main/java/org/usb4java/Context.java index 348f43c..a458e73 100644 --- a/src/main/java/org/usb4java/Context.java +++ b/src/main/java/org/usb4java/Context.java @@ -34,14 +34,22 @@ */ public final class Context { /** The native pointer to the context structure. */ - private Pointer contextPointer; + private Pointer nativeContextPointer; /** - * Constructs a new libusb context. Must be passed to {@link LibUsb#init(Context)} before passing it to any other - * method. + * Sets the context pointer. This must only be called from {@link LibUsb#init(Context)}. + * + * @param nativeContextPointer + * The pointer to set. MUst not be null. */ - public Context() { - // Empty + void init(final Pointer nativeContextPointer) { + if (nativeContextPointer == null) { + throw new IllegalArgumentException("Native context pointer must not be null"); + } + if (this.nativeContextPointer != null) { + throw new IllegalStateException("Context already initialized"); + } + this.nativeContextPointer = nativeContextPointer; } /** @@ -49,23 +57,20 @@ public Context() { * * @return The native pointer to the context structure. */ - public Pointer getPointer() { - return this.contextPointer; - } - - /** - * Sets the context pointer. This must only be called from {@link LibUsb#init(Context)}. - * - * @param pointer - * The pointer to set. - */ - void setPointer(final Pointer pointer) { - this.contextPointer = pointer; + Pointer getNative() { + if (this.nativeContextPointer == null) { + throw new IllegalStateException("Context not initialized"); + } + return this.nativeContextPointer; } @Override public int hashCode() { - return this.contextPointer.hashCode(); + final long nativePointer = Pointer.nativeValue(this.nativeContextPointer); + final int prime = 31; + int result = 1; + result = (prime * result) + (int) (nativePointer ^ (nativePointer >>> 32)); + return result; } @Override @@ -80,11 +85,14 @@ public boolean equals(final Object obj) { return false; } final Context other = (Context) obj; - return (this.contextPointer != null && this.contextPointer.equals(other.contextPointer)); + if (Pointer.nativeValue(this.nativeContextPointer) != Pointer.nativeValue(other.nativeContextPointer)) { + return false; + } + return true; } @Override public String toString() { - return String.format("libusb context " + this.contextPointer); + return String.format("libusb context 0x%x", Pointer.nativeValue(this.nativeContextPointer)); } } diff --git a/src/main/java/org/usb4java/LibUsb.java b/src/main/java/org/usb4java/LibUsb.java index 7da5153..5f45712 100644 --- a/src/main/java/org/usb4java/LibUsb.java +++ b/src/main/java/org/usb4java/LibUsb.java @@ -20,13 +20,11 @@ package org.usb4java; import java.io.FileDescriptor; -import java.nio.Buffer; import java.nio.ByteBuffer; import java.nio.IntBuffer; import java.nio.LongBuffer; import java.nio.charset.CharacterCodingException; import java.nio.charset.Charset; -import java.nio.charset.CharsetDecoder; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; @@ -36,6 +34,7 @@ import org.usb4java.jna.NativeVersion; import com.sun.jna.Native; +import com.sun.jna.NativeLibrary; import com.sun.jna.Pointer; import com.sun.jna.ptr.IntByReference; import com.sun.jna.ptr.PointerByReference; @@ -446,7 +445,7 @@ public final class LibUsb { /** We unwrap the BOS => define its maximum size. */ public static final byte DT_BOS_MAX_SIZE = DT_BOS_SIZE + BT_USB_2_0_EXTENSION_SIZE - + BT_SS_USB_DEVICE_CAPABILITY_SIZE + BT_CONTAINER_ID_SIZE; + + BT_SS_USB_DEVICE_CAPABILITY_SIZE + BT_CONTAINER_ID_SIZE; // Endpoint direction. Values for bit 7 of the endpoint address scheme. @@ -625,17 +624,20 @@ public final class LibUsb { /** * Hotplug callbacks (to correctly manage calls and additional data). */ - private static final ConcurrentMap> hotplugCallbacks = - new ConcurrentHashMap>(); + private static final ConcurrentMap> hotplugCallbacks = new ConcurrentHashMap>(); /** * Pollfd listeners (to support different listeners for different contexts). */ - private static final ConcurrentMap> pollfdListeners = - new ConcurrentHashMap>(); + private static final ConcurrentMap> pollfdListeners = new ConcurrentHashMap>(); /** The JNA interface to the libusb library. */ - private static NativeLibUsb lib = (NativeLibUsb) Native.loadLibrary("usb-1.0", NativeLibUsb.class); + private static NativeLibUsb lib; + + static { + NativeLibrary.addSearchPath("usb-1.0", "/lib/arm-linux-gnueabihf"); + lib = (NativeLibUsb) Native.loadLibrary("usb-1.0", NativeLibUsb.class); + } /** * Private constructor to prevent instantiation. @@ -650,12 +652,12 @@ private LibUsb() { * * @return The API version of the underlying libusb library. * @deprecated The API version can no longer be read from JNA because it is implemented as a define. Use - * {@link #getVersion()} instead to read the libusb library version. This deprecated method converts - * the library version to an API version which is not really correct but acceptable. + * {@link #getVersion()} instead to read the libusb library version. This deprecated method converts the + * library version to an API version which is not really correct but acceptable. */ @Deprecated public static int getApiVersion() { - NativeVersion version = lib.libusb_get_version(); + final NativeVersion version = lib.libusb_get_version(); return version.major << 24 | version.minor << 16 | version.micro; } @@ -680,7 +682,7 @@ public static int init(final Context context) { final PointerByReference contextRef = new PointerByReference(); final int result = lib.libusb_init(contextRef); - context.setPointer(contextRef.getValue()); + context.init(contextRef.getValue()); return result; } @@ -693,7 +695,7 @@ public static int init(final Context context) { * The {@link Context} to deinitialize, or NULL for the default context. */ public static void exit(final Context context) { - lib.libusb_exit(context == null ? null : context.getPointer()); + lib.libusb_exit(context == null ? null : context.getNative()); } /** @@ -720,7 +722,7 @@ public static void exit(final Context context) { * The log level to set. */ public static void setDebug(final Context context, final int level) { - lib.libusb_set_debug(context == null ? null : context.getPointer(), level); + lib.libusb_set_debug(context == null ? null : context.getNative(), level); } /** @@ -752,7 +754,7 @@ public static Version getVersion() { */ public static int getDeviceList(final Context context, final DeviceList list) { final PointerByReference listRef = new PointerByReference(); - final int result = lib.libusb_get_device_list(context == null ? null : context.getPointer(), listRef); + final int result = lib.libusb_get_device_list(context == null ? null : context.getNative(), listRef); if (result >= 0) { list.init(listRef.getValue(), result); } @@ -770,7 +772,7 @@ public static int getDeviceList(final Context context, final DeviceList list) { * Whether to unref the devices in the list. */ public static void freeDeviceList(final DeviceList list, final boolean unrefDevices) { - lib.libusb_free_device_list(list.getPointer(), unrefDevices ? 1 : 0); + lib.libusb_free_device_list(list.getPointer(), unrefDevices ? 1 : 0); } /** @@ -985,10 +987,9 @@ public static int open(final Device device, final DeviceHandle handle) { * The idProduct value to search for. * @return A handle for the first found device or NULL on error or if the device could not be found. */ - public static DeviceHandle openDeviceWithVidPid(final Context context, final short vendorId, - final short productId) { - return new DeviceHandle(lib.libusb_open_device_with_vid_pid(context == null ? null : context.getPointer(), - vendorId, productId)); + public static DeviceHandle openDeviceWithVidPid(final Context context, final short vendorId, final short productId) { + return new DeviceHandle(lib.libusb_open_device_with_vid_pid(context == null ? null : context.getNative(), + vendorId, productId)); } /** @@ -1007,7 +1008,7 @@ public static DeviceHandle openDeviceWithVidPid(final Context context, final sho public static void close(final DeviceHandle handle) { lib.libusb_close(handle.getPointer()); } - + /** * Get the underlying device for a handle. * @@ -1044,7 +1045,7 @@ public static int getConfiguration(final DeviceHandle handle, final IntBuffer co final IntByReference configRef = new IntByReference(); final int result = lib.libusb_get_configuration(handle.getPointer(), configRef); if (result == SUCCESS) { - config.put(0, configRef.getValue()); + config.put(0, configRef.getValue()); } return result; } @@ -1175,7 +1176,7 @@ public static int setInterfaceAltSetting(final DeviceHandle handle, final int in public static int clearHalt(final DeviceHandle handle, final byte endpoint) { return lib.libusb_clear_halt(handle.getPointer(), endpoint); } - + /** * Perform a USB port reset to reinitialize a device. * @@ -1428,7 +1429,7 @@ public static short cpuToLe16(final short x) { */ public static int getDeviceDescriptor(final Device device, final DeviceDescriptor descriptor) { return lib.libusb_get_device_descriptor(device.getNative(), descriptor.getNative()); - + } /** @@ -1442,20 +1443,18 @@ public static int getDeviceDescriptor(final Device device, final DeviceDescripto * Output buffer for ASCII string descriptor. * @return Number of bytes returned in data, or ERROR code on failure. */ - public static int getStringDescriptorAscii(final DeviceHandle handle, final byte index, - final StringBuffer string) { + public static int getStringDescriptorAscii(final DeviceHandle handle, final byte index, final StringBuffer string) { final ByteBuffer buffer = ByteBuffer.allocateDirect(128); final int result = lib.libusb_get_string_descriptor_ascii(handle.getPointer(), index, buffer, 128); if (result >= 0) { try { string.append(Charset.forName("ASCII").newDecoder().decode(buffer)); - } - catch (CharacterCodingException e) { + } catch (final CharacterCodingException e) { // Should not happen because libusb returns ASCII and we decode ASCII. But just in case we forward // the exception throw new RuntimeException(e.toString(), e); } - } + } return result; } @@ -1501,8 +1500,8 @@ public static String getStringDescriptor(final DeviceHandle handle, final byte i * @see #getConfigDescriptor(Device, byte, ConfigDescriptor) */ public static int getActiveConfigDescriptor(final Device device, final ConfigDescriptor descriptor) { - PointerByReference descriptorRef = new PointerByReference(); - int result = lib.libusb_get_active_config_descriptor(device.getNative(), descriptorRef); + final PointerByReference descriptorRef = new PointerByReference(); + final int result = lib.libusb_get_active_config_descriptor(device.getNative(), descriptorRef); if (result == SUCCESS) { descriptor.init(new NativeConfigDescriptor(descriptorRef.getValue())); } @@ -1527,8 +1526,8 @@ public static int getActiveConfigDescriptor(final Device device, final ConfigDes * @see #getConfigDescriptorByValue(Device, byte, ConfigDescriptor) */ public static int getConfigDescriptor(final Device device, final byte index, final ConfigDescriptor descriptor) { - PointerByReference descriptorRef = new PointerByReference(); - int result = lib.libusb_get_config_descriptor(device.getNative(), index, descriptorRef); + final PointerByReference descriptorRef = new PointerByReference(); + final int result = lib.libusb_get_config_descriptor(device.getNative(), index, descriptorRef); if (result == SUCCESS) { descriptor.init(new NativeConfigDescriptor(descriptorRef.getValue())); } @@ -1573,7 +1572,7 @@ public static int getConfigDescriptorByValue(final Device device, final byte val * The configuration descriptor to free */ public static void freeConfigDescriptor(final ConfigDescriptor descriptor) { - lib.libusb_free_config_descriptor(descriptor.getNative()); + lib.libusb_free_config_descriptor(descriptor.getNative().getPointer()); } /** @@ -1590,7 +1589,7 @@ public static void freeConfigDescriptor(final ConfigDescriptor descriptor) { * code on error */ public static int getSsEndpointCompanionDescriptor(final Context context, - final EndpointDescriptor endpointDescriptor, final SsEndpointCompanionDescriptor companionDescriptor) { + final EndpointDescriptor endpointDescriptor, final SsEndpointCompanionDescriptor companionDescriptor) { // TODO throw new RuntimeException("Not implemented yet"); } @@ -1651,7 +1650,7 @@ public static void freeBosDescriptor(final BosDescriptor descriptor) { * @return 0 on success a LIBUSB_ERROR code on error */ public static int getUsb20ExtensionDescriptor(final Context context, - final BosDevCapabilityDescriptor devCapDescriptor, final Usb20ExtensionDescriptor extensionDescriptor) { + final BosDevCapabilityDescriptor devCapDescriptor, final Usb20ExtensionDescriptor extensionDescriptor) { // TODO throw new RuntimeException("Not implemented yet"); } @@ -1684,8 +1683,8 @@ public static void freeUsb20ExtensionDescriptor(final Usb20ExtensionDescriptor e * @return {@link #SUCCESS} on success, an error code on error. */ public static int getSsUsbDeviceCapabilityDescriptor(final Context context, - final BosDevCapabilityDescriptor devCapDescriptor, - final SsUsbDeviceCapabilityDescriptor ssUsbDeviceCapabilityDescriptor) { + final BosDevCapabilityDescriptor devCapDescriptor, + final SsUsbDeviceCapabilityDescriptor ssUsbDeviceCapabilityDescriptor) { // TODO throw new RuntimeException("Not implemented yet"); } @@ -1701,7 +1700,7 @@ public static int getSsUsbDeviceCapabilityDescriptor(final Context context, * The descriptor to free. */ public static void freeSsUsbDeviceCapabilityDescriptor( - final SsUsbDeviceCapabilityDescriptor ssUsbDeviceCapabilityDescriptor) { + final SsUsbDeviceCapabilityDescriptor ssUsbDeviceCapabilityDescriptor) { // TODO throw new RuntimeException("Not implemented yet"); } @@ -1719,7 +1718,7 @@ public static void freeSsUsbDeviceCapabilityDescriptor( * @return {@link #SUCCESS} on success or an error code on error */ public static int getContainerIdDescriptor(final Context context, - final BosDevCapabilityDescriptor devCapDescriptor, final ContainerIdDescriptor containerIdDescriptor) { + final BosDevCapabilityDescriptor devCapDescriptor, final ContainerIdDescriptor containerIdDescriptor) { // TODO throw new RuntimeException("Not implemented yet"); } @@ -1756,7 +1755,7 @@ public static void freeContainerIdDescriptor(final ContainerIdDescriptor contain */ public static int getDescriptor(final DeviceHandle handle, final byte type, final byte index, final ByteBuffer data) { return controlTransfer(handle, ENDPOINT_IN, REQUEST_GET_DESCRIPTOR, - (short) (((type & 0xff) << 8) | (index & 0xff)), (short) 0, data, 1000); + (short) (((type & 0xff) << 8) | (index & 0xff)), (short) 0, data, 1000); } /** @@ -1777,9 +1776,9 @@ public static int getDescriptor(final DeviceHandle handle, final byte type, fina * @see #getStringDescriptorAscii(DeviceHandle, byte, StringBuffer) */ public static int getStringDescriptor(final DeviceHandle handle, final byte index, final short langId, - final ByteBuffer data) { + final ByteBuffer data) { return controlTransfer(handle, ENDPOINT_IN, REQUEST_GET_DESCRIPTOR, - (short) ((DT_STRING << 8) | (index & 0xff)), langId, data, 1000); + (short) ((DT_STRING << 8) | (index & 0xff)), langId, data, 1000); } /** @@ -1810,9 +1809,9 @@ public static int getStringDescriptor(final DeviceHandle handle, final byte inde * the device has been disconnected, another ERROR code on other failures */ public static int controlTransfer(final DeviceHandle handle, final byte bmRequestType, final byte bRequest, - final short wValue, final short wIndex, final ByteBuffer data, final long timeout) { - // TODO - throw new RuntimeException("Not implemented yet"); + final short wValue, final short wIndex, final ByteBuffer data, final long timeout) { + return lib.libusb_control_transfer(handle.getPointer(), bmRequestType, bRequest, wValue, wIndex, + data, (short) data.remaining(), (int) timeout); } /** @@ -1847,7 +1846,7 @@ public static int controlTransfer(final DeviceHandle handle, final byte bmReques * another ERROR code on other failures. */ public static int bulkTransfer(final DeviceHandle handle, final byte endpoint, final ByteBuffer data, - final IntBuffer transferred, final long timeout) { + final IntBuffer transferred, final long timeout) { // TODO throw new RuntimeException("Not implemented yet"); } @@ -1887,7 +1886,7 @@ public static int bulkTransfer(final DeviceHandle handle, final byte endpoint, f * on other error */ public static int interruptTransfer(final DeviceHandle handle, final byte endpoint, final ByteBuffer data, - final IntBuffer transferred, final long timeout) { + final IntBuffer transferred, final long timeout) { // TODO throw new RuntimeException("Not implemented yet"); } @@ -2071,8 +2070,7 @@ public static int waitForEvent(final Context context, final long timeout) { * Buffer for completion integer to check, or NULL. * @return 0 on success, or a ERROR code on failure */ - public static int handleEventsTimeoutCompleted(final Context context, final long timeout, - final IntBuffer completed) { + public static int handleEventsTimeoutCompleted(final Context context, final long timeout, final IntBuffer completed) { // TODO throw new RuntimeException("Not implemented yet"); } @@ -2240,7 +2238,7 @@ public static int getNextTimeout(final Context context, final LongBuffer timeout * User data to be passed back to callbacks (useful for passing context information). */ public static synchronized void setPollfdNotifiers(final Context context, final PollfdListener listener, - final Object userData) { + final Object userData) { // TODO // long contextId; // @@ -2470,7 +2468,7 @@ public static ControlSetup controlTransferGetSetup(final Transfer transfer) { * See {@link ControlSetup#wLength()}. */ public static void fillControlSetup(final ByteBuffer buffer, final byte bmRequestType, final byte bRequest, - final short wValue, final short wIndex, final short wLength) { + final short wValue, final short wIndex, final short wLength) { final ControlSetup setup = new ControlSetup(buffer); setup.setBmRequestType(bmRequestType); setup.setBRequest(bRequest); @@ -2514,7 +2512,7 @@ public static void fillControlSetup(final ByteBuffer buffer, final byte bmReques * Timeout for the transfer in milliseconds. */ public static void fillControlTransfer(final Transfer transfer, final DeviceHandle handle, final ByteBuffer buffer, - final TransferCallback callback, final Object userData, final long timeout) { + final TransferCallback callback, final Object userData, final long timeout) { transfer.setDevHandle(handle); transfer.setEndpoint((byte) 0); transfer.setType(TRANSFER_TYPE_CONTROL); @@ -2547,7 +2545,7 @@ public static void fillControlTransfer(final Transfer transfer, final DeviceHand * Timeout for the transfer in milliseconds. */ public static void fillBulkTransfer(final Transfer transfer, final DeviceHandle handle, final byte endpoint, - final ByteBuffer buffer, final TransferCallback callback, final Object userData, final long timeout) { + final ByteBuffer buffer, final TransferCallback callback, final Object userData, final long timeout) { transfer.setDevHandle(handle); transfer.setEndpoint(endpoint); transfer.setType(TRANSFER_TYPE_BULK); @@ -2578,8 +2576,8 @@ public static void fillBulkTransfer(final Transfer transfer, final DeviceHandle * Timeout for the transfer in milliseconds. */ public static void fillBulkStreamTransfer(final Transfer transfer, final DeviceHandle handle, final byte endpoint, - final int streamId, final ByteBuffer buffer, final TransferCallback callback, final Object userData, - final long timeout) { + final int streamId, final ByteBuffer buffer, final TransferCallback callback, final Object userData, + final long timeout) { fillBulkTransfer(transfer, handle, endpoint, buffer, callback, userData, timeout); transfer.setType(TRANSFER_TYPE_BULK_STREAM); transfer.setStreamId(streamId); @@ -2604,7 +2602,7 @@ public static void fillBulkStreamTransfer(final Transfer transfer, final DeviceH * Timeout for the transfer in milliseconds. */ public static void fillInterruptTransfer(final Transfer transfer, final DeviceHandle handle, final byte endpoint, - final ByteBuffer buffer, final TransferCallback callback, final Object userData, final long timeout) { + final ByteBuffer buffer, final TransferCallback callback, final Object userData, final long timeout) { transfer.setDevHandle(handle); transfer.setEndpoint(endpoint); transfer.setType(TRANSFER_TYPE_INTERRUPT); @@ -2635,8 +2633,8 @@ public static void fillInterruptTransfer(final Transfer transfer, final DeviceHa * Timeout for the transfer in milliseconds. */ public static void fillIsoTransfer(final Transfer transfer, final DeviceHandle handle, final byte endpoint, - final ByteBuffer buffer, final int numIsoPackets, final TransferCallback callback, final Object userData, - final long timeout) { + final ByteBuffer buffer, final int numIsoPackets, final TransferCallback callback, final Object userData, + final long timeout) { transfer.setDevHandle(handle); transfer.setEndpoint(endpoint); transfer.setType(TRANSFER_TYPE_ISOCHRONOUS); @@ -2658,7 +2656,7 @@ public static void fillIsoTransfer(final Transfer transfer, final DeviceHandle h * @see #getMaxPacketSize(Device, byte) */ public static void setIsoPacketLengths(final Transfer transfer, final int length) { - for (final IsoPacketDescriptor isoDesc: transfer.isoPacketDesc()) { + for (final IsoPacketDescriptor isoDesc : transfer.isoPacketDesc()) { isoDesc.setLength(length); } } @@ -2785,8 +2783,8 @@ static int hotplugCallback(final Context context, final Device device, final int * @return {@link #SUCCESS} on success, some ERROR code on failure. */ public static synchronized int hotplugRegisterCallback(final Context context, final int events, final int flags, - final int vendorId, final int productId, final int deviceClass, final HotplugCallback callback, - final Object userData, final HotplugCallbackHandle callbackHandle) { + final int vendorId, final int productId, final int deviceClass, final HotplugCallback callback, + final Object userData, final HotplugCallbackHandle callbackHandle) { if (callback == null) { throw new IllegalArgumentException("callback must not be null"); } @@ -2796,17 +2794,16 @@ public static synchronized int hotplugRegisterCallback(final Context context, fi hotplugCallbacks.put(globalHotplugId, new ImmutablePair(callback, userData)); // Mask the values for conversion to int in libusb API. - final int result = - hotplugRegisterCallbackNative(context, events, flags, (vendorId == LibUsb.HOTPLUG_MATCH_ANY) - ? (LibUsb.HOTPLUG_MATCH_ANY) : (vendorId & 0xFFFF), (productId == LibUsb.HOTPLUG_MATCH_ANY) - ? (LibUsb.HOTPLUG_MATCH_ANY) : (productId & 0xFFFF), (deviceClass == LibUsb.HOTPLUG_MATCH_ANY) - ? (LibUsb.HOTPLUG_MATCH_ANY) : (deviceClass & 0xFF), callbackHandle, globalHotplugId); + final int result = hotplugRegisterCallbackNative(context, events, flags, + (vendorId == LibUsb.HOTPLUG_MATCH_ANY) ? (LibUsb.HOTPLUG_MATCH_ANY) : (vendorId & 0xFFFF), + (productId == LibUsb.HOTPLUG_MATCH_ANY) ? (LibUsb.HOTPLUG_MATCH_ANY) : (productId & 0xFFFF), + (deviceClass == LibUsb.HOTPLUG_MATCH_ANY) ? (LibUsb.HOTPLUG_MATCH_ANY) : (deviceClass & 0xFF), + callbackHandle, globalHotplugId); if (result == LibUsb.SUCCESS) { // Increment globalHotplugId by one, like the libusb handle. globalHotplugId++; - } - else { + } else { // When registration failed then remove the hotplug callback from // our list. hotplugCallbacks.remove(globalHotplugId); @@ -2838,8 +2835,8 @@ public static synchronized int hotplugRegisterCallback(final Context context, fi * @return {@link #SUCCESS} on success, some ERROR code on failure. */ static int hotplugRegisterCallbackNative(final Context context, final int events, final int flags, - final int vendorId, final int productId, final int deviceClass, final HotplugCallbackHandle callbackHandle, - final long hotplugId) { + final int vendorId, final int productId, final int deviceClass, final HotplugCallbackHandle callbackHandle, + final long hotplugId) { // TODO throw new RuntimeException("Not implemented yet"); } diff --git a/src/main/java/org/usb4java/jna/NativeBosDescriptor.java b/src/main/java/org/usb4java/jna/NativeBosDescriptor.java new file mode 100644 index 0000000..a8a54a8 --- /dev/null +++ b/src/main/java/org/usb4java/jna/NativeBosDescriptor.java @@ -0,0 +1,61 @@ +/* + * Copyright 2013 Klaus Reimer + * See LICENSE.md for licensing information. + * + * Based on libusb : + * + * Copyright 2001 Johannes Erdfelt + * Copyright 2007-2009 Daniel Drake + * Copyright 2010-2012 Peter Stuge + * Copyright 2008-2013 Nathan Hjelm + * Copyright 2009-2013 Pete Batard + * Copyright 2009-2013 Ludovic Rousseau + * Copyright 2010-2012 Michael Plante + * Copyright 2011-2013 Hans de Goede + * Copyright 2012-2013 Martin Pieuchot + * Copyright 2012-2013 Toby Gray + */ + +package org.usb4java.jna; + +import java.util.Arrays; +import java.util.List; + +import com.sun.jna.Pointer; +import com.sun.jna.Structure; + +/** + * A structure representing the Binary Device Object Store (BOS) descriptor. + * + * This descriptor is documented in section 9.6.2 of the USB 3.0 specification. All multiple-byte fields are represented + * in host-endian format. + * + * @author Klaus Reimer (k@ailis.de) + */ +public final class NativeBosDescriptor extends Structure { + public NativeBosDescriptor(final Pointer pointer) { + super(pointer); + read(); + } + + /** The size of this descriptor (in bytes). */ + public byte bLength; + + /** The descriptor type. */ + public byte bDescriptorType; + + /** The length of this descriptor and all of its sub descriptors. */ + public short wTotalLength; + + /** The number of separate device capability descriptors in the BOS. */ + public byte bNumDeviceCaps; + + /** The array with the device capability descriptors. */ + public NativeBosDevCapabilityDescriptor dev_capability; + + @Override + protected List getFieldOrder() { + return Arrays.asList(new String[] { "bLength", "bDescriptorType", "wTotalLength", "bNumDeviceCaps", + "dev_capability" }); + } +} diff --git a/src/main/java/org/usb4java/jna/NativeBosDevCapabilityDescriptor.java b/src/main/java/org/usb4java/jna/NativeBosDevCapabilityDescriptor.java new file mode 100644 index 0000000..113819e --- /dev/null +++ b/src/main/java/org/usb4java/jna/NativeBosDevCapabilityDescriptor.java @@ -0,0 +1,53 @@ +/* + * Copyright 2013 Klaus Reimer + * See LICENSE.md for licensing information. + * + * Based on libusb : + * + * Copyright 2001 Johannes Erdfelt + * Copyright 2007-2009 Daniel Drake + * Copyright 2010-2012 Peter Stuge + * Copyright 2008-2013 Nathan Hjelm + * Copyright 2009-2013 Pete Batard + * Copyright 2009-2013 Ludovic Rousseau + * Copyright 2010-2012 Michael Plante + * Copyright 2011-2013 Hans de Goede + * Copyright 2012-2013 Martin Pieuchot + * Copyright 2012-2013 Toby Gray + */ + +package org.usb4java.jna; + +import java.util.Arrays; +import java.util.List; + +import com.sun.jna.Pointer; +import com.sun.jna.Structure; + +/** + * A generic representation of a BOS Device Capability descriptor. + * + * It is advised to check bDevCapabilityType and call the matching + * get*Descriptor method to get a structure fully matching the type. + * + * @author Klaus Reimer (k@ailis.de) + */ +public final class NativeBosDevCapabilityDescriptor extends Structure { + /** The size of ths descriptor (in bytes). */ + public byte bLength; + + /** The descriptor type. */ + public byte bDescriptorType; + + /** The device capability type. */ + public byte bDevCapabilityType; + + /** The device capability data (bLength - 3 bytes). */ + public Pointer dev_capability_data; + + @Override + protected List getFieldOrder() { + return Arrays.asList(new String[] { "bLength", "bDescriptorType", "bDevCapabilityType", + "dev_capability_data" }); + } +} diff --git a/src/main/java/org/usb4java/jna/NativeConfigDescriptor.java b/src/main/java/org/usb4java/jna/NativeConfigDescriptor.java index b14af8b..0afb125 100644 --- a/src/main/java/org/usb4java/jna/NativeConfigDescriptor.java +++ b/src/main/java/org/usb4java/jna/NativeConfigDescriptor.java @@ -24,6 +24,7 @@ import com.sun.jna.Pointer; import com.sun.jna.Structure; +import com.sun.jna.Structure.ByReference; /** * A structure representing the standard USB configuration descriptor. @@ -34,8 +35,20 @@ * @author Klaus Reimer (k@ailis.de) */ public class NativeConfigDescriptor extends Structure { + /** + * Creates a new native config descriptor backed by the memory the specified pointer points to. + * + * @param pointer + * The pointer to the native config descriptor memory. + */ public NativeConfigDescriptor(final Pointer pointer) { super(pointer); + if (pointer == null) { + throw new IllegalArgumentException("Native config descriptor pointer must not be null"); + } + if (Pointer.nativeValue(pointer) == 0) { + throw new IllegalArgumentException("Native config descriptor pointer must not be 0"); + } read(); } diff --git a/src/main/java/org/usb4java/jna/NativeContainerIdDescriptor.java b/src/main/java/org/usb4java/jna/NativeContainerIdDescriptor.java new file mode 100644 index 0000000..bb7476d --- /dev/null +++ b/src/main/java/org/usb4java/jna/NativeContainerIdDescriptor.java @@ -0,0 +1,62 @@ +/* + * Copyright 2013 Klaus Reimer + * See LICENSE.md for licensing information. + * + * Based on libusb : + * + * Copyright 2001 Johannes Erdfelt + * Copyright 2007-2009 Daniel Drake + * Copyright 2010-2012 Peter Stuge + * Copyright 2008-2013 Nathan Hjelm + * Copyright 2009-2013 Pete Batard + * Copyright 2009-2013 Ludovic Rousseau + * Copyright 2010-2012 Michael Plante + * Copyright 2011-2013 Hans de Goede + * Copyright 2012-2013 Martin Pieuchot + * Copyright 2012-2013 Toby Gray + */ + +package org.usb4java.jna; + +import java.util.Arrays; +import java.util.List; + +import com.sun.jna.Pointer; +import com.sun.jna.Structure; + +/** + * A structure representing the Container ID descriptor. + * + * This descriptor is documented in section 9.6.2.3 of the USB 3.0 + * specification. All multiple-byte fields, except UUIDs, are represented in + * host-endian format. + * + * @author Klaus Reimer (k@ailis.de) + */ +public final class NativeContainerIdDescriptor extends Structure { + public NativeContainerIdDescriptor(final Pointer pointer) { + super(pointer); + read(); + } + + /** The size of this descriptor (in bytes). */ + public byte bLength; + + /** The descriptor type. */ + public byte bDescriptorType; + + /** The device capability type. */ + public byte bDevCapabilityType; + + /** The reserved field. */ + public byte bReserved; + + /** The 128 bit UUID. */ + public Pointer containerId; + + @Override + protected List getFieldOrder() { + return Arrays.asList(new String[] { "bLength", "bDescriptorType", "bDevCapabilityType", "bReserved", + "containerId" }); + } +} diff --git a/src/main/java/org/usb4java/jna/NativeLibUsb.java b/src/main/java/org/usb4java/jna/NativeLibUsb.java index 3cd2b31..8669a49 100644 --- a/src/main/java/org/usb4java/jna/NativeLibUsb.java +++ b/src/main/java/org/usb4java/jna/NativeLibUsb.java @@ -97,9 +97,33 @@ public interface NativeLibUsb extends Library { int libusb_get_config_descriptor_by_value(Pointer device, byte bConfigurationValue, PointerByReference config); - void libusb_free_config_descriptor(NativeConfigDescriptor config); - - /* ... */ - + void libusb_free_config_descriptor(Pointer config); + + int libusb_get_ss_endpoint_companion_descriptor(Pointer context, NativeEndpointDescriptor endpoint, + PointerByReference ep_comp); + + void libusb_free_ss_endpoint_companion_descriptor(Pointer ep_comp); + + int libusb_get_bos_descriptor(Pointer handle, PointerByReference bos); + + void libusb_free_bos_descriptor(Pointer bos); + + int libusb_get_usb_2_0_extension_descriptor(Pointer context, NativeBosDevCapabilityDescriptor dev_cap, + PointerByReference usb_2_0_extension); + + void libusb_free_usb_2_0_extension_descriptor(Pointer usb_2_0_extension); + + int libusb_get_ss_usb_device_capability_descriptor(Pointer context, NativeBosDevCapabilityDescriptor dev_cap, + PointerByReference ss_usb_device_cap); + + void libusb_free_ss_usb_device_capability_descriptor(Pointer ss_usb_device_cap); + + int libusb_get_container_id_descriptor(Pointer context, NativeBosDevCapabilityDescriptor dev_cap, + PointerByReference container_id); + + void libusb_free_container_id_descriptor(Pointer container_id); + int libusb_get_string_descriptor_ascii(Pointer handle, byte desc_index, ByteBuffer data, int length); + + int libusb_control_transfer(Pointer handle, byte bmRequestType, byte bRequest, short wValue, short wIndex, ByteBuffer data, short wLength, int timeout); } diff --git a/src/main/java/org/usb4java/jna/NativeSsEndpointCompanionDescriptor.java b/src/main/java/org/usb4java/jna/NativeSsEndpointCompanionDescriptor.java new file mode 100644 index 0000000..150d76e --- /dev/null +++ b/src/main/java/org/usb4java/jna/NativeSsEndpointCompanionDescriptor.java @@ -0,0 +1,68 @@ +/* + * Copyright 2013 Klaus Reimer + * See LICENSE.md for licensing information. + * + * Based on libusb : + * + * Copyright 2001 Johannes Erdfelt + * Copyright 2007-2009 Daniel Drake + * Copyright 2010-2012 Peter Stuge + * Copyright 2008-2013 Nathan Hjelm + * Copyright 2009-2013 Pete Batard + * Copyright 2009-2013 Ludovic Rousseau + * Copyright 2010-2012 Michael Plante + * Copyright 2011-2013 Hans de Goede + * Copyright 2012-2013 Martin Pieuchot + * Copyright 2012-2013 Toby Gray + */ + +package org.usb4java.jna; + +import java.util.Arrays; +import java.util.List; + +import com.sun.jna.Pointer; +import com.sun.jna.Structure; + +/** + * A structure representing the superspeed endpoint companion descriptor. + * + * This descriptor is documented in section 9.6.7 of the USB 3.0 specification. + * All multiple-byte fields are represented in host-endian format. + * + * @author Klaus Reimer (k@ailis.de) + */ +public final class NativeSsEndpointCompanionDescriptor extends Structure { + public NativeSsEndpointCompanionDescriptor(final Pointer pointer) { + super(pointer); + read(); + } + + /** The size of this descriptor (in bytes). */ + public byte bLength; + + /** The descriptor type. */ + public byte bDescriptorType; + + /** The maximum number of packets the endpoint can send or receive as part of a burst. */ + public byte bMaxBurst; + + /** + * The attributes. In bulk endpoint: bits 4:0 represents the + * maximum number of streams the EP supports. In isochronous endpoint: + * bits 1:0 represents the Mult - a zero based value that determines the + * maximum number of packets within a service interval. + */ + public byte bmAttributes; + + /** + * The total number of bytes this endpoint will transfer every service interval. Valid only for periodic endpoints. + */ + public short wBytesPerInterval; + + @Override + protected List getFieldOrder() { + return Arrays.asList(new String[] { "bLength", "bDescriptorType", "bMaxBurst", "bmAttributes", + "wBytesPerInterval" }); + } +} diff --git a/src/main/java/org/usb4java/jna/NativeSsUsbDeviceCapabilityDescriptor.java b/src/main/java/org/usb4java/jna/NativeSsUsbDeviceCapabilityDescriptor.java new file mode 100644 index 0000000..83cdedb --- /dev/null +++ b/src/main/java/org/usb4java/jna/NativeSsUsbDeviceCapabilityDescriptor.java @@ -0,0 +1,69 @@ +/* + * Copyright 2013 Klaus Reimer + * See LICENSE.md for licensing information. + * + * Based on libusb : + * + * Copyright 2001 Johannes Erdfelt + * Copyright 2007-2009 Daniel Drake + * Copyright 2010-2012 Peter Stuge + * Copyright 2008-2013 Nathan Hjelm + * Copyright 2009-2013 Pete Batard + * Copyright 2009-2013 Ludovic Rousseau + * Copyright 2010-2012 Michael Plante + * Copyright 2011-2013 Hans de Goede + * Copyright 2012-2013 Martin Pieuchot + * Copyright 2012-2013 Toby Gray + */ + +package org.usb4java.jna; + +import java.util.Arrays; +import java.util.List; + +import com.sun.jna.Pointer; +import com.sun.jna.Structure; + +/** + * A structure representing the SuperSpeed USB Device Capability descriptor. This descriptor is documented in section + * 9.6.2.2 of the USB 3.0 specification. + * + * All multiple-byte fields are represented in host-endian format. + * + * @author Klaus Reimer (k@ailis.de) + */ +public final class NativeSsUsbDeviceCapabilityDescriptor extends Structure { + public NativeSsUsbDeviceCapabilityDescriptor(final Pointer pointer) { + super(pointer); + read(); + } + + /** The size of this descriptor (in bytes). */ + public byte bLength; + + /** The descriptor type. */ + public byte bDescriptorType; + + /** The device capability type. */ + public byte bDevCapabilityType; + + /** The bitmap of supported device level features. */ + public byte bmAttributes; + + /** The bitmap encoding of the speed supported by this device when operating in SuperSpeed mode. */ + public short wSpeedSupported; + + /** The lowest speed at which all the functionality supported by the device is available to the user. */ + public byte bFunctionalitySupport; + + /** The U1 Device Exit Latency. */ + public byte bU1DevExitLat; + + /** The U2 Device Exit Latency. */ + public short bU2DevExitLat; + + @Override + protected List getFieldOrder() { + return Arrays.asList(new String[] { "bLength", "bDescriptorType", "bDevCapabilityType", "bmAttributes", + "wSpeedSupported", "bFunctionalitySupport", "bU1DevExitLat", "bU2DevExitLat" }); + }} diff --git a/src/main/java/org/usb4java/jna/NativeUsb20ExtensionDescriptor.java b/src/main/java/org/usb4java/jna/NativeUsb20ExtensionDescriptor.java new file mode 100644 index 0000000..6d927f3 --- /dev/null +++ b/src/main/java/org/usb4java/jna/NativeUsb20ExtensionDescriptor.java @@ -0,0 +1,58 @@ +/* + * Copyright 2013 Klaus Reimer + * See LICENSE.md for licensing information. + * + * Based on libusb : + * + * Copyright 2001 Johannes Erdfelt + * Copyright 2007-2009 Daniel Drake + * Copyright 2010-2012 Peter Stuge + * Copyright 2008-2013 Nathan Hjelm + * Copyright 2009-2013 Pete Batard + * Copyright 2009-2013 Ludovic Rousseau + * Copyright 2010-2012 Michael Plante + * Copyright 2011-2013 Hans de Goede + * Copyright 2012-2013 Martin Pieuchot + * Copyright 2012-2013 Toby Gray + */ + +package org.usb4java.jna; + +import java.util.Arrays; +import java.util.List; + +import com.sun.jna.Pointer; +import com.sun.jna.Structure; + + +/** + * A structure representing the USB 2.0 Extension descriptor. This descriptor is documented in section 9.6.2.1 of the + * USB 3.0 specification. + * + * All multiple-byte fields are represented in host-endian format. + * + * @author Klaus Reimer (k@ailis.de) + */ +public final class NativeUsb20ExtensionDescriptor extends Structure { + public NativeUsb20ExtensionDescriptor(final Pointer pointer) { + super(pointer); + read(); + } + + /** The size of this descriptor (in bytes). */ + public byte bLength; + + /** The descriptor type. */ + public byte bDescriptorType; + + /** The device capability type. */ + public byte bDevCapabilityType; + + /** The bitmap of supported device level features. */ + public int bmAttributes; + + @Override + protected List getFieldOrder() { + return Arrays.asList(new String[] { "bLength", "bDescriptorType", "bDevCapabilityType", "bmAttributes" }); + } +} From f29c7f964e9a8cfc9542c49819ceeb1aabc50725 Mon Sep 17 00:00:00 2001 From: Klaus Reimer Date: Sat, 18 Apr 2015 14:43:25 +0200 Subject: [PATCH 5/5] Check version in getDevicePort and getParent --- src/main/java/org/usb4java/LibUsb.java | 20 +++- src/main/java/org/usb4java/Version.java | 146 +++++++++++++++++++++--- 2 files changed, 147 insertions(+), 19 deletions(-) diff --git a/src/main/java/org/usb4java/LibUsb.java b/src/main/java/org/usb4java/LibUsb.java index 5f45712..80edbed 100644 --- a/src/main/java/org/usb4java/LibUsb.java +++ b/src/main/java/org/usb4java/LibUsb.java @@ -631,6 +631,12 @@ public final class LibUsb { */ private static final ConcurrentMap> pollfdListeners = new ConcurrentHashMap>(); + /** The cached libusb version. Automatically set when {@link #getVersion()} is called for the first time. */ + private static Version version; + + /** Constant for version 1.0.12 to check for existance of some methods introduces in this version. */ + private static final Version VERSION_1_0_12 = new Version(1, 0, 12); + /** The JNA interface to the libusb library. */ private static NativeLibUsb lib; @@ -726,12 +732,16 @@ public static void setDebug(final Context context, final int level) { } /** - * Returns the version of the libusb runtime. + * Returns the version of the libusb runtime. The version is only read once and then it is cached so no native + * communication is needed anymore during runtime when it has first been read. * * @return The version of the libusb runtime. */ public static Version getVersion() { - return new Version(lib.libusb_get_version()); + if (version == null) { + version = new Version(lib.libusb_get_version()); + } + return version; } /** @@ -794,6 +804,9 @@ public static int getBusNumber(final Device device) { * @return The port number (0 if not available). */ public static int getPortNumber(final Device device) { + if (getVersion().isOlderThan(VERSION_1_0_12)) { + return 0; + } return lib.libusb_get_port_number(device.getNative()); } @@ -846,6 +859,9 @@ public static int getPortPath(final Context context, final Device device, final * {@link #freeDeviceList(DeviceList, boolean)} block. */ public static Device getParent(final Device device) { + if (getVersion().isOlderThan(VERSION_1_0_12)) { + return null; + } final Pointer pointer = lib.libusb_get_parent(device.getNative()); return pointer == null ? null : new Device(pointer); } diff --git a/src/main/java/org/usb4java/Version.java b/src/main/java/org/usb4java/Version.java index 7546563..619fd62 100644 --- a/src/main/java/org/usb4java/Version.java +++ b/src/main/java/org/usb4java/Version.java @@ -27,18 +27,98 @@ * * @author Klaus Reimer (k@ailis.de) */ -public final class Version { - /** The native version structure. */ - private final NativeVersion version; +public final class Version implements Comparable { + /** The major version. */ + private final int major; + + /** The minor version. */ + private final int minor; + + /** The micro version. */ + private final int micro; + + /** The nano version. */ + private final int nano; + + /** The release candidate suffix string. */ + private final String rc; + + /** + * Creates a new version container with the specified components. + * + * @param major + * The major version. + * @param minor + * The minor version. + */ + public Version(final int major, final int minor) { + this(major, minor, 0, 0, ""); + } + + /** + * Creates a new version container with the specified components. + * + * @param major + * The major version. + * @param minor + * The minor version. + * @param micro + * The micro version. + */ + public Version(final int major, final int minor, final int micro) { + this(major, minor, micro, 0, ""); + } + + /** + * Creates a new version container with the specified components. + * + * @param major + * The major version. + * @param minor + * The minor version. + * @param micro + * The micro version. + * @param nano + * The nano version. + */ + public Version(final int major, final int minor, final int micro, final int nano) { + this(major, minor, micro, nano, ""); + } + + /** + * Creates a new version container with the specified components. + * + * @param major + * The major version. + * @param minor + * The minor version. + * @param micro + * The micro version. + * @param nano + * The nano version. + * @param rc + * The release candidate suffix string. + */ + public Version(final int major, final int minor, final int micro, final int nano, final String rc) { + this.major = major; + this.minor = minor; + this.micro = micro; + this.nano = nano; + this.rc = rc; + } /** * Creates a new version container from the specified native version structure. - * + * * @param version * The native version structure. */ public Version(final NativeVersion version) { - this.version = version; + this.major = version.major & 0xff; + this.minor = version.minor & 0xff; + this.micro = version.micro & 0xffff; + this.nano = version.nano & 0xffff; + this.rc = version.rc; } /** @@ -47,7 +127,7 @@ public Version(final NativeVersion version) { * @return The library major version. */ public int major() { - return this.version.major & 0xff; + return this.major; } /** @@ -56,7 +136,7 @@ public int major() { * @return The library minor version. */ public int minor() { - return this.version.minor & 0xff; + return this.minor; } /** @@ -65,7 +145,7 @@ public int minor() { * @return The library micro version. */ public int micro() { - return this.version.micro & 0xffff; + return this.micro; } /** @@ -74,7 +154,7 @@ public int micro() { * @return The library nano version. */ public int nano() { - return this.version.nano & 0xffff; + return this.nano; } /** @@ -83,13 +163,13 @@ public int nano() { * @return The release candidate suffix string. */ public String rc() { - return this.version.rc; + return this.rc; } - + @Override public int hashCode() { - return new HashCodeBuilder().append(this.major()).append(this.minor()).append(this.micro()).append(this.nano()) - .append(this.rc()).toHashCode(); + return new HashCodeBuilder().append(this.major).append(this.minor).append(this.micro).append(this.nano) + .append(this.rc).toHashCode(); } @Override @@ -106,13 +186,45 @@ public boolean equals(final Object obj) { final Version other = (Version) obj; - return new EqualsBuilder().append(this.major(), other.major()).append(this.minor(), other.minor()) - .append(this.micro(), other.micro()).append(this.nano(), other.nano()).append(this.rc(), other.rc()) - .isEquals(); + return new EqualsBuilder().append(this.major, other.major).append(this.minor, other.minor) + .append(this.micro, other.micro).append(this.nano, other.nano).append(this.rc, other.rc).isEquals(); } @Override public String toString() { - return this.major() + "." + this.minor() + "." + this.micro() + "." + this.nano() + this.rc(); + return this.major + "." + this.minor + "." + this.micro + "." + this.nano + this.rc; + } + + @Override + public int compareTo(final Version other) { + if (this.major > other.major) { + return 1; + } + if (this.major < other.major) { + return -1; + } + if (this.minor > other.minor) { + return 1; + } + if (this.minor < other.minor) { + return -1; + } + if (this.micro > other.micro) { + return 1; + } + if (this.micro < other.micro) { + return -1; + } + if (this.nano > other.nano) { + return 1; + } + if (this.nano < other.nano) { + return -1; + } + return 0; + } + + public boolean isOlderThan(final Version other) { + return compareTo(other) < 0; } }