diff --git a/src/main/c/.gitignore b/src/main/c/.gitignore index 724070f..a7a2d38 100644 --- a/src/main/c/.gitignore +++ b/src/main/c/.gitignore @@ -24,3 +24,5 @@ install-sh ltmain.sh m4 missing +ar-lib +compile diff --git a/src/main/c/build/common.sh b/src/main/c/build/common.sh index c9eca51..f477ef3 100644 --- a/src/main/c/build/common.sh +++ b/src/main/c/build/common.sh @@ -2,27 +2,28 @@ cd "$(dirname $0)" SRCDIR="$(pwd)/.." TMPDIR="$SRCDIR/tmp" DOWNLOADS="$SRCDIR/downloads" -LIBUSB="libusbx" -LIBUSB_VERSION="1.0.16" -LIBUSB_RC="-rc8" -LIBUSBX_VERSION="1.0.16" -LIBUSBX_RC="" + +LIBUSB="stable" +LIBUSB_STABLE_VERSION="1.0.16" +LIBUSB_STABLE_RC="" +LIBUSB_BETA_VERSION="1.0.16" +LIBUSB_BETA_RC="-rc3" build() { - if [ "$LIBUSB" = "libusbx" ] + if [ "$LIBUSB" = "stable" ] then - LIBUSB_NAME="libusbx-$LIBUSBX_VERSION$LIBUSBX_RC" + LIBUSB_NAME="libusbx-$LIBUSB_STABLE_VERSION$LIBUSB_STABLE_RC" LIBUSB_ARCHIVE="$LIBUSB_NAME.tar.bz2" - LIBUSB_URL="http://downloads.sf.net/project/libusbx/releases/$LIBUSBX_VERSION/source/$LIBUSB_ARCHIVE" + LIBUSB_URL="http://downloads.sf.net/project/libusbx/releases/$LIBUSB_STABLE_VERSION/source/$LIBUSB_ARCHIVE" else - LIBUSB_NAME="libusb-$LIBUSB_VERSION$LIBUSB_RC" + LIBUSB_NAME="libusbx-$LIBUSB_BETA_VERSION$LIBUSB_BETA_RC" LIBUSB_ARCHIVE="$LIBUSB_NAME.tar.bz2" - LIBUSB_URL="http://downloads.sf.net/project/libusb/libusb-1.0/libusb-$LIBUSB_VERSION$LIBUSB_RC/$LIBUSB_ARCHIVE" + LIBUSB_URL="http://downloads.sf.net/project/libusbx/releases/$LIBUSB_BETA_VERSION/source/$LIBUSB_ARCHIVE" fi DISTDIR="$SRCDIR/../resources/de/ailis/usb4java/libusb/$OS-$ARCH" - + # Clean up rm -rf "$TMPDIR" rm -rf "$DISTDIR" @@ -62,7 +63,7 @@ build() CFLAGS="$CFLAGS $USB4JAVA_CFLAGS" \ ./configure --prefix=/ --host="$HOST" $USB4JAVA_CONFIG make clean install-strip DESTDIR="$TMPDIR" - + # Copy dist files to java resources directory mkdir -p "$DISTDIR" cp -faL 2>/dev/null \ diff --git a/src/main/c/build/linux-x86_64.sh b/src/main/c/build/linux-x86_64.sh index 9d25cb8..9d14f94 100755 --- a/src/main/c/build/linux-x86_64.sh +++ b/src/main/c/build/linux-x86_64.sh @@ -9,9 +9,8 @@ set -e OS="linux" ARCH="x86_64" HOST="$ARCH-$OS-gnu" -CFLAGS="-m64 -Wl,--wrap=memcpy" +CFLAGS="-m64" LIBUSB_CONFIG="--disable-shared --disable-udev" USB4JAVA_LIBS="-lrt" -USB4JAVA_CFLAGS="-DWRAP_MEMCPY" build diff --git a/src/main/c/build/osx-x86.sh b/src/main/c/build/osx-x86.sh index d265188..4636bf6 100755 --- a/src/main/c/build/osx-x86.sh +++ b/src/main/c/build/osx-x86.sh @@ -12,6 +12,5 @@ ARCH="x86" CFLAGS="-arch i686" LIBUSB_CONFIG="--disable-shared" USB4JAVA_LIBS="-lobjc -Wl,-framework,IOKit -Wl,-framework,CoreFoundation" -LIBUSB="libusb" build diff --git a/src/main/c/build/osx-x86_64.sh b/src/main/c/build/osx-x86_64.sh index b1278aa..b98186a 100755 --- a/src/main/c/build/osx-x86_64.sh +++ b/src/main/c/build/osx-x86_64.sh @@ -12,6 +12,5 @@ ARCH="x86_64" CFLAGS="-arch x86_64" LIBUSB_CONFIG="--disable-shared" USB4JAVA_LIBS="-lobjc -Wl,-framework,IOKit -Wl,-framework,CoreFoundation" -LIBUSB="libusb" build diff --git a/src/main/c/configure.ac b/src/main/c/configure.ac index 8e6a85a..8818253 100644 --- a/src/main/c/configure.ac +++ b/src/main/c/configure.ac @@ -1,13 +1,16 @@ AC_PREREQ([2.61]) AC_INIT([libusb4java], [1.0.0], [k@ailis.de]) -AM_INIT_AUTOMAKE([foreign -Wall -Wno-extra-portability -Werror]) +AM_INIT_AUTOMAKE([foreign -Wall -Werror]) +m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES(yes)]) AC_CONFIG_MACRO_DIR([m4]) AC_CONFIG_HEADERS([config.h]) AC_CONFIG_SRCDIR([src/usb4java.h]) AC_LANG_C AC_PROG_CC +AC_PROG_CC_STDC AM_PROG_LIBTOOL +m4_ifdef([AM_PROG_AR], [AM_PROG_AR]) AC_CHECK_JAVA AC_CHECK_SIZEOF([void *]) PKG_CHECK_MODULES([LIBUSB], [libusb-1.0]) diff --git a/src/main/c/src/ConfigDescriptor.c b/src/main/c/src/ConfigDescriptor.c index db49416..9a5e8d4 100644 --- a/src/main/c/src/ConfigDescriptor.c +++ b/src/main/c/src/ConfigDescriptor.c @@ -7,7 +7,7 @@ #include "Interface.h" void setConfigDescriptor(JNIEnv* env, - struct libusb_config_descriptor* descriptor, jobject object) + const struct libusb_config_descriptor* descriptor, jobject object) { SET_POINTER(env, descriptor, object, "configDescriptorPointer"); } @@ -35,7 +35,7 @@ JNIEXPORT jbyte JNICALL METHOD_NAME(ConfigDescriptor, bLength) struct libusb_config_descriptor *descriptor = unwrapConfigDescriptor(env, this); if (!descriptor) return 0; - return descriptor->bLength; + return (jbyte) descriptor->bLength; } /** @@ -49,7 +49,7 @@ JNIEXPORT jbyte JNICALL METHOD_NAME(ConfigDescriptor, bDescriptorType) struct libusb_config_descriptor *descriptor = unwrapConfigDescriptor(env, this); if (!descriptor) return 0; - return descriptor->bDescriptorType; + return (jbyte) descriptor->bDescriptorType; } /** @@ -63,7 +63,7 @@ JNIEXPORT jshort JNICALL METHOD_NAME(ConfigDescriptor, wTotalLength) struct libusb_config_descriptor *descriptor = unwrapConfigDescriptor(env, this); if (!descriptor) return 0; - return descriptor->wTotalLength; + return (jshort) descriptor->wTotalLength; } /** @@ -77,7 +77,7 @@ JNIEXPORT jbyte JNICALL METHOD_NAME(ConfigDescriptor, bNumInterfaces) struct libusb_config_descriptor *descriptor = unwrapConfigDescriptor(env, this); if (!descriptor) return 0; - return descriptor->bNumInterfaces; + return (jbyte) descriptor->bNumInterfaces; } /** @@ -91,7 +91,7 @@ JNIEXPORT jbyte JNICALL METHOD_NAME(ConfigDescriptor, bConfigurationValue) struct libusb_config_descriptor *descriptor = unwrapConfigDescriptor(env, this); if (!descriptor) return 0; - return descriptor->bConfigurationValue; + return (jbyte) descriptor->bConfigurationValue; } /** @@ -105,7 +105,7 @@ JNIEXPORT jbyte JNICALL METHOD_NAME(ConfigDescriptor, iConfiguration) struct libusb_config_descriptor *descriptor = unwrapConfigDescriptor(env, this); if (!descriptor) return 0; - return descriptor->iConfiguration; + return (jbyte) descriptor->iConfiguration; } /** @@ -119,7 +119,7 @@ JNIEXPORT jbyte JNICALL METHOD_NAME(ConfigDescriptor, bmAttributes) struct libusb_config_descriptor *descriptor = unwrapConfigDescriptor(env, this); if (!descriptor) return 0; - return descriptor->bmAttributes; + return (jbyte) descriptor->bmAttributes; } /** @@ -133,7 +133,7 @@ JNIEXPORT jbyte JNICALL METHOD_NAME(ConfigDescriptor, bMaxPower) struct libusb_config_descriptor *descriptor = unwrapConfigDescriptor(env, this); if (!descriptor) return 0; - return descriptor->MaxPower; + return (jbyte) descriptor->MaxPower; } /** @@ -162,8 +162,7 @@ JNIEXPORT jobject JNICALL METHOD_NAME(ConfigDescriptor, extra) struct libusb_config_descriptor *descriptor = unwrapConfigDescriptor(env, this); if (!descriptor) return NULL; - return (*env)->NewDirectByteBuffer(env, (void *) descriptor->extra, - descriptor->extra_length); + return NewDirectReadOnlyByteBuffer(env, descriptor->extra, descriptor->extra_length); } /** diff --git a/src/main/c/src/ConfigDescriptor.h b/src/main/c/src/ConfigDescriptor.h index b5d8bea..a7d2039 100644 --- a/src/main/c/src/ConfigDescriptor.h +++ b/src/main/c/src/ConfigDescriptor.h @@ -8,7 +8,7 @@ #include "usb4java.h" -void setConfigDescriptor(JNIEnv*, struct libusb_config_descriptor*, jobject); +void setConfigDescriptor(JNIEnv*, const struct libusb_config_descriptor*, jobject); struct libusb_config_descriptor* unwrapConfigDescriptor(JNIEnv*, jobject); void resetConfigDescriptor(JNIEnv*, jobject); diff --git a/src/main/c/src/Context.c b/src/main/c/src/Context.c index 5f98f03..cf43868 100644 --- a/src/main/c/src/Context.c +++ b/src/main/c/src/Context.c @@ -5,7 +5,7 @@ #include "Context.h" -void setContext(JNIEnv* env, libusb_context* context, jobject object) +void setContext(JNIEnv* env, const libusb_context* context, jobject object) { SET_POINTER(env, context, object, "contextPointer"); } diff --git a/src/main/c/src/Context.h b/src/main/c/src/Context.h index d348a1a..24c45c3 100644 --- a/src/main/c/src/Context.h +++ b/src/main/c/src/Context.h @@ -8,7 +8,7 @@ #include "usb4java.h" -void setContext(JNIEnv*, libusb_context*, jobject); +void setContext(JNIEnv*, const libusb_context*, jobject); libusb_context* unwrapContext(JNIEnv*, jobject); void resetContext(JNIEnv*, jobject); diff --git a/src/main/c/src/Device.c b/src/main/c/src/Device.c index ad05f85..f91ce28 100644 --- a/src/main/c/src/Device.c +++ b/src/main/c/src/Device.c @@ -5,7 +5,7 @@ #include "Device.h" -jobject wrapDevice(JNIEnv* env, libusb_device* device) +jobject wrapDevice(JNIEnv* env, const libusb_device* device) { WRAP_POINTER(env, device, "Device", "devicePointer"); } @@ -14,3 +14,8 @@ libusb_device* unwrapDevice(JNIEnv* env, jobject device) { UNWRAP_POINTER(env, device, libusb_device*, "devicePointer"); } + +void resetDevice(JNIEnv* env, jobject object) +{ + RESET_POINTER(env, object, "devicePointer"); +} diff --git a/src/main/c/src/Device.h b/src/main/c/src/Device.h index 9eea1a3..d6f2d2f 100644 --- a/src/main/c/src/Device.h +++ b/src/main/c/src/Device.h @@ -8,7 +8,8 @@ #include "usb4java.h" -jobject wrapDevice(JNIEnv*, libusb_device*); +jobject wrapDevice(JNIEnv*, const libusb_device*); libusb_device* unwrapDevice(JNIEnv*, jobject); +void resetDevice(JNIEnv*, jobject); #endif diff --git a/src/main/c/src/DeviceDescriptor.c b/src/main/c/src/DeviceDescriptor.c index 97a8b0c..3472897 100644 --- a/src/main/c/src/DeviceDescriptor.c +++ b/src/main/c/src/DeviceDescriptor.c @@ -6,17 +6,21 @@ #include "DeviceDescriptor.h" void setDeviceDescriptor(JNIEnv* env, - struct libusb_device_descriptor* descriptor, jobject object) + const struct libusb_device_descriptor* descriptor, jobject object) { - SET_DATA(env, descriptor, sizeof(struct libusb_device_descriptor), - object, "deviceDescriptorData"); + SET_POINTER(env, descriptor, object, "deviceDescriptorPointer"); } -struct libusb_device_descriptor* unwrapDeviceDescriptor(JNIEnv* env, - jobject descriptor) +struct libusb_device_descriptor* unwrapDeviceDescriptor(JNIEnv *env, + jobject obj) { - UNWRAP_DATA(env, descriptor, struct libusb_device_descriptor*, - "deviceDescriptorData"); + UNWRAP_POINTER(env, obj, struct libusb_device_descriptor*, + "deviceDescriptorPointer"); +} + +void resetDeviceDescriptor(JNIEnv* env, jobject obj) +{ + RESET_POINTER(env, obj, "deviceDescriptorPointer"); } /** @@ -30,7 +34,7 @@ JNIEXPORT jbyte JNICALL METHOD_NAME(DeviceDescriptor, bLength) struct libusb_device_descriptor* descriptor = unwrapDeviceDescriptor(env, this); if (!descriptor) return 0; - return descriptor->bLength; + return (jbyte) descriptor->bLength; } /** @@ -44,7 +48,7 @@ JNIEXPORT jbyte JNICALL METHOD_NAME(DeviceDescriptor, bDescriptorType) struct libusb_device_descriptor* descriptor = unwrapDeviceDescriptor(env, this); if (!descriptor) return 0; - return descriptor->bDescriptorType; + return (jbyte) descriptor->bDescriptorType; } /** @@ -58,7 +62,7 @@ JNIEXPORT jshort JNICALL METHOD_NAME(DeviceDescriptor, bcdUSB) struct libusb_device_descriptor* descriptor = unwrapDeviceDescriptor(env, this); if (!descriptor) return 0; - return descriptor->bcdUSB; + return (jshort) descriptor->bcdUSB; } /** @@ -72,7 +76,7 @@ JNIEXPORT jbyte JNICALL METHOD_NAME(DeviceDescriptor, bDeviceClass) struct libusb_device_descriptor* descriptor = unwrapDeviceDescriptor(env, this); if (!descriptor) return 0; - return descriptor->bDeviceClass; + return (jbyte) descriptor->bDeviceClass; } /** @@ -86,7 +90,7 @@ JNIEXPORT jbyte JNICALL METHOD_NAME(DeviceDescriptor, bDeviceSubClass) struct libusb_device_descriptor* descriptor = unwrapDeviceDescriptor(env, this); if (!descriptor) return 0; - return descriptor->bDeviceSubClass; + return (jbyte) descriptor->bDeviceSubClass; } /** @@ -100,7 +104,7 @@ JNIEXPORT jbyte JNICALL METHOD_NAME(DeviceDescriptor, bDeviceProtocol) struct libusb_device_descriptor* descriptor = unwrapDeviceDescriptor(env, this); if (!descriptor) return 0; - return descriptor->bDeviceProtocol; + return (jbyte) descriptor->bDeviceProtocol; } /** @@ -114,7 +118,7 @@ JNIEXPORT jbyte JNICALL METHOD_NAME(DeviceDescriptor, bMaxPacketSize0) struct libusb_device_descriptor* descriptor = unwrapDeviceDescriptor(env, this); if (!descriptor) return 0; - return descriptor->bMaxPacketSize0; + return (jbyte) descriptor->bMaxPacketSize0; } /** @@ -128,7 +132,7 @@ JNIEXPORT jshort JNICALL METHOD_NAME(DeviceDescriptor, idVendor) struct libusb_device_descriptor* descriptor = unwrapDeviceDescriptor(env, this); if (!descriptor) return 0; - return descriptor->idVendor; + return (jshort) descriptor->idVendor; } /** @@ -142,7 +146,7 @@ JNIEXPORT jshort JNICALL METHOD_NAME(DeviceDescriptor, idProduct) struct libusb_device_descriptor* descriptor = unwrapDeviceDescriptor(env, this); if (!descriptor) return 0; - return descriptor->idProduct; + return (jshort) descriptor->idProduct; } /** @@ -156,7 +160,7 @@ JNIEXPORT jshort JNICALL METHOD_NAME(DeviceDescriptor, bcdDevice) struct libusb_device_descriptor* descriptor = unwrapDeviceDescriptor(env, this); if (!descriptor) return 0; - return descriptor->bcdDevice; + return (jshort) descriptor->bcdDevice; } @@ -171,7 +175,7 @@ JNIEXPORT jbyte JNICALL METHOD_NAME(DeviceDescriptor, iManufacturer) struct libusb_device_descriptor* descriptor = unwrapDeviceDescriptor(env, this); if (!descriptor) return 0; - return descriptor->iManufacturer; + return (jbyte) descriptor->iManufacturer; } /** @@ -185,7 +189,7 @@ JNIEXPORT jbyte JNICALL METHOD_NAME(DeviceDescriptor, iProduct) struct libusb_device_descriptor* descriptor = unwrapDeviceDescriptor(env, this); if (!descriptor) return 0; - return descriptor->iProduct; + return (jbyte) descriptor->iProduct; } /** @@ -197,7 +201,7 @@ JNIEXPORT jbyte JNICALL METHOD_NAME(DeviceDescriptor, iSerialNumber) struct libusb_device_descriptor* descriptor = unwrapDeviceDescriptor(env, this); if (!descriptor) return 0; - return descriptor->iSerialNumber; + return (jbyte) descriptor->iSerialNumber; } /** @@ -211,5 +215,5 @@ JNIEXPORT jbyte JNICALL METHOD_NAME(DeviceDescriptor, bNumConfigurations) struct libusb_device_descriptor* descriptor = unwrapDeviceDescriptor(env, this); if (!descriptor) return 0; - return descriptor->bNumConfigurations; + return (jbyte) descriptor->bNumConfigurations; } diff --git a/src/main/c/src/DeviceDescriptor.h b/src/main/c/src/DeviceDescriptor.h index 857a1dd..faf66a7 100644 --- a/src/main/c/src/DeviceDescriptor.h +++ b/src/main/c/src/DeviceDescriptor.h @@ -8,7 +8,8 @@ #include "usb4java.h" -void setDeviceDescriptor(JNIEnv*, struct libusb_device_descriptor*, jobject); +void setDeviceDescriptor(JNIEnv*, const struct libusb_device_descriptor*, jobject); struct libusb_device_descriptor* unwrapDeviceDescriptor(JNIEnv*, jobject); +void resetDeviceDescriptor(JNIEnv*, jobject); #endif diff --git a/src/main/c/src/DeviceHandle.c b/src/main/c/src/DeviceHandle.c index 0de351b..2d06da0 100644 --- a/src/main/c/src/DeviceHandle.c +++ b/src/main/c/src/DeviceHandle.c @@ -5,19 +5,21 @@ #include "DeviceHandle.h" -void setDeviceHandle(JNIEnv* env, libusb_device_handle* deviceHandle, jobject object) +void setDeviceHandle(JNIEnv* env, const libusb_device_handle* deviceHandle, + jobject object) { SET_POINTER(env, deviceHandle, object, "deviceHandlePointer"); } -jobject wrapDeviceHandle(JNIEnv* env, libusb_device_handle* deviceHandle) +jobject wrapDeviceHandle(JNIEnv* env, const libusb_device_handle* deviceHandle) { WRAP_POINTER(env, deviceHandle, "DeviceHandle", "deviceHandlePointer"); } libusb_device_handle* unwrapDeviceHandle(JNIEnv* env, jobject deviceHandle) { - UNWRAP_POINTER(env, deviceHandle, libusb_device_handle*, "deviceHandlePointer"); + UNWRAP_POINTER(env, deviceHandle, libusb_device_handle*, + "deviceHandlePointer"); } void resetDeviceHandle(JNIEnv* env, jobject object) diff --git a/src/main/c/src/DeviceHandle.h b/src/main/c/src/DeviceHandle.h index 81ff999..c234d4f 100644 --- a/src/main/c/src/DeviceHandle.h +++ b/src/main/c/src/DeviceHandle.h @@ -8,8 +8,8 @@ #include "usb4java.h" -void setDeviceHandle(JNIEnv*, libusb_device_handle*, jobject); -jobject wrapDeviceHandle(JNIEnv*, libusb_device_handle*); +void setDeviceHandle(JNIEnv*, const libusb_device_handle*, jobject); +jobject wrapDeviceHandle(JNIEnv*, const libusb_device_handle*); libusb_device_handle* unwrapDeviceHandle(JNIEnv*, jobject); void resetDeviceHandle(JNIEnv*, jobject); diff --git a/src/main/c/src/DeviceList.c b/src/main/c/src/DeviceList.c index c51e339..cdbfe56 100644 --- a/src/main/c/src/DeviceList.c +++ b/src/main/c/src/DeviceList.c @@ -6,12 +6,12 @@ #include "DeviceList.h" #include "Device.h" -void setDeviceList(JNIEnv* env, libusb_device** list, int size, jobject object) +void setDeviceList(JNIEnv* env, libusb_device* const * list, jint size, jobject object) { SET_POINTER(env, list, object, "deviceListPointer"); - jclass cls = (*env)->GetObjectClass(env, object); - jfieldID field = (*env)->GetFieldID(env, cls, "size", "I"); + // We already have the class from the previous call. + field = (*env)->GetFieldID(env, cls, "size", "I"); (*env)->SetIntField(env, object, field, size); } @@ -23,6 +23,11 @@ libusb_device** unwrapDeviceList(JNIEnv* env, jobject list) void resetDeviceList(JNIEnv* env, jobject obj) { RESET_POINTER(env, obj, "deviceListPointer"); + + // We already have the class from the previous call. + // Reset size field to zero too. + field = (*env)->GetFieldID(env, cls, "size", "I"); + (*env)->SetIntField(env, obj, field, 0); } /** @@ -33,9 +38,13 @@ JNIEXPORT jobject JNICALL METHOD_NAME(DeviceList, get) JNIEnv *env, jobject this, jint index ) { + libusb_device **list = unwrapDeviceList(env, this); + if (!list) return NULL; + jclass cls = (*env)->GetObjectClass(env, this); jfieldID field = (*env)->GetFieldID(env, cls, "size", "I"); int size = (*env)->GetIntField(env, this, field); if (index < 0 || index >= size) return NULL; - return wrapDevice(env, unwrapDeviceList(env, this)[index]); + + return wrapDevice(env, list[index]); } diff --git a/src/main/c/src/DeviceList.h b/src/main/c/src/DeviceList.h index 79cf469..23df636 100644 --- a/src/main/c/src/DeviceList.h +++ b/src/main/c/src/DeviceList.h @@ -8,7 +8,7 @@ #include "usb4java.h" -void setDeviceList(JNIEnv*, libusb_device**, int, jobject); +void setDeviceList(JNIEnv*, libusb_device* const *, jint, jobject); libusb_device** unwrapDeviceList(JNIEnv*, jobject); void resetDeviceList(JNIEnv*, jobject); diff --git a/src/main/c/src/EndpointDescriptor.c b/src/main/c/src/EndpointDescriptor.c index 24c79c7..07fd399 100644 --- a/src/main/c/src/EndpointDescriptor.c +++ b/src/main/c/src/EndpointDescriptor.c @@ -14,14 +14,14 @@ jobject wrapEndpointDescriptor(JNIEnv *env, jobjectArray wrapEndpointDescriptors(JNIEnv *env, int count, const struct libusb_endpoint_descriptor *descriptors) { - int i; - jobjectArray array = (jobjectArray) (*env)->NewObjectArray(env, count, (*env)->FindClass(env, PACKAGE_DIR"/EndpointDescriptor"), NULL); - for (i = 0; i < count; i++) + + for (int i = 0; i < count; i++) (*env)->SetObjectArrayElement(env, array, i, wrapEndpointDescriptor(env, &descriptors[i])); + return array; } @@ -42,7 +42,7 @@ JNIEXPORT jbyte JNICALL METHOD_NAME(EndpointDescriptor, bLength) struct libusb_endpoint_descriptor* descriptor = unwrapEndpointDescriptor(env, this); if (!descriptor) return 0; - return descriptor->bLength; + return (jbyte) descriptor->bLength; } /** @@ -56,7 +56,7 @@ JNIEXPORT jbyte JNICALL METHOD_NAME(EndpointDescriptor, bDescriptorType) struct libusb_endpoint_descriptor* descriptor = unwrapEndpointDescriptor(env, this); if (!descriptor) return 0; - return descriptor->bDescriptorType; + return (jbyte) descriptor->bDescriptorType; } /** @@ -70,7 +70,7 @@ JNIEXPORT jbyte JNICALL METHOD_NAME(EndpointDescriptor, bEndpointAddress) struct libusb_endpoint_descriptor* descriptor = unwrapEndpointDescriptor(env, this); if (!descriptor) return 0; - return descriptor->bEndpointAddress; + return (jbyte) descriptor->bEndpointAddress; } /** @@ -84,7 +84,7 @@ JNIEXPORT jbyte JNICALL METHOD_NAME(EndpointDescriptor, bmAttributes) struct libusb_endpoint_descriptor* descriptor = unwrapEndpointDescriptor(env, this); if (!descriptor) return 0; - return descriptor->bmAttributes; + return (jbyte) descriptor->bmAttributes; } /** @@ -98,7 +98,7 @@ JNIEXPORT jshort JNICALL METHOD_NAME(EndpointDescriptor, wMaxPacketSize) struct libusb_endpoint_descriptor* descriptor = unwrapEndpointDescriptor(env, this); if (!descriptor) return 0; - return descriptor->wMaxPacketSize; + return (jshort) descriptor->wMaxPacketSize; } /** @@ -112,7 +112,7 @@ JNIEXPORT jbyte JNICALL METHOD_NAME(EndpointDescriptor, bInterval) struct libusb_endpoint_descriptor* descriptor = unwrapEndpointDescriptor(env, this); if (!descriptor) return 0; - return descriptor->bInterval; + return (jbyte) descriptor->bInterval; } /** @@ -126,13 +126,13 @@ JNIEXPORT jbyte JNICALL METHOD_NAME(EndpointDescriptor, bRefresh) struct libusb_endpoint_descriptor* descriptor = unwrapEndpointDescriptor(env, this); if (!descriptor) return 0; - return descriptor->bRefresh; + return (jbyte) descriptor->bRefresh; } /** * byte bSynchAddress() */ -JNIEXPORT jint JNICALL METHOD_NAME(EndpointDescriptor, bSynchAddress) +JNIEXPORT jbyte JNICALL METHOD_NAME(EndpointDescriptor, bSynchAddress) ( JNIEnv *env, jobject this ) @@ -140,7 +140,7 @@ JNIEXPORT jint JNICALL METHOD_NAME(EndpointDescriptor, bSynchAddress) struct libusb_endpoint_descriptor* descriptor = unwrapEndpointDescriptor(env, this); if (!descriptor) return 0; - return descriptor->bSynchAddress; + return (jbyte) descriptor->bSynchAddress; } /** @@ -154,8 +154,7 @@ JNIEXPORT jobject JNICALL METHOD_NAME(EndpointDescriptor, extra) struct libusb_endpoint_descriptor *descriptor = unwrapEndpointDescriptor(env, this); if (!descriptor) return NULL; - return (*env)->NewDirectByteBuffer(env, (void *) descriptor->extra, - descriptor->extra_length); + return NewDirectReadOnlyByteBuffer(env, descriptor->extra, descriptor->extra_length); } /** diff --git a/src/main/c/src/EndpointDescriptor.h b/src/main/c/src/EndpointDescriptor.h index 74f9cf0..e7c1f06 100644 --- a/src/main/c/src/EndpointDescriptor.h +++ b/src/main/c/src/EndpointDescriptor.h @@ -8,6 +8,8 @@ #include "usb4java.h" +jobject wrapEndpointDescriptor(JNIEnv*, + const struct libusb_endpoint_descriptor*); jobjectArray wrapEndpointDescriptors(JNIEnv*, int, const struct libusb_endpoint_descriptor*); struct libusb_endpoint_descriptor* unwrapEndpointDescriptor(JNIEnv*, diff --git a/src/main/c/src/Interface.c b/src/main/c/src/Interface.c index 7598150..a74d2c5 100644 --- a/src/main/c/src/Interface.c +++ b/src/main/c/src/Interface.c @@ -14,14 +14,13 @@ jobject wrapInterface(JNIEnv *env, const struct libusb_interface *iface) jobjectArray wrapInterfaces(JNIEnv *env, int count, const struct libusb_interface *interfaces) { - int i; - jobjectArray array = (jobjectArray) (*env)->NewObjectArray(env, count, (*env)->FindClass(env, PACKAGE_DIR"/Interface"), NULL); - for (i = 0; i < count; i++) + for (int i = 0; i < count; i++) (*env)->SetObjectArrayElement(env, array, i, wrapInterface(env, &interfaces[i])); + return array; } @@ -30,14 +29,14 @@ struct libusb_interface *unwrapInterface(JNIEnv *env, jobject obj) UNWRAP_POINTER(env, obj, struct libusb_interface*, "interfacePointer"); } -JNIEXPORT jshort JNICALL METHOD_NAME(Interface, numAltsetting) +JNIEXPORT jint JNICALL METHOD_NAME(Interface, numAltsetting) ( JNIEnv *env, jobject this ) { struct libusb_interface* interface = unwrapInterface(env, this); if (!interface) return 0; - return (jshort) interface->num_altsetting; + return interface->num_altsetting; } JNIEXPORT jobjectArray JNICALL METHOD_NAME(Interface, altsetting) diff --git a/src/main/c/src/Interface.h b/src/main/c/src/Interface.h index 60af22a..d9af0c1 100644 --- a/src/main/c/src/Interface.h +++ b/src/main/c/src/Interface.h @@ -8,7 +8,8 @@ #include "usb4java.h" -extern jobject wrapInterface(JNIEnv *, const struct libusb_interface *); -extern jobjectArray wrapInterfaces(JNIEnv *, int, const struct libusb_interface *); +jobject wrapInterface(JNIEnv *, const struct libusb_interface *); +jobjectArray wrapInterfaces(JNIEnv *, int, const struct libusb_interface *); +struct libusb_interface *unwrapInterface(JNIEnv *, jobject); #endif diff --git a/src/main/c/src/InterfaceDescriptor.c b/src/main/c/src/InterfaceDescriptor.c index dead0fd..4b993bb 100644 --- a/src/main/c/src/InterfaceDescriptor.c +++ b/src/main/c/src/InterfaceDescriptor.c @@ -17,14 +17,13 @@ jobject wrapInterfaceDescriptor(JNIEnv *env, jobjectArray wrapInterfaceDescriptors(JNIEnv *env, int count, const struct libusb_interface_descriptor *descriptors) { - int i; - jobjectArray array = (jobjectArray) (*env)->NewObjectArray(env, count, (*env)->FindClass(env, PACKAGE_DIR"/InterfaceDescriptor"), NULL); - for (i = 0; i < count; i++) + for (int i = 0; i < count; i++) (*env)->SetObjectArrayElement(env, array, i, wrapInterfaceDescriptor(env, &descriptors[i])); + return array; } @@ -46,7 +45,7 @@ JNIEXPORT jbyte JNICALL METHOD_NAME(InterfaceDescriptor, bLength) struct libusb_interface_descriptor* descriptor = unwrapInterfaceDescriptor(env, this); if (!descriptor) return 0; - return descriptor->bLength; + return (jbyte) descriptor->bLength; } /** @@ -60,7 +59,7 @@ JNIEXPORT jbyte JNICALL METHOD_NAME(InterfaceDescriptor, bDescriptorType) struct libusb_interface_descriptor* descriptor = unwrapInterfaceDescriptor(env, this); if (!descriptor) return 0; - return descriptor->bDescriptorType; + return (jbyte) descriptor->bDescriptorType; } /** @@ -74,7 +73,7 @@ JNIEXPORT jbyte JNICALL METHOD_NAME(InterfaceDescriptor, bInterfaceNumber) struct libusb_interface_descriptor* descriptor = unwrapInterfaceDescriptor(env, this); if (!descriptor) return 0; - return descriptor->bInterfaceNumber; + return (jbyte) descriptor->bInterfaceNumber; } /** @@ -88,7 +87,7 @@ JNIEXPORT jbyte JNICALL METHOD_NAME(InterfaceDescriptor, bAlternateSetting) struct libusb_interface_descriptor* descriptor = unwrapInterfaceDescriptor(env, this); if (!descriptor) return 0; - return descriptor->bAlternateSetting; + return (jbyte) descriptor->bAlternateSetting; } /** @@ -102,7 +101,7 @@ JNIEXPORT jbyte JNICALL METHOD_NAME(InterfaceDescriptor, bNumEndpoints) struct libusb_interface_descriptor* descriptor = unwrapInterfaceDescriptor(env, this); if (!descriptor) return 0; - return descriptor->bNumEndpoints; + return (jbyte) descriptor->bNumEndpoints; } /** @@ -116,7 +115,7 @@ JNIEXPORT jbyte JNICALL METHOD_NAME(InterfaceDescriptor, bInterfaceClass) struct libusb_interface_descriptor* descriptor = unwrapInterfaceDescriptor(env, this); if (!descriptor) return 0; - return descriptor->bInterfaceClass; + return (jbyte) descriptor->bInterfaceClass; } /** @@ -130,7 +129,7 @@ JNIEXPORT jbyte JNICALL METHOD_NAME(InterfaceDescriptor, bInterfaceSubClass) struct libusb_interface_descriptor* descriptor = unwrapInterfaceDescriptor(env, this); if (!descriptor) return 0; - return descriptor->bInterfaceSubClass; + return (jbyte) descriptor->bInterfaceSubClass; } /** @@ -144,7 +143,7 @@ JNIEXPORT jbyte JNICALL METHOD_NAME(InterfaceDescriptor, bInterfaceProtocol) struct libusb_interface_descriptor* descriptor = unwrapInterfaceDescriptor(env, this); if (!descriptor) return 0; - return descriptor->bInterfaceProtocol; + return (jbyte) descriptor->bInterfaceProtocol; } /** @@ -158,7 +157,7 @@ JNIEXPORT jbyte JNICALL METHOD_NAME(InterfaceDescriptor, iInterface) struct libusb_interface_descriptor* descriptor = unwrapInterfaceDescriptor(env, this); if (!descriptor) return 0; - return descriptor->iInterface; + return (jbyte) descriptor->iInterface; } /** @@ -187,7 +186,7 @@ JNIEXPORT jobject JNICALL METHOD_NAME(InterfaceDescriptor, extra) struct libusb_interface_descriptor *descriptor = unwrapInterfaceDescriptor(env, this); if (!descriptor) return NULL; - return (*env)->NewDirectByteBuffer(env, (void *) descriptor->extra, + return NewDirectReadOnlyByteBuffer(env, descriptor->extra, descriptor->extra_length); } diff --git a/src/main/c/src/InterfaceDescriptor.h b/src/main/c/src/InterfaceDescriptor.h index 9b99fbc..9ec8318 100644 --- a/src/main/c/src/InterfaceDescriptor.h +++ b/src/main/c/src/InterfaceDescriptor.h @@ -8,7 +8,10 @@ #include "usb4java.h" +jobject wrapInterfaceDescriptor(JNIEnv*, + const struct libusb_interface_descriptor*); jobjectArray wrapInterfaceDescriptors(JNIEnv*, int, const struct libusb_interface_descriptor*); +struct libusb_interface_descriptor *unwrapInterfaceDescriptor(JNIEnv*, jobject); #endif diff --git a/src/main/c/src/IsoPacketDescriptor.c b/src/main/c/src/IsoPacketDescriptor.c new file mode 100644 index 0000000..d1d3e39 --- /dev/null +++ b/src/main/c/src/IsoPacketDescriptor.c @@ -0,0 +1,88 @@ +#include "IsoPacketDescriptor.h" + +jobject wrapIsoPacketDescriptor(JNIEnv *env, + const struct libusb_iso_packet_descriptor *descriptor) +{ + WRAP_POINTER(env, descriptor, "IsoPacketDescriptor", + "isoPacketDescriptorPointer"); +} + +jobjectArray wrapIsoPacketDescriptors(JNIEnv *env, int count, + const struct libusb_iso_packet_descriptor *descriptors) +{ + jobjectArray array = (jobjectArray) (*env)->NewObjectArray(env, count, + (*env)->FindClass(env, PACKAGE_DIR"/IsoPacketDescriptor"), NULL); + + for (int i = 0; i < count; i++) + (*env)->SetObjectArrayElement(env, array, i, + wrapIsoPacketDescriptor(env, &descriptors[i])); + + return array; +} + +struct libusb_iso_packet_descriptor *unwrapIsoPacketDescriptor(JNIEnv *env, + jobject obj) +{ + UNWRAP_POINTER(env, obj, struct libusb_iso_packet_descriptor*, + "isoPacketDescriptorPointer"); +} + +/** + * int length() + */ +JNIEXPORT jint JNICALL METHOD_NAME(IsoPacketDescriptor, length) +( + JNIEnv *env, jobject this +) +{ + struct libusb_iso_packet_descriptor *isopacket = + unwrapIsoPacketDescriptor(env, this); + if (!isopacket) return 0; + + return (jint) isopacket->length; +} + +/** + * void setLength(int) + */ +JNIEXPORT void JNICALL METHOD_NAME(IsoPacketDescriptor, setLength) +( + JNIEnv *env, jobject this, jint length +) +{ + struct libusb_iso_packet_descriptor *isopacket = + unwrapIsoPacketDescriptor(env, this); + if (!isopacket) return; + + isopacket->length = (unsigned int) length; +} + +/** + * int actualLength() + */ +JNIEXPORT jint JNICALL METHOD_NAME(IsoPacketDescriptor, actualLength) +( + JNIEnv *env, jobject this +) +{ + struct libusb_iso_packet_descriptor *isopacket = + unwrapIsoPacketDescriptor(env, this); + if (!isopacket) return 0; + + return (jint) isopacket->actual_length; +} + +/** + * int status() + */ +JNIEXPORT jint JNICALL METHOD_NAME(IsoPacketDescriptor, status) +( + JNIEnv *env, jobject this +) +{ + struct libusb_iso_packet_descriptor *isopacket = + unwrapIsoPacketDescriptor(env, this); + if (!isopacket) return 0; + + return isopacket->status; +} diff --git a/src/main/c/src/IsoPacketDescriptor.h b/src/main/c/src/IsoPacketDescriptor.h new file mode 100644 index 0000000..4057dd1 --- /dev/null +++ b/src/main/c/src/IsoPacketDescriptor.h @@ -0,0 +1,12 @@ +#ifndef USB4JAVA_ISO_PACKET_DESCRIPTOR_H +#define USB4JAVA_ISO_PACKET_DESCRIPTOR_H + +#include "usb4java.h" + +jobject wrapIsoPacketDescriptor(JNIEnv*, + const struct libusb_iso_packet_descriptor*); +jobjectArray wrapIsoPacketDescriptors(JNIEnv*, int, + const struct libusb_iso_packet_descriptor*); +struct libusb_iso_packet_descriptor *unwrapIsoPacketDescriptor(JNIEnv*, jobject); + +#endif diff --git a/src/main/c/src/LibUsb.c b/src/main/c/src/LibUsb.c index af18231..387b752 100644 --- a/src/main/c/src/LibUsb.c +++ b/src/main/c/src/LibUsb.c @@ -30,9 +30,7 @@ #include "ContainerIdDescriptor.h" #include "Transfer.h" -static JavaVM *jvm; - -static int defaultContextInitialized = 0; +static int defaultContextRefcnt = 0; /** * Version getVersion() @@ -57,7 +55,7 @@ JNIEXPORT jint JNICALL METHOD_NAME(LibUsb, getApiVersion) } /** - * int init() + * int init(Context) */ JNIEXPORT jint JNICALL METHOD_NAME(LibUsb, init) ( @@ -66,44 +64,50 @@ JNIEXPORT jint JNICALL METHOD_NAME(LibUsb, init) { if (!context) { - if (defaultContextInitialized) - { - return illegalState(env, "Default context already initialized"); - } int result = libusb_init(NULL); - if (!result) defaultContextInitialized = 1; + if (result == LIBUSB_SUCCESS) defaultContextRefcnt++; return result; } else { + NOT_SET(env, context, "contextPointer", return 0); + libusb_context *ctx; int result = libusb_init(&ctx); - setContext(env, ctx, context); + if (result == LIBUSB_SUCCESS) setContext(env, ctx, context); return result; } } /** - * void exit() + * void exit(Context) */ JNIEXPORT void JNICALL METHOD_NAME(LibUsb, exit) ( JNIEnv *env, jclass class, jobject context ) { - struct libusb_context *ctx = unwrapContext(env, context); - if (!ctx && context) return; - - if (!context && !defaultContextInitialized) + if (!context) { - illegalState(env, "Default context not initialized"); - return; + if (defaultContextRefcnt <= 0) + { + illegalState(env, "default context is not initialized"); + return; + } + + libusb_exit(NULL); + + defaultContextRefcnt--; } - libusb_exit(ctx); - if (context) - resetContext(env, context); else - defaultContextInitialized = 0; + { + libusb_context *ctx = unwrapContext(env, context); + if (!ctx) return; + + libusb_exit(ctx); + + resetContext(env, context); + } } /** @@ -114,7 +118,7 @@ JNIEXPORT void JNICALL METHOD_NAME(LibUsb, setDebug) JNIEnv *env, jclass class, jobject context, jint level ) { - struct libusb_context *ctx = unwrapContext(env, context); + libusb_context *ctx = unwrapContext(env, context); if (!ctx && context) return; libusb_set_debug(ctx, level); } @@ -128,12 +132,13 @@ JNIEXPORT jint JNICALL METHOD_NAME(LibUsb, getDeviceList) ) { NOT_NULL(env, deviceList, return 0); - struct libusb_context *ctx = unwrapContext(env, context); + NOT_SET(env, deviceList, "deviceListPointer", return 0); + libusb_context *ctx = unwrapContext(env, context); if (!ctx && context) return 0; libusb_device **list; ssize_t result = libusb_get_device_list(ctx, &list); - if (result >= 0) setDeviceList(env, list, result, deviceList); - return result; + if (result >= 0) setDeviceList(env, list, (jint) result, deviceList); + return (jint) result; } /** @@ -180,26 +185,24 @@ JNIEXPORT jint JNICALL METHOD_NAME(LibUsb, getPortNumber) } /** - * int getPortNumbers(Device, byte[]) + * int getPortNumbers(Device, ByteBuffer) */ JNIEXPORT jint JNICALL METHOD_NAME(LibUsb, getPortNumbers) ( - JNIEnv *env, jclass class, jobject device, jbyteArray path + JNIEnv *env, jclass class, jobject device, jobject path ) { NOT_NULL(env, device, return 0); NOT_NULL(env, path, return 0); + DIRECT_BUFFER(env, path, path_ptr, return 0); libusb_device *dev = unwrapDevice(env, device); if (!dev) return 0; - jsize size = (*env)->GetArrayLength(env, path); - unsigned char buffer[size]; - int result = libusb_get_port_numbers(dev, buffer, size); - if (result > 0) (*env)->SetByteArrayRegion(env, path, 0, result, (jbyte *) buffer); - return result; + jlong path_size = (*env)->GetDirectBufferCapacity(env, path); + return libusb_get_port_numbers(dev, path_ptr, path_size); } /** - * int getPortNumber(Device) + * Device getParent(Device) */ JNIEXPORT jobject JNICALL METHOD_NAME(LibUsb, getParent) ( @@ -209,11 +212,7 @@ JNIEXPORT jobject JNICALL METHOD_NAME(LibUsb, getParent) NOT_NULL(env, device, return NULL); libusb_device *dev = unwrapDevice(env, device); if (!dev) return NULL; - #if defined(LIBUSBX_API_VERSION) - return wrapDevice(env, libusb_get_parent(dev)); - #else - return NULL; - #endif + return wrapDevice(env, libusb_get_parent(dev)); } /** @@ -245,31 +244,33 @@ JNIEXPORT jint JNICALL METHOD_NAME(LibUsb, getDeviceSpeed) } /** - * int getMaxPacketSize(Device, int) + * int getMaxPacketSize(Device, byte) */ JNIEXPORT jint JNICALL METHOD_NAME(LibUsb, getMaxPacketSize) ( - JNIEnv *env, jclass class, jobject device, jint endpoint + JNIEnv *env, jclass class, jobject device, jbyte endpoint ) { NOT_NULL(env, device, return 0); libusb_device *dev = unwrapDevice(env, device); if (!dev) return 0; - return libusb_get_max_packet_size(dev, endpoint); + + return libusb_get_max_packet_size(dev, (unsigned char) endpoint); } /** - * int getMaxIsoPacketSize(Device, int) + * int getMaxIsoPacketSize(Device, byte) */ JNIEXPORT jint JNICALL METHOD_NAME(LibUsb, getMaxIsoPacketSize) ( - JNIEnv *env, jclass class, jobject device, jint endpoint + JNIEnv *env, jclass class, jobject device, jbyte endpoint ) { NOT_NULL(env, device, return 0); libusb_device *dev = unwrapDevice(env, device); if (!dev) return 0; - return libusb_get_max_iso_packet_size(dev, endpoint); + + return libusb_get_max_iso_packet_size(dev, (unsigned char) endpoint); } /** @@ -283,8 +284,8 @@ JNIEXPORT jobject JNICALL METHOD_NAME(LibUsb, refDevice) NOT_NULL(env, device, return NULL); libusb_device *dev = unwrapDevice(env, device); if (!dev) return NULL; - libusb_ref_device(dev); - return device; + + return wrapDevice(env, libusb_ref_device(dev)); } /** @@ -299,6 +300,7 @@ JNIEXPORT void JNICALL METHOD_NAME(LibUsb, unrefDevice) libusb_device *dev = unwrapDevice(env, device); if (!dev) return; libusb_unref_device(dev); + resetDevice(env, device); } /** @@ -311,27 +313,28 @@ JNIEXPORT jint JNICALL METHOD_NAME(LibUsb, open) { NOT_NULL(env, device, return 0); NOT_NULL(env, handle, return 0); + NOT_SET(env, handle, "deviceHandlePointer", return 0); libusb_device *dev = unwrapDevice(env, device); if (!dev) return 0; libusb_device_handle *deviceHandle; int result = libusb_open(dev, &deviceHandle); - if (!result) setDeviceHandle(env, deviceHandle, handle); + if (result == LIBUSB_SUCCESS) setDeviceHandle(env, deviceHandle, handle); return result; } /** - * DeviceHandle open(Context, int, int) + * DeviceHandle openDeviceWithVidPid(Context, short, short) */ JNIEXPORT jobject JNICALL METHOD_NAME(LibUsb, openDeviceWithVidPid) ( - JNIEnv *env, jclass class, jobject context, jint vendorId, - jint productId + JNIEnv *env, jclass class, jobject context, jshort vendorId, + jshort productId ) { - struct libusb_context *ctx = unwrapContext(env, context); + libusb_context *ctx = unwrapContext(env, context); if (!ctx && context) return NULL; return wrapDeviceHandle(env, libusb_open_device_with_vid_pid( - ctx, vendorId, productId)); + ctx, (uint16_t) vendorId, (uint16_t) productId)); } /** @@ -377,11 +380,11 @@ JNIEXPORT jint JNICALL METHOD_NAME(LibUsb, getConfiguration) if (!dev_handle) return 0; int config; int result = libusb_get_configuration(dev_handle, &config); - if (!result) + if (result == LIBUSB_SUCCESS) { jclass cls = (*env)->GetObjectClass(env, buffer); jmethodID method = (*env)->GetMethodID(env, cls, "put", "(II)Ljava/nio/IntBuffer;"); - (*env)->CallVoidMethod(env, buffer, method, 0, config); + (*env)->CallObjectMethod(env, buffer, method, 0, config); } return result; } @@ -443,17 +446,18 @@ JNIEXPORT jint JNICALL METHOD_NAME(LibUsb, setInterfaceAltSetting) } /** - * int clearHalt(DeviceHandle, int) + * int clearHalt(DeviceHandle, byte) */ JNIEXPORT jint JNICALL METHOD_NAME(LibUsb, clearHalt) ( - JNIEnv *env, jclass class, jobject handle, jint endpoint + JNIEnv *env, jclass class, jobject handle, jbyte endpoint ) { NOT_NULL(env, handle, return 0); libusb_device_handle *dev_handle = unwrapDeviceHandle(env, handle); if (!dev_handle) return 0; - return libusb_clear_halt(dev_handle, endpoint); + + return libusb_clear_halt(dev_handle, (unsigned char) endpoint); } /** @@ -513,7 +517,7 @@ JNIEXPORT jint JNICALL METHOD_NAME(LibUsb, attachKernelDriver) } /** - * int attachKernelDriver(DeviceHandle, int) + * int setAutoDetachKernelDriver(DeviceHandle, boolean) */ JNIEXPORT jint JNICALL METHOD_NAME(LibUsb, setAutoDetachKernelDriver) ( @@ -534,7 +538,7 @@ JNIEXPORT jboolean JNICALL METHOD_NAME(LibUsb, hasCapability) JNIEnv *env, jclass class, jint capability ) { - return libusb_has_capability(capability); + return (jboolean) libusb_has_capability((uint32_t) capability); } /** @@ -542,57 +546,58 @@ JNIEXPORT jboolean JNICALL METHOD_NAME(LibUsb, hasCapability) */ JNIEXPORT jstring JNICALL METHOD_NAME(LibUsb, errorName) ( - JNIEnv *env, jobject this, jint code + JNIEnv *env, jclass class, jint code ) { return (*env)->NewStringUTF(env, libusb_error_name(code)); } /** - * int setLocale(string) + * int setLocale(String) */ JNIEXPORT jint JNICALL METHOD_NAME(LibUsb, setLocale) ( - JNIEnv *env, jobject this, jstring locale + JNIEnv *env, jobject class, jstring locale ) { - const char *nativeLocale = (*env)->GetStringUTFChars(env, locale, 0); + NOT_NULL(env, locale, return 0); + const char *nativeLocale = (*env)->GetStringUTFChars(env, locale, NULL); int result = libusb_setlocale(nativeLocale); (*env)->ReleaseStringUTFChars(env, locale, nativeLocale); return result; } /** - * string strError(int) + * String strError(int) */ JNIEXPORT jstring JNICALL METHOD_NAME(LibUsb, strError) ( - JNIEnv *env, jobject this, jint code + JNIEnv *env, jobject class, jint code ) { return (*env)->NewStringUTF(env, libusb_strerror(code)); } /** - * int le16ToCpu(int) + * short le16ToCpu(short) */ -JNIEXPORT jint JNICALL METHOD_NAME(LibUsb, le16ToCpu) +JNIEXPORT jshort JNICALL METHOD_NAME(LibUsb, le16ToCpu) ( - JNIEnv *env, jobject this, jint x + JNIEnv *env, jclass class, jshort x ) { - return libusb_le16_to_cpu(x); + return (jshort) libusb_le16_to_cpu((uint16_t) x); } /** - * int cpuToLe16(int) + * short cpuToLe16(short) */ -JNIEXPORT jint JNICALL METHOD_NAME(LibUsb, cpuToLe16) +JNIEXPORT jshort JNICALL METHOD_NAME(LibUsb, cpuToLe16) ( - JNIEnv *env, jobject this, jint x + JNIEnv *env, jclass class, jshort x ) { - return libusb_cpu_to_le16(x); + return (jshort) libusb_cpu_to_le16((uint16_t) x); } /** @@ -605,34 +610,62 @@ JNIEXPORT jint JNICALL METHOD_NAME(LibUsb, getDeviceDescriptor) { NOT_NULL(env, device, return 0); NOT_NULL(env, descriptor, return 0); + NOT_SET(env, descriptor, "deviceDescriptorPointer", return 0); libusb_device *dev = unwrapDevice(env, device); if (!dev) return 0; - struct libusb_device_descriptor *data = - malloc(sizeof(struct libusb_device_descriptor)); - int result = libusb_get_device_descriptor(dev, data); - if (!result) setDeviceDescriptor(env, data, descriptor); + + struct libusb_device_descriptor *dev_desc = calloc(1, sizeof(*dev_desc)); + if (!dev_desc) return LIBUSB_ERROR_NO_MEM; + + int result = libusb_get_device_descriptor(dev, dev_desc); + if (result == LIBUSB_SUCCESS) + { + setDeviceDescriptor(env, dev_desc, descriptor); + } + else + { + free(dev_desc); + } return result; } /** - * int getStringDescriptorAscii(DeviceHandle, int, StringBuffer, int) + * void freeDeviceDescriptor(DeviceDescriptor) + */ +JNIEXPORT void JNICALL METHOD_NAME(LibUsb, freeDeviceDescriptor) +( + JNIEnv *env, jclass class, jobject descriptor +) +{ + NOT_NULL(env, descriptor, return); + struct libusb_device_descriptor *dev_desc = unwrapDeviceDescriptor(env, + descriptor); + if (!dev_desc) return; + + free(dev_desc); + resetDeviceDescriptor(env, descriptor); +} + +/** + * int getStringDescriptorAscii(DeviceHandle, byte, StringBuffer) */ JNIEXPORT jint JNICALL METHOD_NAME(LibUsb, getStringDescriptorAscii) ( - JNIEnv *env, jclass class, jobject handle, jint index, jobject string, - jint length + JNIEnv *env, jclass class, jobject handle, jbyte index, jobject string ) { NOT_NULL(env, handle, return 0); NOT_NULL(env, string, return 0); libusb_device_handle *dev_handle = unwrapDeviceHandle(env, handle); if (!dev_handle) return 0; - unsigned char buffer[length + 1]; + // Maximum size of a descriptor is 256 bytes, -2 for length/type = 254, /2 because of Unicode = 127 characters + // and then +1 for the terminating NUL byte for C strings (the descriptor itself doesn't necessarily have one!). + unsigned char buffer[127 + 1]; int result = libusb_get_string_descriptor_ascii( - dev_handle, index, buffer, length); + dev_handle, (uint8_t) index, buffer, 127); if (result >= 0) { - buffer[result] = 0; + buffer[result] = 0x00; jobject tmp = (*env)->NewStringUTF(env, (char *) buffer); jclass cls = (*env)->GetObjectClass(env, string); jmethodID method = (*env)->GetMethodID(env, cls, "append", @@ -651,48 +684,51 @@ JNIEXPORT jint JNICALL METHOD_NAME(LibUsb, getActiveConfigDescriptor) { NOT_NULL(env, device, return 0); NOT_NULL(env, descriptor, return 0); + NOT_SET(env, descriptor, "configDescriptorPointer", return 0); libusb_device *dev = unwrapDevice(env, device); if (!dev) return 0; struct libusb_config_descriptor *config; int result = libusb_get_active_config_descriptor(dev, &config); - if (!result) setConfigDescriptor(env, config, descriptor); + if (result == LIBUSB_SUCCESS) setConfigDescriptor(env, config, descriptor); return result; } /** - * int getConfigDescriptor(Device, int, ConfigDescriptor) + * int getConfigDescriptor(Device, byte, ConfigDescriptor) */ JNIEXPORT jint JNICALL METHOD_NAME(LibUsb, getConfigDescriptor) ( - JNIEnv *env, jclass class, jobject device, jint index, jobject descriptor + JNIEnv *env, jclass class, jobject device, jbyte index, jobject descriptor ) { NOT_NULL(env, device, return 0); NOT_NULL(env, descriptor, return 0); + NOT_SET(env, descriptor, "configDescriptorPointer", return 0); libusb_device *dev = unwrapDevice(env, device); if (!dev) return 0; struct libusb_config_descriptor *config; - int result = libusb_get_config_descriptor(dev, index, &config); - if (!result) setConfigDescriptor(env, config, descriptor); + int result = libusb_get_config_descriptor(dev, (uint8_t) index, &config); + if (result == LIBUSB_SUCCESS) setConfigDescriptor(env, config, descriptor); return result; } /** - * int getConfigDescriptorByValue(Device, int, ConfigDescriptor) + * int getConfigDescriptorByValue(Device, byte, ConfigDescriptor) */ JNIEXPORT jint JNICALL METHOD_NAME(LibUsb, getConfigDescriptorByValue) ( - JNIEnv *env, jclass class, jobject device, jint index, jobject descriptor + JNIEnv *env, jclass class, jobject device, jbyte index, jobject descriptor ) { NOT_NULL(env, device, return 0); NOT_NULL(env, descriptor, return 0); + NOT_SET(env, descriptor, "configDescriptorPointer", return 0); libusb_device *dev = unwrapDevice(env, device); if (!dev) return 0; struct libusb_config_descriptor *config; int result = libusb_get_config_descriptor_by_value( - dev, index, &config); - if (!result) setConfigDescriptor(env, config, descriptor); + dev, (uint8_t) index, &config); + if (result == LIBUSB_SUCCESS) setConfigDescriptor(env, config, descriptor); return result; } @@ -705,7 +741,7 @@ JNIEXPORT void JNICALL METHOD_NAME(LibUsb, freeConfigDescriptor) ) { NOT_NULL(env, descriptor, return); - struct libusb_config_descriptor *config = unwrapConfigDescriptor(env, + struct libusb_config_descriptor *config = unwrapConfigDescriptor(env, descriptor); if (!config) return; libusb_free_config_descriptor(config); @@ -713,7 +749,7 @@ JNIEXPORT void JNICALL METHOD_NAME(LibUsb, freeConfigDescriptor) } /** - * int getSsEndpointCompanionDescriptor(Device, int, SsEndpointCompanionDescriptor) + * int getSsEndpointCompanionDescriptor(Context, EndpointDescriptor, SsEndpointCompanionDescriptor) */ JNIEXPORT jint JNICALL METHOD_NAME(LibUsb, getSsEndpointCompanionDescriptor) ( @@ -721,16 +757,19 @@ JNIEXPORT jint JNICALL METHOD_NAME(LibUsb, getSsEndpointCompanionDescriptor) jobject companionDescriptor ) { + libusb_context *ctx = unwrapContext(env, context); + if (!ctx && context) return 0; NOT_NULL(env, endpointDescriptor, return 0); NOT_NULL(env, companionDescriptor, return 0); - libusb_context *ctx = unwrapContext(env, context); + NOT_SET(env, companionDescriptor, "ssEndpointCompanionDescriptor", return 0); + 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, + if (result == LIBUSB_SUCCESS) setSsEndpointCompanionDescriptor(env, companion_descriptor, companionDescriptor); return result; } @@ -743,7 +782,7 @@ JNIEXPORT void JNICALL METHOD_NAME(LibUsb, freeSsEndpointCompanionDescriptor) JNIEnv *env, jclass class, jobject companionDescriptor ) { - if (!companionDescriptor) return; + NOT_NULL(env, companionDescriptor, return); struct libusb_ss_endpoint_companion_descriptor *companion_descriptor = unwrapSsEndpointCompanionDescriptor(env, companionDescriptor); if (!companion_descriptor) return; @@ -756,16 +795,18 @@ JNIEXPORT void JNICALL METHOD_NAME(LibUsb, freeSsEndpointCompanionDescriptor) */ JNIEXPORT jint JNICALL METHOD_NAME(LibUsb, getBosDescriptor) ( - JNIEnv *env, jclass class, jobject handle, jobject descriptor + JNIEnv *env, jclass class, jobject handle, jobject bosDescriptor ) { NOT_NULL(env, handle, return 0); - NOT_NULL(env, descriptor, return 0); + NOT_NULL(env, bosDescriptor, return 0); + NOT_SET(env, bosDescriptor, "bosDescriptorPointer", return 0); + libusb_device_handle *dev_handle = unwrapDeviceHandle(env, handle); if (!dev_handle) return 0; struct libusb_bos_descriptor *bos_descriptor; int result = libusb_get_bos_descriptor(dev_handle, &bos_descriptor); - if (!result) setBosDescriptor(env, bos_descriptor, descriptor); + if (result == LIBUSB_SUCCESS) setBosDescriptor(env, bos_descriptor, bosDescriptor); return result; } @@ -777,7 +818,7 @@ JNIEXPORT void JNICALL METHOD_NAME(LibUsb, freeBosDescriptor) JNIEnv *env, jclass class, jobject bosDescriptor ) { - if (!bosDescriptor) return; + NOT_NULL(env, bosDescriptor, return); struct libusb_bos_descriptor *bos_descriptor = unwrapBosDescriptor(env, bosDescriptor); if (!bos_descriptor) return; @@ -794,16 +835,19 @@ JNIEXPORT jint JNICALL METHOD_NAME(LibUsb, getUsb20ExtensionDescriptor) jobject extensionDescriptor ) { + libusb_context *ctx = unwrapContext(env, context); + if (!ctx && context) return 0; NOT_NULL(env, devCapDescriptor, return 0); NOT_NULL(env, extensionDescriptor, return 0); - libusb_context *ctx = unwrapContext(env, context); + NOT_SET(env, extensionDescriptor, "usb20ExtensionDescriptorPointer", return 0); + struct libusb_bos_dev_capability_descriptor *devcap_descriptor = unwrapBosDevCapabilityDescriptor(env, devCapDescriptor); if (!devcap_descriptor) return 0; struct libusb_usb_2_0_extension_descriptor *extension_descriptor; int result = libusb_get_usb_2_0_extension_descriptor(ctx, devcap_descriptor, &extension_descriptor); - if (!result) setUsb20ExtensionDescriptor(env, extension_descriptor, + if (result == LIBUSB_SUCCESS) setUsb20ExtensionDescriptor(env, extension_descriptor, extensionDescriptor); return result; } @@ -816,7 +860,7 @@ JNIEXPORT void JNICALL METHOD_NAME(LibUsb, freeUsb20ExtensionDescriptor) JNIEnv *env, jclass class, jobject extensionDescriptor ) { - if (!extensionDescriptor) return; + NOT_NULL(env, extensionDescriptor, return); struct libusb_usb_2_0_extension_descriptor *extension_descriptor = unwrapUsb20ExtensionDescriptor(env, extensionDescriptor); if (!extension_descriptor) return; @@ -833,16 +877,19 @@ JNIEXPORT jint JNICALL METHOD_NAME(LibUsb, getSsUsbDeviceCapabilityDescriptor) jobject ssUsbDeviceCapabilityDescriptor ) { + libusb_context *ctx = unwrapContext(env, context); + if (!ctx && context) return 0; NOT_NULL(env, devCapDescriptor, return 0); NOT_NULL(env, ssUsbDeviceCapabilityDescriptor, return 0); - libusb_context *ctx = unwrapContext(env, context); + NOT_SET(env, ssUsbDeviceCapabilityDescriptor, "ssUsbDeviceCapabilityDescriptorPointer", return 0); + struct libusb_bos_dev_capability_descriptor *devcap_descriptor = unwrapBosDevCapabilityDescriptor(env, devCapDescriptor); if (!devcap_descriptor) return 0; struct libusb_ss_usb_device_capability_descriptor *descriptor; int result = libusb_get_ss_usb_device_capability_descriptor(ctx, devcap_descriptor, &descriptor); - if (!result) setSsUsbDeviceCapabilityDescriptor(env, descriptor, + if (result == LIBUSB_SUCCESS) setSsUsbDeviceCapabilityDescriptor(env, descriptor, ssUsbDeviceCapabilityDescriptor); return result; } @@ -855,7 +902,7 @@ JNIEXPORT void JNICALL METHOD_NAME(LibUsb, freeSsUsbDeviceCapabilityDescriptor) JNIEnv *env, jclass class, jobject ssUsbDeviceCapabilityDescriptor ) { - if (!ssUsbDeviceCapabilityDescriptor) return; + NOT_NULL(env, ssUsbDeviceCapabilityDescriptor, return); struct libusb_ss_usb_device_capability_descriptor *descriptor = unwrapSsUsbDeviceCapabilityDescriptor(env, ssUsbDeviceCapabilityDescriptor); if (!descriptor) return; @@ -872,16 +919,19 @@ JNIEXPORT jint JNICALL METHOD_NAME(LibUsb, getContainerIdDescriptor) jobject containerIdDescriptor ) { + libusb_context *ctx = unwrapContext(env, context); + if (!ctx && context) return 0; NOT_NULL(env, devCapDescriptor, return 0); NOT_NULL(env, containerIdDescriptor, return 0); - libusb_context *ctx = unwrapContext(env, context); + NOT_SET(env, containerIdDescriptor, "containerIdDescriptorPointer", return 0); + struct libusb_bos_dev_capability_descriptor *devcap_descriptor = unwrapBosDevCapabilityDescriptor(env, devCapDescriptor); if (!devcap_descriptor) return 0; struct libusb_container_id_descriptor *container_id_descriptor; int result = libusb_get_container_id_descriptor(ctx, devcap_descriptor, &container_id_descriptor); - if (!result) setContainerIdDescriptor(env, container_id_descriptor, + if (result == LIBUSB_SUCCESS) setContainerIdDescriptor(env, container_id_descriptor, containerIdDescriptor); return result; } @@ -894,7 +944,7 @@ JNIEXPORT void JNICALL METHOD_NAME(LibUsb, freeContainerIdDescriptor) JNIEnv *env, jclass class, jobject containerIdDescriptor ) { - if (!containerIdDescriptor) return; + NOT_NULL(env, containerIdDescriptor, return); struct libusb_container_id_descriptor *container_id_descriptor = unwrapContainerIdDescriptor(env, containerIdDescriptor); if (!container_id_descriptor) return; @@ -903,119 +953,79 @@ JNIEXPORT void JNICALL METHOD_NAME(LibUsb, freeContainerIdDescriptor) } /** - * int getDescriptor(DeviceHandle, int, int, ByteBuffer) - */ -JNIEXPORT jint JNICALL METHOD_NAME(LibUsb, getDescriptor) -( - JNIEnv *env, jclass class, jobject handle, jint type, jint index, - jobject data -) -{ - NOT_NULL(env, handle, return 0); - NOT_NULL(env, data, return 0); - DIRECT_BUFFER(env, data, return 0); - libusb_device_handle *dev_handle = unwrapDeviceHandle(env, handle); - if (!dev_handle) return 0; - unsigned char *ptr = (*env)->GetDirectBufferAddress(env, data); - jlong size = (*env)->GetDirectBufferCapacity(env, data); - return libusb_get_descriptor(dev_handle, type, index, ptr, size); -} - -/** - * int getStringDescriptor(DeviceHandle, int, int, ByteBuffer) - */ -JNIEXPORT jint JNICALL METHOD_NAME(LibUsb, getStringDescriptor) -( - JNIEnv *env, jclass class, jobject handle, jint index, jint langId, - jobject data -) -{ - NOT_NULL(env, handle, return 0); - NOT_NULL(env, data, return 0); - DIRECT_BUFFER(env, data, return 0); - libusb_device_handle *dev_handle = unwrapDeviceHandle(env, handle); - if (!dev_handle) return 0; - unsigned char *ptr = (*env)->GetDirectBufferAddress(env, data); - jlong size = (*env)->GetDirectBufferCapacity(env, data); - return libusb_get_string_descriptor(dev_handle, index, langId, ptr, size); -} - -/** - * int controlTransfer(DeviceHandle, int, int, int, int, ByteBuffer, int) + * int controlTransfer(DeviceHandle, byte, byte, short, short, ByteBuffer, long) */ JNIEXPORT jint JNICALL METHOD_NAME(LibUsb, controlTransfer) ( - JNIEnv *env, jclass class, jobject handle, jint bmRequestType, - jint bRequest, jint wValue, jint wIndex, jobject data, jint timeout + JNIEnv *env, jclass class, jobject handle, jbyte bmRequestType, + jbyte bRequest, jshort wValue, jshort wIndex, jobject data, jlong timeout ) { NOT_NULL(env, handle, return 0); NOT_NULL(env, data, return 0); - DIRECT_BUFFER(env, data, return 0); + DIRECT_BUFFER(env, data, data_ptr, return 0); libusb_device_handle *dev_handle = unwrapDeviceHandle(env, handle); if (!dev_handle) return 0; - unsigned char *ptr = (*env)->GetDirectBufferAddress(env, data); - jlong size = (*env)->GetDirectBufferCapacity(env, data); - return libusb_control_transfer(dev_handle, bmRequestType, bRequest, - wValue, wIndex, ptr, size, timeout); + jlong data_size = (*env)->GetDirectBufferCapacity(env, data); + return libusb_control_transfer(dev_handle, (uint8_t) bmRequestType, + (uint8_t) bRequest, (uint16_t) wValue, (uint16_t) wIndex, data_ptr, + (uint16_t) data_size, (unsigned int) timeout); } /** - * int bulkTransfer(DeviceHandle, int, int, int, int, ByteBuffer, int) + * int bulkTransfer(DeviceHandle, byte, ByteBuffer, IntBuffer, long) */ JNIEXPORT jint JNICALL METHOD_NAME(LibUsb, bulkTransfer) ( - JNIEnv *env, jclass class, jobject handle, jint endpoint, - jobject data, jobject transferred, jint timeout + JNIEnv *env, jclass class, jobject handle, jbyte endpoint, + jobject data, jobject transferred, jlong timeout ) { NOT_NULL(env, handle, return 0); NOT_NULL(env, data, return 0); NOT_NULL(env, transferred, return 0); - DIRECT_BUFFER(env, data, return 0); + DIRECT_BUFFER(env, data, data_ptr, return 0); libusb_device_handle *dev_handle = unwrapDeviceHandle(env, handle); if (!dev_handle) return 0; int sent; - unsigned char *ptr = (*env)->GetDirectBufferAddress(env, data); - jlong size = (*env)->GetDirectBufferCapacity(env, data); - int result = libusb_bulk_transfer(dev_handle, endpoint, ptr, size, &sent, - timeout); - if (!result) + jlong data_size = (*env)->GetDirectBufferCapacity(env, data); + int result = libusb_bulk_transfer(dev_handle, (unsigned char) endpoint, + data_ptr, (int) data_size, &sent, (unsigned int) timeout); + if (result == LIBUSB_SUCCESS) { jclass cls = (*env)->GetObjectClass(env, transferred); jmethodID method = (*env)->GetMethodID(env, cls, "put", "(II)Ljava/nio/IntBuffer;"); - (*env)->CallVoidMethod(env, transferred, method, 0, sent); + (*env)->CallObjectMethod(env, transferred, method, 0, sent); } return result; } /** - * int interruptTransfer(DeviceHandle, int, int, int, int, ByteBuffer, int) + * int interruptTransfer(DeviceHandle, byte, ByteBuffer, IntBuffer, long) */ JNIEXPORT jint JNICALL METHOD_NAME(LibUsb, interruptTransfer) ( - JNIEnv *env, jclass class, jobject handle, jint endpoint, - jobject data, jobject transferred, jint timeout + JNIEnv *env, jclass class, jobject handle, jbyte endpoint, + jobject data, jobject transferred, jlong timeout ) { NOT_NULL(env, handle, return 0); NOT_NULL(env, data, return 0); NOT_NULL(env, transferred, return 0); - DIRECT_BUFFER(env, data, return 0); + DIRECT_BUFFER(env, data, data_ptr, return 0); libusb_device_handle *dev_handle = unwrapDeviceHandle(env, handle); if (!dev_handle) return 0; int sent; - unsigned char *ptr = (*env)->GetDirectBufferAddress(env, data); - jlong size = (*env)->GetDirectBufferCapacity(env, data); - int result = libusb_interrupt_transfer(dev_handle, endpoint, ptr, size, - &sent, timeout); - if (!result) + jlong data_size = (*env)->GetDirectBufferCapacity(env, data); + int result = libusb_interrupt_transfer(dev_handle, (unsigned char) endpoint, + data_ptr, (int) data_size, &sent, (unsigned int) timeout); + if (result == LIBUSB_SUCCESS) { jclass cls = (*env)->GetObjectClass(env, transferred); jmethodID method = (*env)->GetMethodID(env, cls, "put", "(II)Ljava/nio/IntBuffer;"); - (*env)->CallVoidMethod(env, transferred, method, 0, sent); + (*env)->CallObjectMethod(env, transferred, method, 0, sent); } return result; } @@ -1028,7 +1038,7 @@ JNIEXPORT jint JNICALL METHOD_NAME(LibUsb, tryLockEvents) JNIEnv *env, jclass class, jobject context ) { - struct libusb_context *ctx = unwrapContext(env, context); + libusb_context *ctx = unwrapContext(env, context); if (!ctx && context) return 0; return libusb_try_lock_events(ctx); } @@ -1041,7 +1051,7 @@ JNIEXPORT void JNICALL METHOD_NAME(LibUsb, lockEvents) JNIEnv *env, jclass class, jobject context ) { - struct libusb_context *ctx = unwrapContext(env, context); + libusb_context *ctx = unwrapContext(env, context); if (!ctx && context) return; libusb_lock_events(ctx); } @@ -1054,7 +1064,7 @@ JNIEXPORT void JNICALL METHOD_NAME(LibUsb, unlockEvents) JNIEnv *env, jclass class, jobject context ) { - struct libusb_context *ctx = unwrapContext(env, context); + libusb_context *ctx = unwrapContext(env, context); if (!ctx && context) return; libusb_unlock_events(ctx); } @@ -1067,7 +1077,7 @@ JNIEXPORT jint JNICALL METHOD_NAME(LibUsb, eventHandlingOk) JNIEnv *env, jclass class, jobject context ) { - struct libusb_context *ctx = unwrapContext(env, context); + libusb_context *ctx = unwrapContext(env, context); if (!ctx && context) return 0; return libusb_event_handling_ok(ctx); } @@ -1080,7 +1090,7 @@ JNIEXPORT jint JNICALL METHOD_NAME(LibUsb, eventHandlerActive) JNIEnv *env, jclass class, jobject context ) { - struct libusb_context *ctx = unwrapContext(env, context); + libusb_context *ctx = unwrapContext(env, context); if (!ctx && context) return 0; return libusb_event_handler_active(ctx); } @@ -1093,7 +1103,7 @@ JNIEXPORT void JNICALL METHOD_NAME(LibUsb, lockEventWaiters) JNIEnv *env, jclass class, jobject context ) { - struct libusb_context *ctx = unwrapContext(env, context); + libusb_context *ctx = unwrapContext(env, context); if (!ctx && context) return; libusb_lock_event_waiters(ctx); } @@ -1106,7 +1116,7 @@ JNIEXPORT void JNICALL METHOD_NAME(LibUsb, unlockEventWaiters) JNIEnv *env, jclass class, jobject context ) { - struct libusb_context *ctx = unwrapContext(env, context); + libusb_context *ctx = unwrapContext(env, context); if (!ctx && context) return; libusb_unlock_event_waiters(ctx); } @@ -1119,11 +1129,12 @@ JNIEXPORT jint JNICALL METHOD_NAME(LibUsb, waitForEvent) JNIEnv *env, jclass class, jobject context, jlong timeout ) { - struct libusb_context *ctx = unwrapContext(env, context); + libusb_context *ctx = unwrapContext(env, context); if (!ctx && context) return 0; struct timeval tv; - tv.tv_sec = timeout / 1000000; - tv.tv_usec = timeout % 1000000; + tv.tv_sec = (long int) timeout / 1000000; + tv.tv_usec = (long int) timeout % 1000000; + return libusb_wait_for_event(ctx, &tv); } @@ -1136,20 +1147,20 @@ JNIEXPORT jint JNICALL METHOD_NAME(LibUsb, handleEventsTimeoutCompleted) jobject completed ) { - struct libusb_context *ctx = unwrapContext(env, context); + int *complete = NULL; + if (completed) + { + DIRECT_BUFFER(env, completed, complete_tmp, return 0); + complete = (int *) complete_tmp; + } + + libusb_context *ctx = unwrapContext(env, context); if (!ctx && context) return 0; struct timeval tv; - tv.tv_sec = timeout / 1000000; - tv.tv_usec = timeout % 1000000; - int complete; - int result = libusb_handle_events_timeout_completed(ctx, &tv, &complete); - if (!result && completed) - { - jclass cls = (*env)->GetObjectClass(env, completed); - jmethodID method = (*env)->GetMethodID(env, cls, "put", "(II)Ljava/nio/IntBuffer;"); - (*env)->CallVoidMethod(env, completed, method, 0, complete); - } - return result; + tv.tv_sec = (long int) timeout / 1000000; + tv.tv_usec = (long int) timeout % 1000000; + + return libusb_handle_events_timeout_completed(ctx, &tv, complete); } /** @@ -1160,11 +1171,12 @@ JNIEXPORT jint JNICALL METHOD_NAME(LibUsb, handleEventsTimeout) JNIEnv *env, jclass class, jobject context, jlong timeout ) { - struct libusb_context *ctx = unwrapContext(env, context); + libusb_context *ctx = unwrapContext(env, context); if (!ctx && context) return 0; struct timeval tv; - tv.tv_sec = timeout / 1000000; - tv.tv_usec = timeout % 1000000; + tv.tv_sec = (long int) timeout / 1000000; + tv.tv_usec = (long int) timeout % 1000000; + return libusb_handle_events_timeout(ctx, &tv); } @@ -1176,7 +1188,7 @@ JNIEXPORT jint JNICALL METHOD_NAME(LibUsb, handleEvents) JNIEnv *env, jclass class, jobject context ) { - struct libusb_context *ctx = unwrapContext(env, context); + libusb_context *ctx = unwrapContext(env, context); if (!ctx && context) return 0; return libusb_handle_events(ctx); } @@ -1189,17 +1201,17 @@ JNIEXPORT jint JNICALL METHOD_NAME(LibUsb, handleEventsCompleted) JNIEnv *env, jclass class, jobject context, jobject completed ) { - struct libusb_context *ctx = unwrapContext(env, context); - if (!ctx && context) return 0; - int complete; - int result = libusb_handle_events_completed(ctx, &complete); - if (!result && completed) + int *complete = NULL; + if (completed) { - jclass cls = (*env)->GetObjectClass(env, completed); - jmethodID method = (*env)->GetMethodID(env, cls, "put", "(II)Ljava/nio/IntBuffer;"); - (*env)->CallVoidMethod(env, completed, method, 0, complete); + DIRECT_BUFFER(env, completed, complete_tmp, return 0); + complete = (int *) complete_tmp; } - return result; + + libusb_context *ctx = unwrapContext(env, context); + if (!ctx && context) return 0; + + return libusb_handle_events_completed(ctx, complete); } /** @@ -1210,11 +1222,12 @@ JNIEXPORT jint JNICALL METHOD_NAME(LibUsb, handleEventsLocked) JNIEnv *env, jclass class, jobject context, jlong timeout ) { - struct libusb_context *ctx = unwrapContext(env, context); + libusb_context *ctx = unwrapContext(env, context); if (!ctx && context) return 0; struct timeval tv; - tv.tv_sec = timeout / 1000000; - tv.tv_usec = timeout % 1000000; + tv.tv_sec = (long int) timeout / 1000000; + tv.tv_usec = (long int) timeout % 1000000; + return libusb_handle_events_locked(ctx, &tv); } @@ -1226,7 +1239,7 @@ JNIEXPORT jint JNICALL METHOD_NAME(LibUsb, pollfdsHandleTimeouts) JNIEnv *env, jclass class, jobject context ) { - struct libusb_context *ctx = unwrapContext(env, context); + libusb_context *ctx = unwrapContext(env, context); if (!ctx && context) return 0; return libusb_pollfds_handle_timeouts(ctx); } @@ -1239,7 +1252,8 @@ JNIEXPORT jint JNICALL METHOD_NAME(LibUsb, getNextTimeout) JNIEnv *env, jclass class, jobject context, jobject timeout ) { - struct libusb_context *ctx = unwrapContext(env, context); + NOT_NULL(env, timeout, return 0); + libusb_context *ctx = unwrapContext(env, context); if (!ctx && context) return 0; struct timeval tv; int result = libusb_get_next_timeout(ctx, &tv); @@ -1247,9 +1261,9 @@ JNIEXPORT jint JNICALL METHOD_NAME(LibUsb, getNextTimeout) { jclass cls = (*env)->GetObjectClass(env, timeout); jmethodID method = (*env)->GetMethodID(env, cls, "put", - "(II)Ljava/nio/LongBuffer;"); - (*env)->CallVoidMethod(env, timeout, method, 0, - tv.tv_sec * 1000000 + tv.tv_usec); + "(IJ)Ljava/nio/LongBuffer;"); + (*env)->CallObjectMethod(env, timeout, method, 0, + (jlong) (tv.tv_sec * 1000000 + tv.tv_usec)); } return result; } @@ -1264,8 +1278,9 @@ static void LIBUSB_CALL triggerPollfdAdded(int fd, short events, void *user_data jclass cls = (*env)->FindClass(env, PACKAGE_DIR"/LibUsb"); jmethodID method = (*env)->GetStaticMethodID(env, cls, - "triggerPollfdAdded", "(Ljava/io/FileDescriptor;)V"); - (*env)->CallStaticVoidMethod(env, cls, method, object, events); + "triggerPollfdAdded", "(Ljava/io/FileDescriptor;IJ)V"); + (*env)->CallStaticVoidMethod(env, cls, method, object, (jint) events, + (jlong) (intptr_t) user_data); THREAD_END } @@ -1280,25 +1295,26 @@ static void LIBUSB_CALL triggerPollfdRemoved(int fd, void *user_data) jclass cls = (*env)->FindClass(env, PACKAGE_DIR"/LibUsb"); jmethodID method = (*env)->GetStaticMethodID(env, cls, - "triggerPollfdRemoved", "(Ljava/io/FileDescriptor;)V"); - (*env)->CallStaticVoidMethod(env, cls, method, object); + "triggerPollfdRemoved", "(Ljava/io/FileDescriptor;J)V"); + (*env)->CallStaticVoidMethod(env, cls, method, object, + (jlong) (intptr_t) user_data); THREAD_END } /** - * void setPollfdNotifiers(Context) + * void setPollfdNotifiers(Context, long) */ JNIEXPORT void JNICALL METHOD_NAME(LibUsb, setPollfdNotifiers) ( - JNIEnv *env, jclass class, jobject context + JNIEnv *env, jclass class, jobject context, jlong context_id ) { - struct libusb_context *ctx = unwrapContext(env, context); + libusb_context *ctx = unwrapContext(env, context); if (!ctx && context) return; - (*env)->GetJavaVM(env, &jvm); - libusb_set_pollfd_notifiers(ctx, triggerPollfdAdded, triggerPollfdRemoved, - NULL); + + libusb_set_pollfd_notifiers(ctx, &triggerPollfdAdded, &triggerPollfdRemoved, + (void *) (intptr_t) context_id); } /** @@ -1309,7 +1325,7 @@ JNIEXPORT void JNICALL METHOD_NAME(LibUsb, unsetPollfdNotifiers) JNIEnv *env, jclass class, jobject context ) { - struct libusb_context *ctx = unwrapContext(env, context); + libusb_context *ctx = unwrapContext(env, context); if (!ctx && context) return; libusb_set_pollfd_notifiers(ctx, NULL, NULL, NULL); } @@ -1322,7 +1338,27 @@ JNIEXPORT jobject JNICALL METHOD_NAME(LibUsb, allocTransfer) JNIEnv *env, jclass class, jint isoPackets ) { - return wrapTransfer(env, libusb_alloc_transfer(isoPackets)); + struct libusb_transfer *transfer = libusb_alloc_transfer(isoPackets); + if (!transfer) return NULL; + + struct transfer_data *transferData = calloc(1, sizeof(*transferData)); + if (!transferData) + { + libusb_free_transfer(transfer); + return NULL; + } + + transfer->user_data = transferData; + transferData->maxNumIsoPackets = (size_t) isoPackets; + + jobject transferObject = wrapTransfer(env, transfer); + + // Make sure the cleanup callback is always there, as it's perfectly legal + // to not set any callback and still enable the FREE_TRANSFER flag, in which + // case one would expect the Java Transfer object to be properly cleaned up. + cleanupCallbackEnable(env, transferObject); + + return transferObject; } /** @@ -1330,11 +1366,45 @@ JNIEXPORT jobject JNICALL METHOD_NAME(LibUsb, allocTransfer) */ JNIEXPORT void JNICALL METHOD_NAME(LibUsb, freeTransfer) ( - JNIEnv *env, jclass class, jobject transfer + JNIEnv *env, jclass class, jobject trans ) { - struct libusb_transfer *handle = unwrapTransfer(env, transfer); - if (!handle) return; - libusb_free_transfer(handle); - resetTransfer(env, transfer); + NOT_NULL(env, trans, return); + struct libusb_transfer *transfer = unwrapTransfer(env, trans); + if (!transfer) return; + + cleanupGlobalReferences(env, trans); + resetTransfer(env, trans); + free(transfer->user_data); + libusb_free_transfer(transfer); +} + +/** + * int submitTransfer(Transfer) + */ +JNIEXPORT jint JNICALL METHOD_NAME(LibUsb, submitTransfer) +( + JNIEnv *env, jclass class, jobject trans +) +{ + NOT_NULL(env, trans, return 0); + struct libusb_transfer *transfer = unwrapTransfer(env, trans); + if (!transfer) return 0; + + return libusb_submit_transfer(transfer); +} + +/** + * int cancelTransfer(Transfer) + */ +JNIEXPORT jint JNICALL METHOD_NAME(LibUsb, cancelTransfer) +( + JNIEnv *env, jclass class, jobject trans +) +{ + NOT_NULL(env, trans, return 0); + struct libusb_transfer *transfer = unwrapTransfer(env, trans); + if (!transfer) return 0; + + return libusb_cancel_transfer(transfer); } diff --git a/src/main/c/src/Makefile.am b/src/main/c/src/Makefile.am index fc42833..abae2e5 100644 --- a/src/main/c/src/Makefile.am +++ b/src/main/c/src/Makefile.am @@ -1,5 +1,5 @@ lib_LTLIBRARIES = libusb4java.la -libusb4java_la_CFLAGS = -Wall -Werror $(LIBUSB_CFLAGS) +libusb4java_la_CFLAGS = -pedantic -Wall -Wextra -Wformat=2 -Winit-self -Wunused -Wno-unused-parameter -Wuninitialized -Wundef -Wshadow -Wbad-function-cast -Wcast-qual -Wcast-align -Wwrite-strings -Wconversion -Wstrict-prototypes -Wredundant-decls -Wnested-externs $(LIBUSB_CFLAGS) libusb4java_la_LIBADD = $(LIBUSB_LIBS) libusb4java_la_LDFLAGS = -version-info 1:0:0 -no-undefined EXTRA_DIST = *.h @@ -17,6 +17,7 @@ libusb4java_la_SOURCES = \ Interface.c \ InterfaceDescriptor.c \ EndpointDescriptor.c \ + IsoPacketDescriptor.c \ Transfer.c \ SsEndpointCompanionDescriptor.c \ BosDescriptor.c \ diff --git a/src/main/c/src/Transfer.c b/src/main/c/src/Transfer.c index 80bdc0b..b613e41 100644 --- a/src/main/c/src/Transfer.c +++ b/src/main/c/src/Transfer.c @@ -3,22 +3,33 @@ * See COPYING file for copying conditions */ +#include #include "Transfer.h" #include "DeviceHandle.h" +#include "IsoPacketDescriptor.h" -jobject wrapTransfer(JNIEnv* env, struct libusb_transfer* transfer) +static void LIBUSB_CALL cleanupCallback(struct libusb_transfer *transfer); +static void LIBUSB_CALL transferCallback(struct libusb_transfer *transfer); + +jobject wrapTransfer(JNIEnv* env, const struct libusb_transfer* transfer) { - WRAP_POINTER(env, transfer, "Transfer", "pointer"); + WRAP_POINTER(env, transfer, "Transfer", "transferPointer"); } -struct libusb_transfer* unwrapTransfer(JNIEnv *env, jobject obj) +struct libusb_transfer* unwrapTransfer(JNIEnv* env, jobject obj) { - UNWRAP_POINTER(env, obj, struct libusb_transfer*, "pointer"); + UNWRAP_POINTER(env, obj, struct libusb_transfer*, "transferPointer"); } void resetTransfer(JNIEnv* env, jobject obj) { - RESET_POINTER(env, obj, "pointer"); + RESET_POINTER(env, obj, "transferPointer"); + + // We already have the class from the previous call. + // Reset transferBuffer field to NULL too. + field = (*env)->GetFieldID(env, cls, "transferBuffer", + "Ljava/nio/ByteBuffer;"); + (*env)->SetObjectField(env, obj, field, NULL); } /** @@ -29,84 +40,110 @@ JNIEXPORT void JNICALL METHOD_NAME(Transfer, setDevHandle) JNIEnv *env, jobject this, jobject handle ) { - unwrapTransfer(env, this)->dev_handle = unwrapDeviceHandle(env, handle); + libusb_device_handle *dev_handle = unwrapDeviceHandle(env, handle); + if (!dev_handle && handle) return; + struct libusb_transfer *transfer = unwrapTransfer(env, this); + if (!transfer) return; + + transfer->dev_handle = dev_handle; } /** - * DeviceHandle getDevHandle() + * DeviceHandle devHandle() */ -JNIEXPORT jobject JNICALL METHOD_NAME(Transfer, getDevHandle) +JNIEXPORT jobject JNICALL METHOD_NAME(Transfer, devHandle) ( JNIEnv *env, jobject this ) { - return wrapDeviceHandle(env, unwrapTransfer(env, this)->dev_handle); + struct libusb_transfer *transfer = unwrapTransfer(env, this); + if (!transfer) return NULL; + + return wrapDeviceHandle(env, transfer->dev_handle); } /** - * void setFlags(int) + * void setFlags(byte) */ JNIEXPORT void JNICALL METHOD_NAME(Transfer, setFlags) ( - JNIEnv *env, jobject this, jint flags + JNIEnv *env, jobject this, jbyte flags ) { - unwrapTransfer(env, this)->flags = flags; + struct libusb_transfer *transfer = unwrapTransfer(env, this); + if (!transfer) return; + + transfer->flags = (uint8_t) flags; } /** - * int getFlags() + * byte flags() */ -JNIEXPORT jint JNICALL METHOD_NAME(Transfer, getFlags) +JNIEXPORT jbyte JNICALL METHOD_NAME(Transfer, flags) ( JNIEnv *env, jobject this ) { - return unwrapTransfer(env, this)->flags; + struct libusb_transfer *transfer = unwrapTransfer(env, this); + if (!transfer) return 0; + + return (jbyte) transfer->flags; } /** - * void setEndpoint(int) + * void setEndpoint(byte) */ JNIEXPORT void JNICALL METHOD_NAME(Transfer, setEndpoint) ( - JNIEnv *env, jobject this, jint endpoint + JNIEnv *env, jobject this, jbyte endpoint ) { - unwrapTransfer(env, this)->endpoint = endpoint; + struct libusb_transfer *transfer = unwrapTransfer(env, this); + if (!transfer) return; + + transfer->endpoint = (unsigned char) endpoint; } /** - * int getEndpoint() + * byte endpoint() */ -JNIEXPORT jint JNICALL METHOD_NAME(Transfer, getEndpoint) +JNIEXPORT jbyte JNICALL METHOD_NAME(Transfer, endpoint) ( JNIEnv *env, jobject this ) { - return unwrapTransfer(env, this)->endpoint; + struct libusb_transfer *transfer = unwrapTransfer(env, this); + if (!transfer) return 0; + + return (jbyte) transfer->endpoint; } /** - * void setType(int) + * void setType(byte) */ JNIEXPORT void JNICALL METHOD_NAME(Transfer, setType) ( - JNIEnv *env, jobject this, jint type + JNIEnv *env, jobject this, jbyte type ) { - unwrapTransfer(env, this)->type = type; + struct libusb_transfer *transfer = unwrapTransfer(env, this); + if (!transfer) return; + + transfer->type = (unsigned char) type; } /** - * int getType() + * byte type() */ -JNIEXPORT jint JNICALL METHOD_NAME(Transfer, getType) +JNIEXPORT jbyte JNICALL METHOD_NAME(Transfer, type) ( JNIEnv *env, jobject this ) { - return unwrapTransfer(env, this)->type; + struct libusb_transfer *transfer = unwrapTransfer(env, this); + if (!transfer) return 0; + + return (jbyte) transfer->type; } /** @@ -117,27 +154,350 @@ JNIEXPORT void JNICALL METHOD_NAME(Transfer, setTimeout) JNIEnv *env, jobject this, jlong timeout ) { - unwrapTransfer(env, this)->timeout = timeout; + struct libusb_transfer *transfer = unwrapTransfer(env, this); + if (!transfer) return; + + transfer->timeout = (unsigned int) timeout; } /** - * long getTimeout() + * long timeout() */ -JNIEXPORT jlong JNICALL METHOD_NAME(Transfer, getTimeout) +JNIEXPORT jlong JNICALL METHOD_NAME(Transfer, timeout) ( JNIEnv *env, jobject this ) { - return unwrapTransfer(env, this)->timeout; + struct libusb_transfer *transfer = unwrapTransfer(env, this); + if (!transfer) return 0; + + return transfer->timeout; } /** - * int getStatus() + * int status() */ -JNIEXPORT jint JNICALL METHOD_NAME(Transfer, getStatus) +JNIEXPORT jint JNICALL METHOD_NAME(Transfer, status) ( JNIEnv *env, jobject this ) { - return unwrapTransfer(env, this)->status; + struct libusb_transfer *transfer = unwrapTransfer(env, this); + if (!transfer) return 0; + + return transfer->status; +} + +/** + * void setLengthNative(int) + */ +JNIEXPORT void JNICALL METHOD_NAME(Transfer, setLengthNative) +( + JNIEnv *env, jobject this, jint length +) +{ + struct libusb_transfer *transfer = unwrapTransfer(env, this); + if (!transfer) return; + + transfer->length = length; +} + +/** + * int length() + */ +JNIEXPORT jint JNICALL METHOD_NAME(Transfer, length) +( + JNIEnv *env, jobject this +) +{ + struct libusb_transfer *transfer = unwrapTransfer(env, this); + if (!transfer) return 0; + + return transfer->length; +} + +/** + * int actualLength() + */ +JNIEXPORT jint JNICALL METHOD_NAME(Transfer, actualLength) +( + JNIEnv *env, jobject this +) +{ + struct libusb_transfer *transfer = unwrapTransfer(env, this); + if (!transfer) return 0; + + return transfer->actual_length; +} + +void cleanupGlobalReferences(JNIEnv *env, jobject obj) +{ + struct libusb_transfer *transfer = unwrapTransfer(env, obj); + if (!transfer) return; + + struct transfer_data *transferData = + ((struct transfer_data *) transfer->user_data); + + // Cleanup all global references, if any currently exist. + if (transferData->callbackObject != NULL) + { + (*env)->DeleteGlobalRef(env, transferData->callbackObject); + } + + if (transferData->callbackUserDataObject != NULL) + { + (*env)->DeleteGlobalRef(env, transferData->callbackUserDataObject); + } + + if (transferData->transferObject != NULL) + { + (*env)->DeleteGlobalRef(env, transferData->transferObject); + } +} + +void cleanupCallbackEnable(JNIEnv *env, jobject obj) +{ + struct libusb_transfer *transfer = unwrapTransfer(env, obj); + if (!transfer) return; + + struct transfer_data *transferData = + ((struct transfer_data *) transfer->user_data); + + transferData->transferObject = (*env)->NewGlobalRef(env, obj); + + transfer->callback = &cleanupCallback; + + transferData->callbackObject = NULL; + transferData->callbackObjectMethod = 0; +} + +static void LIBUSB_CALL cleanupCallback(struct libusb_transfer *transfer) +{ + THREAD_BEGIN(env) + + struct transfer_data *transferData = + ((struct transfer_data *) transfer->user_data); + + // The saved reference to the Java Transfer object. + jobject jTransfer = transferData->transferObject; + + // Cleanup Java Transfer object too, if requested. + if (transfer->flags & LIBUSB_TRANSFER_FREE_TRANSFER) + { + cleanupGlobalReferences(env, jTransfer); + resetTransfer(env, jTransfer); + free(transferData); + } + + THREAD_END +} + +static void LIBUSB_CALL transferCallback(struct libusb_transfer *transfer) +{ + THREAD_BEGIN(env) + + struct transfer_data *transferData = + ((struct transfer_data *) transfer->user_data); + + // The saved references to the Java TransferCallback object. + jobject jCallback = transferData->callbackObject; + jmethodID jCallbackMethod = transferData->callbackObjectMethod; + + // The saved reference to the Java Transfer object. + jobject jTransfer = transferData->transferObject; + + // Read flags before calling the Java method, as it could + // free the Transfer itself. + if (transfer->flags & LIBUSB_TRANSFER_FREE_TRANSFER) + { + // Call back into Java. + (*env)->CallVoidMethod(env, jCallback, jCallbackMethod, jTransfer); + + // Cleanup Java Transfer object too, if requested. + cleanupGlobalReferences(env, jTransfer); + resetTransfer(env, jTransfer); + free(transferData); + } + else + { + // Call back into Java. + (*env)->CallVoidMethod(env, jCallback, jCallbackMethod, jTransfer); + } + + THREAD_END +} + +/** + * void setCallback(TransferCallback) + */ +JNIEXPORT void JNICALL METHOD_NAME(Transfer, setCallback) +( + JNIEnv *env, jobject this, jobject callback +) +{ + struct libusb_transfer *transfer = unwrapTransfer(env, this); + if (!transfer) return; + + struct transfer_data *transferData = + ((struct transfer_data *) transfer->user_data); + + if (transferData->transferObject != NULL) + { + (*env)->DeleteGlobalRef(env, transferData->transferObject); + } + + if (transferData->callbackObject != NULL) + { + (*env)->DeleteGlobalRef(env, transferData->callbackObject); + } + + if (callback != NULL) + { + transferData->transferObject = (*env)->NewGlobalRef(env, this); + + transfer->callback = &transferCallback; + + jclass cls = (*env)->GetObjectClass(env, callback); + jmethodID method = (*env)->GetMethodID(env, cls, "processTransfer", + "(L"PACKAGE_DIR"/Transfer;)V"); + + transferData->callbackObject = (*env)->NewGlobalRef(env, callback); + transferData->callbackObjectMethod = method; + } + else + { + cleanupCallbackEnable(env, this); + } +} + +/** + * TransferCallback callback() + */ +JNIEXPORT jobject JNICALL METHOD_NAME(Transfer, callback) +( + JNIEnv *env, jobject this +) +{ + struct libusb_transfer *transfer = unwrapTransfer(env, this); + if (!transfer) return NULL; + + return ((struct transfer_data *) transfer->user_data)->callbackObject; +} + +/** + * void setUserData(Object) + */ +JNIEXPORT void JNICALL METHOD_NAME(Transfer, setUserData) +( + JNIEnv *env, jobject this, jobject userData +) +{ + struct libusb_transfer *transfer = unwrapTransfer(env, this); + if (!transfer) return; + + struct transfer_data *transferData = + ((struct transfer_data *) transfer->user_data); + + if (transferData->callbackUserDataObject != NULL) + { + (*env)->DeleteGlobalRef(env, transferData->callbackUserDataObject); + } + + if (userData != NULL) + { + transferData->callbackUserDataObject = (*env)->NewGlobalRef(env, + userData); + } + else + { + transferData->callbackUserDataObject = NULL; + } +} + +/** + * Object userData() + */ +JNIEXPORT jobject JNICALL METHOD_NAME(Transfer, userData) +( + JNIEnv *env, jobject this +) +{ + struct libusb_transfer *transfer = unwrapTransfer(env, this); + if (!transfer) return NULL; + + return ((struct transfer_data *) transfer->user_data)->callbackUserDataObject; +} + +/** + * void setBufferNative(ByteBuffer) + */ +JNIEXPORT void JNICALL METHOD_NAME(Transfer, setBufferNative) +( + JNIEnv *env, jobject this, jobject buffer +) +{ + unsigned char *buffer_ptr = NULL; + if (buffer) + { + DIRECT_BUFFER(env, buffer, buffer_tmp, return); + buffer_ptr = buffer_tmp; + } + + struct libusb_transfer *transfer = unwrapTransfer(env, this); + if (!transfer) return; + + transfer->buffer = buffer_ptr; +} + +/** + * void setNumIsoPackets(int) + */ +JNIEXPORT void JNICALL METHOD_NAME(Transfer, setNumIsoPackets) +( + JNIEnv *env, jobject this, jint numIsoPackets +) +{ + struct libusb_transfer *transfer = unwrapTransfer(env, this); + if (!transfer) return; + + // Check that calls to setNumIsoPackets() never set a number exceeding + // the maximum, which was originally set at allocTransfer() time. + if (((struct transfer_data *) transfer->user_data)->maxNumIsoPackets + < (size_t) numIsoPackets) + { + illegalArgument(env, + "numIsoPackets exceeds maximum allowed number set with allocTransfer()"); + return; + } + + transfer->num_iso_packets = numIsoPackets; +} + +/** + * int numIsoPackets() + */ +JNIEXPORT jint JNICALL METHOD_NAME(Transfer, numIsoPackets) +( + JNIEnv *env, jobject this +) +{ + struct libusb_transfer *transfer = unwrapTransfer(env, this); + if (!transfer) return 0; + + return transfer->num_iso_packets; +} + +/** + * IsoPacketDescriptor[] isoPacketDesc() + */ +JNIEXPORT jobjectArray JNICALL METHOD_NAME(Transfer, isoPacketDesc) +( + JNIEnv *env, jobject this +) +{ + struct libusb_transfer *transfer = unwrapTransfer(env, this); + if (!transfer) return NULL; + + return wrapIsoPacketDescriptors(env, transfer->num_iso_packets, + transfer->iso_packet_desc); } diff --git a/src/main/c/src/Transfer.h b/src/main/c/src/Transfer.h index dbca82d..d77d44b 100644 --- a/src/main/c/src/Transfer.h +++ b/src/main/c/src/Transfer.h @@ -8,7 +8,19 @@ #include "usb4java.h" -jobject wrapTransfer(JNIEnv*, struct libusb_transfer*); +struct transfer_data +{ + jobject transferObject; + jobject callbackObject; + jmethodID callbackObjectMethod; + jobject callbackUserDataObject; + size_t maxNumIsoPackets; +}; + +void cleanupGlobalReferences(JNIEnv*, jobject); +void cleanupCallbackEnable(JNIEnv*, jobject); + +jobject wrapTransfer(JNIEnv*, const struct libusb_transfer*); struct libusb_transfer* unwrapTransfer(JNIEnv*, jobject); void resetTransfer(JNIEnv*, jobject); diff --git a/src/main/c/src/Version.c b/src/main/c/src/Version.c index 8902640..d4eebed 100644 --- a/src/main/c/src/Version.c +++ b/src/main/c/src/Version.c @@ -7,12 +7,12 @@ jobject wrapVersion(JNIEnv* env, const struct libusb_version* pointer) { - WRAP_POINTER(env, pointer, "Version", "pointer"); + WRAP_POINTER(env, pointer, "Version", "versionPointer"); } const struct libusb_version* unwrapVersion(JNIEnv* env, jobject object) { - UNWRAP_POINTER(env, object, struct libusb_version*, "pointer"); + UNWRAP_POINTER(env, object, const struct libusb_version*, "versionPointer"); } /** @@ -55,7 +55,20 @@ JNIEXPORT jint JNICALL METHOD_NAME(Version, micro) } /** - * string rc() + * int nano() + */ +JNIEXPORT jint JNICALL METHOD_NAME(Version, nano) +( + JNIEnv *env, jobject this +) +{ + const struct libusb_version *version = unwrapVersion(env, this); + if (!version) return 0; + return version->nano; +} + +/** + * String rc() */ JNIEXPORT jstring JNICALL METHOD_NAME(Version, rc) ( diff --git a/src/main/c/src/usb4java.c b/src/main/c/src/usb4java.c index c148ca7..3dca321 100644 --- a/src/main/c/src/usb4java.c +++ b/src/main/c/src/usb4java.c @@ -5,15 +5,37 @@ #include "usb4java.h" -jint illegalArgument(JNIEnv *env, char *message) +JavaVM *jvm = NULL; + +jint illegalArgument(JNIEnv *env, const char *message) { jclass cls = (*env)->FindClass(env, "java/lang/IllegalArgumentException"); return (*env)->ThrowNew(env, cls, message); } -jint illegalState(JNIEnv *env, char *message) +jint illegalState(JNIEnv *env, const char *message) { jclass cls = (*env)->FindClass(env, "java/lang/IllegalStateException"); return (*env)->ThrowNew(env, cls, message); } +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wcast-qual" +jobject NewDirectReadOnlyByteBuffer(JNIEnv *env, const void *mem, + int mem_length) +{ + jobject buffer = (*env)->NewDirectByteBuffer(env, (void *) mem, mem_length); + + // Get a read-only buffer from this buffer. + jclass cls = (*env)->GetObjectClass(env, buffer); + jmethodID method = (*env)->GetMethodID(env, cls, "asReadOnlyBuffer", + "()Ljava/nio/ByteBuffer;"); + return (*env)->CallObjectMethod(env, buffer, method); +} +#pragma GCC diagnostic pop + +jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) +{ + jvm = vm; + return JNI_VERSION_1_4; +} diff --git a/src/main/c/src/usb4java.h b/src/main/c/src/usb4java.h index 35e245f..5f29849 100644 --- a/src/main/c/src/usb4java.h +++ b/src/main/c/src/usb4java.h @@ -20,21 +20,16 @@ #endif #define SET_POINTER(ENV, PTR, OBJECT, FIELD) \ -{ \ jclass cls = (*ENV)->GetObjectClass(ENV, OBJECT); \ jfieldID field = (*ENV)->GetFieldID(ENV, cls, FIELD, "J"); \ - (*ENV)->SetLongField(ENV, OBJECT, field, (jptr) PTR); \ -} + (*ENV)->SetLongField(ENV, OBJECT, field, (jptr) PTR); #define RESET_POINTER(ENV, OBJECT, FIELD) \ -{ \ jclass cls = (*ENV)->GetObjectClass(ENV, OBJECT); \ jfieldID field = (*ENV)->GetFieldID(ENV, cls, FIELD, "J"); \ - (*ENV)->SetLongField(ENV, OBJECT, field, 0); \ -} + (*ENV)->SetLongField(ENV, OBJECT, field, 0); #define WRAP_POINTER(ENV, PTR, CLASS_NAME, FIELD) \ -{ \ if (!PTR) return NULL; \ jclass cls = (*ENV)->FindClass(ENV, PACKAGE_DIR"/"CLASS_NAME); \ if (cls == NULL) return NULL; \ @@ -43,53 +38,24 @@ jobject object = (*ENV)->NewObject(ENV, cls, constructor); \ jfieldID field = (*ENV)->GetFieldID(ENV, cls, FIELD, "J"); \ (*ENV)->SetLongField(ENV, object, field, (jptr) PTR); \ - return object; \ -} + return object; #define UNWRAP_POINTER(ENV, OBJECT, TYPE, FIELD) \ -{ \ if (!OBJECT) return NULL; \ jclass cls = (*ENV)->GetObjectClass(ENV, OBJECT); \ jfieldID field = (*ENV)->GetFieldID(ENV, cls, FIELD, "J"); \ jptr ptr = (jptr) (*ENV)->GetLongField(ENV, OBJECT, field); \ if (!ptr) illegalState(ENV, FIELD" is not initialized"); \ - return (TYPE) (jptr) (*ENV)->GetLongField(ENV, OBJECT, field); \ -} + return (TYPE) ptr; -#define SET_DATA(ENV, PTR, SIZE, OBJECT, FIELD) \ -{ \ - jclass cls = (*ENV)->GetObjectClass(ENV, OBJECT); \ - jfieldID field = (*ENV)->GetFieldID(ENV, cls, FIELD, \ - "Ljava/nio/ByteBuffer;"); \ - jobject buffer = (*ENV)->NewDirectByteBuffer(env, PTR, SIZE); \ - (*ENV)->SetObjectField(ENV, OBJECT, field, buffer); \ -} - -#define UNWRAP_DATA(ENV, OBJECT, TYPE, FIELD) \ -{ \ - jclass cls = (*ENV)->GetObjectClass(ENV, OBJECT); \ - jfieldID field = (*ENV)->GetFieldID(ENV, cls, FIELD, \ - "Ljava/nio/ByteBuffer;"); \ - jobject buffer = (*ENV)->GetObjectField(ENV, OBJECT, field); \ - if (!buffer) \ - { \ - illegalState(ENV, FIELD" is not initialized"); \ - return NULL; \ - } \ - return (TYPE) (*ENV)->GetDirectBufferAddress(ENV, buffer); \ -} - -#define DIRECT_BUFFER(ENV, VAR, ACTION) \ -{ \ - jclass cls = (*ENV)->GetObjectClass(ENV, VAR); \ - jmethodID method = (*ENV)->GetMethodID(ENV, cls, "isDirect", \ - "()Z"); \ - if (!(*ENV)->CallBooleanMethod(ENV, VAR, method)) \ - { \ - illegalArgument(ENV, #VAR" must be a direct buffer"); \ - ACTION; \ - } \ -} +// GetDirectBufferAddress returns NULL if called on a non-direct buffer. +#define DIRECT_BUFFER(ENV, VAR, BUFFER, ACTION) \ + unsigned char *BUFFER = (*ENV)->GetDirectBufferAddress(ENV, VAR); \ + if (!BUFFER) \ + { \ + illegalArgument(ENV, #VAR" must be a direct buffer"); \ + ACTION; \ + } #define NOT_NULL(ENV, VAR, ACTION) \ if (!VAR) \ @@ -98,6 +64,16 @@ ACTION; \ } +#define NOT_SET(ENV, VAR, FIELD, ACTION) \ + jclass cls = (*ENV)->GetObjectClass(ENV, VAR); \ + jfieldID field = (*ENV)->GetFieldID(ENV, cls, FIELD, "J"); \ + jptr ptr = (jptr) (*ENV)->GetLongField(ENV, VAR, field); \ + if (ptr) \ + { \ + illegalState(ENV, FIELD" is already initialized"); \ + ACTION; \ + } + #define THREAD_BEGIN(ENV) \ JNIEnv *ENV; \ jint getEnvResult = (*jvm)->GetEnv(jvm, (void **) &ENV, JNI_VERSION_1_4); \ @@ -105,9 +81,14 @@ (*jvm)->AttachCurrentThread(jvm, (void**) &ENV, NULL); #define THREAD_END \ - if (getEnvResult == JNI_EDETACHED) (*jvm)->DetachCurrentThread(jvm); + if (getEnvResult == JNI_EDETACHED) \ + (*jvm)->DetachCurrentThread(jvm); -jint illegalArgument(JNIEnv *env, char *message); -jint illegalState(JNIEnv *env, char *message); +extern JavaVM *jvm; + +jint illegalArgument(JNIEnv *env, const char *message); +jint illegalState(JNIEnv *env, const char *message); +jobject NewDirectReadOnlyByteBuffer(JNIEnv *env, const void *mem, + int mem_length); #endif diff --git a/src/main/c/src/wrappers.c b/src/main/c/src/wrappers.c deleted file mode 100644 index da85ad0..0000000 --- a/src/main/c/src/wrappers.c +++ /dev/null @@ -1,15 +0,0 @@ -/* - * Copyright (C) 2013 Klaus Reimer (k@ailis.de) - * See COPYING file for copying conditions - */ - -#include - -// Enforce usage of older memcpy to be compatible with older libc versions -#if WRAP_MEMCPY -asm (".symver memcpy, memcpy@GLIBC_2.2.5"); -void *__wrap_memcpy(void *dest, const void *src, size_t n) -{ - return memcpy(dest, src, n); -} -#endif diff --git a/src/main/java/de/ailis/usb4java/AbstractDevice.java b/src/main/java/de/ailis/usb4java/AbstractDevice.java index d82191e..f7eeacb 100644 --- a/src/main/java/de/ailis/usb4java/AbstractDevice.java +++ b/src/main/java/de/ailis/usb4java/AbstractDevice.java @@ -121,7 +121,7 @@ abstract class AbstractDevice implements UsbDevice for (int i = 0; i < numConfigurations; i += 1) { final ConfigDescriptor configDescriptor = new ConfigDescriptor(); - final int result = LibUsb.getConfigDescriptor(device, i, + final int result = LibUsb.getConfigDescriptor(device, (byte) i, configDescriptor); if (result < 0) { @@ -521,8 +521,8 @@ abstract class AbstractDevice implements UsbDevice { final DeviceHandle handle = open(); final ByteBuffer buffer = ByteBuffer.allocateDirect(256); - final int result = LibUsb.getDescriptor(handle, LibUsb.DT_STRING, 0, - buffer); + final int result = LibUsb.getDescriptor(handle, LibUsb.DT_STRING, + (byte) 0, buffer); if (result < 0) throw new LibUsbException( "Unable to get string descriptor languages", result); diff --git a/src/main/java/de/ailis/usb4java/libusb/ConfigDescriptor.java b/src/main/java/de/ailis/usb4java/libusb/ConfigDescriptor.java index 175b8f5..2fcb213 100644 --- a/src/main/java/de/ailis/usb4java/libusb/ConfigDescriptor.java +++ b/src/main/java/de/ailis/usb4java/libusb/ConfigDescriptor.java @@ -113,53 +113,19 @@ public final class ConfigDescriptor implements UsbConfigurationDescriptor * @return The descriptor dump. */ public String dump() - { - return dump(null); - } - - /** - * Returns a dump of this descriptor. - * - * @param handle - * 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 StringBuilder builder = new StringBuilder(); - builder - .append(String.format("%s" - + " extralen %17d%n" - + " extra:%n" - + "%s%n", - DescriptorUtils.dump(this), - extraLength(), - DescriptorUtils.dump(extra()).replaceAll("(?m)^", " "))); - for (final Interface descriptor: iface()) - { - builder.append(descriptor.dump(handle) - .replaceAll("(?m)^", " ")); - } - return builder.toString(); - } - @Override - public boolean equals(final Object obj) - { - if (obj == null) return false; - if (obj == this) return true; - if (obj.getClass() != getClass()) return false; - final ConfigDescriptor other = (ConfigDescriptor) obj; - return new EqualsBuilder() - .append(bDescriptorType(), other.bDescriptorType()) - .append(bLength(), other.bLength()) - .append(bConfigurationValue(), other.bConfigurationValue()) - .append(bmAttributes(), other.bmAttributes()) - .append(bNumInterfaces(), other.bNumInterfaces()) - .append(iConfiguration(), other.iConfiguration()) - .append(bMaxPower(), other.bMaxPower()) - .append(wTotalLength(), other.wTotalLength()).isEquals(); + builder.append(String.format("%s%n" + " extralen %17d%n" + + " extra:%n" + "%s", DescriptorUtils.dump(this), extraLength(), + DescriptorUtils.dump(extra()).replaceAll("(?m)^", " "))); + + for (final Interface iface : iface()) + { + builder.append("%n" + iface.dump()); + } + + return builder.toString(); } @Override @@ -174,11 +140,45 @@ public final class ConfigDescriptor implements UsbConfigurationDescriptor .append(iConfiguration()) .append(bmAttributes()) .append(bMaxPower()) + .append(iface()) .append(extra()) .append(extraLength()) .toHashCode(); } + @Override + public boolean equals(final Object obj) + { + if (this == obj) + { + return true; + } + if (obj == null) + { + return false; + } + if (getClass() != obj.getClass()) + { + return false; + } + + final ConfigDescriptor other = (ConfigDescriptor) obj; + + 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() { diff --git a/src/main/java/de/ailis/usb4java/libusb/Context.java b/src/main/java/de/ailis/usb4java/libusb/Context.java index db9d0f7..fa79641 100644 --- a/src/main/java/de/ailis/usb4java/libusb/Context.java +++ b/src/main/java/de/ailis/usb4java/libusb/Context.java @@ -18,8 +18,6 @@ package de.ailis.usb4java.libusb; -import org.apache.commons.lang3.builder.HashCodeBuilder; - /** * Structure representing a libusb session. The concept of individual libusb * sessions allows for your program to use two libraries (or dynamically load @@ -41,14 +39,14 @@ public final class Context { /** The native pointer to the context structure. */ private long contextPointer; - + /** * Constructs a new libusb context. Must be passed to * {@link LibUsb#init(Context)} before passing it to any other method. */ public Context() { - // Empty + // Empty } /** @@ -60,19 +58,43 @@ public final class Context { return this.contextPointer; } - + @Override public int hashCode() { - return new HashCodeBuilder().append(this.contextPointer).toHashCode(); + final int prime = 31; + int result = 1; + result = (prime * result) + + (int) (contextPointer ^ (contextPointer >>> 32)); + return result; } - + @Override public boolean equals(final Object obj) { - if (this == obj) return true; - if (obj == null || getClass() != obj.getClass()) return false; + if (this == obj) + { + return true; + } + if (obj == null) + { + return false; + } + if (getClass() != obj.getClass()) + { + return false; + } final Context other = (Context) obj; - return this.contextPointer == other.contextPointer; - } + if (contextPointer != other.contextPointer) + { + return false; + } + return true; + } + + @Override + public String toString() + { + return String.format("libusb context 0x%x", contextPointer); + } } diff --git a/src/main/java/de/ailis/usb4java/libusb/ControlSetup.java b/src/main/java/de/ailis/usb4java/libusb/ControlSetup.java new file mode 100644 index 0000000..566c85d --- /dev/null +++ b/src/main/java/de/ailis/usb4java/libusb/ControlSetup.java @@ -0,0 +1,131 @@ +package de.ailis.usb4java.libusb; + +import java.nio.ByteBuffer; +import java.nio.ByteOrder; + +import de.ailis.usb4java.utils.BufferUtils; + +public final class ControlSetup +{ + private final ByteBuffer controlSetup; + + ControlSetup(final ByteBuffer buffer) + { + if (buffer == null) + { + throw new IllegalArgumentException("buffer cannot be null"); + } + + controlSetup = BufferUtils.slice(buffer, 0, LibUsb.CONTROL_SETUP_SIZE); + + // Control Setup (as all of USB) is Little Endian. + controlSetup.order(ByteOrder.LITTLE_ENDIAN); + } + + /** + * USB Control Setup is always 8 bytes long. + * Structured as follows: + * byte 0: bmRequestType + * byte 1: bRequest + * bytes 2-3: wValue (Little Endian) + * bytes 4-5: wIndex (Little Endian) + * bytes 6-7: wLength (Little Endian) + */ + + public byte bmRequestType() + { + return controlSetup.get(0); + } + + public void setBmRequestType(final byte bmRequestType) + { + controlSetup.put(0, bmRequestType); + } + + public byte bRequest() + { + return controlSetup.get(1); + } + + public void setBRequest(final byte bRequest) + { + controlSetup.put(1, bRequest); + } + + public short wValue() + { + return controlSetup.getShort(2); + } + + public void setWValue(final short wValue) + { + controlSetup.putShort(2, wValue); + } + + public short wIndex() + { + return controlSetup.getShort(4); + } + + public void setWIndex(final short wIndex) + { + controlSetup.putShort(4, wIndex); + } + + public short wLength() + { + return controlSetup.getShort(6); + } + + public void setWLength(final short wLength) + { + controlSetup.putShort(6, wLength); + } + + @Override + public int hashCode() + { + final int prime = 31; + int result = 1; + result = (prime * result) + + ((controlSetup == null) ? 0 : controlSetup.hashCode()); + return result; + } + + @Override + public boolean equals(final Object obj) + { + if (this == obj) + { + return true; + } + if (obj == null) + { + return false; + } + if (getClass() != obj.getClass()) + { + return false; + } + final ControlSetup other = (ControlSetup) obj; + if (controlSetup == null) + { + if (other.controlSetup != null) + { + return false; + } + } + else if (!controlSetup.equals(other.controlSetup)) + { + return false; + } + return true; + } + + @Override + public String toString() + { + return String.format("libusb control setup with buffer %s", + controlSetup.toString()); + } +} diff --git a/src/main/java/de/ailis/usb4java/libusb/Device.java b/src/main/java/de/ailis/usb4java/libusb/Device.java index 2af764e..16bd6a3 100644 --- a/src/main/java/de/ailis/usb4java/libusb/Device.java +++ b/src/main/java/de/ailis/usb4java/libusb/Device.java @@ -18,8 +18,6 @@ package de.ailis.usb4java.libusb; -import org.apache.commons.lang3.builder.HashCodeBuilder; - /** * Structure representing a USB device detected on the system. * @@ -54,7 +52,7 @@ public final class Device { // Empty } - + /** * Returns the native pointer to the device structure. * @@ -64,25 +62,43 @@ public final class Device { return this.devicePointer; } - + @Override public int hashCode() { - return new HashCodeBuilder().append(this.devicePointer).toHashCode(); + final int prime = 31; + int result = 1; + result = (prime * result) + + (int) (devicePointer ^ (devicePointer >>> 32)); + return result; } @Override public boolean equals(final Object obj) { - if (this == obj) return true; - if (obj == null || getClass() != obj.getClass()) return false; + if (this == obj) + { + return true; + } + if (obj == null) + { + return false; + } + if (getClass() != obj.getClass()) + { + return false; + } final Device other = (Device) obj; - return this.devicePointer == other.devicePointer; + if (devicePointer != other.devicePointer) + { + return false; + } + return true; } @Override public String toString() { - return String.format("libusb device 0x%x", this.devicePointer); + return String.format("libusb device 0x%x", devicePointer); } } diff --git a/src/main/java/de/ailis/usb4java/libusb/DeviceDescriptor.java b/src/main/java/de/ailis/usb4java/libusb/DeviceDescriptor.java index 3056e70..2d2968a 100644 --- a/src/main/java/de/ailis/usb4java/libusb/DeviceDescriptor.java +++ b/src/main/java/de/ailis/usb4java/libusb/DeviceDescriptor.java @@ -18,8 +18,6 @@ package de.ailis.usb4java.libusb; -import java.nio.ByteBuffer; - import javax.usb.UsbDeviceDescriptor; import org.apache.commons.lang3.builder.EqualsBuilder; @@ -37,8 +35,8 @@ import de.ailis.usb4java.utils.DescriptorUtils; */ public final class DeviceDescriptor implements UsbDeviceDescriptor { - /** The native data of the descriptor structure. */ - private ByteBuffer deviceDescriptorData; + /** The native pointer to the descriptor structure. */ + private long deviceDescriptorPointer; /** * Constructs a new device descriptor which can be passed to the @@ -50,13 +48,13 @@ public final class DeviceDescriptor implements UsbDeviceDescriptor } /** - * Returns the native data of the descriptor structure. + * Returns the native pointer. * - * @return The native data. + * @return The native pointer. */ - public ByteBuffer getData() + public long getPointer() { - return this.deviceDescriptorData; + return this.deviceDescriptorPointer; } @Override @@ -121,41 +119,15 @@ public final class DeviceDescriptor implements UsbDeviceDescriptor */ public String dump(final DeviceHandle handle) { - final String sManufacturer = LibUsb.getStringDescriptor(handle, + final String sManufacturer = LibUsb.getStringDescriptor(handle, iManufacturer()); final String sProduct = LibUsb.getStringDescriptor(handle, iProduct()); - final String sSerialNumber = LibUsb.getStringDescriptor(handle, + final String sSerialNumber = LibUsb.getStringDescriptor(handle, iSerialNumber()); - return DescriptorUtils.dump(this, sManufacturer, sProduct, + return DescriptorUtils.dump(this, sManufacturer, sProduct, sSerialNumber); } - @Override - public boolean equals(final Object obj) - { - if (obj == null) return false; - if (obj == this) return true; - if (obj.getClass() != getClass()) return false; - final DeviceDescriptor other = (DeviceDescriptor) obj; - return new EqualsBuilder() - .append(bDescriptorType(), other.bDescriptorType()) - .append(bLength(), other.bLength()) - .append(idProduct(), other.idProduct()) - .append(idVendor(), other.idVendor()) - .append(bcdDevice(), other.bcdDevice()) - .append(bcdUSB(), other.bcdUSB()) - .append(bDescriptorType(), other.bDescriptorType()) - .append(bDeviceClass(), other.bDeviceClass()) - .append(bDeviceProtocol(), other.bDeviceProtocol()) - .append(bDeviceSubClass(), other.bDeviceSubClass()) - .append(bLength(), other.bLength()) - .append(bMaxPacketSize0(), other.bMaxPacketSize0()) - .append(bNumConfigurations(), other.bNumConfigurations()) - .append(iManufacturer(), other.iManufacturer()) - .append(iProduct(), other.iProduct()) - .append(iSerialNumber(), other.iSerialNumber()).isEquals(); - } - @Override public int hashCode() { @@ -173,7 +145,44 @@ public final class DeviceDescriptor implements UsbDeviceDescriptor .append(iManufacturer()) .append(iProduct()) .append(iSerialNumber()) - .append(bNumConfigurations()).toHashCode(); + .append(bNumConfigurations()) + .toHashCode(); + } + + @Override + public boolean equals(final Object obj) + { + if (this == obj) + { + return true; + } + if (obj == null) + { + return false; + } + if (getClass() != obj.getClass()) + { + return false; + } + + final DeviceDescriptor other = (DeviceDescriptor) obj; + + return new EqualsBuilder() + .append(bLength(), other.bLength()) + .append(bDescriptorType(), other.bDescriptorType()) + .append(bcdUSB(), other.bcdUSB()) + .append(bDeviceClass(), other.bDeviceClass()) + .append(bDeviceSubClass(), other.bDeviceSubClass()) + .append(bDeviceProtocol(), other.bDeviceProtocol()) + .append(bMaxPacketSize0(), other.bMaxPacketSize0()) + .append(idVendor(), other.idVendor()) + .append(idProduct(), other.idProduct()) + .append(bcdDevice(), other.bcdDevice()) + .append(iManufacturer(), other.iManufacturer()) + .append(iProduct(), other.iProduct()) + .append(iSerialNumber(), other.iSerialNumber()) + .append(bNumConfigurations(), other.bNumConfigurations()) + .isEquals(); } @Override diff --git a/src/main/java/de/ailis/usb4java/libusb/DeviceHandle.java b/src/main/java/de/ailis/usb4java/libusb/DeviceHandle.java index 3a0f762..371083b 100644 --- a/src/main/java/de/ailis/usb4java/libusb/DeviceHandle.java +++ b/src/main/java/de/ailis/usb4java/libusb/DeviceHandle.java @@ -18,8 +18,6 @@ package de.ailis.usb4java.libusb; -import org.apache.commons.lang3.builder.HashCodeBuilder; - /** * Structure representing a handle on a USB device. * @@ -59,22 +57,39 @@ public final class DeviceHandle @Override public int hashCode() { - return new HashCodeBuilder().append(this.deviceHandlePointer) - .toHashCode(); + final int prime = 31; + int result = 1; + result = (prime * result) + + (int) (deviceHandlePointer ^ (deviceHandlePointer >>> 32)); + return result; } @Override public boolean equals(final Object obj) { - if (this == obj) return true; - if (obj == null || getClass() != obj.getClass()) return false; + if (this == obj) + { + return true; + } + if (obj == null) + { + return false; + } + if (getClass() != obj.getClass()) + { + return false; + } final DeviceHandle other = (DeviceHandle) obj; - return this.deviceHandlePointer == other.deviceHandlePointer; + if (deviceHandlePointer != other.deviceHandlePointer) + { + return false; + } + return true; } @Override public String toString() { - return String.format("libusb handle 0x%x", this.deviceHandlePointer); + return String.format("libusb device handle 0x%x", deviceHandlePointer); } } diff --git a/src/main/java/de/ailis/usb4java/libusb/DeviceList.java b/src/main/java/de/ailis/usb4java/libusb/DeviceList.java index 8c2ee99..09b0fad 100644 --- a/src/main/java/de/ailis/usb4java/libusb/DeviceList.java +++ b/src/main/java/de/ailis/usb4java/libusb/DeviceList.java @@ -20,8 +20,6 @@ package de.ailis.usb4java.libusb; import java.util.Iterator; -import org.apache.commons.lang3.builder.HashCodeBuilder; - /** * List of devices as returned by * {@link LibUsb#getDeviceList(Context, DeviceList)}. @@ -43,7 +41,7 @@ public final class DeviceList implements Iterable public DeviceList() { // Empty - } + } /** * Returns the native pointer. @@ -54,7 +52,7 @@ public final class DeviceList implements Iterable { return this.deviceListPointer; } - + /** * Returns the number of devices in the list. * @@ -83,16 +81,45 @@ public final class DeviceList implements Iterable @Override public int hashCode() { - return new HashCodeBuilder().append(this.deviceListPointer) - .toHashCode(); + final int prime = 31; + int result = 1; + result = (prime * result) + + (int) (deviceListPointer ^ (deviceListPointer >>> 32)); + result = (prime * result) + size; + return result; } @Override public boolean equals(final Object obj) { - if (this == obj) return true; - if (obj == null || getClass() != obj.getClass()) return false; + if (this == obj) + { + return true; + } + if (obj == null) + { + return false; + } + if (getClass() != obj.getClass()) + { + return false; + } final DeviceList other = (DeviceList) obj; - return this.deviceListPointer == other.deviceListPointer; + if (deviceListPointer != other.deviceListPointer) + { + return false; + } + if (size != other.size) + { + return false; + } + return true; + } + + @Override + public String toString() + { + return String.format("libusb device list 0x%x with size %d", + deviceListPointer, size); } } diff --git a/src/main/java/de/ailis/usb4java/libusb/DeviceListIterator.java b/src/main/java/de/ailis/usb4java/libusb/DeviceListIterator.java index 7deeacf..7e9bd1a 100644 --- a/src/main/java/de/ailis/usb4java/libusb/DeviceListIterator.java +++ b/src/main/java/de/ailis/usb4java/libusb/DeviceListIterator.java @@ -34,13 +34,13 @@ final class DeviceListIterator implements Iterator @Override public boolean hasNext() { - return this.nextIndex < this.devices.getSize(); + return nextIndex < devices.getSize(); } @Override public Device next() { - return this.devices.get(this.nextIndex++); + return devices.get(nextIndex++); } @Override diff --git a/src/main/java/de/ailis/usb4java/libusb/EndpointDescriptor.java b/src/main/java/de/ailis/usb4java/libusb/EndpointDescriptor.java index 459f49a..40b4065 100644 --- a/src/main/java/de/ailis/usb4java/libusb/EndpointDescriptor.java +++ b/src/main/java/de/ailis/usb4java/libusb/EndpointDescriptor.java @@ -41,14 +41,14 @@ public final class EndpointDescriptor implements UsbEndpointDescriptor private long endpointDescriptorPointer; /** - * Package-private constructor to prevent manual instantiation. Endpoint + * Package-private constructor to prevent manual instantiation. Endpoint * descriptors are always created by JNI. */ EndpointDescriptor() { // Empty } - + /** * Returns the native pointer. * @@ -116,35 +116,15 @@ public final class EndpointDescriptor implements UsbEndpointDescriptor */ public String dump() { - return String.format("%s" + return String.format("%s%n" + " extralen %17d%n" + " extra:%n" - + "%s%n", + + "%s", DescriptorUtils.dump(this), extraLength(), DescriptorUtils.dump(extra()).replaceAll("(?m)^", " ")); } - @Override - public boolean equals(final Object obj) - { - if (obj == null) return false; - if (obj == this) return true; - if (obj.getClass() != getClass()) return false; - final EndpointDescriptor other = (EndpointDescriptor) obj; - return new EqualsBuilder() - .append(bDescriptorType(), other.bDescriptorType()) - .append(bLength(), other.bLength()) - .append(bEndpointAddress(), other.bEndpointAddress()) - .append(bmAttributes(), other.bmAttributes()) - .append(bInterval(), other.bInterval()) - .append(bSynchAddress(), other.bSynchAddress()) - .append(wMaxPacketSize(), other.wMaxPacketSize()) - .append(extraLength(), other.extraLength()) - .append(extra(), other.extra()) - .isEquals(); - } - @Override public int hashCode() { @@ -162,6 +142,38 @@ public final class EndpointDescriptor implements UsbEndpointDescriptor .toHashCode(); } + @Override + public boolean equals(final Object obj) + { + if (this == obj) + { + return true; + } + if (obj == null) + { + return false; + } + if (getClass() != obj.getClass()) + { + return false; + } + + final EndpointDescriptor other = (EndpointDescriptor) obj; + + return new EqualsBuilder() + .append(bLength(), other.bLength()) + .append(bDescriptorType(), other.bDescriptorType()) + .append(bEndpointAddress(), other.bEndpointAddress()) + .append(bmAttributes(), other.bmAttributes()) + .append(wMaxPacketSize(), other.wMaxPacketSize()) + .append(bInterval(), other.bInterval()) + .append(bRefresh(), other.bRefresh()) + .append(bSynchAddress(), other.bSynchAddress()) + .append(extra(), other.extra()) + .append(extraLength(), other.extraLength()) + .isEquals(); + } + @Override public String toString() { diff --git a/src/main/java/de/ailis/usb4java/libusb/Interface.java b/src/main/java/de/ailis/usb4java/libusb/Interface.java index dc1659f..20f3d3d 100644 --- a/src/main/java/de/ailis/usb4java/libusb/Interface.java +++ b/src/main/java/de/ailis/usb4java/libusb/Interface.java @@ -18,6 +18,7 @@ package de.ailis.usb4java.libusb; +import org.apache.commons.lang3.builder.EqualsBuilder; import org.apache.commons.lang3.builder.HashCodeBuilder; /** @@ -31,14 +32,14 @@ public final class Interface private long interfacePointer; /** - * Package-private constructor to prevent manual instantiation. Interfaces + * Package-private constructor to prevent manual instantiation. Interfaces * are always created by JNI. */ Interface() { // Empty } - + /** * Returns the native pointer. * @@ -48,7 +49,7 @@ public final class Interface { return this.interfacePointer; } - + /** * Returns the array with interface descriptors. The length of this array is * determined by the {@link #numAltsetting()} field. @@ -70,43 +71,53 @@ public final class Interface * @return The interface dump. */ public String dump() - { - return dump(null); - } - - /** - * Returns a dump of this descriptor. - * - * @param handle - * 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 StringBuilder builder = new StringBuilder(); - for (final InterfaceDescriptor descriptor : altsetting()) + + builder.append(String.format("Interface:%n" + " numAltsetting %10d", + numAltsetting())); + + for (final InterfaceDescriptor intDesc : altsetting()) { - builder.append(descriptor.dump(handle)); + builder.append("%n" + intDesc.dump()); } + return builder.toString(); } @Override public int hashCode() { - return new HashCodeBuilder().append(this.interfacePointer).toHashCode(); + return new HashCodeBuilder() + .append(altsetting()) + .append(numAltsetting()) + .toHashCode(); } @Override public boolean equals(final Object obj) { - if (this == obj) return true; - if (obj == null || getClass() != obj.getClass()) return false; + if (this == obj) + { + return true; + } + if (obj == null) + { + return false; + } + if (getClass() != obj.getClass()) + { + return false; + } + final Interface other = (Interface) obj; - return this.interfacePointer == other.interfacePointer; + + return new EqualsBuilder() + .append(altsetting(), other.altsetting()) + .append(numAltsetting(), other.numAltsetting()) + .isEquals(); } - + @Override public String toString() { diff --git a/src/main/java/de/ailis/usb4java/libusb/InterfaceDescriptor.java b/src/main/java/de/ailis/usb4java/libusb/InterfaceDescriptor.java index d781646..b9bf465 100644 --- a/src/main/java/de/ailis/usb4java/libusb/InterfaceDescriptor.java +++ b/src/main/java/de/ailis/usb4java/libusb/InterfaceDescriptor.java @@ -41,14 +41,14 @@ public final class InterfaceDescriptor implements UsbInterfaceDescriptor private long interfaceDescriptorPointer; /** - * Package-private constructor to prevent manual instantiation. Interface + * Package-private constructor to prevent manual instantiation. Interface * descriptors are always created by JNI. */ InterfaceDescriptor() { // Empty } - + /** * Returns the native pointer. * @@ -116,59 +116,19 @@ public final class InterfaceDescriptor implements UsbInterfaceDescriptor * @return The descriptor dump. */ public String dump() - { - return dump(null); - } - - /** - * Returns a dump of this descriptor. - * - * @param handle - * 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 StringBuilder builder = new StringBuilder(); - final int iInterface = iInterface(); - String sInterface = LibUsb.getStringDescriptor(handle, iInterface); - if (sInterface == null) sInterface = ""; - builder.append(String.format("%s" - + " extralen %17d%n" - + " extra:%n" - + "%s%n", - DescriptorUtils.dump(this), - extraLength(), - DescriptorUtils.dump(extra()).replaceAll("(?m)^", " "))); - if (extraLength() != 0) return builder.toString(); - for (final EndpointDescriptor edesc: endpoint()) - { - builder.append(edesc.dump().replaceAll("(?m)^", " ")); - } - return builder.toString(); - } - @Override - public boolean equals(final Object obj) - { - if (obj == null) return false; - if (obj == this) return true; - if (obj.getClass() != getClass()) return false; - final InterfaceDescriptor other = (InterfaceDescriptor) obj; - return new EqualsBuilder() - .append(bDescriptorType(), other.bDescriptorType()) - .append(bLength(), other.bLength()) - .append(bAlternateSetting(), other.bAlternateSetting()) - .append(bInterfaceClass(), other.bInterfaceClass()) - .append(bInterfaceNumber(), other.bInterfaceNumber()) - .append(bInterfaceProtocol(), other.bInterfaceProtocol()) - .append(bInterfaceSubClass(), other.bInterfaceSubClass()) - .append(bNumEndpoints(), other.bNumEndpoints()) - .append(iInterface(), other.iInterface()) - .append(extraLength(), other.extraLength()) - .append(extra(), other.extra()) - .isEquals(); + builder.append(String.format("%s%n" + " extralen %17d%n" + + " extra:%n" + "%s", DescriptorUtils.dump(this), extraLength(), + DescriptorUtils.dump(extra()).replaceAll("(?m)^", " "))); + + for (final EndpointDescriptor epDesc : endpoint()) + { + builder.append("%n" + epDesc.dump()); + } + + return builder.toString(); } @Override @@ -184,11 +144,46 @@ public final class InterfaceDescriptor implements UsbInterfaceDescriptor .append(bInterfaceSubClass()) .append(bInterfaceProtocol()) .append(iInterface()) + .append(endpoint()) .append(extra()) .append(extraLength()) .toHashCode(); } + @Override + public boolean equals(final Object obj) + { + if (this == obj) + { + return true; + } + if (obj == null) + { + return false; + } + if (getClass() != obj.getClass()) + { + return false; + } + + final InterfaceDescriptor other = (InterfaceDescriptor) obj; + + return new EqualsBuilder() + .append(bLength(), other.bLength()) + .append(bDescriptorType(), other.bDescriptorType()) + .append(bInterfaceNumber(), other.bInterfaceNumber()) + .append(bAlternateSetting(), other.bAlternateSetting()) + .append(bNumEndpoints(), other.bNumEndpoints()) + .append(bInterfaceClass(), other.bInterfaceClass()) + .append(bInterfaceSubClass(), other.bInterfaceSubClass()) + .append(bInterfaceProtocol(), other.bInterfaceProtocol()) + .append(iInterface(), other.iInterface()) + .append(endpoint(), other.endpoint()) + .append(extra(), other.extra()) + .append(extraLength(), other.extraLength()) + .isEquals(); + } + @Override public String toString() { diff --git a/src/main/java/de/ailis/usb4java/libusb/IsoPacketDescriptor.java b/src/main/java/de/ailis/usb4java/libusb/IsoPacketDescriptor.java new file mode 100644 index 0000000..4a9daab --- /dev/null +++ b/src/main/java/de/ailis/usb4java/libusb/IsoPacketDescriptor.java @@ -0,0 +1,77 @@ +package de.ailis.usb4java.libusb; + +public final class IsoPacketDescriptor +{ + /** The native pointer to the descriptor structure. */ + private long isoPacketDescriptorPointer; + + /** + * Package-private constructor to prevent manual instantiation. + * IsoPacketDescriptors are always created by JNI. + */ + IsoPacketDescriptor() + { + // Empty + } + + /** + * Returns the native pointer. + * + * @return The native pointer. + */ + public long getPointer() + { + return isoPacketDescriptorPointer; + } + + public native int length(); + + // 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 native int actualLength(); + + public native int status(); + + @Override + public int hashCode() + { + final int prime = 31; + int result = 1; + result = (prime * result) + + (int) (isoPacketDescriptorPointer ^ (isoPacketDescriptorPointer >>> 32)); + return result; + } + + @Override + public boolean equals(final Object obj) + { + if (this == obj) + { + return true; + } + if (obj == null) + { + return false; + } + if (getClass() != obj.getClass()) + { + return false; + } + final IsoPacketDescriptor other = (IsoPacketDescriptor) obj; + if (isoPacketDescriptorPointer != other.isoPacketDescriptorPointer) + { + return false; + } + return true; + } + + @Override + public String toString() + { + return String.format("libusb iso packet descriptor 0x%x", + isoPacketDescriptorPointer); + } +} diff --git a/src/main/java/de/ailis/usb4java/libusb/LibUsb.java b/src/main/java/de/ailis/usb4java/libusb/LibUsb.java index 949957a..4be1897 100644 --- a/src/main/java/de/ailis/usb4java/libusb/LibUsb.java +++ b/src/main/java/de/ailis/usb4java/libusb/LibUsb.java @@ -21,6 +21,13 @@ package de.ailis.usb4java.libusb; import java.io.FileDescriptor; import java.nio.ByteBuffer; import java.nio.IntBuffer; +import java.nio.LongBuffer; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; + +import org.apache.commons.lang3.tuple.ImmutablePair; + +import de.ailis.usb4java.utils.BufferUtils; /** * Static class providing the constants and functions of libusb. @@ -159,75 +166,75 @@ public final class LibUsb // Standard requests, as defined in table 9-5 of the USB 3.0 specifications. /** Request status of the specific recipient. */ - public static final int REQUEST_GET_STATUS = 0x00; + public static final byte REQUEST_GET_STATUS = 0x00; /** Clear or disable a specific feature. */ - public static final int REQUEST_CLEAR_FEATURE = 0x01; + public static final byte REQUEST_CLEAR_FEATURE = 0x01; /** Set or enable a specific feature. */ - public static final int REQUEST_SET_FEATURE = 0x03; + public static final byte REQUEST_SET_FEATURE = 0x03; /** Set device address for all future accesses. */ - public static final int REQUEST_SET_ADDRESS = 0x05; + public static final byte REQUEST_SET_ADDRESS = 0x05; /** Set device address for all future accesses. */ - public static final int REQUEST_GET_DESCRIPTOR = 0x06; + public static final byte REQUEST_GET_DESCRIPTOR = 0x06; /** Set device address for all future accesses. */ - public static final int REQUEST_SET_DESCRIPTOR = 0x07; + public static final byte REQUEST_SET_DESCRIPTOR = 0x07; /** Get the current device configuration value. */ - public static final int REQUEST_GET_CONFIGURATION = 0x08; + public static final byte REQUEST_GET_CONFIGURATION = 0x08; /** Get the current device configuration value. */ - public static final int REQUEST_SET_CONFIGURATION = 0x09; + public static final byte REQUEST_SET_CONFIGURATION = 0x09; /** Return the selected alternate setting for the specified interface. */ - public static final int REQUEST_GET_INTERFACE = 0x0a; + public static final byte REQUEST_GET_INTERFACE = 0x0A; /** Select an alternate interface for the specified interface. */ - public static final int REQUEST_SET_INTERFACE = 0x0b; + public static final byte REQUEST_SET_INTERFACE = 0x0B; /** Set then report an endpoint's synchronization frame. */ - public static final int REQUEST_SYNCH_FRAME = 0x0c; + public static final byte REQUEST_SYNCH_FRAME = 0x0C; /** Sets both the U1 and U2 Exit Latency. */ - public static final int REQUEST_SET_SEL = 0x30; + 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. */ - public static final int SET_ISOCH_DELAY = 0x31; + public static final byte SET_ISOCH_DELAY = 0x31; // Request type bits of the bmRequestType field in control transfers. /** Standard. */ - public static final int REQUEST_TYPE_STANDARD = 0; + public static final byte REQUEST_TYPE_STANDARD = 0; /** Class. */ - public static final int REQUEST_TYPE_CLASS = 32; + public static final byte REQUEST_TYPE_CLASS = 32; /** Vendor. */ - public static final int REQUEST_TYPE_VENDOR = 64; + public static final byte REQUEST_TYPE_VENDOR = 64; /** Reserved. */ - public static final int REQUEST_TYPE_RESERVED = 96; + public static final byte REQUEST_TYPE_RESERVED = 96; // Recipient bits of the bmRequestType field in control transfers. // Values 4 through 31 are reserved. /** Device. */ - public static final int RECIPIENT_DEVICE = 0x00; + public static final byte RECIPIENT_DEVICE = 0x00; /** Interface. */ - public static final int RECIPIENT_INTERFACE = 0x01; + public static final byte RECIPIENT_INTERFACE = 0x01; /** Endpoint. */ - public static final int RECIPIENT_ENDPOINT = 0x02; + public static final byte RECIPIENT_ENDPOINT = 0x02; /** Other. */ - public static final int RECIPIENT_OTHER = 0x03; + public static final byte RECIPIENT_OTHER = 0x03; // Capabilities supported by an instance of libusb on the current running // platform. Test if the loaded library supports a given capability by @@ -254,6 +261,8 @@ public final class LibUsb */ public static final int CAP_SUPPORTS_DETACH_KERNEL_DRIVER = 0x0101; + public static final short CONTROL_SETUP_SIZE = 8; + // Device and/or Interface Class codes. /** @@ -261,61 +270,61 @@ public final class LibUsb * that each interface specifies its own class information and all * interfaces operate independently. */ - public static final int CLASS_PER_INTERFACE = 0; + public static final byte CLASS_PER_INTERFACE = 0; /** Audio class. */ - public static final int CLASS_AUDIO = 1; + public static final byte CLASS_AUDIO = 1; /** Communications class. */ - public static final int CLASS_COMM = 2; + public static final byte CLASS_COMM = 2; /** Human Interface Device class. */ - public static final int CLASS_HID = 3; + public static final byte CLASS_HID = 3; /** Physical. */ - public static final int CLASS_PHYSICAL = 5; + public static final byte CLASS_PHYSICAL = 5; /** Image class. */ - public static final int CLASS_PTP = 6; + public static final byte CLASS_PTP = 6; /** Image class. */ - public static final int CLASS_IMAGE = 6; + public static final byte CLASS_IMAGE = 6; /** Printer class. */ - public static final int CLASS_PRINTER = 7; + public static final byte CLASS_PRINTER = 7; /** Mass storage class. */ - public static final int CLASS_MASS_STORAGE = 8; + public static final byte CLASS_MASS_STORAGE = 8; /** Hub class. */ - public static final int CLASS_HUB = 9; + public static final byte CLASS_HUB = 9; /** Data class. */ - public static final int CLASS_DATA = 10; + public static final byte CLASS_DATA = 10; /** Smart Card. */ - public static final int CLASS_SMART_CARD = 0x0b; + public static final byte CLASS_SMART_CARD = 0x0B; /** Content Security. */ - public static final int CLASS_CONTENT_SECURITY = 0x0d; + public static final byte CLASS_CONTENT_SECURITY = 0x0D; /** Video. */ - public static final int CLASS_VIDEO = 0x0e; + public static final byte CLASS_VIDEO = 0x0E; /** Personal Healthcare. */ - public static final int CLASS_PERSONAL_HEALTHCARE = 0x0f; + public static final byte CLASS_PERSONAL_HEALTHCARE = 0x0F; /** Diagnostic Device. */ - public static final int CLASS_DIAGNOSTIC_DEVICE = 0xdc; + public static final byte CLASS_DIAGNOSTIC_DEVICE = (byte) 0xDC; /** Wireless class. */ - public static final int CLASS_WIRELESS = 0xe0; + public static final byte CLASS_WIRELESS = (byte) 0xE0; /** Application class. */ - public static final int CLASS_APPLICATION = 0xfe; + public static final byte CLASS_APPLICATION = (byte) 0xFE; /** Class is vendor-specific. */ - public static final int CLASS_VENDOR_SPEC = 0xff; + public static final byte CLASS_VENDOR_SPEC = (byte) 0xFF; // Descriptor types as defined by the USB specification. @@ -324,160 +333,170 @@ public final class LibUsb * * @see DeviceDescriptor */ - public static final int DT_DEVICE = 0x01; + public static final byte DT_DEVICE = 0x01; /** * Configuration descriptor. * * @see ConfigDescriptor */ - public static final int DT_CONFIG = 0x02; + public static final byte DT_CONFIG = 0x02; /** String descriptor. */ - public static final int DT_STRING = 0x03; + public static final byte DT_STRING = 0x03; /** * Interface descriptor. * * @see InterfaceDescriptor */ - public static final int DT_INTERFACE = 0x04; + public static final byte DT_INTERFACE = 0x04; /** * Endpoint descriptor. * * @see EndpointDescriptor */ - public static final int DT_ENDPOINT = 0x05; + public static final byte DT_ENDPOINT = 0x05; /** * BOS descriptor. * * @see BosDescriptor */ - public static final int DT_BOS = 0x0f; + public static final byte DT_BOS = 0x0F; /** * Device Capability descriptor. * * @see BosDevCapabilityDescriptor */ - public static final int DT_DEVICE_CAPABILITY = 0x10; + public static final byte DT_DEVICE_CAPABILITY = 0x10; /** HID descriptor. */ - public static final int DT_HID = 0x21; + public static final byte DT_HID = 0x21; /** HID report descriptor. */ - public static final int DT_REPORT = 0x22; + public static final byte DT_REPORT = 0x22; /** Physical descriptor. */ - public static final int DT_PHYSICAL = 0x23; + public static final byte DT_PHYSICAL = 0x23; /** Hub descriptor. */ - public static final int DT_HUB = 0x29; + public static final byte DT_HUB = 0x29; /** SuperSpeed Hub descriptor. */ - public static final int DT_SUPERSPEED_HUB = 0x2a; + public static final byte DT_SUPERSPEED_HUB = 0x2A; /** * SuperSpeed Endpoint Companion descriptor. * * @see SsEndpointCompanionDescriptor */ - public static final int DT_SS_ENDPOINT_COMPANION = 0x30; + public static final byte DT_SS_ENDPOINT_COMPANION = 0x30; // Descriptor sizes per descriptor type /** Size of a device descriptor. */ - public static final int DT_DEVICE_SIZE = 18; + public static final byte DT_DEVICE_SIZE = 18; /** Size of a config descriptor. */ - public static final int DT_CONFIG_SIZE = 9; + public static final byte DT_CONFIG_SIZE = 9; /** Size of an interface descriptor. */ - public static final int DT_INTERFACE_SIZE = 9; + public static final byte DT_INTERFACE_SIZE = 9; /** Size of an interface descriptor. */ - public static final int DT_ENDPOINT_SIZE = 7; + public static final byte DT_ENDPOINT_SIZE = 7; /** Size of an interface descriptor. */ - public static final int DT_ENDPOINT_AUDIO_SIZE = 9; + public static final byte DT_ENDPOINT_AUDIO_SIZE = 9; /** Size of an interface descriptor. */ - public static final int DT_HUB_NONVAR_SIZE = 7; + public static final byte DT_HUB_NONVAR_SIZE = 7; // Endpoint direction. Values for bit 7 of the endpoint address scheme. /** In: device-to-host. */ - public static final int ENDPOINT_IN = 0x80; + public static final byte ENDPOINT_IN = (byte) 0x80; /** Out: host-to-device. */ - public static final int ENDPOINT_OUT = 0x00; + public static final byte ENDPOINT_OUT = 0x00; // === Masks ============================================================= /** Endpoint address mask. */ - public static final int ENDPOINT_ADDRESS_MASK = 0x0f; + public static final byte ENDPOINT_ADDRESS_MASK = 0x0F; /** Endpoint direction mask. */ - public static final int ENDPOINT_DIR_MASK = 0x80; + public static final byte ENDPOINT_DIR_MASK = (byte) 0x80; /** Transfer type mask. */ - public static final int TRANSFER_TYPE_MASK = 0x03; + public static final byte TRANSFER_TYPE_MASK = 0x03; // Endpoint transfer type. Values for bits 0:1 of the endpoint attributes // field. /** Control endpoint. */ - public static final int TRANSFER_TYPE_CONTROL = 0; + public static final byte TRANSFER_TYPE_CONTROL = 0; /** Isochronous endpoint. */ - public static final int TRANSFER_TYPE_ISOCHRONOUS = 1; + public static final byte TRANSFER_TYPE_ISOCHRONOUS = 1; /** Bulk endpoint. */ - public static final int TRANSFER_TYPE_BULK = 2; + public static final byte TRANSFER_TYPE_BULK = 2; /** Interrupt endpoint. */ - public static final int TRANSFER_TYPE_INTERRUPT = 3; + public static final byte TRANSFER_TYPE_INTERRUPT = 3; // Synchronization type for isochronous endpoints. // Values for bits 2:3 of the bmAttributes field in // EndpointDescriptor. + public static final byte ISO_SYNC_TYPE_MASK = 0x0C; + /** No synchronization. */ - public static final int ISO_SYNC_TYPE_NONE = 0; + public static final byte ISO_SYNC_TYPE_NONE = 0; /** Asynchronous. */ - public static final int ISO_SYNC_TYPE_ASYNC = 1; + public static final byte ISO_SYNC_TYPE_ASYNC = 1; /** Adaptive. */ - public static final int ISO_SYNC_TYPE_ADAPTIVE = 2; + public static final byte ISO_SYNC_TYPE_ADAPTIVE = 2; /** Synchronous. */ - public static final int ISO_SYNC_TYPE_SYNC = 3; + public static final byte ISO_SYNC_TYPE_SYNC = 3; // Usage type for isochronous endpoints. Values for bits 4:5 of the // bmAttributes field in EndpointDescriptor. + public static final byte ISO_USAGE_TYPE_MASK = 0x30; + /** Data endpoint. */ - public static final int ISO_USAGE_TYPE_DATA = 0; + public static final byte ISO_USAGE_TYPE_DATA = 0; /** Feedback endpoint. */ - public static final int ISO_USAGE_TYPE_FEEDBACK = 1; + public static final byte ISO_USAGE_TYPE_FEEDBACK = 1; /** Implicit feedback Data endpoint. */ - public static final int ISO_USAGE_TYPE_IMPLICIT = 2; + public static final byte ISO_USAGE_TYPE_IMPLICIT = 2; /** Report short frames as errors. */ - public static final int TRANSFER_SHORT_NOT_OK = 1; + public static final byte TRANSFER_SHORT_NOT_OK = 1; // Transfer flags /** * Automatically free transfer buffer during {@link #freeTransfer(Transfer)} - * TODO Not sure how to do this memory management between Java and C. + * + * Please note that this flag 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 int TRANSFER_FREE_BUFFER = 2; + public static final byte TRANSFER_FREE_BUFFER = 0; // Originally 2 /** * Automatically call {@link #freeTransfer(Transfer)} after callback @@ -487,7 +506,7 @@ public final class LibUsb * {@link #freeTransfer(Transfer)} from your transfer callback, as this will * result in a double-free when this flag is acted upon. */ - public static final int TRANSFER_FREE_TRANSFER = 4; + public static final byte TRANSFER_FREE_TRANSFER = 4; /** * Terminate transfers that are a multiple of the endpoint's wMaxPacketSize @@ -511,7 +530,7 @@ public final class LibUsb * libusb_submit_transfer() will return {@link #ERROR_NOT_SUPPORTED} for * every transfer where this flag is set. */ - public static final int TRANSFER_ADD_ZERO_PACKET = 8; + public static final byte TRANSFER_ADD_ZERO_PACKET = 8; // Transfer status codes @@ -542,14 +561,11 @@ public final class LibUsb /** Device sent more data than requested. */ public static final int TRANSFER_OVERFLOW = 6; - /** The maximum size of a string (Unicode). */ - private static final int MAX_STRING_SIZE = 126; - - /** The currently set pollfd listener. */ - private static PollfdListener pollfdListener; - - /** The currently set pollfd listener user data. */ - private static Object pollfdListenerUserData; + /** + * pollfd listeners (to support different listeners for different contexts). + */ + private static final ConcurrentMap> pollfdListeners = + new ConcurrentHashMap>(); static { @@ -586,7 +602,7 @@ public final class LibUsb * default context. Only valid on return code 0. * @return 0 on success or a error code on failure. */ - public static native int init(final Context context); + public static synchronized native int init(final Context context); /** * Deinitialize libusb. @@ -598,7 +614,7 @@ public final class LibUsb * The {@link Context} to deinitialize, or NULL for the default * context. */ - public static native void exit(final Context context); + public static synchronized native void exit(final Context context); /** * Set log message verbosity. @@ -707,12 +723,12 @@ public final class LibUsb * array is too small */ public static native int getPortNumbers(final Device device, - final byte[] path); + final ByteBuffer path); /** * Get the list of all port numbers from root for the specified device. * - * @deprecated Please use {@link #getPortNumbers(Device, byte[])} instead. + * @deprecated Please use {@link #getPortNumbers(Device, ByteBuffer)} instead. * * @param context * The context. @@ -725,8 +741,8 @@ public final class LibUsb * array is too small */ @Deprecated - public static int getPortPaths(final Context context, - final Device device, final byte[] path) + public static int getPortPath(final Context context, + final Device device, final ByteBuffer path) { return getPortNumbers(device, path); } @@ -734,6 +750,10 @@ public final class LibUsb /** * 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. + * * @param device * A device * @return The device parent or NULL if not available. You should issue a @@ -785,7 +805,7 @@ public final class LibUsb * does not exist {@link #ERROR_OTHER} on other failure */ public static native int getMaxPacketSize(final Device device, - final int endpoint); + final byte endpoint); /** * Calculate the maximum packet size which a specific endpoint is capable @@ -802,10 +822,8 @@ public final class LibUsb * * This function is useful for setting up isochronous transfers, for example * you might pass the return value from this function to - * libusb_set_iso_packet_lengths() in order to set the length field of every - * isochronous packet in a transfer. - * - * TODO Link to libusb_set_iso_packet_lengths when implemented + * {@link #setIsoPacketLengths(Transfer, int)} in order to set the length + * field of every isochronous packet in a transfer. * * @param device * A device. @@ -816,7 +834,7 @@ public final class LibUsb * {@link #ERROR_OTHER} on other failure. */ public static native int getMaxIsoPacketSize(final Device device, - final int endpoint); + final byte endpoint); /** * Increment the reference count of a device. @@ -885,7 +903,7 @@ public final class LibUsb * device could not be found. */ public static native DeviceHandle openDeviceWithVidPid( - final Context context, final int vendorId, final int productId); + final Context context, final short vendorId, final short productId); /** * Close a device handle. @@ -905,8 +923,9 @@ public final class LibUsb /** * Get the underlying device for a handle. * - * This function does not modify the reference count of the returned device, - * so do not feel compelled to unreference it when you are done. + * 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. @@ -1076,7 +1095,7 @@ public final class LibUsb * disconnected, another ERROR code on other failure. */ public static native int clearHalt(final DeviceHandle handle, - final int endpoint); + final byte endpoint); /** * Perform a USB port reset to reinitialize a device. @@ -1274,7 +1293,7 @@ public final class LibUsb * The little-endian value to convert * @return the value in host-endian byte order */ - public static native int le16ToCpu(final int x); + public static native short le16ToCpu(final short x); /** * Convert a 16-bit value from host-endian to little-endian format. @@ -1286,7 +1305,7 @@ public final class LibUsb * The host-endian value to convert * @return the value in little-endian byte order */ - public static native int cpuToLe16(final int x); + public static native short cpuToLe16(final short x); /** * Get the USB device descriptor for a given device. @@ -1303,6 +1322,23 @@ public final class LibUsb public static native int getDeviceDescriptor(final Device device, final DeviceDescriptor descriptor); + /** + * Free a device descriptor obtained from + * {@link #getDeviceDescriptor(Device, DeviceDescriptor)}. + * + * It is safe to call this function with a NULL device parameter, in which + * case the function simply returns. + * + * This function is not present in the libusb-1.0 API, but since + * getDeviceDescriptor() requires memory to be allocated manually, + * a way to deallocate it from Java is required to avoid a memory leak. + * + * @param descriptor + * The device descriptor to free + */ + public static native void freeDeviceDescriptor( + final DeviceDescriptor descriptor); + /** * Retrieve a string descriptor in C style ASCII. * @@ -1312,18 +1348,15 @@ public final class LibUsb * The index of the descriptor to retrieve. * @param string * Output buffer for ASCII string descriptor. - * @param length - * Maximum number of bytes to read. * @return Number of bytes returned in data, or ERROR code on failure. */ public static native int getStringDescriptorAscii( - final DeviceHandle handle, final int index, final StringBuffer string, - final int length); + final DeviceHandle handle, final byte index, final StringBuffer string); /** * A simple wrapper around - * {@link #getStringDescriptorAscii(DeviceHandle, int, StringBuffer, int)} - * Simply returns the string (Maximum length of 126) if possible. If not + * {@link #getStringDescriptorAscii(DeviceHandle, int, 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. * @@ -1336,15 +1369,20 @@ public final class LibUsb * @return The string or null if it could not be read. */ public static String getStringDescriptor(final DeviceHandle handle, - final int index) + final byte index) { - if (handle == null || index == 0) return null; + if ((handle == null) || (index == 0)) + { + return null; + } + final StringBuffer buffer = new StringBuffer(); - if (getStringDescriptorAscii(handle, index, buffer, - MAX_STRING_SIZE) >= 0) + + if (getStringDescriptorAscii(handle, index, buffer) >= 0) { return buffer.toString(); } + return null; } @@ -1390,7 +1428,7 @@ public final class LibUsb * @see #getConfigDescriptorByValue(Device, int, ConfigDescriptor) */ public static native int getConfigDescriptor(final Device device, - final int index, final ConfigDescriptor descriptor); + final byte index, final ConfigDescriptor descriptor); /** * Get a USB configuration descriptor with a specific bConfigurationValue. @@ -1414,7 +1452,7 @@ public final class LibUsb * @see #getConfigDescriptor(Device, int, ConfigDescriptor) */ public static native int getConfigDescriptorByValue(final Device device, - final int value, final ConfigDescriptor descriptor); + final byte value, final ConfigDescriptor descriptor); /** * Free a configuration descriptor obtained from @@ -1614,8 +1652,12 @@ public final class LibUsb * @return number of bytes returned in data, or ERROR code on failure * */ - public static native int getDescriptor(final DeviceHandle handle, - final int type, final int 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 << 8) | index), (short) 0, data, 1000); + } /** * Retrieve a descriptor from a device. @@ -1633,10 +1675,14 @@ public final class LibUsb * @param data * Output buffer for descriptor. * @return number of bytes returned in data, or LIBUSB_ERROR code on failure - * @see #getStringDescriptorAscii(DeviceHandle, int, StringBuffer, int) + * @see #getStringDescriptorAscii(DeviceHandle, int, StringBuffer) */ - public static native int getStringDescriptor(final DeviceHandle handle, - final int index, final int 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), langId, data, 1000); + } /** * Perform a USB control transfer. @@ -1671,8 +1717,8 @@ public final class LibUsb * disconnected, another ERROR code on other failures */ public static native int controlTransfer(final DeviceHandle handle, - final int bmRequestType, final int bRequest, final int wValue, - final int wIndex, final ByteBuffer data, final int timeout); + final byte bmRequestType, final byte bRequest, final short wValue, + final short wIndex, final ByteBuffer data, final long timeout); /** * Perform a USB bulk transfer. @@ -1716,8 +1762,8 @@ public final class LibUsb * been disconnected, another ERROR code on other failures. */ public static native int bulkTransfer(final DeviceHandle handle, - final int endpoint, final ByteBuffer data, final IntBuffer transferred, - final int timeout); + final byte endpoint, final ByteBuffer data, final IntBuffer transferred, + final long timeout); /** * Perform a USB interrupt transfer. @@ -1762,8 +1808,8 @@ public final class LibUsb * has been disconnected, another ERROR code on other error */ public static native int interruptTransfer(final DeviceHandle handle, - final int endpoint, final ByteBuffer data, final IntBuffer transferred, - final int timeout); + final byte endpoint, final ByteBuffer data, final IntBuffer transferred, + final long timeout); /** * Attempt to acquire the event handling lock. @@ -1937,6 +1983,11 @@ public final class LibUsb * 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, as in the following code: + * ByteBuffer.allocateDirect(Integer.SIZE / Byte.SIZE).asIntBuffer() + * * @param context * the context to operate on, or NULL for the default context * @param timeout @@ -2100,7 +2151,7 @@ public final class LibUsb * or {@link #ERROR_OTHER} failure */ public static native int getNextTimeout(final Context context, - final IntBuffer timeout); + final LongBuffer timeout); /** * Register notification functions for file descriptor additions/removals. @@ -2130,12 +2181,30 @@ public final class LibUsb public static void setPollfdNotifiers(final Context context, final PollfdListener listener, final Object userData) { - pollfdListener = listener; - pollfdListenerUserData = userData; - if (listener == null) - unsetPollfdNotifiers(context); + long contextId; + + if (context == null) + { + contextId = 0; // NULL pointer has value 0. + } else - setPollfdNotifiers(context); + { + contextId = context.getPointer(); + } + + if (listener == null) + { + unsetPollfdNotifiers(context); + + pollfdListeners.remove(contextId); + } + else + { + setPollfdNotifiers(context, contextId); + + pollfdListeners.put(contextId, + new ImmutablePair(listener, userData)); + } } /** @@ -2146,11 +2215,19 @@ public final class LibUsb * The new file descriptor, * @param events * events to monitor for, see libusb_pollfd for a description + * @param contextId + * A unique identifier for the originating context. */ - static void triggerPollfdAdded(final FileDescriptor fd, final int events) + static void triggerPollfdAdded(final FileDescriptor fd, final int events, + final long contextId) { - if (pollfdListener != null) - pollfdListener.pollfdAdded(fd, events, pollfdListenerUserData); + final ImmutablePair listener = pollfdListeners + .get(contextId); + + if (listener != null) + { + listener.left.pollfdAdded(fd, events, listener.right); + } } /** @@ -2158,11 +2235,19 @@ public final class LibUsb * * @param fd * The removed file descriptor. + * @param contextId + * A unique identifier for the originating context. */ - static void triggerPollfdRemoved(final FileDescriptor fd) + static void triggerPollfdRemoved(final FileDescriptor fd, + final long contextId) { - if (pollfdListener != null) - pollfdListener.pollfdRemoved(fd, pollfdListenerUserData); + final ImmutablePair listener = pollfdListeners + .get(contextId); + + if (listener != null) + { + listener.left.pollfdRemoved(fd, listener.right); + } } /** @@ -2171,8 +2256,11 @@ public final class LibUsb * * @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 setPollfdNotifiers(final Context context); + static native void setPollfdNotifiers(final Context context, + final long contextId); /** * Tells libusb to stop informing this class about pollfd additions and @@ -2183,6 +2271,20 @@ public final class LibUsb */ static native void unsetPollfdNotifiers(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)}. + * + * @return A newly allocated transfer, or NULL on error + */ + public static Transfer allocTransfer() + { + return allocTransfer(0); + } + /** * Allocate a libusb transfer with a specified number of isochronous packet * descriptors. @@ -2216,9 +2318,8 @@ public final class LibUsb * This should be called for all transfers allocated with * {@link #allocTransfer(int)}. * - * If the LIBUSB_TRANSFER_FREE_BUFFER flag is set and the transfer buffer is - * non-NULL, this function will also free the transfer buffer using the - * standard system memory allocator (e.g. free()). + * 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. @@ -2230,4 +2331,160 @@ public final class LibUsb * The transfer to free */ public static native void freeTransfer(final Transfer transfer); + + /** + * Submit a transfer. + * + * This function will fire off the USB transfer and then return immediately. + * + * @param transfer + * The transfer to submit + * @return 0 on success, {@link #LIBUSB_ERROR_NO_DEVICE} if the device has been + * disconnected, {@link #LIBUSB_ERROR_BUSY} if the transfer has already been + * submitted. {@link #LIBUSB_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 #LIBUSB_TRANSFER_CANCELLED}. + * + * @param transfer + * The transfer to cancel + * @return 0 on success, {@link #LIBUSB_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 ByteBuffer controlTransferGetData(final Transfer transfer) + { + return BufferUtils.slice(transfer.buffer(), CONTROL_SETUP_SIZE, + transfer.buffer().limit() - CONTROL_SETUP_SIZE); + } + + public static ControlSetup controlTransferGetSetup(final Transfer transfer) + { + return new ControlSetup(transfer.buffer()); + } + + 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); + setup.setWValue(wValue); + setup.setWIndex(wIndex); + setup.setWLength(wLength); + } + + 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); + transfer.setTimeout(timeout); + transfer.setBuffer(buffer); + transfer.setUserData(userData); + transfer.setCallback(callback); + + // Set length based on wLength from Control Setup. + final ControlSetup setup = new ControlSetup(buffer); + transfer.setLength(CONTROL_SETUP_SIZE + (setup.wLength() & 0xFFFF)); + } + + 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); + transfer.setTimeout(timeout); + transfer.setBuffer(buffer); + transfer.setUserData(userData); + transfer.setCallback(callback); + } + + 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); + transfer.setTimeout(timeout); + transfer.setBuffer(buffer); + transfer.setUserData(userData); + transfer.setCallback(callback); + } + + 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); + transfer.setTimeout(timeout); + transfer.setBuffer(buffer); + transfer.setNumIsoPackets(numIsoPackets); + transfer.setUserData(userData); + transfer.setCallback(callback); + } + + public static void setIsoPacketLengths(final Transfer transfer, + final int length) + { + for (final IsoPacketDescriptor isoDesc : transfer.isoPacketDesc()) + { + isoDesc.setLength(length); + } + } + + 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++) + { + offset += isoDescriptors[i].length(); + } + + return BufferUtils.slice(transfer.buffer(), offset, + isoDescriptors[packet].length()); + } + + 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()); + } } diff --git a/src/main/java/de/ailis/usb4java/libusb/LibUsbException.java b/src/main/java/de/ailis/usb4java/libusb/LibUsbException.java index 528a369..8eba711 100644 --- a/src/main/java/de/ailis/usb4java/libusb/LibUsbException.java +++ b/src/main/java/de/ailis/usb4java/libusb/LibUsbException.java @@ -22,7 +22,7 @@ import javax.usb.UsbException; /** * libusb-specific USB exception. - * + * * @author Klaus Reimer (k@ailis.de) */ public final class LibUsbException extends UsbException @@ -35,7 +35,7 @@ public final class LibUsbException extends UsbException /** * Constructor. - * + * * @param message * The error message. * @param errorCode @@ -50,11 +50,11 @@ public final class LibUsbException extends UsbException /** * Returns the error code. - * + * * @return The error code */ public int getErrorCode() { - return this.errorCode; + return errorCode; } } diff --git a/src/main/java/de/ailis/usb4java/libusb/Transfer.java b/src/main/java/de/ailis/usb4java/libusb/Transfer.java index a4c56fb..e3a47e8 100644 --- a/src/main/java/de/ailis/usb4java/libusb/Transfer.java +++ b/src/main/java/de/ailis/usb4java/libusb/Transfer.java @@ -32,12 +32,18 @@ import java.nio.ByteBuffer; public final class Transfer { /** The native pointer to the transfer structure. */ - private long pointer; + private long transferPointer; + + // Keeping a reference to the buffer has multiple benefits: faster get(), GC + // prevention (while Transfer is alive) and you can check the buffer's + // original capacity (needed to check setLength() properly). + private ByteBuffer transferBuffer; /** - * Constructs a new transfer structure. + * Package-private constructor to prevent manual instantiation. + * Transfers are always created by JNI with allocTransfer(). */ - public Transfer() + Transfer() { // Empty } @@ -49,7 +55,7 @@ public final class Transfer */ public long getPointer() { - return this.pointer; + return transferPointer; } /** @@ -57,7 +63,7 @@ public final class Transfer * * @return The handle of the device. */ - public native DeviceHandle getDevHandle(); + public native DeviceHandle devHandle(); /** * Sets the handle of the device that this transfer will be submitted to. @@ -72,7 +78,7 @@ public final class Transfer * * @return The transfer flags. */ - public native int getFlags(); + public native byte flags(); /** * Sets the bitwise OR combination of libusb transfer flags. @@ -80,14 +86,14 @@ public final class Transfer * @param flags * The transfer flags to set. */ - public native void setFlags(final int flags); + public native void setFlags(final byte flags); /** * Returns the address of the endpoint where this transfer will be sent. * * @return The endpoint address. */ - public native int getEndpoint(); + public native byte endpoint(); /** * Sets the address of the endpoint where this transfer will be sent. @@ -95,14 +101,14 @@ public final class Transfer * @param endpoint * The endpoint address to set */ - public native void setEndpoint(final int endpoint); + public native void setEndpoint(final byte endpoint); /** * Returns the type of the endpoint. * * @return The endpoint type. */ - public native int getType(); + public native byte type(); /** * Sets the type of the endpoint. @@ -110,7 +116,7 @@ public final class Transfer * @param type * The endpoint type to set. */ - public native void setType(final int type); + public native void setType(final byte type); /** * Returns the timeout for this transfer in milliseconds. A value of 0 @@ -118,7 +124,7 @@ public final class Transfer * * @return The timeout. */ - public native long getTimeout(); + public native long timeout(); /** * Sets the timeout for this transfer in milliseconds. A value of 0 @@ -127,7 +133,7 @@ public final class Transfer * @param timeout * The timeout to set. */ - public native void setTimeout(final int timeout); + public native void setTimeout(final long timeout); /** * Returns the status of the transfer. Read-only, and only for use within @@ -140,22 +146,47 @@ public final class Transfer * * @return The transfer status. */ - public native int getStatus(); + public native int status(); /** * Returns the length of the data buffer. * * @return The data buffer length. */ - public native int getLength(); + public native int length(); /** * Sets the length of the data buffer. * + * This is checked against the maximum capacity of the supplied ByteBuffer. + * * @param length * The data buffer length to set. */ - public native void setLength(final int length); + public void setLength(final int length) + { + // Verify that the new length doesn't exceed the current buffer's + // maximum capacity. + if (length != 0) + { + if (transferBuffer == null) + { + throw new IllegalArgumentException( + "buffer is null, only a length of 0 is allowed"); + } + + if (transferBuffer.capacity() < length) + { + throw new IllegalArgumentException( + "buffer too small for requested length"); + } + } + + // Native call. + setLengthNative(length); + } + + native void setLengthNative(final int length); /** * Returns the actual length of data that was transferred. Read-only, and @@ -164,14 +195,50 @@ public final class Transfer * * @return The actual length of the transferred data. */ - public native int getActualLength(); + public native int actualLength(); + + /** + * Returns the current callback object. + * + * @return The current callback object. + */ + public native TransferCallback callback(); + + /** + * Sets the callback object. + * + * This will be invoked when the transfer completes, fails, or is cancelled. + * + * @param callback + * The callback object to use. + */ + public native void setCallback(final TransferCallback callback); + + /** + * Returns the current user data object. + * + * @return The current user data object. + */ + public native Object userData(); + + /** + * Sets the user data object, representing user context data to pass to + * the callback function and that can be accessed from there. + * + * @param userData + * The user data object to set. + */ + public native void setUserData(final Object userData); /** * Returns the data buffer. * * @return The data buffer. */ - public native ByteBuffer getBuffer(); + public ByteBuffer buffer() + { + return transferBuffer; + } /** * Sets the data buffer. @@ -179,7 +246,27 @@ public final class Transfer * @param buffer * The data buffer to set. */ - public native void setBuffer(final ByteBuffer buffer); + public void setBuffer(final ByteBuffer buffer) + { + // Native call. + setBufferNative(buffer); + + if (buffer != null) + { + // Set new length based on buffer's capacity. + setLengthNative(buffer.capacity()); + } + else + { + setLengthNative(0); + } + + // Once we know the native calls have gone through, update the + // reference. + transferBuffer = buffer; + } + + native void setBufferNative(final ByteBuffer buffer); /** * Returns the number of isochronous packets. Only used for I/O with @@ -187,7 +274,7 @@ public final class Transfer * * @return The number of isochronous packets. */ - public native int getNumIsoPackets(); + public native int numIsoPackets(); /** * Sets the number of isochronous packets. @@ -196,4 +283,50 @@ public final class Transfer * The number of isochronous packets to set. */ public native void setNumIsoPackets(final int numIsoPackets); + + /** + * Array of isochronous packet descriptors, for isochronous transfers only. + * + * @return The array of isochronous packet descriptors. + */ + public native IsoPacketDescriptor[] isoPacketDesc(); + + @Override + public int hashCode() + { + final int prime = 31; + int result = 1; + result = (prime * result) + + (int) (transferPointer ^ (transferPointer >>> 32)); + return result; + } + + @Override + public boolean equals(final Object obj) + { + if (this == obj) + { + return true; + } + if (obj == null) + { + return false; + } + if (getClass() != obj.getClass()) + { + return false; + } + final Transfer other = (Transfer) obj; + if (transferPointer != other.transferPointer) + { + return false; + } + return true; + } + + @Override + public String toString() + { + return String.format("libusb transfer 0x%x", transferPointer); + } } diff --git a/src/main/java/de/ailis/usb4java/libusb/TransferCallback.java b/src/main/java/de/ailis/usb4java/libusb/TransferCallback.java new file mode 100644 index 0000000..3406b99 --- /dev/null +++ b/src/main/java/de/ailis/usb4java/libusb/TransferCallback.java @@ -0,0 +1,6 @@ +package de.ailis.usb4java.libusb; + +public interface TransferCallback +{ + void processTransfer(Transfer transfer); +} diff --git a/src/main/java/de/ailis/usb4java/libusb/Version.java b/src/main/java/de/ailis/usb4java/libusb/Version.java index 89b0452..fa832b7 100644 --- a/src/main/java/de/ailis/usb4java/libusb/Version.java +++ b/src/main/java/de/ailis/usb4java/libusb/Version.java @@ -30,8 +30,8 @@ import org.apache.commons.lang3.builder.HashCodeBuilder; public final class Version implements Comparable { /** The native pointer to the version structure. */ - private long pointer; - + private long versionPointer; + /** * Package-private constructor to prevent manual instantiation. An instance * is only returned by the JNI method {@link LibUsb#getVersion()}. @@ -48,7 +48,7 @@ public final class Version implements Comparable */ public long getPointer() { - return this.pointer; + return versionPointer; } /** @@ -72,6 +72,13 @@ public final class Version implements Comparable */ public native int micro(); + /** + * Returns the library nano version. + * + * @return The library nano version. + */ + public native int nano(); + /** * Returns the release candidate suffix string, e.g. "-rc4". * @@ -79,29 +86,41 @@ public final class Version implements Comparable */ public native String rc(); - @Override - public String toString() - { - return major() + "." + minor() + "." + micro() + rc(); - } - @Override public int hashCode() { - return new HashCodeBuilder().append(this.pointer).toHashCode(); + return new HashCodeBuilder() + .append(major()) + .append(minor()) + .append(micro()) + .append(nano()) + .append(rc()) + .toHashCode(); } @Override public boolean equals(final Object obj) { - if (obj == null) return false; - if (obj == this) return true; - if (obj.getClass() != getClass()) return false; + if (this == obj) + { + return true; + } + if (obj == null) + { + return false; + } + if (getClass() != obj.getClass()) + { + return false; + } + final Version other = (Version) obj; + return new EqualsBuilder() .append(major(), other.major()) .append(minor(), other.minor()) .append(micro(), other.micro()) + .append(nano(), other.nano()) .append(rc(), other.rc()) .isEquals(); } @@ -109,11 +128,27 @@ public final class Version implements Comparable @Override public int compareTo(final Version other) { + if (this == other) + { + return 0; + } + if (other == null) + { + return 1; + } + return new CompareToBuilder() .append(major(), other.major()) .append(minor(), other.minor()) .append(micro(), other.micro()) + .append(nano(), other.nano()) .append(rc(), other.rc()) .toComparison(); } + + @Override + public String toString() + { + return major() + "." + minor() + "." + micro() + "." + nano() + rc(); + } } diff --git a/src/main/java/de/ailis/usb4java/utils/BufferUtils.java b/src/main/java/de/ailis/usb4java/utils/BufferUtils.java new file mode 100644 index 0000000..c19c71c --- /dev/null +++ b/src/main/java/de/ailis/usb4java/utils/BufferUtils.java @@ -0,0 +1,43 @@ +package de.ailis.usb4java.utils; + +import java.nio.ByteBuffer; +import java.nio.IntBuffer; +import java.nio.LongBuffer; + +public final class BufferUtils +{ + private static final int intSize = Integer.SIZE / Byte.SIZE; + private static final int longSize = Long.SIZE / Byte.SIZE; + + public static ByteBuffer allocateByteBuffer(final int bytes) + { + return ByteBuffer.allocateDirect(bytes); + } + + public static IntBuffer allocateIntBuffer() + { + return ByteBuffer.allocateDirect(intSize).asIntBuffer(); + } + + public static LongBuffer allocateLongBuffer() + { + return ByteBuffer.allocateDirect(longSize).asLongBuffer(); + } + + public static ByteBuffer slice(final ByteBuffer buffer, final int offset, + final int length) + { + final int oldPosition = buffer.position(); + final int oldLimit = buffer.limit(); + + buffer.position(offset); + buffer.limit(offset + length); + + final ByteBuffer slice = buffer.slice(); + + buffer.position(oldPosition); + buffer.limit(oldLimit); + + return slice; + } +} diff --git a/src/main/java/de/ailis/usb4java/utils/DescriptorUtils.java b/src/main/java/de/ailis/usb4java/utils/DescriptorUtils.java index b568f73..90f0f80 100644 --- a/src/main/java/de/ailis/usb4java/utils/DescriptorUtils.java +++ b/src/main/java/de/ailis/usb4java/utils/DescriptorUtils.java @@ -24,15 +24,16 @@ import de.ailis.usb4java.libusb.LibUsb; public final class DescriptorUtils { /** Mapping from USB class id to USB class name. */ - private static final Map CLASS_NAMES = - new HashMap(); + private static final Map CLASS_NAMES = + new HashMap(); static { - CLASS_NAMES.put(LibUsb.CLASS_PER_INTERFACE, "Per interface"); + CLASS_NAMES.put(LibUsb.CLASS_PER_INTERFACE, "Per Interface"); CLASS_NAMES.put(LibUsb.CLASS_AUDIO, "Audio"); CLASS_NAMES.put(LibUsb.CLASS_COMM, "Communications"); CLASS_NAMES.put(LibUsb.CLASS_HID, "HID"); + CLASS_NAMES.put(LibUsb.CLASS_PHYSICAL, "Physical"); CLASS_NAMES.put(LibUsb.CLASS_IMAGE, "Imaging"); CLASS_NAMES.put(LibUsb.CLASS_PRINTER, "Printer"); CLASS_NAMES.put(LibUsb.CLASS_MASS_STORAGE, "Mass Storage"); @@ -41,13 +42,12 @@ public final class DescriptorUtils CLASS_NAMES.put(LibUsb.CLASS_SMART_CARD, "Smart Card"); CLASS_NAMES.put(LibUsb.CLASS_CONTENT_SECURITY, "Content Security"); CLASS_NAMES.put(LibUsb.CLASS_VIDEO, "Video"); - CLASS_NAMES.put(LibUsb.CLASS_VENDOR_SPEC, "Vendor-specific"); - CLASS_NAMES.put(LibUsb.CLASS_APPLICATION, "Application"); CLASS_NAMES.put(LibUsb.CLASS_PERSONAL_HEALTHCARE, "Personal Healthcare"); CLASS_NAMES.put(LibUsb.CLASS_DIAGNOSTIC_DEVICE, "Diagnostic Device"); CLASS_NAMES.put(LibUsb.CLASS_WIRELESS, "Wireless"); - + CLASS_NAMES.put(LibUsb.CLASS_APPLICATION, "Application"); + CLASS_NAMES.put(LibUsb.CLASS_VENDOR_SPEC, "Vendor-specific"); } /** @@ -66,10 +66,15 @@ public final class DescriptorUtils * The numeric USB class. * @return The USB class name. */ - public static String getUSBClassName(final int usbClass) + public static String getUSBClassName(final byte usbClass) { final String name = CLASS_NAMES.get(usbClass); - if (name == null) return "Unknown"; + + if (name == null) + { + return "Unknown"; + } + return name; } @@ -80,9 +85,9 @@ public final class DescriptorUtils * The binary-coded decimal to decode. * @return The decoded binary-coded decimal. */ - public static String decodeBCD(final int bcd) + public static String decodeBCD(final short bcd) { - return String.format("%x.%02x", (bcd & 0xff00) >> 8, bcd & 0xff); + return String.format("%x.%02x", (bcd & 0xFF00) >> 8, bcd & 0x00FF); } /** @@ -94,25 +99,31 @@ public final class DescriptorUtils */ public static String dump(final ByteBuffer bytes) { - final int columns = 16; bytes.rewind(); + final int columns = 16; final StringBuilder builder = new StringBuilder(); + int i = 0; while (bytes.hasRemaining()) { - if (i % columns != 0) + if ((i % columns) != 0) + { builder.append(' '); + } else if (i >= columns) + { builder.append(String.format("%n")); + } + builder.append(String.format("%02x", bytes.get())); i++; } + return builder.toString(); } /** - * Dumps the specified USB device descriptor into a string and - * returns it. + * Dumps the specified USB device descriptor into a string and returns it. * * @param descriptor * The USB device descriptor to dump. @@ -124,8 +135,7 @@ public final class DescriptorUtils } /** - * Dumps the specified USB device descriptor into a string and - * returns it. + * Dumps the specified USB device descriptor into a string and returns it. * * @param descriptor * The USB device descriptor to dump. @@ -159,19 +169,19 @@ public final class DescriptorUtils descriptor.bDescriptorType(), decodeBCD(descriptor.bcdUSB()), descriptor.bDeviceClass() & 0xff, - getUSBClassName(descriptor.bDeviceClass() & 0xff), + getUSBClassName(descriptor.bDeviceClass()), descriptor.bDeviceSubClass() & 0xff, descriptor.bDeviceProtocol() & 0xff, descriptor.bMaxPacketSize0() & 0xff, String.format("0x%04x", descriptor.idVendor() & 0xffff), String.format("0x%04x", descriptor.idProduct() & 0xffff), decodeBCD(descriptor.bcdDevice()), - descriptor.iManufacturer() & 0xff, - manufacturer == null ? "" : " " + manufacturer, + descriptor.iManufacturer() & 0xff, + (manufacturer == null) ? ("") : (" " + manufacturer), descriptor.iProduct() & 0xff, - product == null ? "" : " " + product, - descriptor.iSerialNumber() & 0xff, - serial == null ? "" : " " + serial, + (product == null) ? ("") : (" " + product), + descriptor.iSerialNumber() & 0xff, + (serial == null) ? ("") : (" " + serial), descriptor.bNumConfigurations() & 0xff); } @@ -203,16 +213,16 @@ public final class DescriptorUtils descriptor.bConfigurationValue() & 0xff, descriptor.iConfiguration() & 0xff, String.format("0x%02x", descriptor.bmAttributes() & 0xff), - (descriptor.bmAttributes() & 64) == 0 ? "(Bus Powered)" : - "Self Powered", - (descriptor.bmAttributes() & 32) == 0 ? "" : - String.format(" Remote Wakeup%n"), + ((descriptor.bmAttributes() & 64) == 0) ? ("(Bus Powered)") + : ("Self Powered"), + ((descriptor.bmAttributes() & 32) == 0) ? ("") + : String.format(" Remote Wakeup%n"), (descriptor.bMaxPower() & 0xff) * 2); } /** - * Dumps the specified USB interface descriptor into a string and - * returns it. + * Dumps the specified USB interface descriptor into a string and returns + * it. * * @param descriptor * The USB interface descriptor to dump. @@ -236,15 +246,14 @@ public final class DescriptorUtils descriptor.bAlternateSetting() & 0xff, descriptor.bNumEndpoints() & 0xff, descriptor.bInterfaceClass() & 0xff, - getUSBClassName(descriptor.bInterfaceClass() & 0xff), + getUSBClassName(descriptor.bInterfaceClass()), descriptor.bInterfaceSubClass() & 0xff, descriptor.bInterfaceProtocol() & 0xff, descriptor.iInterface() & 0xff); } /** - * Dumps the specified USB endpoint descriptor into a string and - * returns it. + * Dumps the specified USB endpoint descriptor into a string and returns it. * * @param descriptor * The USB endpoint descriptor to dump. @@ -265,12 +274,12 @@ public final class DescriptorUtils descriptor.bLength(), descriptor.bDescriptorType(), String.format("0x%02x", descriptor.bEndpointAddress() & 0xff), - descriptor.bEndpointAddress() & 0xf, - (descriptor.bEndpointAddress() & 0x80) == 0 ? "OUT" : "IN", + descriptor.bEndpointAddress() & 0xf, + ((descriptor.bEndpointAddress() & 0x80) == 0) ? ("OUT") : ("IN"), descriptor.bmAttributes() & 0xff, - getTransferTypeName(descriptor.bmAttributes() & 0xff), - getSynchTypeName(descriptor.bmAttributes() & 0xff), - getUsageTypeName(descriptor.bmAttributes() & 0xff), + getTransferTypeName(descriptor.bmAttributes()), + getSynchTypeName(descriptor.bmAttributes()), + getUsageTypeName(descriptor.bmAttributes()), descriptor.wMaxPacketSize() & 0xffff, descriptor.bInterval() & 0xff); } @@ -283,18 +292,20 @@ public final class DescriptorUtils * The endpoint attributes value. * @return The transfer type name. */ - public static String getTransferTypeName(final int bmAttributes) + public static String getTransferTypeName(final byte bmAttributes) { - switch (bmAttributes & 3) + switch (bmAttributes & LibUsb.TRANSFER_TYPE_MASK) { - case 1: + case LibUsb.TRANSFER_TYPE_CONTROL: + return "Control"; + case LibUsb.TRANSFER_TYPE_ISOCHRONOUS: return "Isochronous"; - case 2: + case LibUsb.TRANSFER_TYPE_BULK: return "Bulk"; - case 3: + case LibUsb.TRANSFER_TYPE_INTERRUPT: return "Interrupt"; default: - return "Control"; + return "Unknown"; } } @@ -306,18 +317,20 @@ public final class DescriptorUtils * The endpoint attributes value. * @return The synch type name. */ - public static String getSynchTypeName(final int bmAttributes) + public static String getSynchTypeName(final byte bmAttributes) { - switch ((bmAttributes >> 2) & 3) + switch ((bmAttributes & LibUsb.ISO_SYNC_TYPE_MASK) >> 2) { - case 1: + case LibUsb.ISO_SYNC_TYPE_NONE: + return "None"; + case LibUsb.ISO_SYNC_TYPE_ASYNC: return "Asynchronous"; - case 2: + case LibUsb.ISO_SYNC_TYPE_ADAPTIVE: return "Adaptive"; - case 3: + case LibUsb.ISO_SYNC_TYPE_SYNC: return "Synchronous"; default: - return "None"; + return "Unknown"; } } @@ -328,18 +341,20 @@ public final class DescriptorUtils * The endpoint attributes value. * @return The usage type name. */ - public static String getUsageTypeName(final int bmAttributes) + public static String getUsageTypeName(final byte bmAttributes) { - switch ((bmAttributes >> 4) & 3) + switch ((bmAttributes & LibUsb.ISO_USAGE_TYPE_MASK) >> 4) { - case 1: + case LibUsb.ISO_USAGE_TYPE_DATA: + return "Data"; + case LibUsb.ISO_USAGE_TYPE_FEEDBACK: return "Feedback"; - case 2: - return "Explicit Feedback Data"; - case 3: + case LibUsb.ISO_USAGE_TYPE_IMPLICIT: + return "Implicit Feedback Data"; + case 3: // b11 is considered "Reserved" according to USB 3.0 spec. return "Reserved"; default: - return "Data"; + return "Unknown"; } } diff --git a/src/main/resources/de/ailis/usb4java/libusb/linux-arm/libusb4java.so b/src/main/resources/de/ailis/usb4java/libusb/linux-arm/libusb4java.so index d4e40d5..7850c02 100644 Binary files a/src/main/resources/de/ailis/usb4java/libusb/linux-arm/libusb4java.so and b/src/main/resources/de/ailis/usb4java/libusb/linux-arm/libusb4java.so differ diff --git a/src/main/resources/de/ailis/usb4java/libusb/osx-x86/libusb4java.dylib b/src/main/resources/de/ailis/usb4java/libusb/osx-x86/libusb4java.dylib index 1e2c745..df2530b 100644 Binary files a/src/main/resources/de/ailis/usb4java/libusb/osx-x86/libusb4java.dylib and b/src/main/resources/de/ailis/usb4java/libusb/osx-x86/libusb4java.dylib differ diff --git a/src/main/resources/de/ailis/usb4java/libusb/osx-x86_64/libusb4java.dylib b/src/main/resources/de/ailis/usb4java/libusb/osx-x86_64/libusb4java.dylib index 24f4e4a..6886f66 100644 Binary files a/src/main/resources/de/ailis/usb4java/libusb/osx-x86_64/libusb4java.dylib and b/src/main/resources/de/ailis/usb4java/libusb/osx-x86_64/libusb4java.dylib differ diff --git a/src/main/resources/de/ailis/usb4java/libusb/windows-x86/libusb-1.0.dll b/src/main/resources/de/ailis/usb4java/libusb/windows-x86/libusb-1.0.dll index bc53c15..4197e46 100644 Binary files a/src/main/resources/de/ailis/usb4java/libusb/windows-x86/libusb-1.0.dll and b/src/main/resources/de/ailis/usb4java/libusb/windows-x86/libusb-1.0.dll differ diff --git a/src/main/resources/de/ailis/usb4java/libusb/windows-x86/libusb4java.dll b/src/main/resources/de/ailis/usb4java/libusb/windows-x86/libusb4java.dll index f78c714..6d1e367 100644 Binary files a/src/main/resources/de/ailis/usb4java/libusb/windows-x86/libusb4java.dll and b/src/main/resources/de/ailis/usb4java/libusb/windows-x86/libusb4java.dll differ diff --git a/src/main/resources/de/ailis/usb4java/libusb/windows-x86_64/libusb-1.0.dll b/src/main/resources/de/ailis/usb4java/libusb/windows-x86_64/libusb-1.0.dll index 0c28325..a305a31 100644 Binary files a/src/main/resources/de/ailis/usb4java/libusb/windows-x86_64/libusb-1.0.dll and b/src/main/resources/de/ailis/usb4java/libusb/windows-x86_64/libusb-1.0.dll differ diff --git a/src/main/resources/de/ailis/usb4java/libusb/windows-x86_64/libusb4java.dll b/src/main/resources/de/ailis/usb4java/libusb/windows-x86_64/libusb4java.dll index 98b5dc0..9ed574a 100644 Binary files a/src/main/resources/de/ailis/usb4java/libusb/windows-x86_64/libusb4java.dll and b/src/main/resources/de/ailis/usb4java/libusb/windows-x86_64/libusb4java.dll differ diff --git a/src/test/java/de/ailis/usb4java/libusb/LibUSBDeviceTest.java b/src/test/java/de/ailis/usb4java/libusb/LibUSBDeviceTest.java index 39c826f..9668d67 100644 --- a/src/test/java/de/ailis/usb4java/libusb/LibUSBDeviceTest.java +++ b/src/test/java/de/ailis/usb4java/libusb/LibUSBDeviceTest.java @@ -34,16 +34,16 @@ public class LibUSBDeviceTest private Device device; /** The device endpoint to test with. */ - private int endpoint; + private byte endpoint; /** The value of the active configuration. */ - private int configValue; + private byte configValue; /** The vendor ID of the device we test. */ - private int vendorId; + private short vendorId; /** The manufacturer ID of the device we test. */ - private int productId; + private short productId; /** * Set up the test. @@ -51,19 +51,21 @@ public class LibUSBDeviceTest @Before public void setUp() { - this.context = new Context(); - LibUsb.init(this.context); + context = new Context(); + LibUsb.init(context); try { - this.device = findTestDevice(); - if (this.device == null) + device = findTestDevice(); + if (device == null) + { throw new IllegalStateException("Need at least one USB device " + "with at least one endpoint to execute this test"); + } } catch (Throwable e) { - this.device = null; + device = null; } } @@ -75,22 +77,29 @@ public class LibUSBDeviceTest private Device findTestDevice() { DeviceList list = new DeviceList(); - if (LibUsb.getDeviceList(this.context, list) <= 0) return null; + if (LibUsb.getDeviceList(context, list) <= 0) + { + return null; + } try { for (Device device: list) { DeviceDescriptor descriptor = new DeviceDescriptor(); if (LibUsb.getDeviceDescriptor(device, descriptor) != 0) + { continue; - this.vendorId = descriptor.idVendor(); - this.productId = descriptor.idProduct(); + } + vendorId = descriptor.idVendor(); + productId = descriptor.idProduct(); ConfigDescriptor config = new ConfigDescriptor(); if (LibUsb.getActiveConfigDescriptor(device, config) < 0) + { return null; + } try { - this.configValue = config.bConfigurationValue(); + configValue = config.bConfigurationValue(); for (int j = 0; j < config.bNumInterfaces(); j++) { Interface iface = config.iface()[j]; @@ -100,7 +109,7 @@ public class LibUSBDeviceTest iface.altsetting()[k]; if (ifaceDescriptor.bNumEndpoints() > 1) { - this.endpoint = ifaceDescriptor.endpoint()[0]. + endpoint = ifaceDescriptor.endpoint()[0]. bEndpointAddress(); return LibUsb.refDevice(device); } @@ -126,8 +135,14 @@ public class LibUSBDeviceTest @After public void tearDown() { - if (this.device != null) LibUsb.unrefDevice(this.device); - if (this.context != null) LibUsb.exit(this.context); + if (device != null) + { + LibUsb.unrefDevice(device); + } + if (context != null) + { + LibUsb.exit(context); + } } /** @@ -137,8 +152,8 @@ public class LibUSBDeviceTest public void testGetBusNumber() { assumeUsbTestsEnabled(); - assumeNotNull(this.device); - assertTrue(LibUsb.getBusNumber(this.device) >= 0); + assumeNotNull(device); + assertTrue(LibUsb.getBusNumber(device) >= 0); } /** @@ -148,69 +163,126 @@ public class LibUSBDeviceTest public void testGetPortNumber() { assumeUsbTestsEnabled(); - assumeNotNull(this.device); - assertTrue(LibUsb.getPortNumber(this.device) >= 0); + assumeNotNull(device); + assertTrue(LibUsb.getPortNumber(device) >= 0); } /** +<<<<<<< HEAD * Tests the {@link LibUsb#getPortNumbers(Device, byte[])} method. +======= + * Tests the {@link LibUsb#getPortPath(Context, Device, ByteBuffer)} method. +>>>>>>> origin/asyncio */ @Test public void testGetPortNumbers() { assumeUsbTestsEnabled(); +<<<<<<< HEAD assumeNotNull(this.device); byte[] path = new byte[8]; int result = LibUsb.getPortNumbers(this.device, path); +======= + assumeNotNull(device); + ByteBuffer path = ByteBuffer.allocateDirect(8); + int result = LibUsb.getPortPath(context, device, path); +>>>>>>> origin/asyncio assertTrue(result > 0); - assertTrue(result <= path.length); + assertTrue(result <= path.capacity()); } /** +<<<<<<< HEAD * Tests the {@link LibUsb#getPortNumbers(Device, byte[])} method with +======= + * Tests the {@link LibUsb#getPortPath(Context, Device, ByteBuffer)} method with +>>>>>>> origin/asyncio * 0-sized path buffer. */ @Test public void testGetPortNumbersWithTooSmallBuffer() { assumeUsbTestsEnabled(); +<<<<<<< HEAD assumeNotNull(this.device); byte[] path = new byte[0]; int result = LibUsb.getPortNumbers(this.device, path); +======= + assumeNotNull(device); + ByteBuffer path = ByteBuffer.allocateDirect(0); + int result = LibUsb.getPortPath(context, device, path); +>>>>>>> origin/asyncio assertEquals(LibUsb.ERROR_OVERFLOW, result); } /** +<<<<<<< HEAD * Tests the {@link LibUsb#getPortNumbers(Device, byte[])} method +======= + * Tests the {@link LibUsb#getPortPath(Context, Device, ByteBuffer)} method +>>>>>>> origin/asyncio * without a device. */ @Test(expected = IllegalArgumentException.class) public void testGetPortNumbersWithoutDevice() { assumeUsbTestsEnabled(); +<<<<<<< HEAD LibUsb.getPortNumbers(null, new byte[8]); } /** * Tests the {@link LibUsb#getPortNumbers(Device, byte[])} method +======= + LibUsb.getPortPath(context, null, ByteBuffer.allocateDirect(8)); + } + + /** + * Tests the {@link LibUsb#getPortPath(Context, Device, ByteBuffer)} method +>>>>>>> origin/asyncio * without a buffer. */ @Test(expected = IllegalArgumentException.class) public void testGetPortNumbersWithoutBuffer() { assumeUsbTestsEnabled(); +<<<<<<< HEAD LibUsb.getPortNumbers(this.device, null); } /** * Tests {@link LibUsb#getPortNumbers(Device, byte[])} method with +======= + LibUsb.getPortPath(context, device, null); + } + + /** + * Tests {@link LibUsb#getPortPath(Context, Device, ByteBuffer)} method with + * uninitialized USB context. + */ + @Test(expected = IllegalStateException.class) + public void testGetPortPathWithUninitializedContext() + { + assumeUsbTestsEnabled(); + assumeNotNull(device); + final Context context = new Context(); + LibUsb.getPortPath(context, device, ByteBuffer.allocateDirect(16)); + } + + /** + * Tests {@link LibUsb#getPortPath(Context, Device, ByteBuffer)} method with +>>>>>>> origin/asyncio * uninitialized device. */ @Test(expected = IllegalStateException.class) public void testGetPortNumbersWithUninitializedDevice() { assumeUsbTestsEnabled(); +<<<<<<< HEAD LibUsb.getPortNumbers(new Device(), new byte[16]); +======= + LibUsb.getPortPath(context, new Device(), ByteBuffer.allocateDirect(16)); +>>>>>>> origin/asyncio } /** @@ -220,17 +292,17 @@ public class LibUSBDeviceTest public void testGetParent() { assumeUsbTestsEnabled(); - assumeNotNull(this.device); + assumeNotNull(device); DeviceList list = new DeviceList(); - LibUsb.getDeviceList(this.context, list); + LibUsb.getDeviceList(context, list); try { - Device parent = LibUsb.getParent(this.device); + Device parent = LibUsb.getParent(device); // We cannot test anything else here. Parent can be null if our // test device is a root device. We just make sure that it can't // be the device itself. - assertNotEquals(parent, this.device); + assertNotEquals(parent, device); } finally { @@ -255,8 +327,8 @@ public class LibUSBDeviceTest public void testGetDeviceAddress() { assumeUsbTestsEnabled(); - assumeNotNull(this.device); - assertTrue(LibUsb.getDeviceAddress(this.device) >= 0); + assumeNotNull(device); + assertTrue(LibUsb.getDeviceAddress(device) >= 0); } /** @@ -277,9 +349,9 @@ public class LibUSBDeviceTest public void testGetDeviceSpeed() { assumeUsbTestsEnabled(); - assumeNotNull(this.device); - int speed = LibUsb.getDeviceSpeed(this.device); - assertTrue(speed >= LibUsb.SPEED_UNKNOWN && speed <= LibUsb.SPEED_SUPER); + assumeNotNull(device); + int speed = LibUsb.getDeviceSpeed(device); + assertTrue((speed >= LibUsb.SPEED_UNKNOWN) && (speed <= LibUsb.SPEED_SUPER)); } /** @@ -293,71 +365,71 @@ public class LibUSBDeviceTest } /** - * Tests the {@link LibUsb#getMaxPacketSize(Device, int)} method. + * Tests the {@link LibUsb#getMaxPacketSize(Device, byte)} method. */ @Test public void testGetMaxPacketSizeWithInvalidEndpoint() { assumeUsbTestsEnabled(); - assumeNotNull(this.device); + assumeNotNull(device); assertEquals(LibUsb.ERROR_NOT_FOUND, - LibUsb.getMaxPacketSize(this.device, 0)); + LibUsb.getMaxPacketSize(device, (byte) 0)); } /** - * Tests the {@link LibUsb#getMaxPacketSize(Device, int)} method. + * Tests the {@link LibUsb#getMaxPacketSize(Device, byte)} method. */ @Test public void testGetMaxPacketSize() { assumeUsbTestsEnabled(); - assumeNotNull(this.device); - assertTrue(LibUsb.getMaxPacketSize(this.device, this.endpoint) > 0); + assumeNotNull(device); + assertTrue(LibUsb.getMaxPacketSize(device, endpoint) > 0); } /** - * Tests the {@link LibUsb#getMaxPacketSize(Device, int)} method without a + * Tests the {@link LibUsb#getMaxPacketSize(Device, byte)} method without a * device. */ @Test(expected = IllegalArgumentException.class) public void testGetMaxPacketSizeWithoutDevice() { assumeUsbTestsEnabled(); - LibUsb.getMaxPacketSize(null, 0); + LibUsb.getMaxPacketSize(null, (byte) 0); } /** - * Tests the {@link LibUsb#getMaxIsoPacketSize(Device, int)} method. + * Tests the {@link LibUsb#getMaxIsoPacketSize(Device, byte)} method. */ @Test public void testGetMaxIsoPacketSizeWithInvalidEndpoint() { assumeUsbTestsEnabled(); - assumeNotNull(this.device); + assumeNotNull(device); assertEquals(LibUsb.ERROR_NOT_FOUND, - LibUsb.getMaxIsoPacketSize(this.device, 0)); + LibUsb.getMaxIsoPacketSize(device, (byte) 0)); } /** - * Tests the {@link LibUsb#getMaxIsoPacketSize(Device, int)} method. + * Tests the {@link LibUsb#getMaxIsoPacketSize(Device, byte)} method. */ @Test public void testGetMaxIsoPacketSize() { assumeUsbTestsEnabled(); - assumeNotNull(this.device); - assertTrue(LibUsb.getMaxIsoPacketSize(this.device, this.endpoint) > 0); + assumeNotNull(device); + assertTrue(LibUsb.getMaxIsoPacketSize(device, endpoint) > 0); } /** - * Tests the {@link LibUsb#getMaxIsoPacketSize(Device, int)} method without + * Tests the {@link LibUsb#getMaxIsoPacketSize(Device, byte)} method without * a device. */ @Test(expected = IllegalArgumentException.class) public void testGetMaxIsoPacketSizeWithoutDevice() { assumeUsbTestsEnabled(); - LibUsb.getMaxIsoPacketSize(null, 0); + LibUsb.getMaxIsoPacketSize(null, (byte) 0); } /** @@ -368,7 +440,7 @@ public class LibUSBDeviceTest public void testRefUnRefDevice() { assumeUsbTestsEnabled(); - assumeNotNull(this.device); + assumeNotNull(device); Device device = LibUsb.refDevice(this.device); try { @@ -411,10 +483,10 @@ public class LibUSBDeviceTest public void testOpenAndClose() { assumeUsbTestsEnabled(); - assumeNotNull(this.device); + assumeNotNull(device); DeviceHandle handle = new DeviceHandle(); - int result = LibUsb.open(this.device, handle); - assertTrue(result == LibUsb.SUCCESS || result == LibUsb.ERROR_ACCESS); + int result = LibUsb.open(device, handle); + assertTrue((result == LibUsb.SUCCESS) || (result == LibUsb.ERROR_ACCESS)); if (result == LibUsb.SUCCESS) { LibUsb.close(handle); @@ -451,7 +523,7 @@ public class LibUSBDeviceTest public void testOpenWithoutHandle() { assumeUsbTestsEnabled(); - LibUsb.open(this.device, null); + LibUsb.open(device, null); } /** @@ -473,9 +545,12 @@ public class LibUSBDeviceTest public void testOpenDeviceWithVidPid() { assumeUsbTestsEnabled(); - DeviceHandle handle = LibUsb.openDeviceWithVidPid(this.context, - this.vendorId, this.productId); - if (handle != null) LibUsb.close(handle); + DeviceHandle handle = LibUsb.openDeviceWithVidPid(context, + vendorId, productId); + if (handle != null) + { + LibUsb.close(handle); + } } /** @@ -557,14 +632,14 @@ public class LibUSBDeviceTest } /** - * Tests the {@link LibUsb#clearHalt(DeviceHandle, int)} method without a + * Tests the {@link LibUsb#clearHalt(DeviceHandle, byte)} method without a * handle. */ @Test(expected = IllegalArgumentException.class) public void testClearHaltWithoutHandle() { assumeUsbTestsEnabled(); - LibUsb.clearHalt(null, 0); + LibUsb.clearHalt(null, (byte) 0); } /** @@ -630,7 +705,7 @@ public class LibUSBDeviceTest public void testGetDeviceDescriptorWithoutDescriptor() { assumeUsbTestsEnabled(); - LibUsb.getDeviceDescriptor(this.device, null); + LibUsb.getDeviceDescriptor(device, null); } /** @@ -645,16 +720,16 @@ public class LibUSBDeviceTest public void testGetDeviceDescriptor() { assumeUsbTestsEnabled(); - assumeNotNull(this.device); + assumeNotNull(device); DeviceDescriptor desc = new DeviceDescriptor(); - LibUsb.getDeviceDescriptor(this.device, desc); + LibUsb.getDeviceDescriptor(device, desc); desc.bcdDevice(); desc.bcdUSB(); assertEquals(LibUsb.DT_DEVICE, desc.bDescriptorType()); desc.bDeviceClass(); desc.bDeviceProtocol(); desc.bDeviceSubClass(); - assertEquals(desc.getData().limit(), desc.bLength()); + assertTrue(desc.bLength() > 0); desc.bMaxPacketSize0(); desc.bNumConfigurations(); } @@ -680,7 +755,7 @@ public class LibUSBDeviceTest public void testGetActiveConfigDescriptorWithoutDescriptor() { assumeUsbTestsEnabled(); - LibUsb.getActiveConfigDescriptor(this.device, null); + LibUsb.getActiveConfigDescriptor(device, null); } /** @@ -702,7 +777,9 @@ public class LibUSBDeviceTest assertTrue(desc.wTotalLength() >= desc.bLength()); for (Interface iface: desc.iface()) + { validateInterface(iface); + } } /** @@ -773,9 +850,9 @@ public class LibUSBDeviceTest public void testGetActiveConfigDescriptor() { assumeUsbTestsEnabled(); - assumeNotNull(this.device); + assumeNotNull(device); ConfigDescriptor desc = new ConfigDescriptor(); - LibUsb.getActiveConfigDescriptor(this.device, desc); + LibUsb.getActiveConfigDescriptor(device, desc); try { validateConfigDescriptor(desc); @@ -788,39 +865,39 @@ public class LibUSBDeviceTest /** * Tests the - * {@link LibUsb#getConfigDescriptor(Device, int, ConfigDescriptor)} method + * {@link LibUsb#getConfigDescriptor(Device, byte, ConfigDescriptor)} method * without a device. */ @Test(expected = IllegalArgumentException.class) public void testGetConfigDescriptorWithoutDevice() { assumeUsbTestsEnabled(); - LibUsb.getConfigDescriptor(null, 0, new ConfigDescriptor()); + LibUsb.getConfigDescriptor(null, (byte) 0, new ConfigDescriptor()); } /** * Tests the - * {@link LibUsb#getConfigDescriptor(Device, int, ConfigDescriptor)} method + * {@link LibUsb#getConfigDescriptor(Device, byte, ConfigDescriptor)} method * without a descriptor. */ @Test(expected = IllegalArgumentException.class) public void testGetConfigDescriptorWithoutDescriptor() { assumeUsbTestsEnabled(); - LibUsb.getConfigDescriptor(this.device, 0, null); + LibUsb.getConfigDescriptor(device, (byte) 0, null); } /** * Tests the - * {@link LibUsb#getConfigDescriptor(Device, int, ConfigDescriptor)} method. + * {@link LibUsb#getConfigDescriptor(Device, byte, ConfigDescriptor)} method. */ @Test public void testGetConfigDescriptor() { assumeUsbTestsEnabled(); - assumeNotNull(this.device); + assumeNotNull(device); ConfigDescriptor desc = new ConfigDescriptor(); - LibUsb.getConfigDescriptor(this.device, 0, desc); + LibUsb.getConfigDescriptor(device, (byte) 0, desc); try { validateConfigDescriptor(desc); @@ -833,40 +910,40 @@ public class LibUSBDeviceTest /** * Tests the - * {@link LibUsb#getConfigDescriptorByValue(Device, int, ConfigDescriptor)} + * {@link LibUsb#getConfigDescriptorByValue(Device, byte, ConfigDescriptor)} * method without a device. */ @Test(expected = IllegalArgumentException.class) public void testGetConfigDescriptorByValueWithoutDevice() { assumeUsbTestsEnabled(); - LibUsb.getConfigDescriptorByValue(null, 0, new ConfigDescriptor()); + LibUsb.getConfigDescriptorByValue(null, (byte) 0, new ConfigDescriptor()); } /** * Tests the - * {@link LibUsb#getConfigDescriptorByValue(Device, int, ConfigDescriptor)} + * {@link LibUsb#getConfigDescriptorByValue(Device, byte, ConfigDescriptor)} * method without a descriptor. */ @Test(expected = IllegalArgumentException.class) public void testGetConfigDescriptorByValueWithoutDescriptor() { assumeUsbTestsEnabled(); - LibUsb.getConfigDescriptorByValue(this.device, 0, null); + LibUsb.getConfigDescriptorByValue(device, (byte) 0, null); } /** * Tests the - * {@link LibUsb#getConfigDescriptorByValue(Device, int, ConfigDescriptor)} + * {@link LibUsb#getConfigDescriptorByValue(Device, byte, ConfigDescriptor)} * method. */ @Test public void testGetConfigDescriptorByValue() { assumeUsbTestsEnabled(); - assumeNotNull(this.device); + assumeNotNull(device); ConfigDescriptor desc = new ConfigDescriptor(); - LibUsb.getConfigDescriptorByValue(this.device, this.configValue, desc); + LibUsb.getConfigDescriptorByValue(device, configValue, desc); try { validateConfigDescriptor(desc); @@ -900,214 +977,214 @@ public class LibUSBDeviceTest /** * Tests the - * {@link LibUsb#getStringDescriptorAscii(DeviceHandle, int, StringBuffer, int)} + * {@link LibUsb#getStringDescriptorAscii(DeviceHandle, byte, StringBuffer)} * method without a handle. */ @Test(expected = IllegalArgumentException.class) public void testGetStringDescriptorAsciiWithoutHandle() { assumeUsbTestsEnabled(); - LibUsb.getStringDescriptorAscii(null, 0, new StringBuffer(), 0); + LibUsb.getStringDescriptorAscii(null, (byte) 0, new StringBuffer()); } /** * Tests the - * {@link LibUsb#getStringDescriptorAscii(DeviceHandle, int, StringBuffer, int)} + * {@link LibUsb#getStringDescriptorAscii(DeviceHandle, byte, StringBuffer)} * method without a buffer. */ @Test(expected = IllegalArgumentException.class) public void testGetStringDescriptorAsciiWithoutBuffer() { assumeUsbTestsEnabled(); - LibUsb.getStringDescriptorAscii(new DeviceHandle(), 0, null, 0); + LibUsb.getStringDescriptorAscii(new DeviceHandle(), (byte) 0, null); } /** * Tests the - * {@link LibUsb#getDescriptor(DeviceHandle, int, int, ByteBuffer)} method + * {@link LibUsb#getDescriptor(DeviceHandle, byte, byte, ByteBuffer)} method * without a handle. */ @Test(expected = IllegalArgumentException.class) public void testGetDescriptorWithoutHandle() { assumeUsbTestsEnabled(); - LibUsb.getDescriptor(null, 0, 0, ByteBuffer.allocate(18)); + LibUsb.getDescriptor(null, (byte) 0, (byte) 0, ByteBuffer.allocate(18)); } /** * Tests the - * {@link LibUsb#getDescriptor(DeviceHandle, int, int, ByteBuffer)} method + * {@link LibUsb#getDescriptor(DeviceHandle, byte, byte, ByteBuffer)} method * without a buffer. */ @Test(expected = IllegalArgumentException.class) public void testGetDescriptorWithoutBuffer() { assumeUsbTestsEnabled(); - LibUsb.getDescriptor(new DeviceHandle(), 0, 0, null); + LibUsb.getDescriptor(new DeviceHandle(), (byte) 0, (byte) 0, null); } /** * Tests the - * {@link LibUsb#getStringDescriptor(DeviceHandle, int, int, ByteBuffer)} + * {@link LibUsb#getStringDescriptor(DeviceHandle, byte, short, ByteBuffer)} * method without a handle. */ @Test(expected = IllegalArgumentException.class) public void testGetStringDescriptorWithoutHandle() { assumeUsbTestsEnabled(); - LibUsb.getStringDescriptor(null, 0, 0, ByteBuffer.allocate(18)); + LibUsb.getStringDescriptor(null, (byte) 0, (short) 0, ByteBuffer.allocate(18)); } /** * Tests the - * {@link LibUsb#getStringDescriptor(DeviceHandle, int, int, ByteBuffer)} + * {@link LibUsb#getStringDescriptor(DeviceHandle, byte, short, ByteBuffer)} * method without a buffer. */ @Test(expected = IllegalArgumentException.class) public void testGetStringDescriptorWithoutBuffer() { assumeUsbTestsEnabled(); - LibUsb.getStringDescriptor(new DeviceHandle(), 0, 0, null); + LibUsb.getStringDescriptor(new DeviceHandle(), (byte) 0, (short) 0, null); } /** * Tests the - * {@link LibUsb#controlTransfer(DeviceHandle, int, int, int, int, ByteBuffer, int)} + * {@link LibUsb#controlTransfer(DeviceHandle, byte, byte, short, short, ByteBuffer, long)} * method without a handle. */ @Test(expected = IllegalArgumentException.class) public void testControlTransferWithoutHandle() { assumeUsbTestsEnabled(); - LibUsb.controlTransfer(null, 0, 0, 0, 0, ByteBuffer.allocate(0), 0); + LibUsb.controlTransfer(null, (byte) 0, (byte) 0, (short) 0, (short) 0, ByteBuffer.allocate(0), 0); } /** * Tests the - * {@link LibUsb#controlTransfer(DeviceHandle, int, int, int, int, ByteBuffer, int)} + * {@link LibUsb#controlTransfer(DeviceHandle, byte, byte, short, short, ByteBuffer, long)} * method without a buffer. */ @Test(expected = IllegalArgumentException.class) public void testControlTransferWithoutBuffer() { assumeUsbTestsEnabled(); - LibUsb.controlTransfer(new DeviceHandle(), 0, 0, 0, 0, null, 0); + LibUsb.controlTransfer(new DeviceHandle(), (byte) 0, (byte) 0, (short) 0, (short) 0, null, 0); } /** * Tests the - * {@link LibUsb#controlTransfer(DeviceHandle, int, int, int, int, ByteBuffer, int)} + * {@link LibUsb#controlTransfer(DeviceHandle, byte, byte, short, short, ByteBuffer, long)} * method with an indirect buffer. */ @Test(expected = IllegalArgumentException.class) public void testControlTransferWithIndirectBuffer() { assumeUsbTestsEnabled(); - LibUsb.controlTransfer(new DeviceHandle(), 0, 0, 0, 0, + LibUsb.controlTransfer(new DeviceHandle(), (byte) 0, (byte) 0, (short) 0, (short) 0, ByteBuffer.allocate(0), 0); } /** * Tests the - * {@link LibUsb#bulkTransfer(DeviceHandle, int, ByteBuffer, IntBuffer, int)} + * {@link LibUsb#bulkTransfer(DeviceHandle, byte, ByteBuffer, IntBuffer, long)} * method without a handle. */ @Test(expected = IllegalArgumentException.class) public void testBulkTransferWithoutHandle() { assumeUsbTestsEnabled(); - LibUsb.bulkTransfer(null, 0, ByteBuffer.allocate(0), + LibUsb.bulkTransfer(null, (byte) 0, ByteBuffer.allocate(0), IntBuffer.allocate(1), 0); } /** * Tests the - * {@link LibUsb#bulkTransfer(DeviceHandle, int, ByteBuffer, IntBuffer, int)} + * {@link LibUsb#bulkTransfer(DeviceHandle, byte, ByteBuffer, IntBuffer, long)} * method without a data buffer. */ @Test(expected = IllegalArgumentException.class) public void testBulkTransferWithoutDataBuffer() { assumeUsbTestsEnabled(); - LibUsb.bulkTransfer(new DeviceHandle(), 0, null, + LibUsb.bulkTransfer(new DeviceHandle(), (byte) 0, null, IntBuffer.allocate(1), 0); } /** * Tests the - * {@link LibUsb#bulkTransfer(DeviceHandle, int, ByteBuffer, IntBuffer, int)} + * {@link LibUsb#bulkTransfer(DeviceHandle, byte, ByteBuffer, IntBuffer, long)} * method with an indirect data buffer. */ @Test(expected = IllegalArgumentException.class) public void testBulkTransferWithIndirectDataBuffer() { assumeUsbTestsEnabled(); - LibUsb.bulkTransfer(new DeviceHandle(), 0, ByteBuffer.allocate(0), + LibUsb.bulkTransfer(new DeviceHandle(), (byte) 0, ByteBuffer.allocate(0), IntBuffer.allocate(1), 0); } /** * Tests the - * {@link LibUsb#bulkTransfer(DeviceHandle, int, ByteBuffer, IntBuffer, int)} + * {@link LibUsb#bulkTransfer(DeviceHandle, byte, ByteBuffer, IntBuffer, long)} * method without a transferred buffer. */ @Test(expected = IllegalArgumentException.class) public void testBulkTransferWithoutTransferredBuffer() { assumeUsbTestsEnabled(); - LibUsb.bulkTransfer(new DeviceHandle(), 0, ByteBuffer.allocate(0), + LibUsb.bulkTransfer(new DeviceHandle(), (byte) 0, ByteBuffer.allocate(0), null, 0); } /** * Tests the - * {@link LibUsb#interruptTransfer(DeviceHandle, int, ByteBuffer, IntBuffer, int)} + * {@link LibUsb#interruptTransfer(DeviceHandle, byte, ByteBuffer, IntBuffer, long)} * method without a handle. */ @Test(expected = IllegalArgumentException.class) public void testInterruptTransferWithoutHandle() { assumeUsbTestsEnabled(); - LibUsb.interruptTransfer(null, 0, ByteBuffer.allocate(0), + LibUsb.interruptTransfer(null, (byte) 0, ByteBuffer.allocate(0), IntBuffer.allocate(1), 0); } /** * Tests the - * {@link LibUsb#interruptTransfer(DeviceHandle, int, ByteBuffer, IntBuffer, int)} + * {@link LibUsb#interruptTransfer(DeviceHandle, byte, ByteBuffer, IntBuffer, long)} * method without a data buffer. */ @Test(expected = IllegalArgumentException.class) public void testInterruptTransferWithoutDataBuffer() { assumeUsbTestsEnabled(); - LibUsb.interruptTransfer(new DeviceHandle(), 0, null, + LibUsb.interruptTransfer(new DeviceHandle(), (byte) 0, null, IntBuffer.allocate(1), 0); } /** * Tests the - * {@link LibUsb#interruptTransfer(DeviceHandle, int, ByteBuffer, IntBuffer, int)} + * {@link LibUsb#interruptTransfer(DeviceHandle, byte, ByteBuffer, IntBuffer, long)} * method with an indirect data buffer. */ @Test(expected = IllegalArgumentException.class) public void testInterruptTransferWithIndirectDataBuffer() { assumeUsbTestsEnabled(); - LibUsb.interruptTransfer(new DeviceHandle(), 0, ByteBuffer.allocate(0), + LibUsb.interruptTransfer(new DeviceHandle(), (byte) 0, ByteBuffer.allocate(0), IntBuffer.allocate(1), 0); } /** * Tests the - * {@link LibUsb#interruptTransfer(DeviceHandle, int, ByteBuffer, IntBuffer, int)} + * {@link LibUsb#interruptTransfer(DeviceHandle, byte, ByteBuffer, IntBuffer, long)} * method without a transferred buffer. */ @Test(expected = IllegalArgumentException.class) public void testInterruptTransferWithoutTransferredBuffer() { assumeUsbTestsEnabled(); - LibUsb.interruptTransfer(new DeviceHandle(), 0, ByteBuffer.allocate(0), + LibUsb.interruptTransfer(new DeviceHandle(), (byte) 0, ByteBuffer.allocate(0), null, 0); } @@ -1120,9 +1197,9 @@ public class LibUSBDeviceTest { assumeUsbTestsEnabled(); DeviceList list = new DeviceList(); - assertTrue(LibUsb.getDeviceList(this.context, list) >= 0); + assertTrue(LibUsb.getDeviceList(context, list) >= 0); LibUsb.freeDeviceList(list, true); - + try { LibUsb.freeDeviceList(list, true); @@ -1149,7 +1226,7 @@ public class LibUSBDeviceTest { assertTrue(LibUsb.getDeviceList(null, list) >= 0); LibUsb.freeDeviceList(list, true); - + try { LibUsb.freeDeviceList(list, true); diff --git a/src/test/java/de/ailis/usb4java/libusb/LibUSBGlobalTest.java b/src/test/java/de/ailis/usb4java/libusb/LibUSBGlobalTest.java index 1236b9c..7a21ee4 100644 --- a/src/test/java/de/ailis/usb4java/libusb/LibUSBGlobalTest.java +++ b/src/test/java/de/ailis/usb4java/libusb/LibUSBGlobalTest.java @@ -16,7 +16,7 @@ import org.junit.Before; import org.junit.Test; /** - * Tests the global-scope methods of the {@link LibUsb} class which need a + * Tests the global-scope methods of the {@link LibUsb} class which need a * open USB context. * * @author Klaus Reimer (k@ailis.de) @@ -32,14 +32,14 @@ public class LibUSBGlobalTest @Before public void setUp() { - this.context = new Context(); + context = new Context(); try { - LibUsb.init(this.context); + LibUsb.init(context); } catch (Throwable e) { - this.context = null; + context = null; } } @@ -49,7 +49,10 @@ public class LibUSBGlobalTest @After public void tearDown() { - if (this.context != null) LibUsb.exit(this.context); + if (context != null) + { + LibUsb.exit(context); + } } /** @@ -59,11 +62,11 @@ public class LibUSBGlobalTest public void testSetDebug() { assumeUsbTestsEnabled(); - LibUsb.setDebug(this.context, LibUsb.LOG_LEVEL_DEBUG); - LibUsb.setDebug(this.context, LibUsb.LOG_LEVEL_INFO); - LibUsb.setDebug(this.context, LibUsb.LOG_LEVEL_WARNING); - LibUsb.setDebug(this.context, LibUsb.LOG_LEVEL_ERROR); - LibUsb.setDebug(this.context, LibUsb.LOG_LEVEL_NONE); + LibUsb.setDebug(context, LibUsb.LOG_LEVEL_DEBUG); + LibUsb.setDebug(context, LibUsb.LOG_LEVEL_INFO); + LibUsb.setDebug(context, LibUsb.LOG_LEVEL_WARNING); + LibUsb.setDebug(context, LibUsb.LOG_LEVEL_ERROR); + LibUsb.setDebug(context, LibUsb.LOG_LEVEL_NONE); } /** @@ -74,7 +77,7 @@ public class LibUSBGlobalTest { assumeUsbTestsEnabled(); final DeviceList list = new DeviceList(); - final int result = LibUsb.getDeviceList(this.context, list); + final int result = LibUsb.getDeviceList(context, list); assertTrue( "At least one USB device must be present for the simple unit tests", result > 0); @@ -98,7 +101,7 @@ public class LibUSBGlobalTest public void testGetDeviceListWithoutList() { assumeUsbTestsEnabled(); - LibUsb.getDeviceList(this.context, null); + LibUsb.getDeviceList(context, null); } /** @@ -109,7 +112,7 @@ public class LibUSBGlobalTest public void testEndianConversion() { assumeUsbTestsEnabled(); - assertEquals(0x1234, LibUsb.le16ToCpu(LibUsb.cpuToLe16(0x1234))); + assertEquals(0x1234, LibUsb.le16ToCpu(LibUsb.cpuToLe16((short) 0x1234))); } /** diff --git a/src/test/java/de/ailis/usb4java/libusb/LibUSBTest.java b/src/test/java/de/ailis/usb4java/libusb/LibUSBTest.java index 9276b70..a83a7b6 100644 --- a/src/test/java/de/ailis/usb4java/libusb/LibUSBTest.java +++ b/src/test/java/de/ailis/usb4java/libusb/LibUSBTest.java @@ -16,10 +16,12 @@ import static org.junit.Assert.fail; import java.io.FileDescriptor; import java.nio.ByteBuffer; import java.nio.IntBuffer; +import java.nio.LongBuffer; import org.junit.Test; import de.ailis.usb4java.libusb.mocks.PollfdListenerMock; +import de.ailis.usb4java.utils.BufferUtils; /** * Tests the {@link LibUsb} class. @@ -57,9 +59,9 @@ public class LibUSBTest assertEquals(0x07, LibUsb.REQUEST_SET_DESCRIPTOR); assertEquals(0x08, LibUsb.REQUEST_GET_CONFIGURATION); assertEquals(0x09, LibUsb.REQUEST_SET_CONFIGURATION); - assertEquals(0x0a, LibUsb.REQUEST_GET_INTERFACE); - assertEquals(0x0b, LibUsb.REQUEST_SET_INTERFACE); - assertEquals(0x0c, LibUsb.REQUEST_SYNCH_FRAME); + assertEquals(0x0A, LibUsb.REQUEST_GET_INTERFACE); + assertEquals(0x0B, LibUsb.REQUEST_SET_INTERFACE); + assertEquals(0x0C, LibUsb.REQUEST_SYNCH_FRAME); assertEquals(0x30, LibUsb.REQUEST_SET_SEL); assertEquals(0x31, LibUsb.SET_ISOCH_DELAY); @@ -106,14 +108,14 @@ public class LibUSBTest assertEquals(8, LibUsb.CLASS_MASS_STORAGE); assertEquals(9, LibUsb.CLASS_HUB); assertEquals(10, LibUsb.CLASS_DATA); - assertEquals(0x0b, LibUsb.CLASS_SMART_CARD); - assertEquals(0x0d, LibUsb.CLASS_CONTENT_SECURITY); - assertEquals(0x0e, LibUsb.CLASS_VIDEO); - assertEquals(0x0f, LibUsb.CLASS_PERSONAL_HEALTHCARE); - assertEquals(0xdc, LibUsb.CLASS_DIAGNOSTIC_DEVICE); - assertEquals(0xe0, LibUsb.CLASS_WIRELESS); - assertEquals(0xfe, LibUsb.CLASS_APPLICATION); - assertEquals(0xff, LibUsb.CLASS_VENDOR_SPEC); + assertEquals(0x0B, LibUsb.CLASS_SMART_CARD); + assertEquals(0x0D, LibUsb.CLASS_CONTENT_SECURITY); + assertEquals(0x0E, LibUsb.CLASS_VIDEO); + assertEquals(0x0F, LibUsb.CLASS_PERSONAL_HEALTHCARE); + assertEquals((byte) 0xDC, LibUsb.CLASS_DIAGNOSTIC_DEVICE); + assertEquals((byte) 0xE0, LibUsb.CLASS_WIRELESS); + assertEquals((byte) 0xFE, LibUsb.CLASS_APPLICATION); + assertEquals((byte) 0xFF, LibUsb.CLASS_VENDOR_SPEC); // Descriptor types assertEquals(0x01, LibUsb.DT_DEVICE); @@ -125,10 +127,10 @@ public class LibUSBTest assertEquals(0x22, LibUsb.DT_REPORT); assertEquals(0x23, LibUsb.DT_PHYSICAL); assertEquals(0x29, LibUsb.DT_HUB); - assertEquals(0x2a, LibUsb.DT_SUPERSPEED_HUB); + assertEquals(0x2A, LibUsb.DT_SUPERSPEED_HUB); // Endpoint direction - assertEquals(0x80, LibUsb.ENDPOINT_IN); + assertEquals((byte) 0x80, LibUsb.ENDPOINT_IN); assertEquals(0x00, LibUsb.ENDPOINT_OUT); // Transfer types @@ -160,7 +162,7 @@ public class LibUSBTest assertNotNull(version); assertEquals(1, version.major()); assertEquals(0, version.minor()); - assertTrue(version.micro() > 0 && version.micro() < 100); + assertTrue((version.micro() > 0) && (version.micro() < 100)); assertNotNull(version.rc()); assertTrue(version.toString().startsWith("1.0.")); } @@ -354,25 +356,25 @@ public class LibUSBTest } /** - * Tests the {@link LibUsb#getMaxPacketSize(Device, int)} method with + * Tests the {@link LibUsb#getMaxPacketSize(Device, byte)} method with * uninitialized device. */ @Test(expected = IllegalStateException.class) public void testMaxPacketSizeWithUninitializedDevice() { assumeUsbTestsEnabled(); - LibUsb.getMaxPacketSize(new Device(), 0); + LibUsb.getMaxPacketSize(new Device(), (byte) 0); } /** - * Tests the {@link LibUsb#getMaxIsoPacketSize(Device, int)} method with + * Tests the {@link LibUsb#getMaxIsoPacketSize(Device, byte)} method with * uninitialized device. */ @Test(expected = IllegalStateException.class) public void testMaxIsoPacketSizeWithUninitializedDevice() { assumeUsbTestsEnabled(); - LibUsb.getMaxIsoPacketSize(new Device(), 0); + LibUsb.getMaxIsoPacketSize(new Device(), (byte) 0); } /** @@ -486,14 +488,14 @@ public class LibUSBTest } /** - * Tests the {@link LibUsb#clearHalt(DeviceHandle, int)} method with + * Tests the {@link LibUsb#clearHalt(DeviceHandle, byte)} method with * uninitialized device handle. */ @Test(expected = IllegalStateException.class) public void testClearHaltWithUninitializedHandle() { assumeUsbTestsEnabled(); - LibUsb.clearHalt(new DeviceHandle(), 0); + LibUsb.clearHalt(new DeviceHandle(), (byte) 0); } /** @@ -575,15 +577,15 @@ public class LibUSBTest /** * Tests the - * {@link LibUsb#getStringDescriptorAscii(DeviceHandle, int, StringBuffer, int)} + * {@link LibUsb#getStringDescriptorAscii(DeviceHandle, byte, StringBuffer)} * method with uninitialized device handle. */ @Test(expected = IllegalStateException.class) public void testGetStringDescriptorAsciiWithUninitializedHandle() { assumeUsbTestsEnabled(); - LibUsb.getStringDescriptorAscii(new DeviceHandle(), 0, - new StringBuffer(), 0); + LibUsb.getStringDescriptorAscii(new DeviceHandle(), (byte) 0, + new StringBuffer()); } /** @@ -600,26 +602,26 @@ public class LibUSBTest /** * Tests the - * {@link LibUsb#getConfigDescriptor(Device, int, ConfigDescriptor)} method + * {@link LibUsb#getConfigDescriptor(Device, byte, ConfigDescriptor)} method * with uninitialized device. */ @Test(expected = IllegalStateException.class) public void testGetConfigDescriptorWithUninitializedDevice() { assumeUsbTestsEnabled(); - LibUsb.getConfigDescriptor(new Device(), 0, new ConfigDescriptor()); + LibUsb.getConfigDescriptor(new Device(), (byte) 0, new ConfigDescriptor()); } /** * Tests the - * {@link LibUsb#getConfigDescriptorByValue(Device, int, ConfigDescriptor)} + * {@link LibUsb#getConfigDescriptorByValue(Device, byte, ConfigDescriptor)} * method with uninitialized device. */ @Test(expected = IllegalStateException.class) public void testGetConfigDescriptorByValueWithUninitializedDevice() { assumeUsbTestsEnabled(); - LibUsb.getConfigDescriptorByValue(new Device(), 0, + LibUsb.getConfigDescriptorByValue(new Device(), (byte) 0, new ConfigDescriptor()); } @@ -636,6 +638,7 @@ public class LibUSBTest /** * Tests the +<<<<<<< HEAD * {@link LibUsb#getSsEndpointCompanionDescriptor(Context, EndpointDescriptor, SsEndpointCompanionDescriptor)} * method with uninitialized endpoint. */ @@ -890,65 +893,68 @@ public class LibUSBTest /** * Tests the * {@link LibUsb#getDescriptor(DeviceHandle, int, int, ByteBuffer)} method +======= + * {@link LibUsb#getDescriptor(DeviceHandle, byte, byte, ByteBuffer)} method +>>>>>>> origin/asyncio * with uninitialized device handle. */ @Test(expected = IllegalStateException.class) public void testGetDescriptorWithUninitializedHandle() { assumeUsbTestsEnabled(); - LibUsb.getDescriptor(new DeviceHandle(), 0, 0, + LibUsb.getDescriptor(new DeviceHandle(), (byte) 0, (byte) 0, ByteBuffer.allocateDirect(1)); } /** * Tests the - * {@link LibUsb#getStringDescriptor(DeviceHandle, int, int, ByteBuffer)} + * {@link LibUsb#getStringDescriptor(DeviceHandle, byte, short, ByteBuffer)} * method with uninitialized device handle. */ @Test(expected = IllegalStateException.class) public void testGetStringDescriptorWithUninitializedHandle() { assumeUsbTestsEnabled(); - LibUsb.getStringDescriptor(new DeviceHandle(), 0, 0, + LibUsb.getStringDescriptor(new DeviceHandle(), (byte) 0, (short) 0, ByteBuffer.allocateDirect(1)); } /** * Tests the - * {@link LibUsb#controlTransfer(DeviceHandle, int, int, int, int, ByteBuffer, int)} + * {@link LibUsb#controlTransfer(DeviceHandle, byte, byte, short, short, ByteBuffer, long)} * method with uninitialized device handle. */ @Test(expected = IllegalStateException.class) public void testControlTransferWithUninitializedHandle() { assumeUsbTestsEnabled(); - LibUsb.controlTransfer(new DeviceHandle(), 0, 0, 0, 0, + LibUsb.controlTransfer(new DeviceHandle(), (byte) 0, (byte) 0, (short) 0, (short) 0, ByteBuffer.allocateDirect(1), 0); } /** * Tests the - * {@link LibUsb#bulkTransfer(DeviceHandle, int, ByteBuffer, IntBuffer, int)} + * {@link LibUsb#bulkTransfer(DeviceHandle, byte, ByteBuffer, IntBuffer, long)} * method with uninitialized device handle. */ @Test(expected = IllegalStateException.class) public void testBulkTransferWithUninitializedHandle() { assumeUsbTestsEnabled(); - LibUsb.bulkTransfer(new DeviceHandle(), 0, + LibUsb.bulkTransfer(new DeviceHandle(), (byte) 0, ByteBuffer.allocateDirect(1), IntBuffer.allocate(1), 0); } /** * Tests the - * {@link LibUsb#interruptTransfer(DeviceHandle, int, ByteBuffer, IntBuffer, int)} + * {@link LibUsb#interruptTransfer(DeviceHandle, byte, ByteBuffer, IntBuffer, long)} * method with uninitialized device handle. */ @Test(expected = IllegalStateException.class) public void testInterruptTransferWithUninitializedHandle() { assumeUsbTestsEnabled(); - LibUsb.interruptTransfer(new DeviceHandle(), 0, + LibUsb.interruptTransfer(new DeviceHandle(), (byte) 0, ByteBuffer.allocateDirect(1), IntBuffer.allocate(1), 0); } @@ -964,7 +970,7 @@ public class LibUSBTest } /** - * Tests {@link LibUsb#openDeviceWithVidPid(Context, int, int)} with + * Tests {@link LibUsb#openDeviceWithVidPid(Context, short, short)} with * uninitialized USB context. */ @Test(expected = IllegalStateException.class) @@ -972,7 +978,7 @@ public class LibUSBTest { assumeUsbTestsEnabled(); final Context context = new Context(); - LibUsb.openDeviceWithVidPid(context, 0, 0); + LibUsb.openDeviceWithVidPid(context, (short) 0, (short) 0); } /** @@ -1080,7 +1086,7 @@ public class LibUSBTest { assumeUsbTestsEnabled(); final Context context = new Context(); - LibUsb.handleEventsTimeoutCompleted(context, 53, IntBuffer.allocate(1)); + LibUsb.handleEventsTimeoutCompleted(context, 53, BufferUtils.allocateIntBuffer()); } /** @@ -1116,7 +1122,7 @@ public class LibUSBTest { assumeUsbTestsEnabled(); final Context context = new Context(); - LibUsb.handleEventsCompleted(context, IntBuffer.allocate(1)); + LibUsb.handleEventsCompleted(context, BufferUtils.allocateIntBuffer()); } /** @@ -1152,7 +1158,7 @@ public class LibUSBTest { assumeUsbTestsEnabled(); final Context context = new Context(); - LibUsb.getNextTimeout(context, IntBuffer.allocate(1)); + LibUsb.getNextTimeout(context, LongBuffer.allocate(1)); } /** @@ -1164,7 +1170,7 @@ public class LibUSBTest { assumeUsbTestsEnabled(); final Context context = new Context(); - LibUsb.setPollfdNotifiers(context); + LibUsb.setPollfdNotifiers(context, context.getPointer()); } /** @@ -1194,7 +1200,7 @@ public class LibUSBTest LibUsb.setPollfdNotifiers(context, listener, "test"); FileDescriptor fd = new FileDescriptor(); - LibUsb.triggerPollfdAdded(fd, 53); + LibUsb.triggerPollfdAdded(fd, 53, context.getPointer()); assertEquals(53, listener.addedEvents); assertSame(fd, listener.addedFd); assertSame("test", listener.addedUserData); @@ -1204,7 +1210,7 @@ public class LibUSBTest listener.reset(); fd = new FileDescriptor(); - LibUsb.triggerPollfdRemoved(fd); + LibUsb.triggerPollfdRemoved(fd, context.getPointer()); assertEquals(0, listener.addedEvents); assertNull(listener.addedFd); assertNull(listener.addedUserData); @@ -1215,7 +1221,7 @@ public class LibUSBTest listener.reset(); fd = new FileDescriptor(); - LibUsb.triggerPollfdAdded(fd, 53); + LibUsb.triggerPollfdAdded(fd, 53, context.getPointer()); assertEquals(0, listener.addedEvents); assertNull(listener.addedFd); assertNull(listener.addedUserData); @@ -1225,7 +1231,7 @@ public class LibUSBTest listener.reset(); fd = new FileDescriptor(); - LibUsb.triggerPollfdRemoved(fd); + LibUsb.triggerPollfdRemoved(fd, context.getPointer()); assertEquals(0, listener.addedEvents); assertNull(listener.addedFd); assertNull(listener.addedUserData); diff --git a/src/test/java/de/ailis/usb4java/libusb/TransferTest.java b/src/test/java/de/ailis/usb4java/libusb/TransferTest.java index 5bf6bde..62ab62a 100644 --- a/src/test/java/de/ailis/usb4java/libusb/TransferTest.java +++ b/src/test/java/de/ailis/usb4java/libusb/TransferTest.java @@ -35,14 +35,14 @@ public class TransferTest @Before public void setUp() { - this.context = new Context(); + context = new Context(); try { - LibUsb.init(this.context); + LibUsb.init(context); } catch (Throwable e) { - this.context = null; + context = null; } } @@ -52,7 +52,10 @@ public class TransferTest @After public void tearDown() { - if (this.context != null) LibUsb.exit(this.context); + if (context != null) + { + LibUsb.exit(context); + } } /** @@ -113,19 +116,19 @@ public class TransferTest setPointer(handle, 1); DeviceHandle handle2 = new DeviceHandle(); setPointer(handle2, 2); - assertNull(transfer.getDevHandle()); + assertNull(transfer.devHandle()); transfer.setDevHandle(handle); - assertNotNull(transfer.getDevHandle()); - assertNotSame(handle, transfer.getDevHandle()); - assertNotEquals(handle2, transfer.getDevHandle()); - assertEquals(handle, transfer.getDevHandle()); + assertNotNull(transfer.devHandle()); + assertNotSame(handle, transfer.devHandle()); + assertNotEquals(handle2, transfer.devHandle()); + assertEquals(handle, transfer.devHandle()); transfer.setDevHandle(null); - assertNull(transfer.getDevHandle()); + assertNull(transfer.devHandle()); LibUsb.freeTransfer(transfer); } /** - * Tests the {@link Transfer#setFlags(int)} and {@link Transfer#getFlags()} + * Tests the {@link Transfer#setFlags(byte)} and {@link Transfer#getFlags()} * methods. */ @Test @@ -133,16 +136,16 @@ public class TransferTest { assumeUsbTestsEnabled(); Transfer transfer = LibUsb.allocTransfer(0); - assertEquals(0, transfer.getFlags()); - transfer.setFlags(1); - assertEquals(1, transfer.getFlags()); - transfer.setFlags(0); - assertEquals(0, transfer.getFlags()); + assertEquals(0, transfer.flags()); + transfer.setFlags((byte) 1); + assertEquals(1, transfer.flags()); + transfer.setFlags((byte) 0); + assertEquals(0, transfer.flags()); LibUsb.freeTransfer(transfer); } /** - * Tests the {@link Transfer#setEndpoint(int)} and + * Tests the {@link Transfer#setEndpoint(byte)} and * {@link Transfer#getEndpoint()} methods. */ @Test @@ -150,16 +153,16 @@ public class TransferTest { assumeUsbTestsEnabled(); Transfer transfer = LibUsb.allocTransfer(0); - assertEquals(0, transfer.getEndpoint()); - transfer.setEndpoint(1); - assertEquals(1, transfer.getEndpoint()); - transfer.setEndpoint(0); - assertEquals(0, transfer.getEndpoint()); + assertEquals(0, transfer.endpoint()); + transfer.setEndpoint((byte) 1); + assertEquals(1, transfer.endpoint()); + transfer.setEndpoint((byte) 0); + assertEquals(0, transfer.endpoint()); LibUsb.freeTransfer(transfer); } /** - * Tests the {@link Transfer#setType(int)} and {@link Transfer#getType()} + * Tests the {@link Transfer#setType(byte)} and {@link Transfer#getType()} * methods. */ @Test @@ -167,11 +170,11 @@ public class TransferTest { assumeUsbTestsEnabled(); Transfer transfer = LibUsb.allocTransfer(0); - assertEquals(0, transfer.getType()); - transfer.setType(1); - assertEquals(1, transfer.getType()); - transfer.setType(0); - assertEquals(0, transfer.getType()); + assertEquals(0, transfer.type()); + transfer.setType((byte) 1); + assertEquals(1, transfer.type()); + transfer.setType((byte) 0); + assertEquals(0, transfer.type()); LibUsb.freeTransfer(transfer); } @@ -184,11 +187,11 @@ public class TransferTest { assumeUsbTestsEnabled(); Transfer transfer = LibUsb.allocTransfer(0); - assertEquals(0, transfer.getTimeout()); + assertEquals(0, transfer.timeout()); transfer.setTimeout(1); - assertEquals(1, transfer.getTimeout()); + assertEquals(1, transfer.timeout()); transfer.setTimeout(0); - assertEquals(0, transfer.getTimeout()); + assertEquals(0, transfer.timeout()); LibUsb.freeTransfer(transfer); } @@ -200,7 +203,7 @@ public class TransferTest { assumeUsbTestsEnabled(); Transfer transfer = LibUsb.allocTransfer(0); - assertEquals(0, transfer.getStatus()); + assertEquals(0, transfer.status()); LibUsb.freeTransfer(transfer); } } diff --git a/src/test/java/de/ailis/usb4java/utils/DescriptorUtilsTest.java b/src/test/java/de/ailis/usb4java/utils/DescriptorUtilsTest.java index ee181a8..a5fd2a6 100644 --- a/src/test/java/de/ailis/usb4java/utils/DescriptorUtilsTest.java +++ b/src/test/java/de/ailis/usb4java/utils/DescriptorUtilsTest.java @@ -26,12 +26,12 @@ import de.ailis.usb4java.libusb.LibUsb; public class DescriptorUtilsTest { /** - * Tests the {@link DescriptorUtils#decodeBCD(int)} method. + * Tests the {@link DescriptorUtils#decodeBCD(short)} method. */ @Test public void testDecodeBCD() { - assertEquals("10.20", DescriptorUtils.decodeBCD(0x1020)); + assertEquals("10.20", DescriptorUtils.decodeBCD((short) 0x1020)); } /** @@ -49,52 +49,52 @@ public class DescriptorUtilsTest } /** - * Tests the {@link DescriptorUtils#getSynchTypeName(int)} method. + * Tests the {@link DescriptorUtils#getSynchTypeName(byte)} method. */ @Test public void testGetSynchTypeName() { - assertEquals("None", DescriptorUtils.getSynchTypeName(0)); - assertEquals("Asynchronous", DescriptorUtils.getSynchTypeName(4)); - assertEquals("Adaptive", DescriptorUtils.getSynchTypeName(8)); - assertEquals("Synchronous", DescriptorUtils.getSynchTypeName(12)); + assertEquals("None", DescriptorUtils.getSynchTypeName((byte) 0)); + assertEquals("Asynchronous", DescriptorUtils.getSynchTypeName((byte) 4)); + assertEquals("Adaptive", DescriptorUtils.getSynchTypeName((byte) 8)); + assertEquals("Synchronous", DescriptorUtils.getSynchTypeName((byte) 12)); } /** - * Tests the {@link DescriptorUtils#getUsageTypeName(int)} method. + * Tests the {@link DescriptorUtils#getUsageTypeName(byte)} method. */ @Test public void testGetUsageTypeName() { - assertEquals("Data", DescriptorUtils.getUsageTypeName(0)); - assertEquals("Feedback", DescriptorUtils.getUsageTypeName(16)); - assertEquals("Explicit Feedback Data", - DescriptorUtils.getUsageTypeName(32)); - assertEquals("Reserved", DescriptorUtils.getUsageTypeName(48)); + assertEquals("Data", DescriptorUtils.getUsageTypeName((byte) 0)); + assertEquals("Feedback", DescriptorUtils.getUsageTypeName((byte) 16)); + assertEquals("Implicit Feedback Data", + DescriptorUtils.getUsageTypeName((byte) 32)); + assertEquals("Reserved", DescriptorUtils.getUsageTypeName((byte) 48)); } /** - * Tests the {@link DescriptorUtils#getTransferTypeName(int)} method. + * Tests the {@link DescriptorUtils#getTransferTypeName(byte)} method. */ @Test public void testGetTransferTypeName() { - assertEquals("Control", DescriptorUtils.getTransferTypeName(0)); - assertEquals("Isochronous", DescriptorUtils.getTransferTypeName(1)); - assertEquals("Bulk", DescriptorUtils.getTransferTypeName(2)); - assertEquals("Interrupt", DescriptorUtils.getTransferTypeName(3)); + assertEquals("Control", DescriptorUtils.getTransferTypeName((byte) 0)); + assertEquals("Isochronous", DescriptorUtils.getTransferTypeName((byte) 1)); + assertEquals("Bulk", DescriptorUtils.getTransferTypeName((byte) 2)); + assertEquals("Interrupt", DescriptorUtils.getTransferTypeName((byte) 3)); } - + /** - * Tests the {@link DescriptorUtils#getUSBClassName(int)} method. + * Tests the {@link DescriptorUtils#getUSBClassName(byte)} method. */ @Test public void testGetUSBClassName() { assertEquals("Audio", DescriptorUtils.getUSBClassName(LibUsb.CLASS_AUDIO)); - assertEquals("Unknown", DescriptorUtils.getUSBClassName(0x1234)); + assertEquals("Unknown", DescriptorUtils.getUSBClassName((byte) 0xF3)); } /** @@ -178,7 +178,7 @@ public class DescriptorUtilsTest (byte) 7, (byte) 8, (byte) 9, (byte) 10, (byte) 11, (byte) 12, (byte) 13), "Manufacturer", "Product", "Serial")); } - + /** * Tests the * {@link DescriptorUtils#dump(javax.usb.UsbConfigurationDescriptor)} @@ -248,7 +248,7 @@ public class DescriptorUtilsTest (byte) 1, (byte) 2, (byte) 3, (byte) 4, (byte) 5, (byte) 0x20, (byte) 7))); } - + /** * Tests the {@link DescriptorUtils#dump(javax.usb.UsbInterfaceDescriptor)} * method. @@ -262,7 +262,7 @@ public class DescriptorUtilsTest + " bInterfaceNumber 2\n" + " bAlternateSetting 3\n" + " bNumEndpoints 4\n" - + " bInterfaceClass 5 Unknown\n" + + " bInterfaceClass 5 Physical\n" + " bInterfaceSubClass 6\n" + " bInterfaceProtocol 7\n" + " iInterface 8\n", @@ -312,7 +312,7 @@ public class DescriptorUtilsTest DescriptorUtils.dump(new SimpleUsbEndpointDescriptor((byte) 0, (byte) 1, (byte) 0x82, (byte) 3, (byte) 4, (byte) 5))); } - + /** * Ensure constructor is private. *