diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index 6885638..7e06536 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -8,6 +8,26 @@
Klaus Reimer
+
+
+ Using reunited libusb/libusbx 1.0.16 as backend.
+
+
+ Add new libusb constants: LOW_SPEED_OPERATION, FULL_SPEED_OPERATION,
+ HIGH_SPEED_OPERATION, SUPER_SPEED_OPERATION, BM_LPM_SUPPORT,
+ BM_LTM_SUPPORT, BT_WIRELESS_USB_DEVICE_CAPABILITY, BT_USB_2_0_EXTENSION,
+ BT_SS_USB_DEVICE_CAPABILITY, BT_CONTAINER_ID, CAP_HAS_HOTPLUG,
+ CAP_HAS_HID_ACCESS, CAP_SUPPORTS_DETACH_KERNEL_DRIVER, DT_BOS,
+ DT_DEVICE_CAPABILITY, DT_SS_ENDPOINT_COMPANION
+
+
+ Wrap new libusb methods: getPortNumbers, setAutoDetachKernelDriver,
+ setLocale, strError.
+
+
+ Implement support for SuperSpeed Endpoint Companion Descriptor.
+
+
Rewritten library to use libusb 1.0 as backend.
diff --git a/src/main/c/build/common.sh b/src/main/c/build/common.sh
index 3d78949..c9eca51 100644
--- a/src/main/c/build/common.sh
+++ b/src/main/c/build/common.sh
@@ -6,7 +6,7 @@ LIBUSB="libusbx"
LIBUSB_VERSION="1.0.16"
LIBUSB_RC="-rc8"
LIBUSBX_VERSION="1.0.16"
-LIBUSBX_RC="-rc3"
+LIBUSBX_RC=""
build()
{
diff --git a/src/main/c/src/EndpointDescriptor.h b/src/main/c/src/EndpointDescriptor.h
index 89d710a..74f9cf0 100644
--- a/src/main/c/src/EndpointDescriptor.h
+++ b/src/main/c/src/EndpointDescriptor.h
@@ -10,5 +10,7 @@
jobjectArray wrapEndpointDescriptors(JNIEnv*, int,
const struct libusb_endpoint_descriptor*);
+struct libusb_endpoint_descriptor* unwrapEndpointDescriptor(JNIEnv*,
+ jobject);
#endif
diff --git a/src/main/c/src/LibUsb.c b/src/main/c/src/LibUsb.c
index d7af386..1457020 100644
--- a/src/main/c/src/LibUsb.c
+++ b/src/main/c/src/LibUsb.c
@@ -21,6 +21,8 @@
#include "DeviceList.h"
#include "DeviceDescriptor.h"
#include "ConfigDescriptor.h"
+#include "EndpointDescriptor.h"
+#include "SSEndpointCompanionDescriptor.h"
#include "Transfer.h"
static JavaVM *jvm;
@@ -38,6 +40,17 @@ JNIEXPORT jobject JNICALL METHOD_NAME(LibUsb, getVersion)
return wrapVersion(env, libusb_get_version());
}
+/**
+ * int getApiVersion()
+ */
+JNIEXPORT jint JNICALL METHOD_NAME(LibUsb, getApiVersion)
+(
+ JNIEnv *env, jclass class
+)
+{
+ return LIBUSBX_API_VERSION;
+}
+
/**
* int init()
*/
@@ -502,6 +515,20 @@ JNIEXPORT jint JNICALL METHOD_NAME(LibUsb, attachKernelDriver)
return libusb_attach_kernel_driver(dev_handle, iface);
}
+/**
+ * int attachKernelDriver(DeviceHandle, int)
+ */
+JNIEXPORT jint JNICALL METHOD_NAME(LibUsb, setAutoDetachKernelDriver)
+(
+ JNIEnv *env, jclass class, jobject handle, jboolean enable
+)
+{
+ NOT_NULL(env, handle, return 0);
+ libusb_device_handle *dev_handle = unwrapDeviceHandle(env, handle);
+ if (!dev_handle) return 0;
+ return libusb_set_auto_detach_kernel_driver(dev_handle, enable);
+}
+
/**
* boolean hasCapability(int)
*/
@@ -524,6 +551,31 @@ JNIEXPORT jstring JNICALL METHOD_NAME(LibUsb, errorName)
return (*env)->NewStringUTF(env, libusb_error_name(code));
}
+/**
+ * int setLocale(string)
+ */
+JNIEXPORT jint JNICALL METHOD_NAME(LibUsb, setLocale)
+(
+ JNIEnv *env, jobject this, jstring locale
+)
+{
+ const char *nativeLocale = (*env)->GetStringUTFChars(env, locale, 0);
+ int result = libusb_setlocale(nativeLocale);
+ (*env)->ReleaseStringUTFChars(env, locale, nativeLocale);
+ return result;
+}
+
+/**
+ * string strError(int)
+ */
+JNIEXPORT jstring JNICALL METHOD_NAME(LibUsb, strError)
+(
+ JNIEnv *env, jobject this, jint code
+)
+{
+ return (*env)->NewStringUTF(env, libusb_strerror(code));
+}
+
/**
* int le16ToCpu(int)
*/
@@ -663,6 +715,45 @@ JNIEXPORT void JNICALL METHOD_NAME(LibUsb, freeConfigDescriptor)
resetConfigDescriptor(env, descriptor);
}
+/**
+ * int getSSEndpointCompanionDescriptor(Device, int, SSEndpointCompanionDescriptor)
+ */
+JNIEXPORT jint JNICALL METHOD_NAME(LibUsb, getSSEndpointCompanionDescriptor)
+(
+ JNIEnv *env, jclass class, jobject context, jobject endpointDescriptor,
+ jobject companionDescriptor
+)
+{
+ NOT_NULL(env, endpointDescriptor, return 0);
+ NOT_NULL(env, companionDescriptor, return 0);
+ libusb_context *ctx = unwrapContext(env, context);
+ struct libusb_endpoint_descriptor *endpoint_descriptor =
+ unwrapEndpointDescriptor(env, endpointDescriptor);
+ if (!endpoint_descriptor) return 0;
+ struct libusb_ss_endpoint_companion_descriptor *companion_descriptor;
+ int result = libusb_get_ss_endpoint_companion_descriptor(ctx,
+ endpoint_descriptor, &companion_descriptor);
+ if (!result) setSSEndpointCompanionDescriptor(env, companion_descriptor,
+ companionDescriptor);
+ return result;
+}
+
+/**
+ * void freeSSEndpointCompanionDescriptor(SSEndpointCompanionDescriptor)
+ */
+JNIEXPORT void JNICALL METHOD_NAME(LibUsb, freeSSEndpointCompanionDescriptor)
+(
+ JNIEnv *env, jclass class, jobject companionDescriptor
+)
+{
+ if (!companionDescriptor) return;
+ struct libusb_ss_endpoint_companion_descriptor *companion_descriptor =
+ unwrapSSEndpointCompanionDescriptor(env, companionDescriptor);
+ if (!companion_descriptor) return;
+ libusb_free_ss_endpoint_companion_descriptor(companion_descriptor);
+ resetSSEndpointCompanionDescriptor(env, companionDescriptor);
+}
+
/**
* int getDescriptor(DeviceHandle, int, int, ByteBuffer)
*/
diff --git a/src/main/c/src/Makefile.am b/src/main/c/src/Makefile.am
index 9be6ead..087404a 100644
--- a/src/main/c/src/Makefile.am
+++ b/src/main/c/src/Makefile.am
@@ -17,4 +17,5 @@ libusb4java_la_SOURCES = \
Interface.c \
InterfaceDescriptor.c \
EndpointDescriptor.c \
- Transfer.c
\ No newline at end of file
+ Transfer.c \
+ SSEndpointCompanionDescriptor.c
\ No newline at end of file
diff --git a/src/main/c/src/SSEndpointCompanionDescriptor.c b/src/main/c/src/SSEndpointCompanionDescriptor.c
new file mode 100644
index 0000000..f8b0755
--- /dev/null
+++ b/src/main/c/src/SSEndpointCompanionDescriptor.c
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2013 Klaus Reimer (k@ailis.de)
+ * See COPYING file for copying conditions
+ */
+
+#include "SSEndpointCompanionDescriptor.h"
+#include "Interface.h"
+
+void setSSEndpointCompanionDescriptor(JNIEnv* env,
+ struct libusb_ss_endpoint_companion_descriptor* descriptor, jobject object)
+{
+ SET_POINTER(env, descriptor, object, "ssEndpointCompanionDescriptor");
+}
+
+struct libusb_ss_endpoint_companion_descriptor*
+ unwrapSSEndpointCompanionDescriptor(JNIEnv* env, jobject descriptor)
+{
+ UNWRAP_POINTER(env, descriptor,
+ struct libusb_ss_endpoint_companion_descriptor*,
+ "ssEndpointCompanionDescriptor");
+}
+
+void resetSSEndpointCompanionDescriptor(JNIEnv* env, jobject obj)
+{
+ RESET_POINTER(env, obj, "ssEndpointCompanionDescriptor");
+}
+
+/**
+ * byte bLength()
+ */
+JNIEXPORT jbyte JNICALL METHOD_NAME(SSEndpointCompanionDescriptor, bLength)
+(
+ JNIEnv *env, jobject this
+)
+{
+ struct libusb_ss_endpoint_companion_descriptor *descriptor =
+ unwrapSSEndpointCompanionDescriptor(env, this);
+ if (!descriptor) return 0;
+ return descriptor->bLength;
+}
+
+/**
+ * byte bDescriptorType()
+ */
+JNIEXPORT jbyte JNICALL METHOD_NAME(SSEndpointCompanionDescriptor,
+ bDescriptorType)
+(
+ JNIEnv *env, jobject this
+)
+{
+ struct libusb_ss_endpoint_companion_descriptor *descriptor =
+ unwrapSSEndpointCompanionDescriptor(env, this);
+ if (!descriptor) return 0;
+ return descriptor->bDescriptorType;
+}
+
+/**
+ * byte bMaxBurst()
+ */
+JNIEXPORT jbyte JNICALL METHOD_NAME(SSEndpointCompanionDescriptor, bMaxBurst)
+(
+ JNIEnv *env, jobject this
+)
+{
+ struct libusb_ss_endpoint_companion_descriptor *descriptor =
+ unwrapSSEndpointCompanionDescriptor(env, this);
+ if (!descriptor) return 0;
+ return descriptor->bMaxBurst;
+}
+
+/**
+ * byte bmAttributes()
+ */
+JNIEXPORT jbyte JNICALL METHOD_NAME(SSEndpointCompanionDescriptor, bmAttributes)
+(
+ JNIEnv *env, jobject this
+)
+{
+ struct libusb_ss_endpoint_companion_descriptor *descriptor =
+ unwrapSSEndpointCompanionDescriptor(env, this);
+ if (!descriptor) return 0;
+ return descriptor->bmAttributes;
+}
+
+/**
+ * short wBytesPerInterval()
+ */
+JNIEXPORT jshort JNICALL METHOD_NAME(SSEndpointCompanionDescriptor, wBytesPerInterval)
+(
+ JNIEnv *env, jobject this
+)
+{
+ struct libusb_ss_endpoint_companion_descriptor *descriptor =
+ unwrapSSEndpointCompanionDescriptor(env, this);
+ if (!descriptor) return 0;
+ return descriptor->wBytesPerInterval;
+}
diff --git a/src/main/c/src/SSEndpointCompanionDescriptor.h b/src/main/c/src/SSEndpointCompanionDescriptor.h
new file mode 100644
index 0000000..58a71d6
--- /dev/null
+++ b/src/main/c/src/SSEndpointCompanionDescriptor.h
@@ -0,0 +1,17 @@
+/*
+ * Copyright (C) 2013 Klaus Reimer (k@ailis.de)
+ * See COPYING file for copying conditions
+ */
+
+#ifndef USB4JAVA_SS_ENDPOINT_COMPANION_DESCRIPTOR_H
+#define USB4JAVA_SS_ENDPOINT_COMPANION_DESCRIPTOR_H
+
+#include "usb4java.h"
+
+void setSSEndpointCompanionDescriptor(JNIEnv*,
+ struct libusb_ss_endpoint_companion_descriptor*, jobject);
+struct libusb_ss_endpoint_companion_descriptor*
+ unwrapSSEndpointCompanionDescriptor(JNIEnv*, jobject);
+void resetSSEndpointCompanionDescriptor(JNIEnv*, jobject);
+
+#endif
diff --git a/src/main/java/de/ailis/usb4java/libusb/LibUsb.java b/src/main/java/de/ailis/usb4java/libusb/LibUsb.java
index 3b5a760..208e065 100644
--- a/src/main/java/de/ailis/usb4java/libusb/LibUsb.java
+++ b/src/main/java/de/ailis/usb4java/libusb/LibUsb.java
@@ -107,27 +107,47 @@ public final class LibUsb
/** The device is operating at super speed (5000MBit/s). */
public static final int SPEED_SUPER = 4;
-
- // Supported speeds (wSpeedSupported) bitfield. Indicates what speeds the
- // device supports.
-
+
+ // Supported speeds (wSpeedSupported) bitfield. Indicates what speeds the
+ // device supports.
+
/** Low speed operation supported (1.5MBit/s). */
- public static final int LIBUSB_LOW_SPEED_OPERATION = 1;
+ public static final int LOW_SPEED_OPERATION = 1;
/** Full speed operation supported (12MBit/s). */
- public static final int LIBUSB_FULL_SPEED_OPERATION = 2;
+ public static final int FULL_SPEED_OPERATION = 2;
/** High speed operation supported (480MBit/s). */
- public static final int LIBUSB_HIGH_SPEED_OPERATION = 4;
+ public static final int HIGH_SPEED_OPERATION = 4;
- /** Superspeed operation supported (5000MBit/s). */
- public static final int LIBUSB_SUPER_SPEED_OPERATION = 8;
-
- // Masks for the bits of the bmAttributes field of the USB 2.0 Extension
+ /** Superspeed operation supported (5000MBit/s). */
+ public static final int SUPER_SPEED_OPERATION = 8;
+
+ // Masks for the bits of the bmAttributes field of the USB 2.0 Extension
// descriptor.
-
- /** Supports Link Power Management (LPM). */
- public static final int LIBUSB_BM_LPM_SUPPORT = 2;
+
+ /** Supports Link Power Management (LPM). */
+ public static final int BM_LPM_SUPPORT = 2;
+
+ // Masks for the bits of the bmAttributes field field of the SuperSpeed USB
+ // Device Capability descriptor.
+
+ /** Supports Latency Tolerance Messages (LTM). */
+ public static final int BM_LTM_SUPPORT = 2;
+
+ // USB capability types.
+
+ /** Wireless USB device capability. */
+ public static final int BT_WIRELESS_USB_DEVICE_CAPABILITY = 1;
+
+ /** USB 2.0 extensions. */
+ public static final int BT_USB_2_0_EXTENSION = 2;
+
+ /** SuperSpeed USB device capability. */
+ public static final int BT_SS_USB_DEVICE_CAPABILITY = 3;
+
+ /** Container ID type. */
+ public static final int BT_CONTAINER_ID = 4;
// Standard requests, as defined in table 9-5 of the USB 3.0 specifications.
@@ -202,11 +222,30 @@ public final class LibUsb
/** Other. */
public static final int RECIPIENT_OTHER = 0x03;
- // Capabilities supported by this instance of libusb. Test if the loaded
- // library supports a given capability by calling hasCapability().
+ // Capabilities supported by an instance of libusb on the current running
+ // platform. Test if the loaded library supports a given capability by
+ // calling {@link #hasCapability(int)}
- /** The hasCapability() API is available. */
- public static final int CAP_HAS_CAPABILITY = 0x00;
+ /** The {@link #hasCapability(int)} API is available. */
+ public static final int CAP_HAS_CAPABILITY = 0x0000;
+
+ /** Hotplug support is available on this platform. */
+ 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 libusbx 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.
+ */
+ public static final int CAP_SUPPORTS_DETACH_KERNEL_DRIVER = 0x0101;
// Device and/or Interface Class codes.
@@ -304,6 +343,20 @@ public final class LibUsb
*/
public static final int DT_ENDPOINT = 0x05;
+ /**
+ * BOS descriptor.
+ *
+ * @see BOSDescriptor
+ */
+ public static final int DT_BOS = 0x0f;
+
+ /**
+ * Device Capability descriptor.
+ *
+ * @see BosDevCapabilityDescriptor
+ */
+ public static final int DT_DEVICE_CAPABILITY = 0x10;
+
/** HID descriptor. */
public static final int DT_HID = 0x21;
@@ -316,9 +369,16 @@ public final class LibUsb
/** Hub descriptor. */
public static final int DT_HUB = 0x29;
- /** Hub descriptor. */
+ /** SuperSpeed Hub descriptor. */
public static final int DT_SUPERSPEED_HUB = 0x2a;
+ /**
+ * SuperSpeed Endpoint Companion descriptor.
+ *
+ * @see SSEndpointCompanionDescriptor
+ */
+ public static final int DT_SS_ENDPOINT_COMPANION = 0x30;
+
// Descriptor sizes per descriptor type
/** Size of a device descriptor. */
@@ -497,6 +557,14 @@ public final class LibUsb
// Empty
}
+ /**
+ * 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.
+ */
+ public static native int getApiVersion();
+
/**
* Initialize libusb.
*
@@ -633,9 +701,29 @@ public final class LibUsb
* @return The number of elements filled, {@link #ERROR_OVERFLOW} if the
* array is too small
*/
- public static native int getPortNumbers(final Device device,
+ public static native int getPortNumbers(final Device device,
final byte[] path);
+ /**
+ * @deprecated Please use {@link #getPortNumbers(Device, byte[])} 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
+ */
+ @Deprecated
+ public static int getPortPaths(final Context context,
+ final Device device, final byte[] path)
+ {
+ return getPortNumbers(device, path);
+ }
+
/**
* Get the the parent from the specified device [EXPERIMENTAL].
*
@@ -1081,6 +1169,30 @@ public final class LibUsb
public static native int attachKernelDriver(final DeviceHandle handle,
final int interfaceNumber);
+ /**
+ * Enable/disable libusbx's automatic kernel driver detachment.
+ *
+ * When this is enabled libusbx 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.
+ *
+ * On platforms which do not have {@link #CAP_SUPPORTS_DETACH_KERNEL_DRIVER}
+ * this function will return {@link #ERROR_NOT_SUPPORTED}, and libusbx 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.
+ */
+ public static native int setAutoDetachKernelDriver(
+ final DeviceHandle handle, final boolean enable);
+
/**
* Check at runtime if the loaded library has a given capability.
*
@@ -1102,6 +1214,49 @@ public final class LibUsb
*/
public static native String errorName(final int errorCode);
+ /**
+ * 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.
+ *
+ * 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.
+ *
+ * @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.
+ */
+ public static native int setLocale(final String 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)}.
+ *
+ * The messages always start with a capital letter and end without any dot.
+ *
+ * @param errcode
+ * The error code whose description is desired.
+ * @return A short description of the error code.
+ */
+ public static native String strError(final int errcode);
+
/**
* Convert a 16-bit value from little-endian to host-endian format.
*
@@ -1268,6 +1423,40 @@ public final class LibUsb
public static native void freeConfigDescriptor(
final ConfigDescriptor descriptor);
+ /**
+ * Get an endpoints superspeed endpoint companion descriptor (if any)
+ *
+ * @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.
+ * @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
+ */
+ 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)}
+ * .
+ *
+ * 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);
+
/**
* Retrieve a descriptor from the default control pipe.
*
diff --git a/src/main/java/de/ailis/usb4java/libusb/LibUsbException.java b/src/main/java/de/ailis/usb4java/libusb/LibUsbException.java
index d4af9fe..a59a084 100644
--- a/src/main/java/de/ailis/usb4java/libusb/LibUsbException.java
+++ b/src/main/java/de/ailis/usb4java/libusb/LibUsbException.java
@@ -31,7 +31,7 @@ public final class LibUsbException extends UsbException
public LibUsbException(final String message, final int errorCode)
{
super(String.format("USB error %d: %s: %s", -errorCode, message,
- LibUsb.errorName(errorCode)));
+ LibUsb.strError(errorCode)));
this.errorCode = errorCode;
}
diff --git a/src/main/java/de/ailis/usb4java/libusb/SSEndpointCompanionDescriptor.java b/src/main/java/de/ailis/usb4java/libusb/SSEndpointCompanionDescriptor.java
new file mode 100644
index 0000000..d37129a
--- /dev/null
+++ b/src/main/java/de/ailis/usb4java/libusb/SSEndpointCompanionDescriptor.java
@@ -0,0 +1,143 @@
+/*
+ * Copyright 2013 Klaus Reimer
+ * See LICENSE.md for licensing information.
+ *
+ * Based on libusbx :
+ *
+ * Copyright 2001 Johannes Erdfelt
+ * Copyright 2007-2008 Daniel Drake
+ * Copyright 2012 Pete Batard
+ */
+
+package de.ailis.usb4java.libusb;
+
+import org.apache.commons.lang3.builder.EqualsBuilder;
+import org.apache.commons.lang3.builder.HashCodeBuilder;
+
+/**
+ * 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 SSEndpointCompanionDescriptor
+{
+ /** The native pointer to the descriptor structure. */
+ private long ssEndpointCompanionDescriptor;
+
+ /**
+ * Constructs a new descriptor which can be passed to the
+ * {@link LibUsb#getSSEndpointCompanionDescriptor(Context, EndpointDescriptor, SSEndpointCompanionDescriptor)}
+ * method.
+ */
+ public SSEndpointCompanionDescriptor()
+ {
+ // Empty
+ }
+
+ /**
+ * Returns the native pointer.
+ *
+ * @return The native pointer.
+ */
+ public long getPointer()
+ {
+ return this.ssEndpointCompanionDescriptor;
+ }
+
+ /**
+ * Returns the size of this descriptor (in bytes).
+ *
+ * @return The descriptor size in bytes;
+ */
+ public native byte bLength();
+
+ /**
+ * Returns the descriptor type.
+ *
+ * @return The descriptor type.
+ */
+ public native byte bDescriptorType();
+
+ /**
+ * Returns the maximum number of packets the endpoint can send or receive as
+ * part of a burst.
+ *
+ * @return The maximum number of packets as part of a burst.
+ */
+ public native byte bMaxBurst();
+
+ /**
+ * Returns 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
+ *
+ * @return The attributes.
+ */
+ public native byte bmAttributes();
+
+ /**
+ * Returns the total number of bytes this endpoint will transfer every
+ * service interval. Valid only for periodic endpoints.
+ *
+ * @return The total number of bytes per service interval.
+ */
+ public native short wBytesPerInterval();
+
+ /**
+ * Returns a dump of this descriptor.
+ *
+ * @return The descriptor dump.
+ */
+ public String dump()
+ {
+ return String.format("Device Descriptor:%n"
+ + " bLength %18d%n"
+ + " bDescriptorType %10d%n"
+ + " bMaxBurst %19s%n"
+ + " bmAttributes %13d %s%n"
+ + " wBytesPerInterval %10d",
+ bLength() & 0xff,
+ bDescriptorType() & 0xff,
+ bMaxBurst() & 0xff,
+ bmAttributes() & 0xff,
+ wBytesPerInterval() & 0xffff);
+ }
+
+ @Override
+ public boolean equals(final Object obj)
+ {
+ if (obj == null) return false;
+ if (obj == this) return true;
+ if (obj.getClass() != getClass()) return false;
+ final SSEndpointCompanionDescriptor other =
+ (SSEndpointCompanionDescriptor) obj;
+ return new EqualsBuilder()
+ .append(bDescriptorType(), other.bDescriptorType())
+ .append(bLength(), other.bLength())
+ .append(bMaxBurst(), other.bMaxBurst())
+ .append(bmAttributes(), other.bmAttributes())
+ .append(wBytesPerInterval(), other.wBytesPerInterval()).isEquals();
+ }
+
+ @Override
+ public int hashCode()
+ {
+ return new HashCodeBuilder()
+ .append(bLength())
+ .append(bDescriptorType())
+ .append(bMaxBurst())
+ .append(bmAttributes())
+ .append(wBytesPerInterval())
+ .toHashCode();
+ }
+
+ @Override
+ public String toString()
+ {
+ return dump();
+ }
+}
diff --git a/src/test/java/de/ailis/usb4java/libusb/LibUSBGlobalTest.java b/src/test/java/de/ailis/usb4java/libusb/LibUSBGlobalTest.java
index eb8b2d6..1236b9c 100644
--- a/src/test/java/de/ailis/usb4java/libusb/LibUSBGlobalTest.java
+++ b/src/test/java/de/ailis/usb4java/libusb/LibUSBGlobalTest.java
@@ -133,4 +133,27 @@ public class LibUSBGlobalTest
assertEquals("LIBUSB_ERROR_IO", LibUsb.errorName(LibUsb.ERROR_IO));
assertEquals("**UNKNOWN**", LibUsb.errorName(0x1234));
}
+
+ /**
+ * Tests the {@link LibUsb#strError(int)} method.
+ */
+ @Test
+ public void testStrError()
+ {
+ assumeUsbTestsEnabled();
+ assertEquals("Input/Output Error", LibUsb.strError(LibUsb.ERROR_IO));
+ assertEquals("Other error", LibUsb.strError(0x1234));
+ }
+
+ /**
+ * Tests the {@link LibUsb#setLocale(String)} method.
+ */
+ @Test
+ public void testSetLocale()
+ {
+ assumeUsbTestsEnabled();
+ assertEquals(LibUsb.SUCCESS, LibUsb.setLocale("en"));
+ assertEquals(LibUsb.ERROR_NOT_FOUND, LibUsb.setLocale("zz"));
+ assertEquals(LibUsb.ERROR_INVALID_PARAM, LibUsb.setLocale("zzz"));
+ }
}
diff --git a/src/test/java/de/ailis/usb4java/libusb/LibUSBTest.java b/src/test/java/de/ailis/usb4java/libusb/LibUSBTest.java
index a19053c..c2291ce 100644
--- a/src/test/java/de/ailis/usb4java/libusb/LibUSBTest.java
+++ b/src/test/java/de/ailis/usb4java/libusb/LibUSBTest.java
@@ -165,6 +165,16 @@ public class LibUSBTest
assertTrue(version.toString().startsWith("1.0."));
}
+ /**
+ * Tests the {@link LibUsb#getApiVersion()} method.
+ */
+ @Test
+ public void testGetApiVersion()
+ {
+ assumeUsbTestsEnabled();
+ assertTrue(LibUsb.getApiVersion() >= 0x1000102);
+ }
+
/**
* Tests the initialization and deinitialization of libusb with default
* context.
@@ -175,7 +185,7 @@ public class LibUSBTest
assumeUsbTestsEnabled();
assertEquals(LibUsb.SUCCESS, LibUsb.init(null));
LibUsb.exit(null);
-
+
try
{
// Double-exit should throw exception
@@ -185,7 +195,7 @@ public class LibUSBTest
catch (IllegalStateException e)
{
// Expected behavior
- }
+ }
}
/**
@@ -199,7 +209,7 @@ public class LibUSBTest
Context context = new Context();
assertEquals(LibUsb.SUCCESS, LibUsb.init(context));
LibUsb.exit(context);
-
+
try
{
LibUsb.exit(context);
@@ -530,6 +540,28 @@ public class LibUSBTest
LibUsb.attachKernelDriver(new DeviceHandle(), 0);
}
+ /**
+ * Tests the {@link LibUsb#setAutoDetachKernelDriver(DeviceHandle, boolean)}
+ * method with uninitialized device handle.
+ */
+ @Test(expected = IllegalStateException.class)
+ public void testSetAutoDetachKernelDriverWithUninitializedHandle()
+ {
+ assumeUsbTestsEnabled();
+ LibUsb.setAutoDetachKernelDriver(new DeviceHandle(), true);
+ }
+
+ /**
+ * Tests the {@link LibUsb#setAutoDetachKernelDriver(DeviceHandle, boolean)}
+ * method without a device handle.
+ */
+ @Test(expected = IllegalArgumentException.class)
+ public void testSetAutoDetachKernelDriverWithoutHandle()
+ {
+ assumeUsbTestsEnabled();
+ LibUsb.setAutoDetachKernelDriver(null, true);
+ }
+
/**
* Tests the {@link LibUsb#getDeviceDescriptor(Device, DeviceDescriptor)}
* method with uninitialized device.
@@ -602,6 +634,56 @@ public class LibUSBTest
LibUsb.freeConfigDescriptor(new ConfigDescriptor());
}
+ /**
+ * Tests the
+ * {@link LibUsb#getSSEndpointCompanionDescriptor(Context, EndpointDescriptor, SSEndpointCompanionDescriptor)}
+ * method with uninitialized endpoint.
+ */
+ @Test(expected = IllegalStateException.class)
+ public void testGetSSEndpointCompanionDescriptorWithUninitializedEndpoint()
+ {
+ assumeUsbTestsEnabled();
+ LibUsb.getSSEndpointCompanionDescriptor(null, new EndpointDescriptor(),
+ new SSEndpointCompanionDescriptor());
+ }
+
+ /**
+ * Tests the
+ * {@link LibUsb#getSSEndpointCompanionDescriptor(Context, EndpointDescriptor, SSEndpointCompanionDescriptor)}
+ * method without descriptors.
+ */
+ @Test(expected = IllegalArgumentException.class)
+ public void testGetSSEndpointCompanionDescriptorWithoutDescriptors()
+ {
+ assumeUsbTestsEnabled();
+ LibUsb.getSSEndpointCompanionDescriptor(null, null, null);
+ }
+
+ /**
+ * Tests the
+ * {@link LibUsb#freeSSEndpointCompanionDescriptor(SSEndpointCompanionDescriptor)}
+ * method with uninitialized descriptor.
+ */
+ @Test(expected = IllegalStateException.class)
+ public void testFreeSSEndpointCompanionDescriptorWithUninitializedDescriptor()
+ {
+ assumeUsbTestsEnabled();
+ LibUsb.freeSSEndpointCompanionDescriptor(new SSEndpointCompanionDescriptor());
+ }
+
+
+ /**
+ * Tests the
+ * {@link LibUsb#freeSSEndpointCompanionDescriptor(SSEndpointCompanionDescriptor)}
+ * method with null parameter. Must do nothing.
+ */
+ @Test
+ public void testFreeSSEndpointCompanionDescriptorWithNull()
+ {
+ assumeUsbTestsEnabled();
+ LibUsb.freeSSEndpointCompanionDescriptor(null);
+ }
+
/**
* Tests the
* {@link LibUsb#getDescriptor(DeviceHandle, int, int, ByteBuffer)} method