diff --git a/TODO.txt b/TODO.txt deleted file mode 100644 index 9e5ed42..0000000 --- a/TODO.txt +++ /dev/null @@ -1,2 +0,0 @@ -* Implement hotplug support. -* Implement asynchronous communication in low-level API. \ No newline at end of file diff --git a/pom.xml b/pom.xml index c755280..5f319c5 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ usb4java jar usb4java - 1.1.0-SNAPSHOT + 1.1.1-SNAPSHOT http://kayahr.github.com/usb4java/ USB library for Java based on libusb and implementing javax.usb (JSR-80). diff --git a/src/main/c/.gitignore b/src/main/c/.gitignore index 724070f..7cf4d5f 100644 --- a/src/main/c/.gitignore +++ b/src/main/c/.gitignore @@ -24,3 +24,6 @@ install-sh ltmain.sh m4 missing +ar-lib +compile +.cproject diff --git a/src/main/c/build/common.sh b/src/main/c/build/common.sh index c9eca51..0961af3 100644 --- a/src/main/c/build/common.sh +++ b/src/main/c/build/common.sh @@ -2,41 +2,98 @@ 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="" + +UDEV_VERSION="1.2" + +LIBUSB="stable" +LIBUSB_STABLE_VERSION="1.0.17" +LIBUSB_STABLE_RC="" +LIBUSB_BETA_VERSION="1.0.18" +LIBUSB_BETA_RC="-rc1" build() { - if [ "$LIBUSB" = "libusbx" ] + UDEV_NAME="eudev-$UDEV_VERSION" + UDEV_ARCHIVE="$UDEV_NAME.tar.gz" + UDEV_URL="http://dev.gentoo.org/~blueness/eudev/$UDEV_ARCHIVE" + + 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" - + + # Only Windows needs the shared library, the others want static ones. + if [ "$OS" = "windows" ] + then + LIB_CONFIG="--disable-static --enable-shared" + else + LIB_CONFIG="--enable-static --disable-shared" + fi + # Clean up rm -rf "$TMPDIR" rm -rf "$DISTDIR" + # Udev available only on Linux + if [ "$OS" = "linux" ] + then + + if [ "$UDEV_SUPPORT" = "yes" ] + then + # Download udev if necessary + mkdir -p "$DOWNLOADS" + if [ ! -e "$DOWNLOADS/$UDEV_ARCHIVE" ] + then + if type curl >/dev/null 2>&1 + then + curl -L -o "$DOWNLOADS/$UDEV_ARCHIVE" "$UDEV_URL" + else + wget -O "$DOWNLOADS/$UDEV_ARCHIVE" "$UDEV_URL" + fi + fi + + UDEV_CONFIG="--enable-split-usr --disable-gtk-doc --disable-manpages --disable-gudev \ + --disable-introspection --disable-keymap --disable-libkmod --disable-modules \ + --disable-selinux --disable-rule-generator --disable-blkid $UDEV_CONFIG" + + # Unpack and compile udev + mkdir -p "$TMPDIR" + cd "$TMPDIR" + tar xfz "$DOWNLOADS/$UDEV_ARCHIVE" + cd "$UDEV_NAME" + LIBS="$UDEV_LIBS" \ + CFLAGS="$CFLAGS $UDEV_CFLAGS" \ + ./configure --prefix="$TMPDIR" --host="$HOST" --with-pic $LIB_CONFIG $UDEV_CONFIG + make + make install-strip + + # Enable udev support if selected + LIBUSB_CONFIG="--enable-udev $LIBUSB_CONFIG" + else + # Disable udev support if not selected + LIBUSB_CONFIG="--disable-udev $LIBUSB_CONFIG" + fi + + fi + # Download libusb if necessary mkdir -p "$DOWNLOADS" if [ ! -e "$DOWNLOADS/$LIBUSB_ARCHIVE" ] then - if type curl >/dev/null 2>&1 - then - curl -L -o "$DOWNLOADS/$LIBUSB_ARCHIVE" "$LIBUSB_URL" - else - wget -O "$DOWNLOADS/$LIBUSB_ARCHIVE" "$LIBUSB_URL" - fi + if type curl >/dev/null 2>&1 + then + curl -L -o "$DOWNLOADS/$LIBUSB_ARCHIVE" "$LIBUSB_URL" + else + wget -O "$DOWNLOADS/$LIBUSB_ARCHIVE" "$LIBUSB_URL" + fi fi # Unpack and compile libusb @@ -44,8 +101,10 @@ build() cd "$TMPDIR" tar xfj "$DOWNLOADS/$LIBUSB_ARCHIVE" cd "$LIBUSB_NAME" + PKG_CONFIG_PATH="$TMPDIR/lib/pkgconfig" \ + LIBS="$LIBUSB_LIBS" \ CFLAGS="$CFLAGS $LIBUSB_CFLAGS" \ - ./configure --prefix="$TMPDIR" --host="$HOST" --with-pic $LIBUSB_CONFIG + ./configure --prefix="$TMPDIR" --host="$HOST" --with-pic $LIB_CONFIG $LIBUSB_CONFIG make make install-strip @@ -53,7 +112,7 @@ build() cd "$SRCDIR" if [ ! -e configure ] then - ./autogen.sh + ./autogen.sh fi # Build libusb4java @@ -62,7 +121,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-arm.sh b/src/main/c/build/linux-arm.sh index 9748c1e..22acbf2 100755 --- a/src/main/c/build/linux-arm.sh +++ b/src/main/c/build/linux-arm.sh @@ -9,7 +9,7 @@ set -e OS="linux" ARCH="arm" HOST="$ARCH-$OS-gnueabi" -LIBUSB_CONFIG="--disable-shared" -USB4JAVA_LIBS="-lrt" +CFLAGS="-Os" +UDEV_SUPPORT="no" build diff --git a/src/main/c/build/linux-x86.sh b/src/main/c/build/linux-x86.sh index 08b85bd..355a935 100755 --- a/src/main/c/build/linux-x86.sh +++ b/src/main/c/build/linux-x86.sh @@ -9,8 +9,7 @@ set -e OS="linux" ARCH="x86" HOST="$ARCH-$OS-gnu" -CFLAGS="-m32" -LIBUSB_CONFIG="--disable-shared --disable-udev" -USB4JAVA_LIBS="-lrt" +CFLAGS="-m32 -O2" +UDEV_SUPPORT="yes" build diff --git a/src/main/c/build/linux-x86_64.sh b/src/main/c/build/linux-x86_64.sh index 9d25cb8..e61f153 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" -LIBUSB_CONFIG="--disable-shared --disable-udev" -USB4JAVA_LIBS="-lrt" -USB4JAVA_CFLAGS="-DWRAP_MEMCPY" +CFLAGS="-m64 -O2" +UDEV_SUPPORT="yes" +#USB4JAVA_CFLAGS="-Wl,--wrap=memcpy -DWRAP_MEMCPY" build diff --git a/src/main/c/build/osx-x86.sh b/src/main/c/build/osx-x86.sh index d265188..ccfab0e 100755 --- a/src/main/c/build/osx-x86.sh +++ b/src/main/c/build/osx-x86.sh @@ -9,9 +9,8 @@ set -e OS="osx" ARCH="x86" -CFLAGS="-arch i686" -LIBUSB_CONFIG="--disable-shared" +HOST="i686-apple-darwin" +CFLAGS="-arch i686 -O2" 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..142d891 100755 --- a/src/main/c/build/osx-x86_64.sh +++ b/src/main/c/build/osx-x86_64.sh @@ -9,9 +9,8 @@ set -e OS="osx" ARCH="x86_64" -CFLAGS="-arch x86_64" -LIBUSB_CONFIG="--disable-shared" +HOST="$ARCH-apple-darwin" +CFLAGS="-arch x86_64 -O2" USB4JAVA_LIBS="-lobjc -Wl,-framework,IOKit -Wl,-framework,CoreFoundation" -LIBUSB="libusb" build diff --git a/src/main/c/build/windows-x86.sh b/src/main/c/build/windows-x86.sh index 9b1883b..0ab3fdd 100755 --- a/src/main/c/build/windows-x86.sh +++ b/src/main/c/build/windows-x86.sh @@ -9,6 +9,6 @@ set -e OS="windows" ARCH="x86" HOST="i686-w64-mingw32" -CFLAGS="-m32 -Wl,--add-stdcall-alias" +CFLAGS="-m32 -O2 -Wl,--add-stdcall-alias" build diff --git a/src/main/c/build/windows-x86_64.sh b/src/main/c/build/windows-x86_64.sh index 6482536..26cac5f 100755 --- a/src/main/c/build/windows-x86_64.sh +++ b/src/main/c/build/windows-x86_64.sh @@ -9,6 +9,6 @@ set -e OS="windows" ARCH="x86_64" HOST="$ARCH-w64-mingw32" -CFLAGS="-m64 -Wl,--add-stdcall-alias" +CFLAGS="-m64 -O2 -Wl,--add-stdcall-alias" 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/BosDescriptor.c b/src/main/c/src/BosDescriptor.c index 12aadc5..4a65a2d 100644 --- a/src/main/c/src/BosDescriptor.c +++ b/src/main/c/src/BosDescriptor.c @@ -7,7 +7,7 @@ #include "BosDevCapabilityDescriptor.h" void setBosDescriptor(JNIEnv* env, - struct libusb_bos_descriptor* descriptor, jobject object) + const struct libusb_bos_descriptor* descriptor, jobject object) { SET_POINTER(env, descriptor, object, "bosDescriptorPointer"); } @@ -35,7 +35,7 @@ JNIEXPORT jbyte JNICALL METHOD_NAME(BosDescriptor, bLength) struct libusb_bos_descriptor *descriptor = unwrapBosDescriptor(env, this); if (!descriptor) return 0; - return descriptor->bLength; + return (jbyte) descriptor->bLength; } /** @@ -49,7 +49,7 @@ JNIEXPORT jbyte JNICALL METHOD_NAME(BosDescriptor, bDescriptorType) struct libusb_bos_descriptor *descriptor = unwrapBosDescriptor(env, this); if (!descriptor) return 0; - return descriptor->bDescriptorType; + return (jbyte) descriptor->bDescriptorType; } /** @@ -63,7 +63,7 @@ JNIEXPORT jshort JNICALL METHOD_NAME(BosDescriptor, wTotalLength) struct libusb_bos_descriptor *descriptor = unwrapBosDescriptor(env, this); if (!descriptor) return 0; - return descriptor->wTotalLength; + return (jshort) descriptor->wTotalLength; } /** @@ -77,7 +77,7 @@ JNIEXPORT jbyte JNICALL METHOD_NAME(BosDescriptor, bNumDeviceCaps) struct libusb_bos_descriptor *descriptor = unwrapBosDescriptor(env, this); if (!descriptor) return 0; - return descriptor->bNumDeviceCaps; + return (jbyte) descriptor->bNumDeviceCaps; } /** diff --git a/src/main/c/src/BosDescriptor.h b/src/main/c/src/BosDescriptor.h index c7e0fd4..13166eb 100644 --- a/src/main/c/src/BosDescriptor.h +++ b/src/main/c/src/BosDescriptor.h @@ -8,7 +8,7 @@ #include "usb4java.h" -void setBosDescriptor(JNIEnv*, struct libusb_bos_descriptor*, jobject); +void setBosDescriptor(JNIEnv*, const struct libusb_bos_descriptor*, jobject); struct libusb_bos_descriptor* unwrapBosDescriptor(JNIEnv*, jobject); void resetBosDescriptor(JNIEnv*, jobject); diff --git a/src/main/c/src/BosDevCapabilityDescriptor.c b/src/main/c/src/BosDevCapabilityDescriptor.c index eed2fb9..6bf0cc6 100644 --- a/src/main/c/src/BosDevCapabilityDescriptor.c +++ b/src/main/c/src/BosDevCapabilityDescriptor.c @@ -13,21 +13,21 @@ jobject wrapBosDevCapabilityDescriptor(JNIEnv *env, } jobjectArray wrapBosDevCapabilityDescriptors(JNIEnv *env, int count, - struct libusb_bos_dev_capability_descriptor **descriptors) + struct libusb_bos_dev_capability_descriptor * const *descriptors) { - int i; - jobjectArray array = (jobjectArray) (*env)->NewObjectArray(env, count, (*env)->FindClass(env, PACKAGE_DIR"/BosDevCapabilityDescriptor"), NULL); - for (i = 0; i < count; i++) + + for (int i = 0; i < count; i++) (*env)->SetObjectArrayElement(env, array, i, wrapBosDevCapabilityDescriptor(env, descriptors[i])); + return array; } -struct libusb_bos_dev_capability_descriptor - *unwrapBosDevCapabilityDescriptor(JNIEnv *env, jobject obj) +struct libusb_bos_dev_capability_descriptor* + unwrapBosDevCapabilityDescriptor(JNIEnv *env, jobject obj) { UNWRAP_POINTER(env, obj, struct libusb_bos_dev_capability_descriptor*, "bosDevCapabilityDescriptorPointer"); @@ -44,7 +44,7 @@ JNIEXPORT jbyte JNICALL METHOD_NAME(BosDevCapabilityDescriptor, bLength) struct libusb_bos_dev_capability_descriptor* descriptor = unwrapBosDevCapabilityDescriptor(env, this); if (!descriptor) return 0; - return descriptor->bLength; + return (jbyte) descriptor->bLength; } /** @@ -59,7 +59,7 @@ JNIEXPORT jbyte JNICALL METHOD_NAME(BosDevCapabilityDescriptor, struct libusb_bos_dev_capability_descriptor* descriptor = unwrapBosDevCapabilityDescriptor(env, this); if (!descriptor) return 0; - return descriptor->bDescriptorType; + return (jbyte) descriptor->bDescriptorType; } /** @@ -74,7 +74,7 @@ JNIEXPORT jbyte JNICALL METHOD_NAME(BosDevCapabilityDescriptor, struct libusb_bos_dev_capability_descriptor* descriptor = unwrapBosDevCapabilityDescriptor(env, this); if (!descriptor) return 0; - return descriptor->bDevCapabilityType; + return (jbyte) descriptor->bDevCapabilityType; } /** @@ -89,6 +89,5 @@ JNIEXPORT jobject JNICALL METHOD_NAME(BosDevCapabilityDescriptor, struct libusb_bos_dev_capability_descriptor *descriptor = unwrapBosDevCapabilityDescriptor(env, this); if (!descriptor) return NULL; - return (*env)->NewDirectByteBuffer(env, (void *) - descriptor->dev_capability_data, descriptor->bLength - 3); + return NewDirectReadOnlyByteBuffer(env, descriptor->dev_capability_data, descriptor->bLength - 3); } diff --git a/src/main/c/src/BosDevCapabilityDescriptor.h b/src/main/c/src/BosDevCapabilityDescriptor.h index 82d553c..2cd376c 100644 --- a/src/main/c/src/BosDevCapabilityDescriptor.h +++ b/src/main/c/src/BosDevCapabilityDescriptor.h @@ -8,9 +8,11 @@ #include "usb4java.h" +jobject wrapBosDevCapabilityDescriptor(JNIEnv *, + const struct libusb_bos_dev_capability_descriptor *); jobjectArray wrapBosDevCapabilityDescriptors(JNIEnv*, int, - struct libusb_bos_dev_capability_descriptor**); -struct libusb_bos_dev_capability_descriptor - *unwrapBosDevCapabilityDescriptor(JNIEnv *, jobject); + struct libusb_bos_dev_capability_descriptor * const *); +struct libusb_bos_dev_capability_descriptor* + unwrapBosDevCapabilityDescriptor(JNIEnv *, jobject); #endif 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/ContainerIdDescriptor.c b/src/main/c/src/ContainerIdDescriptor.c index e40e65e..d72625b 100644 --- a/src/main/c/src/ContainerIdDescriptor.c +++ b/src/main/c/src/ContainerIdDescriptor.c @@ -6,7 +6,7 @@ #include "ContainerIdDescriptor.h" void setContainerIdDescriptor(JNIEnv* env, - struct libusb_container_id_descriptor* descriptor, jobject object) + const struct libusb_container_id_descriptor* descriptor, jobject object) { SET_POINTER(env, descriptor, object, "containerIdDescriptorPointer"); } @@ -35,7 +35,7 @@ JNIEXPORT jbyte JNICALL METHOD_NAME(ContainerIdDescriptor, bLength) struct libusb_container_id_descriptor *descriptor = unwrapContainerIdDescriptor(env, this); if (!descriptor) return 0; - return descriptor->bLength; + return (jbyte) descriptor->bLength; } /** @@ -49,7 +49,7 @@ JNIEXPORT jbyte JNICALL METHOD_NAME(ContainerIdDescriptor, bDescriptorType) struct libusb_container_id_descriptor *descriptor = unwrapContainerIdDescriptor(env, this); if (!descriptor) return 0; - return descriptor->bDescriptorType; + return (jbyte) descriptor->bDescriptorType; } /** @@ -63,7 +63,7 @@ JNIEXPORT jbyte JNICALL METHOD_NAME(ContainerIdDescriptor, bDevCapabilityType) struct libusb_container_id_descriptor *descriptor = unwrapContainerIdDescriptor(env, this); if (!descriptor) return 0; - return descriptor->bDevCapabilityType; + return (jbyte) descriptor->bDevCapabilityType; } /** @@ -77,7 +77,7 @@ JNIEXPORT jbyte JNICALL METHOD_NAME(ContainerIdDescriptor, bReserved) struct libusb_container_id_descriptor *descriptor = unwrapContainerIdDescriptor(env, this); if (!descriptor) return 0; - return descriptor->bReserved; + return (jbyte) descriptor->bReserved; } /** @@ -91,6 +91,5 @@ JNIEXPORT jobject JNICALL METHOD_NAME(ContainerIdDescriptor, containerId) struct libusb_container_id_descriptor *descriptor = unwrapContainerIdDescriptor(env, this); if (!descriptor) return NULL; - return (*env)->NewDirectByteBuffer(env, (void *) descriptor->ContainerID, - 16); + return NewDirectReadOnlyByteBuffer(env, descriptor->ContainerID, 16); } diff --git a/src/main/c/src/ContainerIdDescriptor.h b/src/main/c/src/ContainerIdDescriptor.h index 0114aa8..698c8c8 100644 --- a/src/main/c/src/ContainerIdDescriptor.h +++ b/src/main/c/src/ContainerIdDescriptor.h @@ -9,7 +9,7 @@ #include "usb4java.h" void setContainerIdDescriptor(JNIEnv*, - struct libusb_container_id_descriptor*, jobject); + const struct libusb_container_id_descriptor*, jobject); struct libusb_container_id_descriptor* unwrapContainerIdDescriptor(JNIEnv*, jobject); void resetContainerIdDescriptor(JNIEnv*, jobject); diff --git a/src/main/c/src/Context.c b/src/main/c/src/Context.c index 5f98f03..275b3b5 100644 --- a/src/main/c/src/Context.c +++ b/src/main/c/src/Context.c @@ -5,11 +5,16 @@ #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"); } +jobject wrapContext(JNIEnv* env, const libusb_context* context) +{ + WRAP_POINTER(env, context, "Context", "contextPointer"); +} + libusb_context* unwrapContext(JNIEnv* env, jobject context) { UNWRAP_POINTER(env, context, libusb_context*, "contextPointer"); diff --git a/src/main/c/src/Context.h b/src/main/c/src/Context.h index d348a1a..dae4fce 100644 --- a/src/main/c/src/Context.h +++ b/src/main/c/src/Context.h @@ -8,7 +8,8 @@ #include "usb4java.h" -void setContext(JNIEnv*, libusb_context*, jobject); +void setContext(JNIEnv*, const libusb_context*, jobject); +jobject wrapContext(JNIEnv*, const libusb_context*); 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..7ecfbc6 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) { - UNWRAP_DATA(env, descriptor, struct libusb_device_descriptor*, - "deviceDescriptorData"); + UNWRAP_POINTER(env, descriptor, 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..0f21888 100644 --- a/src/main/c/src/DeviceHandle.c +++ b/src/main/c/src/DeviceHandle.c @@ -5,12 +5,13 @@ #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"); } 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..292be4f 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* const *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/HotplugCallbackHandle.c b/src/main/c/src/HotplugCallbackHandle.c new file mode 100644 index 0000000..b641b1f --- /dev/null +++ b/src/main/c/src/HotplugCallbackHandle.c @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2013 Luca Longinotti (l@longi.li) + * See COPYING file for copying conditions + */ + +#include "HotplugCallbackHandle.h" + +void setHotplugCallbackHandle(JNIEnv* env, const libusb_hotplug_callback_handle hotplugHandle, + jobject object) +{ + SET_POINTER(env, hotplugHandle, object, "hotplugCallbackHandleValue"); +} + +libusb_hotplug_callback_handle unwrapHotplugCallbackHandle(JNIEnv* env, jobject hotplugHandle) +{ + // Hotplug callback handles are integers, starting at 1. As such, we can use the same logic + // as for pointers, and consider 0 to be uninitialized/invalid. + if (!hotplugHandle) return 0; + jclass cls = (*env)->GetObjectClass(env, hotplugHandle); + jfieldID field = (*env)->GetFieldID(env, cls, "hotplugCallbackHandleValue", "J"); + jlong val = (*env)->GetLongField(env, hotplugHandle, field); + if (!val) illegalState(env, "hotplugCallbackHandleValue is not initialized"); + return (libusb_hotplug_callback_handle) val; +} + +void resetHotplugCallbackHandle(JNIEnv* env, jobject hotplugHandle) +{ + RESET_POINTER(env, hotplugHandle, "hotplugCallbackHandleValue"); +} diff --git a/src/main/c/src/HotplugCallbackHandle.h b/src/main/c/src/HotplugCallbackHandle.h new file mode 100644 index 0000000..736efd0 --- /dev/null +++ b/src/main/c/src/HotplugCallbackHandle.h @@ -0,0 +1,15 @@ +/* + * Copyright (C) 2013 Luca Longinotti (l@longi.li) + * See COPYING file for copying conditions + */ + +#ifndef USB4JAVA_HOTPLUG_CALLBACK_HANDLE_H +#define USB4JAVA_HOTPLUG_CALLBACK_HANDLE_H + +#include "usb4java.h" + +void setHotplugCallbackHandle(JNIEnv*, const libusb_hotplug_callback_handle, jobject); +libusb_hotplug_callback_handle unwrapHotplugCallbackHandle(JNIEnv*, jobject); +void resetHotplugCallbackHandle(JNIEnv*, jobject); + +#endif 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..69a6b1f --- /dev/null +++ b/src/main/c/src/IsoPacketDescriptor.c @@ -0,0 +1,93 @@ +/* + * Copyright (C) 2013 Luca Longinotti (l@longi.li) + * See COPYING file for copying conditions + */ + +#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..e745219 --- /dev/null +++ b/src/main/c/src/IsoPacketDescriptor.h @@ -0,0 +1,17 @@ +/* + * Copyright (C) 2013 Luca Longinotti (l@longi.li) + * See COPYING file for copying conditions + */ + +#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..3b1d823 100644 --- a/src/main/c/src/LibUsb.c +++ b/src/main/c/src/LibUsb.c @@ -1,5 +1,6 @@ /* * Copyright (C) 2013 Klaus Reimer (k@ailis.de) + * Copyright (C) 2013 Luca Longinotti (l@longi.li) * See COPYING file for copying conditions */ @@ -9,6 +10,7 @@ * Native methods for the LibUsb class. * * @author Klaus Reimer + * @author Luca Longinotti */ #include @@ -29,10 +31,9 @@ #include "SsUsbDeviceCapabilityDescriptor.h" #include "ContainerIdDescriptor.h" #include "Transfer.h" +#include "HotplugCallbackHandle.h" -static JavaVM *jvm; - -static int defaultContextInitialized = 0; +static int defaultContextRefcnt = 0; /** * Version getVersion() @@ -57,7 +58,7 @@ JNIEXPORT jint JNICALL METHOD_NAME(LibUsb, getApiVersion) } /** - * int init() + * int init(Context) */ JNIEXPORT jint JNICALL METHOD_NAME(LibUsb, init) ( @@ -66,44 +67,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 +121,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 +135,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; } /** @@ -144,7 +152,7 @@ JNIEXPORT void JNICALL METHOD_NAME(LibUsb, freeDeviceList) JNIEnv *env, jclass class, jobject deviceList, jboolean unrefDevices ) { - NOT_NULL(env, deviceList, return); + if (!deviceList) return; libusb_device **list = unwrapDeviceList(env, deviceList); if (!list) return; libusb_free_device_list(list, unrefDevices); @@ -180,26 +188,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, (int) path_size); } /** - * int getPortNumber(Device) + * Device getParent(Device) */ JNIEXPORT jobject JNICALL METHOD_NAME(LibUsb, getParent) ( @@ -209,11 +215,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 +247,31 @@ 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 +285,7 @@ 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,17 @@ 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 +516,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 +537,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 +545,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 +609,63 @@ 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 memory again on error. + 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 +) +{ + if (!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; } @@ -704,8 +740,8 @@ JNIEXPORT void JNICALL METHOD_NAME(LibUsb, freeConfigDescriptor) JNIEnv *env, jclass class, jobject descriptor ) { - NOT_NULL(env, descriptor, return); - struct libusb_config_descriptor *config = unwrapConfigDescriptor(env, + if (!descriptor) return; + 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, "ssEndpointCompanionDescriptorPointer", 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; } @@ -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; } @@ -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; } @@ -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; } @@ -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; } @@ -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; } @@ -1258,14 +1272,12 @@ static void LIBUSB_CALL triggerPollfdAdded(int fd, short events, void *user_data { THREAD_BEGIN(env) - jclass fdcls = (*env)->FindClass(env, "java/io/FileDescriptor"); - jmethodID constructor = (*env)->GetMethodID(env, fdcls, "", "(I)V"); - jobject object = (*env)->NewObject(env, fdcls, constructor, fd); + jclass fdCls = (*env)->FindClass(env, "java/io/FileDescriptor"); + jmethodID fdConstructor = (*env)->GetMethodID(env, fdCls, "", "(I)V"); + jobject fdObject = (*env)->NewObject(env, fdCls, fdConstructor, fd); - 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); + (*env)->CallStaticVoidMethod(env, jClassLibUsb, jMethodTriggerPollfdAdded, + fdObject, (jint) events, (jlong) (intptr_t) user_data); THREAD_END } @@ -1274,42 +1286,39 @@ static void LIBUSB_CALL triggerPollfdRemoved(int fd, void *user_data) { THREAD_BEGIN(env) - jclass fdcls = (*env)->FindClass(env, "java/io/FileDescriptor"); - jmethodID constructor = (*env)->GetMethodID(env, fdcls, "", "(I)V"); - jobject object = (*env)->NewObject(env, fdcls, constructor, fd); + jclass fdCls = (*env)->FindClass(env, "java/io/FileDescriptor"); + jmethodID fdConstructor = (*env)->GetMethodID(env, fdCls, "", "(I)V"); + jobject fdObject = (*env)->NewObject(env, fdCls, fdConstructor, fd); - 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); + (*env)->CallStaticVoidMethod(env, jClassLibUsb, jMethodTriggerPollfdRemoved, + fdObject, (jlong) (intptr_t) user_data); THREAD_END } /** - * void setPollfdNotifiers(Context) + * void setPollfdNotifiersNative(Context, long) */ -JNIEXPORT void JNICALL METHOD_NAME(LibUsb, setPollfdNotifiers) +JNIEXPORT void JNICALL METHOD_NAME(LibUsb, setPollfdNotifiersNative) ( - 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); } /** - * void unsetPollfdNotifiers(Context) + * void unsetPollfdNotifiersNative(Context) */ -JNIEXPORT void JNICALL METHOD_NAME(LibUsb, unsetPollfdNotifiers) +JNIEXPORT void JNICALL METHOD_NAME(LibUsb, unsetPollfdNotifiersNative) ( 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 +1331,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 +1359,122 @@ 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); + if (!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); +} + +static int LIBUSB_CALL hotplugCallback(libusb_context *context, + libusb_device *device, libusb_hotplug_event event, void *user_data) +{ + THREAD_BEGIN(env) + + jobject ctx = wrapContext(env, context); + jobject dev = wrapDevice(env, device); + + int result = (*env)->CallStaticIntMethod(env, + jClassLibUsb, jMethodHotplugCallback, ctx, dev, + (jint) event, (jlong) (intptr_t) user_data); + + THREAD_END + + return result; +} + +/** + * int hotplugRegisterCallbackNative(Context, int, int, int, int, int, + * HotplugCallbackHandle, long) + */ +JNIEXPORT jint JNICALL METHOD_NAME(LibUsb, hotplugRegisterCallbackNative) +( + JNIEnv *env, jclass class, jobject context, jint events, jint flags, + jint vendorId, jint productId, jint deviceClass, + jobject callbackHandle, jlong hotplugId +) +{ + libusb_context *ctx = unwrapContext(env, context); + if (!ctx && context) return 0; + + if (callbackHandle != NULL) + { + // If callbackHandle is set, the Java object must be fresh/empty. + NOT_SET(env, callbackHandle, "hotplugCallbackHandleValue", return 0); + } + + // Register the callback. + libusb_hotplug_callback_handle handle; + int result = libusb_hotplug_register_callback(ctx, events, flags, + vendorId, productId, deviceClass, &hotplugCallback, + (void *) (intptr_t) hotplugId, &handle); + + // If callbackHandle is set and registering was successful, we set the handle + // to the value we've gotten from libusb. + if ((callbackHandle != NULL) && (result == LIBUSB_SUCCESS)) + { + setHotplugCallbackHandle(env, handle, callbackHandle); + } + + return result; +} + +/* + * long hotplugDeregisterCallbackNative(Context, HotplugCallbackHandle) + */ +JNIEXPORT jlong JNICALL METHOD_NAME(LibUsb, hotplugDeregisterCallbackNative) +( + JNIEnv *env, jclass class, jobject context, jobject callbackHandle +) +{ + libusb_context *ctx = unwrapContext(env, context); + if (!ctx && context) return 0; + NOT_NULL(env, callbackHandle, return 0); + + libusb_hotplug_callback_handle handle = + unwrapHotplugCallbackHandle(env, callbackHandle); + if (!handle) return 0; + + // Deregister the callback. + libusb_hotplug_deregister_callback(ctx, handle); + + resetHotplugCallbackHandle(env, callbackHandle); + + return handle; } diff --git a/src/main/c/src/Makefile.am b/src/main/c/src/Makefile.am index fc42833..2530c26 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,10 +17,12 @@ libusb4java_la_SOURCES = \ Interface.c \ InterfaceDescriptor.c \ EndpointDescriptor.c \ + IsoPacketDescriptor.c \ Transfer.c \ SsEndpointCompanionDescriptor.c \ BosDescriptor.c \ BosDevCapabilityDescriptor.c \ Usb20ExtensionDescriptor.c \ SsUsbDeviceCapabilityDescriptor.c \ - ContainerIdDescriptor.c + ContainerIdDescriptor.c \ + HotplugCallbackHandle.c diff --git a/src/main/c/src/SsEndpointCompanionDescriptor.c b/src/main/c/src/SsEndpointCompanionDescriptor.c index eeb329c..3f39d8e 100644 --- a/src/main/c/src/SsEndpointCompanionDescriptor.c +++ b/src/main/c/src/SsEndpointCompanionDescriptor.c @@ -7,9 +7,9 @@ #include "Interface.h" void setSsEndpointCompanionDescriptor(JNIEnv* env, - struct libusb_ss_endpoint_companion_descriptor* descriptor, jobject object) + const struct libusb_ss_endpoint_companion_descriptor* descriptor, jobject object) { - SET_POINTER(env, descriptor, object, "ssEndpointCompanionDescriptor"); + SET_POINTER(env, descriptor, object, "ssEndpointCompanionDescriptorPointer"); } struct libusb_ss_endpoint_companion_descriptor* @@ -17,12 +17,12 @@ struct libusb_ss_endpoint_companion_descriptor* { UNWRAP_POINTER(env, descriptor, struct libusb_ss_endpoint_companion_descriptor*, - "ssEndpointCompanionDescriptor"); + "ssEndpointCompanionDescriptorPointer"); } void resetSsEndpointCompanionDescriptor(JNIEnv* env, jobject obj) { - RESET_POINTER(env, obj, "ssEndpointCompanionDescriptor"); + RESET_POINTER(env, obj, "ssEndpointCompanionDescriptorPointer"); } /** @@ -36,7 +36,7 @@ JNIEXPORT jbyte JNICALL METHOD_NAME(SsEndpointCompanionDescriptor, bLength) struct libusb_ss_endpoint_companion_descriptor *descriptor = unwrapSsEndpointCompanionDescriptor(env, this); if (!descriptor) return 0; - return descriptor->bLength; + return (jbyte) descriptor->bLength; } /** @@ -51,7 +51,7 @@ JNIEXPORT jbyte JNICALL METHOD_NAME(SsEndpointCompanionDescriptor, struct libusb_ss_endpoint_companion_descriptor *descriptor = unwrapSsEndpointCompanionDescriptor(env, this); if (!descriptor) return 0; - return descriptor->bDescriptorType; + return (jbyte) descriptor->bDescriptorType; } /** @@ -65,7 +65,7 @@ JNIEXPORT jbyte JNICALL METHOD_NAME(SsEndpointCompanionDescriptor, bMaxBurst) struct libusb_ss_endpoint_companion_descriptor *descriptor = unwrapSsEndpointCompanionDescriptor(env, this); if (!descriptor) return 0; - return descriptor->bMaxBurst; + return (jbyte) descriptor->bMaxBurst; } /** @@ -79,7 +79,7 @@ JNIEXPORT jbyte JNICALL METHOD_NAME(SsEndpointCompanionDescriptor, bmAttributes) struct libusb_ss_endpoint_companion_descriptor *descriptor = unwrapSsEndpointCompanionDescriptor(env, this); if (!descriptor) return 0; - return descriptor->bmAttributes; + return (jbyte) descriptor->bmAttributes; } /** @@ -93,5 +93,5 @@ JNIEXPORT jshort JNICALL METHOD_NAME(SsEndpointCompanionDescriptor, wBytesPerInt struct libusb_ss_endpoint_companion_descriptor *descriptor = unwrapSsEndpointCompanionDescriptor(env, this); if (!descriptor) return 0; - return descriptor->wBytesPerInterval; + return (jshort) descriptor->wBytesPerInterval; } diff --git a/src/main/c/src/SsEndpointCompanionDescriptor.h b/src/main/c/src/SsEndpointCompanionDescriptor.h index e05d2be..3febd7d 100644 --- a/src/main/c/src/SsEndpointCompanionDescriptor.h +++ b/src/main/c/src/SsEndpointCompanionDescriptor.h @@ -9,7 +9,7 @@ #include "usb4java.h" void setSsEndpointCompanionDescriptor(JNIEnv*, - struct libusb_ss_endpoint_companion_descriptor*, jobject); + const struct libusb_ss_endpoint_companion_descriptor*, jobject); struct libusb_ss_endpoint_companion_descriptor* unwrapSsEndpointCompanionDescriptor(JNIEnv*, jobject); void resetSsEndpointCompanionDescriptor(JNIEnv*, jobject); diff --git a/src/main/c/src/SsUsbDeviceCapabilityDescriptor.c b/src/main/c/src/SsUsbDeviceCapabilityDescriptor.c index 26dc131..03e8aa4 100644 --- a/src/main/c/src/SsUsbDeviceCapabilityDescriptor.c +++ b/src/main/c/src/SsUsbDeviceCapabilityDescriptor.c @@ -6,7 +6,7 @@ #include "SsUsbDeviceCapabilityDescriptor.h" void setSsUsbDeviceCapabilityDescriptor(JNIEnv* env, - struct libusb_ss_usb_device_capability_descriptor* descriptor, jobject object) + const struct libusb_ss_usb_device_capability_descriptor* descriptor, jobject object) { SET_POINTER(env, descriptor, object, "ssUsbDeviceCapabilityDescriptorPointer"); } @@ -35,7 +35,7 @@ JNIEXPORT jbyte JNICALL METHOD_NAME(SsUsbDeviceCapabilityDescriptor, bLength) struct libusb_ss_usb_device_capability_descriptor *descriptor = unwrapSsUsbDeviceCapabilityDescriptor(env, this); if (!descriptor) return 0; - return descriptor->bLength; + return (jbyte) descriptor->bLength; } /** @@ -49,7 +49,7 @@ JNIEXPORT jbyte JNICALL METHOD_NAME(SsUsbDeviceCapabilityDescriptor, bDescriptor struct libusb_ss_usb_device_capability_descriptor *descriptor = unwrapSsUsbDeviceCapabilityDescriptor(env, this); if (!descriptor) return 0; - return descriptor->bDescriptorType; + return (jbyte) descriptor->bDescriptorType; } /** @@ -64,11 +64,11 @@ JNIEXPORT jbyte JNICALL METHOD_NAME(SsUsbDeviceCapabilityDescriptor, struct libusb_ss_usb_device_capability_descriptor *descriptor = unwrapSsUsbDeviceCapabilityDescriptor(env, this); if (!descriptor) return 0; - return descriptor->bDevCapabilityType; + return (jbyte) descriptor->bDevCapabilityType; } /** - * int bmAttributes() + * byte bmAttributes() */ JNIEXPORT jbyte JNICALL METHOD_NAME(SsUsbDeviceCapabilityDescriptor, bmAttributes) @@ -79,7 +79,7 @@ JNIEXPORT jbyte JNICALL METHOD_NAME(SsUsbDeviceCapabilityDescriptor, struct libusb_ss_usb_device_capability_descriptor *descriptor = unwrapSsUsbDeviceCapabilityDescriptor(env, this); if (!descriptor) return 0; - return descriptor->bmAttributes; + return (jbyte) descriptor->bmAttributes; } /** @@ -94,7 +94,7 @@ JNIEXPORT jshort JNICALL METHOD_NAME(SsUsbDeviceCapabilityDescriptor, struct libusb_ss_usb_device_capability_descriptor *descriptor = unwrapSsUsbDeviceCapabilityDescriptor(env, this); if (!descriptor) return 0; - return descriptor->wSpeedSupported; + return (jshort) descriptor->wSpeedSupported; } /** @@ -109,7 +109,7 @@ JNIEXPORT jbyte JNICALL METHOD_NAME(SsUsbDeviceCapabilityDescriptor, struct libusb_ss_usb_device_capability_descriptor *descriptor = unwrapSsUsbDeviceCapabilityDescriptor(env, this); if (!descriptor) return 0; - return descriptor->bFunctionalitySupport; + return (jbyte) descriptor->bFunctionalitySupport; } /** @@ -124,7 +124,7 @@ JNIEXPORT jbyte JNICALL METHOD_NAME(SsUsbDeviceCapabilityDescriptor, struct libusb_ss_usb_device_capability_descriptor *descriptor = unwrapSsUsbDeviceCapabilityDescriptor(env, this); if (!descriptor) return 0; - return descriptor->bU1DevExitLat; + return (jbyte) descriptor->bU1DevExitLat; } /** @@ -139,5 +139,5 @@ JNIEXPORT jshort JNICALL METHOD_NAME(SsUsbDeviceCapabilityDescriptor, struct libusb_ss_usb_device_capability_descriptor *descriptor = unwrapSsUsbDeviceCapabilityDescriptor(env, this); if (!descriptor) return 0; - return descriptor->bU2DevExitLat; + return (jshort) descriptor->bU2DevExitLat; } diff --git a/src/main/c/src/SsUsbDeviceCapabilityDescriptor.h b/src/main/c/src/SsUsbDeviceCapabilityDescriptor.h index bbeddbb..bd35734 100644 --- a/src/main/c/src/SsUsbDeviceCapabilityDescriptor.h +++ b/src/main/c/src/SsUsbDeviceCapabilityDescriptor.h @@ -9,7 +9,7 @@ #include "usb4java.h" void setSsUsbDeviceCapabilityDescriptor(JNIEnv*, - struct libusb_ss_usb_device_capability_descriptor*, jobject); + const struct libusb_ss_usb_device_capability_descriptor*, jobject); struct libusb_ss_usb_device_capability_descriptor* unwrapSsUsbDeviceCapabilityDescriptor(JNIEnv*, jobject); void resetSsUsbDeviceCapabilityDescriptor(JNIEnv*, jobject); diff --git a/src/main/c/src/Transfer.c b/src/main/c/src/Transfer.c index 80bdc0b..7316ace 100644 --- a/src/main/c/src/Transfer.c +++ b/src/main/c/src/Transfer.c @@ -1,24 +1,36 @@ /* * Copyright (C) 2013 Klaus Reimer (k@ailis.de) + * Copyright (C) 2013 Luca Longinotti (l@longi.li) * 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 +41,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 +155,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..4710bf5 100644 --- a/src/main/c/src/Transfer.h +++ b/src/main/c/src/Transfer.h @@ -1,5 +1,6 @@ /* * Copyright (C) 2013 Klaus Reimer (k@ailis.de) + * Copyright (C) 2013 Luca Longinotti (l@longi.li) * See COPYING file for copying conditions */ @@ -8,7 +9,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/Usb20ExtensionDescriptor.c b/src/main/c/src/Usb20ExtensionDescriptor.c index 553b62b..e201d48 100644 --- a/src/main/c/src/Usb20ExtensionDescriptor.c +++ b/src/main/c/src/Usb20ExtensionDescriptor.c @@ -6,7 +6,7 @@ #include "Usb20ExtensionDescriptor.h" void setUsb20ExtensionDescriptor(JNIEnv* env, - struct libusb_usb_2_0_extension_descriptor* descriptor, jobject object) + const struct libusb_usb_2_0_extension_descriptor* descriptor, jobject object) { SET_POINTER(env, descriptor, object, "usb20ExtensionDescriptorPointer"); } @@ -35,7 +35,7 @@ JNIEXPORT jbyte JNICALL METHOD_NAME(Usb20ExtensionDescriptor, bLength) struct libusb_usb_2_0_extension_descriptor *descriptor = unwrapUsb20ExtensionDescriptor(env, this); if (!descriptor) return 0; - return descriptor->bLength; + return (jbyte) descriptor->bLength; } /** @@ -49,7 +49,7 @@ JNIEXPORT jbyte JNICALL METHOD_NAME(Usb20ExtensionDescriptor, bDescriptorType) struct libusb_usb_2_0_extension_descriptor *descriptor = unwrapUsb20ExtensionDescriptor(env, this); if (!descriptor) return 0; - return descriptor->bDescriptorType; + return (jbyte) descriptor->bDescriptorType; } /** @@ -64,7 +64,7 @@ JNIEXPORT jbyte JNICALL METHOD_NAME(Usb20ExtensionDescriptor, struct libusb_usb_2_0_extension_descriptor *descriptor = unwrapUsb20ExtensionDescriptor(env, this); if (!descriptor) return 0; - return descriptor->bDevCapabilityType; + return (jbyte) descriptor->bDevCapabilityType; } /** @@ -79,5 +79,5 @@ JNIEXPORT jint JNICALL METHOD_NAME(Usb20ExtensionDescriptor, struct libusb_usb_2_0_extension_descriptor *descriptor = unwrapUsb20ExtensionDescriptor(env, this); if (!descriptor) return 0; - return descriptor->bmAttributes; + return (jint) descriptor->bmAttributes; } diff --git a/src/main/c/src/Usb20ExtensionDescriptor.h b/src/main/c/src/Usb20ExtensionDescriptor.h index d076ec4..ec57bc9 100644 --- a/src/main/c/src/Usb20ExtensionDescriptor.h +++ b/src/main/c/src/Usb20ExtensionDescriptor.h @@ -9,7 +9,7 @@ #include "usb4java.h" void setUsb20ExtensionDescriptor(JNIEnv*, - struct libusb_usb_2_0_extension_descriptor*, jobject); + const struct libusb_usb_2_0_extension_descriptor*, jobject); struct libusb_usb_2_0_extension_descriptor* unwrapUsb20ExtensionDescriptor(JNIEnv*, jobject); void resetUsb20ExtensionDescriptor(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..f93f477 100644 --- a/src/main/c/src/usb4java.c +++ b/src/main/c/src/usb4java.c @@ -1,19 +1,84 @@ /* * Copyright (C) 2013 Klaus Reimer (k@ailis.de) + * Copyright (C) 2013 Luca Longinotti (l@longi.li) * See COPYING file for copying conditions */ #include "usb4java.h" -jint illegalArgument(JNIEnv *env, char *message) +JavaVM *jvm = NULL; + +jclass jClassLibUsb = NULL; +jmethodID jMethodTriggerPollfdAdded = NULL; +jmethodID jMethodTriggerPollfdRemoved = NULL; +jmethodID jMethodHotplugCallback = 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) +{ + // Set JVM to the current one. + jvm = vm; + + // Get the current environment. + JNIEnv *env; + jint getEnvResult = (*vm)->GetEnv(vm, (void **) &env, JNI_VERSION_1_6); + if (getEnvResult != JNI_OK) + { + // Send unrecognized version to signal error and deny library load. + return -1; + } + + // Find classes and methods and cache them. + // Persistence is guaranteed by global references. + jClassLibUsb = (*env)->FindClass(env, PACKAGE_DIR"/LibUsb"); + jClassLibUsb = (*env)->NewGlobalRef(env, jClassLibUsb); + + jMethodTriggerPollfdAdded = (*env)->GetStaticMethodID(env, jClassLibUsb, + "triggerPollfdAdded", "(Ljava/io/FileDescriptor;IJ)V"); + jMethodTriggerPollfdRemoved = (*env)->GetStaticMethodID(env, jClassLibUsb, + "triggerPollfdRemoved", "(Ljava/io/FileDescriptor;J)V"); + jMethodHotplugCallback = (*env)->GetStaticMethodID(env, jClassLibUsb, + "hotplugCallback", "(L"PACKAGE_DIR"/Context;L"PACKAGE_DIR"/Device;IJ)I"); + + return JNI_VERSION_1_6; +} + +void JNICALL JNI_OnUnload(JavaVM *vm, void *reserved) +{ + // Get the current environment. + JNIEnv *env; + jint getEnvResult = (*vm)->GetEnv(vm, (void **) &env, JNI_VERSION_1_6); + if (getEnvResult != JNI_OK) + { + return; + } + + // Cleanup all global references. + (*env)->DeleteGlobalRef(env, jClassLibUsb); +} diff --git a/src/main/c/src/usb4java.h b/src/main/c/src/usb4java.h index 35e245f..c2d317a 100644 --- a/src/main/c/src/usb4java.h +++ b/src/main/c/src/usb4java.h @@ -1,5 +1,6 @@ /* * Copyright (C) 2013 Klaus Reimer (k@ailis.de) + * Copyright (C) 2013 Luca Longinotti (l@longi.li) * See COPYING file for copying conditions */ @@ -20,21 +21,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 +39,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)) \ +// 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,16 +65,38 @@ 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); \ + jint getEnvResult = (*jvm)->GetEnv(jvm, (void **) &ENV, JNI_VERSION_1_6); \ if (getEnvResult == JNI_EDETACHED) \ (*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); +// JVM access. +extern JavaVM *jvm; + +// Callback caching. +extern jclass jClassLibUsb; +extern jmethodID jMethodTriggerPollfdAdded; +extern jmethodID jMethodTriggerPollfdRemoved; +extern jmethodID jMethodHotplugCallback; + +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 index da85ad0..f11f829 100644 --- a/src/main/c/src/wrappers.c +++ b/src/main/c/src/wrappers.c @@ -6,7 +6,7 @@ #include // Enforce usage of older memcpy to be compatible with older libc versions -#if WRAP_MEMCPY +#ifdef WRAP_MEMCPY asm (".symver memcpy, memcpy@GLIBC_2.2.5"); void *__wrap_memcpy(void *dest, const void *src, size_t n) { 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/BosDescriptor.java b/src/main/java/de/ailis/usb4java/libusb/BosDescriptor.java index 5b87d7d..813fcba 100644 --- a/src/main/java/de/ailis/usb4java/libusb/BosDescriptor.java +++ b/src/main/java/de/ailis/usb4java/libusb/BosDescriptor.java @@ -1,9 +1,9 @@ /* * Copyright 2013 Klaus Reimer * See LICENSE.md for licensing information. - * - * Based on libusb : - * + * + * Based on libusb : + * * Copyright 2001 Johannes Erdfelt * Copyright 2007-2009 Daniel Drake * Copyright 2010-2012 Peter Stuge @@ -23,10 +23,10 @@ import org.apache.commons.lang3.builder.HashCodeBuilder; /** * A structure representing the Binary Device Object Store (BOS) descriptor. - * + * * This descriptor is documented in section 9.6.2 of the USB 3.0 specification. * All multiple-byte fields are represented in host-endian format. - * + * * @author Klaus Reimer (k@ailis.de) */ public final class BosDescriptor @@ -36,8 +36,7 @@ public final class BosDescriptor /** * Constructs a new BOS descriptor which can be passed to the - * {@link LibUsb#getBosDescriptor(DeviceHandle, BosDescriptor)} - * method. + * {@link LibUsb#getBosDescriptor(DeviceHandle, BosDescriptor)} method. */ public BosDescriptor() { @@ -46,7 +45,7 @@ public final class BosDescriptor /** * Returns the native pointer. - * + * * @return The native pointer. */ public long getPointer() @@ -56,94 +55,109 @@ public final class BosDescriptor /** * Returns the size of this descriptor (in bytes). - * + * * @return The descriptor size in bytes; */ public native byte bLength(); /** * Returns the descriptor type. - * + * * @return The descriptor type. */ public native byte bDescriptorType(); /** - * Returns the length of this descriptor and all of its sub descriptors. - * + * Returns the length of this descriptor and all of its sub descriptors. + * * @return The total descriptor length. */ public native short wTotalLength(); /** - * Returns the number of separate device capability descriptors in the BOS. - * + * Returns the number of separate device capability descriptors in the BOS. + * * @return The number of device capability descriptors. */ public native byte bNumDeviceCaps(); - + /** * Returns the array with the device capability descriptors. - * + * * @return The array with device capability descriptors. */ public native BosDevCapabilityDescriptor[] devCapability(); /** * Returns a dump of this descriptor. - * + * * @return The descriptor dump. */ public String dump() { final StringBuilder builder = new StringBuilder(); - builder.append(String.format("BOS Descriptor:%n" - + " bLength %18d%n" - + " bDescriptorType %10d%n" - + " wTotalLength %13s%n" - + " bNumDeviceCaps %11s%n", - bLength() & 0xff, - bDescriptorType() & 0xff, - wTotalLength() & 0xffff, - bNumDeviceCaps() & 0xff)); - for (final BosDevCapabilityDescriptor descriptor: devCapability()) + + builder.append(String.format( + "BOS Descriptor:%n" + + " bLength %18d%n" + + " bDescriptorType %10d%n" + + " wTotalLength %13s%n" + + " bNumDeviceCaps %11s%n", + this.bLength() & 0xFF, + this.bDescriptorType() & 0xFF, + this.wTotalLength() & 0xFFFF, + this.bNumDeviceCaps() & 0xFF)); + + for (final BosDevCapabilityDescriptor descriptor : this.devCapability()) { builder.append(descriptor.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 BosDescriptor other = - (BosDescriptor) obj; - return new EqualsBuilder() - .append(bDescriptorType(), other.bDescriptorType()) - .append(bLength(), other.bLength()) - .append(wTotalLength(), other.wTotalLength()) - .append(bNumDeviceCaps(), other.bNumDeviceCaps()) - .append(devCapability(), other.devCapability()).isEquals(); + return builder.toString(); } @Override public int hashCode() { return new HashCodeBuilder() - .append(bLength()) - .append(bDescriptorType()) - .append(wTotalLength()) - .append(bNumDeviceCaps()) - .append(devCapability()) + .append(this.bLength()) + .append(this.bDescriptorType()) + .append(this.wTotalLength()) + .append(this.bNumDeviceCaps()) + .append(this.devCapability()) .toHashCode(); } + @Override + public boolean equals(final Object obj) + { + if (obj == null) + { + return false; + } + if (obj == this) + { + return true; + } + if (obj.getClass() != this.getClass()) + { + return false; + } + + final BosDescriptor other = (BosDescriptor) obj; + + return new EqualsBuilder() + .append(this.bLength(), other.bLength()) + .append(this.bDescriptorType(), other.bDescriptorType()) + .append(this.wTotalLength(), other.wTotalLength()) + .append(this.bNumDeviceCaps(), other.bNumDeviceCaps()) + .append(this.devCapability(), other.devCapability()) + .isEquals(); + } + @Override public String toString() { - return dump(); + return this.dump(); } } diff --git a/src/main/java/de/ailis/usb4java/libusb/BosDevCapabilityDescriptor.java b/src/main/java/de/ailis/usb4java/libusb/BosDevCapabilityDescriptor.java index 76d4445..18ae75a 100644 --- a/src/main/java/de/ailis/usb4java/libusb/BosDevCapabilityDescriptor.java +++ b/src/main/java/de/ailis/usb4java/libusb/BosDevCapabilityDescriptor.java @@ -1,9 +1,9 @@ /* * Copyright 2013 Klaus Reimer * See LICENSE.md for licensing information. - * - * Based on libusb : - * + * + * Based on libusb : + * * Copyright 2001 Johannes Erdfelt * Copyright 2007-2009 Daniel Drake * Copyright 2010-2012 Peter Stuge @@ -27,10 +27,10 @@ import de.ailis.usb4java.utils.DescriptorUtils; /** * A generic representation of a BOS Device Capability descriptor. - * + * * It is advised to check bDevCapabilityType and call the matching * get*Descriptor method to get a structure fully matching the type. - * + * * @author Klaus Reimer (k@ailis.de) */ public final class BosDevCapabilityDescriptor @@ -49,7 +49,7 @@ public final class BosDevCapabilityDescriptor /** * Returns the native pointer. - * + * * @return The native pointer. */ public long getPointer() @@ -59,82 +59,92 @@ public final class BosDevCapabilityDescriptor /** * Returns the size of this descriptor (in bytes). - * + * * @return The descriptor size in bytes; */ public native byte bLength(); /** * Returns the descriptor type. - * + * * @return The descriptor type. */ public native byte bDescriptorType(); /** * Returns the device capability type. - * + * * @return The device capability type. */ public native byte bDevCapabilityType(); /** * Returns the device capability data (bLength - 3 bytes). - * + * * @return The device capability data. */ public native ByteBuffer devCapabilityData(); /** * Returns a dump of this descriptor. - * + * * @return The descriptor dump. */ public String dump() { - return String.format("BOS Device Capability Descriptor:%n" - + " bLength %18d%n" - + " bDescriptorType %10d%n" - + " bDevCapabilityType %7s%n" - + " devCapabilityData:%n%s%n", - bLength() & 0xff, - bDescriptorType() & 0xff, - bDevCapabilityType() & 0xff, - DescriptorUtils.dump(devCapabilityData()) + return String.format( + "BOS Device Capability Descriptor:%n" + + " bLength %18d%n" + + " bDescriptorType %10d%n" + + " bDevCapabilityType %7s%n" + + " devCapabilityData:%n%s%n", + this.bLength() & 0xFF, + this.bDescriptorType() & 0xFF, + this.bDevCapabilityType() & 0xFF, + DescriptorUtils.dump(this.devCapabilityData()) .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 BosDevCapabilityDescriptor other = - (BosDevCapabilityDescriptor) obj; - return new EqualsBuilder() - .append(bDescriptorType(), other.bDescriptorType()) - .append(bLength(), other.bLength()) - .append(bDevCapabilityType(), other.bDevCapabilityType()) - .append(devCapabilityData().array(), - other.devCapabilityData().array()).isEquals(); } @Override public int hashCode() { return new HashCodeBuilder() - .append(bLength()) - .append(bDescriptorType()) - .append(bDevCapabilityType()) - .append(devCapabilityData()) + .append(this.bLength()) + .append(this.bDescriptorType()) + .append(this.bDevCapabilityType()) + .append(this.devCapabilityData()) .toHashCode(); } + @Override + public boolean equals(final Object obj) + { + if (obj == null) + { + return false; + } + if (obj == this) + { + return true; + } + if (obj.getClass() != this.getClass()) + { + return false; + } + + final BosDevCapabilityDescriptor other = (BosDevCapabilityDescriptor) obj; + + return new EqualsBuilder() + .append(this.bLength(), other.bLength()) + .append(this.bDescriptorType(), other.bDescriptorType()) + .append(this.bDevCapabilityType(), other.bDevCapabilityType()) + .append(this.devCapabilityData(), other.devCapabilityData()). + isEquals(); + } + @Override public String toString() { - return dump(); + return this.dump(); } } diff --git a/src/main/java/de/ailis/usb4java/libusb/ConfigDescriptor.java b/src/main/java/de/ailis/usb4java/libusb/ConfigDescriptor.java index 175b8f5..897211c 100644 --- a/src/main/java/de/ailis/usb4java/libusb/ConfigDescriptor.java +++ b/src/main/java/de/ailis/usb4java/libusb/ConfigDescriptor.java @@ -1,9 +1,9 @@ /* * Copyright 2013 Klaus Reimer * See LICENSE.md for licensing information. - * - * Based on libusb : - * + * + * Based on libusb : + * * Copyright 2001 Johannes Erdfelt * Copyright 2007-2009 Daniel Drake * Copyright 2010-2012 Peter Stuge @@ -29,10 +29,10 @@ import de.ailis.usb4java.utils.DescriptorUtils; /** * A structure representing the standard USB configuration descriptor. - * + * * This descriptor is documented in section 9.6.3 of the USB 3.0 specification. * All multiple-byte fields are represented in host-endian format. - * + * * @author Klaus Reimer (k@ailis.de) */ public final class ConfigDescriptor implements UsbConfigurationDescriptor @@ -51,7 +51,7 @@ public final class ConfigDescriptor implements UsbConfigurationDescriptor /** * Returns the native pointer. - * + * * @return The native pointer. */ public long getPointer() @@ -85,103 +85,108 @@ public final class ConfigDescriptor implements UsbConfigurationDescriptor /** * Returns the array with interfaces supported by this configuration. - * + * * @return The array with interfaces. */ public native Interface[] iface(); /** * Extra descriptors. - * + * * If libusb encounters unknown interface descriptors, it will store them * here, should you wish to parse them. - * + * * @return The extra descriptors. */ public native ByteBuffer extra(); /** * Length of the extra descriptors, in bytes. - * + * * @return The extra descriptors length. */ public native int extraLength(); /** * Returns a dump of this descriptor. - * + * * @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), + this.extraLength(), + DescriptorUtils.dump(this.extra()).replaceAll("(?m)^", " "))); + + for (final Interface iface : this.iface()) + { + builder.append("%n" + iface.dump()); + } + + return builder.toString(); } @Override public int hashCode() { return new HashCodeBuilder() - .append(bLength()) - .append(bDescriptorType()) - .append(wTotalLength()) - .append(bNumInterfaces()) - .append(bConfigurationValue()) - .append(iConfiguration()) - .append(bmAttributes()) - .append(bMaxPower()) - .append(extra()) - .append(extraLength()) + .append(this.bLength()) + .append(this.bDescriptorType()) + .append(this.wTotalLength()) + .append(this.bNumInterfaces()) + .append(this.bConfigurationValue()) + .append(this.iConfiguration()) + .append(this.bmAttributes()) + .append(this.bMaxPower()) + .append(this.iface()) + .append(this.extra()) + .append(this.extraLength()) .toHashCode(); } + @Override + public boolean equals(final Object obj) + { + if (this == obj) + { + return true; + } + if (obj == null) + { + return false; + } + if (this.getClass() != obj.getClass()) + { + return false; + } + + final ConfigDescriptor other = (ConfigDescriptor) obj; + + return new EqualsBuilder() + .append(this.bLength(), other.bLength()) + .append(this.bDescriptorType(), other.bDescriptorType()) + .append(this.wTotalLength(), other.wTotalLength()) + .append(this.bNumInterfaces(), other.bNumInterfaces()) + .append(this.bConfigurationValue(), other.bConfigurationValue()) + .append(this.iConfiguration(), other.iConfiguration()) + .append(this.bmAttributes(), other.bmAttributes()) + .append(this.bMaxPower(), other.bMaxPower()) + .append(this.iface(), other.iface()) + .append(this.extra(), other.extra()) + .append(this.extraLength(), other.extraLength()) + .isEquals(); + } + @Override public String toString() { - return dump(); + return this.dump(); } } diff --git a/src/main/java/de/ailis/usb4java/libusb/ContainerIdDescriptor.java b/src/main/java/de/ailis/usb4java/libusb/ContainerIdDescriptor.java index 3fb1b1d..c98d2e6 100644 --- a/src/main/java/de/ailis/usb4java/libusb/ContainerIdDescriptor.java +++ b/src/main/java/de/ailis/usb4java/libusb/ContainerIdDescriptor.java @@ -1,9 +1,9 @@ /* * Copyright 2013 Klaus Reimer * See LICENSE.md for licensing information. - * - * Based on libusb : - * + * + * Based on libusb : + * * Copyright 2001 Johannes Erdfelt * Copyright 2007-2009 Daniel Drake * Copyright 2010-2012 Peter Stuge @@ -27,11 +27,11 @@ import de.ailis.usb4java.utils.DescriptorUtils; /** * A structure representing the Container ID descriptor. - * + * * This descriptor is documented in section 9.6.2.3 of the USB 3.0 * specification. All multiple-byte fields, except UUIDs, are represented in * host-endian format. - * + * * @author Klaus Reimer (k@ailis.de) */ public final class ContainerIdDescriptor @@ -41,8 +41,7 @@ public final class ContainerIdDescriptor /** * Constructs a new Container Id descriptor which can be passed to the - * {@link LibUsb#getContainerIdDescriptor(Context, - * BosDevCapabilityDescriptor, ContainerIdDescriptor)} + * {@link LibUsb#getContainerIdDescriptor(Context, BosDevCapabilityDescriptor, ContainerIdDescriptor)} * method. */ public ContainerIdDescriptor() @@ -52,7 +51,7 @@ public final class ContainerIdDescriptor /** * Returns the native pointer. - * + * * @return The native pointer. */ public long getPointer() @@ -62,91 +61,103 @@ public final class ContainerIdDescriptor /** * Returns the size of this descriptor (in bytes). - * + * * @return The descriptor size in bytes; */ public native byte bLength(); /** * Returns the descriptor type. - * + * * @return The descriptor type. */ public native byte bDescriptorType(); /** * Returns the device capability type. - * + * * @return The device capability type. */ public native byte bDevCapabilityType(); /** * Returns the reserved field. - * + * * @return The reserved field. */ public native byte bReserved(); /** * Returns the 128 bit UUID. - * + * * @return The 128 bit UUID. */ public native ByteBuffer containerId(); /** * Returns a dump of this descriptor. - * + * * @return The descriptor dump. */ public String dump() { - return String.format("Container Id Descriptor:%n" - + " bLength %18d%n" - + " bDescriptorType %10d%n" - + " bDevCapabilityType %7d%n" - + " bReserved %16d%n" - + " containerId:%n%s%n", - bLength() & 0xff, - bDescriptorType() & 0xff, - bDevCapabilityType() & 0xff, - bReserved() & 0xff, - DescriptorUtils.dump(containerId()).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 ContainerIdDescriptor other = - (ContainerIdDescriptor) obj; - return new EqualsBuilder() - .append(bDescriptorType(), other.bDescriptorType()) - .append(bLength(), other.bLength()) - .append(bDevCapabilityType(), other.bDevCapabilityType()) - .append(bReserved(), other.bReserved()) - .append(containerId().array(), other.containerId().array()) - .isEquals(); + return String.format( + "Container ID Descriptor:%n" + + " bLength %18d%n" + + " bDescriptorType %10d%n" + + " bDevCapabilityType %7d%n" + + " bReserved %16d%n" + + " ContainerID:%n%s%n", + this.bLength() & 0xFF, + this.bDescriptorType() & 0xFF, + this.bDevCapabilityType() & 0xFF, + this.bReserved() & 0xFF, + DescriptorUtils.dump(this.containerId()) + .replaceAll("(?m)^", " ")); } @Override public int hashCode() { return new HashCodeBuilder() - .append(bLength()) - .append(bDescriptorType()) - .append(bDevCapabilityType()) - .append(bReserved()) - .append(containerId()) + .append(this.bLength()) + .append(this.bDescriptorType()) + .append(this.bDevCapabilityType()) + .append(this.bReserved()) + .append(this.containerId()) .toHashCode(); } + @Override + public boolean equals(final Object obj) + { + if (obj == null) + { + return false; + } + if (obj == this) + { + return true; + } + if (obj.getClass() != this.getClass()) + { + return false; + } + + final ContainerIdDescriptor other = (ContainerIdDescriptor) obj; + + return new EqualsBuilder() + .append(this.bLength(), other.bLength()) + .append(this.bDescriptorType(), other.bDescriptorType()) + .append(this.bDevCapabilityType(), other.bDevCapabilityType()) + .append(this.bReserved(), other.bReserved()) + .append(this.containerId(), other.containerId()) + .isEquals(); + } + @Override public String toString() { - return dump(); + return this.dump(); } } diff --git a/src/main/java/de/ailis/usb4java/libusb/Context.java b/src/main/java/de/ailis/usb4java/libusb/Context.java index db9d0f7..ea86eb9 100644 --- a/src/main/java/de/ailis/usb4java/libusb/Context.java +++ b/src/main/java/de/ailis/usb4java/libusb/Context.java @@ -1,9 +1,9 @@ /* * Copyright 2013 Klaus Reimer * See LICENSE.md for licensing information. - * - * Based on libusb : - * + * + * Based on libusb : + * * Copyright 2001 Johannes Erdfelt * Copyright 2007-2009 Daniel Drake * Copyright 2010-2012 Peter Stuge @@ -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 @@ -28,51 +26,75 @@ import org.apache.commons.lang3.builder.HashCodeBuilder; * {@link LibUsb#setDebug(Context, int)} will not affect the other user of the * library, and {@link LibUsb#exit(Context)} will not destroy resources that the * other user is still using. - * + * * Sessions are created by {@link LibUsb#init(Context)} and destroyed through * {@link LibUsb#exit(Context)}. If your application is guaranteed to only ever * include a single libusb user (i.e. you), you do not have to worry about * contexts: pass NULL in every function call where a context is required. The * default context will be used. - * + * * @author Klaus Reimer (k@ailis.de) */ 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 } /** * Returns the native pointer to the context structure. - * + * * @return The native pointer to the context structure. */ public long getPointer() { 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) (this.contextPointer ^ (this.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 (this.getClass() != obj.getClass()) + { + return false; + } final Context other = (Context) obj; - return this.contextPointer == other.contextPointer; - } + if (this.contextPointer != other.contextPointer) + { + return false; + } + return true; + } + + @Override + public String toString() + { + return String.format("libusb context 0x%x", this.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..22ceda4 --- /dev/null +++ b/src/main/java/de/ailis/usb4java/libusb/ControlSetup.java @@ -0,0 +1,150 @@ +/* + * Copyright 2013 Luca Longinotti + * See LICENSE.md for licensing information. + * + * Based on libusb : + * + * Copyright 2001 Johannes Erdfelt + * Copyright 2007-2009 Daniel Drake + * Copyright 2010-2012 Peter Stuge + * Copyright 2008-2011 Nathan Hjelm + * Copyright 2009-2012 Pete Batard + * Copyright 2009-2012 Ludovic Rousseau + * Copyright 2010-2012 Michael Plante + * Copyright 2011-2012 Hans de Goede + * Copyright 2012 Martin Pieuchot + * Copyright 2012-2013 Toby Gray + */ + +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"); + } + + this.controlSetup = BufferUtils.slice(buffer, 0, + LibUsb.CONTROL_SETUP_SIZE); + + // Control Setup (as all of USB) is Little Endian. + this.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 this.controlSetup.get(0); + } + + public void setBmRequestType(final byte bmRequestType) + { + this.controlSetup.put(0, bmRequestType); + } + + public byte bRequest() + { + return this.controlSetup.get(1); + } + + public void setBRequest(final byte bRequest) + { + this.controlSetup.put(1, bRequest); + } + + public short wValue() + { + return this.controlSetup.getShort(2); + } + + public void setWValue(final short wValue) + { + this.controlSetup.putShort(2, wValue); + } + + public short wIndex() + { + return this.controlSetup.getShort(4); + } + + public void setWIndex(final short wIndex) + { + this.controlSetup.putShort(4, wIndex); + } + + public short wLength() + { + return this.controlSetup.getShort(6); + } + + public void setWLength(final short wLength) + { + this.controlSetup.putShort(6, wLength); + } + + @Override + public int hashCode() + { + final int prime = 31; + int result = 1; + result = (prime * result) + + ((this.controlSetup == null) ? 0 : this.controlSetup.hashCode()); + return result; + } + + @Override + public boolean equals(final Object obj) + { + if (this == obj) + { + return true; + } + if (obj == null) + { + return false; + } + if (this.getClass() != obj.getClass()) + { + return false; + } + final ControlSetup other = (ControlSetup) obj; + if (this.controlSetup == null) + { + if (other.controlSetup != null) + { + return false; + } + } + else if (!this.controlSetup.equals(other.controlSetup)) + { + return false; + } + return true; + } + + @Override + public String toString() + { + return String.format("libusb control setup with buffer %s", + this.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..f55a302 100644 --- a/src/main/java/de/ailis/usb4java/libusb/Device.java +++ b/src/main/java/de/ailis/usb4java/libusb/Device.java @@ -1,9 +1,9 @@ /* * Copyright 2013 Klaus Reimer * See LICENSE.md for licensing information. - * - * Based on libusb : - * + * + * Based on libusb : + * * Copyright 2001 Johannes Erdfelt * Copyright 2007-2009 Daniel Drake * Copyright 2010-2012 Peter Stuge @@ -18,18 +18,16 @@ package de.ailis.usb4java.libusb; -import org.apache.commons.lang3.builder.HashCodeBuilder; - /** * Structure representing a USB device detected on the system. - * + * * This is an opaque type for which you are only ever provided with a pointer, * usually originating from {@link LibUsb#getDeviceList(Context, DeviceList)}. - * + * * Certain operations can be performed on a device, but in order to do any I/O * you will have to first obtain a device handle using * {@link LibUsb#open(Device, DeviceHandle)}. - * + * * Devices are reference counted with {@link LibUsb#refDevice(Device)} and * {@link LibUsb#unrefDevice(Device)}, and are freed when the reference count * reaches 0. New devices presented by @@ -38,7 +36,7 @@ import org.apache.commons.lang3.builder.HashCodeBuilder; * decrease the reference count on all devices in the list. * {@link LibUsb#open(Device, DeviceHandle)} adds another reference which is * later destroyed by {@link LibUsb#close(DeviceHandle)}. - * + * * @author Klaus Reimer (k@ailis.de) */ public final class Device @@ -54,30 +52,48 @@ public final class Device { // Empty } - + /** * Returns the native pointer to the device structure. - * + * * @return The native pointer to the device structure. */ public long getPointer() { 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) (this.devicePointer ^ (this.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 (this.getClass() != obj.getClass()) + { + return false; + } final Device other = (Device) obj; - return this.devicePointer == other.devicePointer; + if (this.devicePointer != other.devicePointer) + { + return false; + } + return true; } @Override diff --git a/src/main/java/de/ailis/usb4java/libusb/DeviceDescriptor.java b/src/main/java/de/ailis/usb4java/libusb/DeviceDescriptor.java index 3056e70..1885168 100644 --- a/src/main/java/de/ailis/usb4java/libusb/DeviceDescriptor.java +++ b/src/main/java/de/ailis/usb4java/libusb/DeviceDescriptor.java @@ -1,9 +1,9 @@ /* * Copyright 2013 Klaus Reimer * See LICENSE.md for licensing information. - * - * Based on libusb : - * + * + * Based on libusb : + * * Copyright 2001 Johannes Erdfelt * Copyright 2007-2009 Daniel Drake * Copyright 2010-2012 Peter Stuge @@ -18,8 +18,6 @@ package de.ailis.usb4java.libusb; -import java.nio.ByteBuffer; - import javax.usb.UsbDeviceDescriptor; import org.apache.commons.lang3.builder.EqualsBuilder; @@ -29,16 +27,16 @@ import de.ailis.usb4java.utils.DescriptorUtils; /** * A structure representing the standard USB device descriptor. - * + * * This descriptor is documented in section 9.6.1 of the USB 3.0 specification. * All multiple-byte fields are represented in host-endian format. - * + * * @author Klaus Reimer (k@ailis.de) */ public 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. - * - * @return The native data. + * Returns the native pointer. + * + * @return The native pointer. */ - public ByteBuffer getData() + public long getPointer() { - return this.deviceDescriptorData; + return this.deviceDescriptorPointer; } @Override @@ -103,17 +101,17 @@ public final class DeviceDescriptor implements UsbDeviceDescriptor /** * Returns a dump of this descriptor. - * + * * @return The descriptor dump. */ public String dump() { - return dump(null); + return this.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. @@ -121,64 +119,76 @@ public final class DeviceDescriptor implements UsbDeviceDescriptor */ public String dump(final DeviceHandle handle) { - final String sManufacturer = LibUsb.getStringDescriptor(handle, - iManufacturer()); - final String sProduct = LibUsb.getStringDescriptor(handle, iProduct()); - final String sSerialNumber = LibUsb.getStringDescriptor(handle, - iSerialNumber()); - return DescriptorUtils.dump(this, sManufacturer, sProduct, + final String sManufacturer = LibUsb.getStringDescriptor(handle, + this.iManufacturer()); + final String sProduct = LibUsb.getStringDescriptor(handle, + this.iProduct()); + final String sSerialNumber = LibUsb.getStringDescriptor(handle, + this.iSerialNumber()); + return DescriptorUtils.dump(this, sManufacturer, sProduct, sSerialNumber); } - @Override - public 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() { return new HashCodeBuilder() - .append(bLength()) - .append(bDescriptorType()) - .append(bcdUSB()) - .append(bDeviceClass()) - .append(bDeviceSubClass()) - .append(bDeviceProtocol()) - .append(bMaxPacketSize0()) - .append(idVendor()) - .append(idProduct()) - .append(bcdDevice()) - .append(iManufacturer()) - .append(iProduct()) - .append(iSerialNumber()) - .append(bNumConfigurations()).toHashCode(); + .append(this.bLength()) + .append(this.bDescriptorType()) + .append(this.bcdUSB()) + .append(this.bDeviceClass()) + .append(this.bDeviceSubClass()) + .append(this.bDeviceProtocol()) + .append(this.bMaxPacketSize0()) + .append(this.idVendor()) + .append(this.idProduct()) + .append(this.bcdDevice()) + .append(this.iManufacturer()) + .append(this.iProduct()) + .append(this.iSerialNumber()) + .append(this.bNumConfigurations()) + .toHashCode(); + } + + @Override + public boolean equals(final Object obj) + { + if (this == obj) + { + return true; + } + if (obj == null) + { + return false; + } + if (this.getClass() != obj.getClass()) + { + return false; + } + + final DeviceDescriptor other = (DeviceDescriptor) obj; + + return new EqualsBuilder() + .append(this.bLength(), other.bLength()) + .append(this.bDescriptorType(), other.bDescriptorType()) + .append(this.bcdUSB(), other.bcdUSB()) + .append(this.bDeviceClass(), other.bDeviceClass()) + .append(this.bDeviceSubClass(), other.bDeviceSubClass()) + .append(this.bDeviceProtocol(), other.bDeviceProtocol()) + .append(this.bMaxPacketSize0(), other.bMaxPacketSize0()) + .append(this.idVendor(), other.idVendor()) + .append(this.idProduct(), other.idProduct()) + .append(this.bcdDevice(), other.bcdDevice()) + .append(this.iManufacturer(), other.iManufacturer()) + .append(this.iProduct(), other.iProduct()) + .append(this.iSerialNumber(), other.iSerialNumber()) + .append(this.bNumConfigurations(), other.bNumConfigurations()) + .isEquals(); } @Override public String toString() { - return dump(); + return this.dump(); } } diff --git a/src/main/java/de/ailis/usb4java/libusb/DeviceHandle.java b/src/main/java/de/ailis/usb4java/libusb/DeviceHandle.java index 3a0f762..efa075b 100644 --- a/src/main/java/de/ailis/usb4java/libusb/DeviceHandle.java +++ b/src/main/java/de/ailis/usb4java/libusb/DeviceHandle.java @@ -1,9 +1,9 @@ /* * Copyright 2013 Klaus Reimer * See LICENSE.md for licensing information. - * - * Based on libusb : - * + * + * Based on libusb : + * * Copyright 2001 Johannes Erdfelt * Copyright 2007-2009 Daniel Drake * Copyright 2010-2012 Peter Stuge @@ -18,17 +18,15 @@ package de.ailis.usb4java.libusb; -import org.apache.commons.lang3.builder.HashCodeBuilder; - /** * Structure representing a handle on a USB device. - * + * * This is an opaque type for which you are only ever provided with a pointer, * usually originating from {@link LibUsb#open(Device, DeviceHandle)}. - * + * * A device handle is used to perform I/O and other operations. When finished * with a device handle, you should call {@link LibUsb#close(DeviceHandle)}. - * + * * @author Klaus Reimer (k@ailis.de) */ public final class DeviceHandle @@ -48,7 +46,7 @@ public final class DeviceHandle /** * Returns the native pointer to the device handle structure. - * + * * @return The native pointer to the device handle structure. */ public long getPointer() @@ -59,22 +57,40 @@ 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) (this.deviceHandlePointer ^ (this.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 (this.getClass() != obj.getClass()) + { + return false; + } final DeviceHandle other = (DeviceHandle) obj; - return this.deviceHandlePointer == other.deviceHandlePointer; + if (this.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", + this.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..815e809 100644 --- a/src/main/java/de/ailis/usb4java/libusb/DeviceList.java +++ b/src/main/java/de/ailis/usb4java/libusb/DeviceList.java @@ -1,9 +1,9 @@ /* * Copyright 2013 Klaus Reimer * See LICENSE.md for licensing information. - * - * Based on libusb : - * + * + * Based on libusb : + * * Copyright 2001 Johannes Erdfelt * Copyright 2007-2009 Daniel Drake * Copyright 2010-2012 Peter Stuge @@ -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,21 +41,21 @@ public final class DeviceList implements Iterable public DeviceList() { // Empty - } + } /** * Returns the native pointer. - * + * * @return The native pointer. */ public long getPointer() { return this.deviceListPointer; } - + /** * Returns the number of devices in the list. - * + * * @return The number of devices in the list. */ public int getSize() @@ -67,7 +65,7 @@ public final class DeviceList implements Iterable /** * Returns the device with the specified index. - * + * * @param index * The device index. * @return The device or null when index is out of bounds. @@ -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) (this.deviceListPointer ^ (this.deviceListPointer >>> 32)); + result = (prime * result) + this.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 (this.getClass() != obj.getClass()) + { + return false; + } final DeviceList other = (DeviceList) obj; - return this.deviceListPointer == other.deviceListPointer; + if (this.deviceListPointer != other.deviceListPointer) + { + return false; + } + if (this.size != other.size) + { + return false; + } + return true; + } + + @Override + public String toString() + { + return String.format("libusb device list 0x%x with size %d", + this.deviceListPointer, this.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..9e385d3 100644 --- a/src/main/java/de/ailis/usb4java/libusb/DeviceListIterator.java +++ b/src/main/java/de/ailis/usb4java/libusb/DeviceListIterator.java @@ -9,7 +9,7 @@ import java.util.Iterator; /** * Iterator for device list. - * + * * @author Klaus Reimer (k@ailis.de) */ final class DeviceListIterator implements Iterator @@ -22,7 +22,7 @@ final class DeviceListIterator implements Iterator /** * Constructor. - * + * * @param devices * The devices list. */ diff --git a/src/main/java/de/ailis/usb4java/libusb/EndpointDescriptor.java b/src/main/java/de/ailis/usb4java/libusb/EndpointDescriptor.java index 459f49a..d19b69b 100644 --- a/src/main/java/de/ailis/usb4java/libusb/EndpointDescriptor.java +++ b/src/main/java/de/ailis/usb4java/libusb/EndpointDescriptor.java @@ -1,9 +1,9 @@ /* * Copyright 2013 Klaus Reimer * See LICENSE.md for licensing information. - * - * Based on libusb : - * + * + * Based on libusb : + * * Copyright 2001 Johannes Erdfelt * Copyright 2007-2009 Daniel Drake * Copyright 2010-2012 Peter Stuge @@ -29,7 +29,7 @@ import de.ailis.usb4java.utils.DescriptorUtils; /** * A structure representing the standard USB endpoint descriptor. - * + * * This descriptor is documented in section 9.6.6 of the USB 3.0 specification. * All multiple-byte fields are represented in host-endian format. * @@ -41,17 +41,17 @@ 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. - * + * * @return The native pointer. */ public long getPointer() @@ -80,91 +80,104 @@ public final class EndpointDescriptor implements UsbEndpointDescriptor /** * For audio devices only: the rate at which synchronization feedback is * provided. - * + * * @return The synchronization feedback rate. */ public native byte bRefresh(); /** * For audio devices only: the address of the synch endpoint. - * + * * @return The synch endpoint address. */ public native byte bSynchAddress(); /** * Extra descriptors. - * + * * If libusb encounters unknown endpoint descriptors, it will store them * here, should you wish to parse them. - * + * * @return The extra descriptors. */ public native ByteBuffer extra(); /** * Length of the extra descriptors, in bytes. - * + * * @return The extra descriptors length. */ public native int extraLength(); /** * Returns a dump of this descriptor. - * + * * @return The descriptor dump. */ public String dump() { - return String.format("%s" - + " extralen %17d%n" - + " extra:%n" - + "%s%n", + return String.format( + "%s%n" + + " extralen %17d%n" + + " extra:%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(); + this.extraLength(), + DescriptorUtils.dump(this.extra()).replaceAll("(?m)^", " ")); } @Override public int hashCode() { return new HashCodeBuilder() - .append(bLength()) - .append(bDescriptorType()) - .append(bEndpointAddress()) - .append(bmAttributes()) - .append(wMaxPacketSize()) - .append(bInterval()) - .append(bRefresh()) - .append(bSynchAddress()) - .append(extra()) - .append(extraLength()) + .append(this.bLength()) + .append(this.bDescriptorType()) + .append(this.bEndpointAddress()) + .append(this.bmAttributes()) + .append(this.wMaxPacketSize()) + .append(this.bInterval()) + .append(this.bRefresh()) + .append(this.bSynchAddress()) + .append(this.extra()) + .append(this.extraLength()) .toHashCode(); } + @Override + public boolean equals(final Object obj) + { + if (this == obj) + { + return true; + } + if (obj == null) + { + return false; + } + if (this.getClass() != obj.getClass()) + { + return false; + } + + final EndpointDescriptor other = (EndpointDescriptor) obj; + + return new EqualsBuilder() + .append(this.bLength(), other.bLength()) + .append(this.bDescriptorType(), other.bDescriptorType()) + .append(this.bEndpointAddress(), other.bEndpointAddress()) + .append(this.bmAttributes(), other.bmAttributes()) + .append(this.wMaxPacketSize(), other.wMaxPacketSize()) + .append(this.bInterval(), other.bInterval()) + .append(this.bRefresh(), other.bRefresh()) + .append(this.bSynchAddress(), other.bSynchAddress()) + .append(this.extra(), other.extra()) + .append(this.extraLength(), other.extraLength()) + .isEquals(); + } + @Override public String toString() { - return dump(); + return this.dump(); } } diff --git a/src/main/java/de/ailis/usb4java/libusb/HotplugCallback.java b/src/main/java/de/ailis/usb4java/libusb/HotplugCallback.java new file mode 100644 index 0000000..f87ff6a --- /dev/null +++ b/src/main/java/de/ailis/usb4java/libusb/HotplugCallback.java @@ -0,0 +1,11 @@ +/* + * Copyright 2013 Luca Longinotti + * See LICENSE.md for licensing information. + */ + +package de.ailis.usb4java.libusb; + +public interface HotplugCallback +{ + int processEvent(Context context, Device device, int event, Object userData); +} diff --git a/src/main/java/de/ailis/usb4java/libusb/HotplugCallbackHandle.java b/src/main/java/de/ailis/usb4java/libusb/HotplugCallbackHandle.java new file mode 100644 index 0000000..1882ae3 --- /dev/null +++ b/src/main/java/de/ailis/usb4java/libusb/HotplugCallbackHandle.java @@ -0,0 +1,98 @@ +/* + * Copyright 2013 Luca Longinotti + * See LICENSE.md for licensing information. + * + * Based on libusb : + * + * Copyright 2001 Johannes Erdfelt + * Copyright 2007-2009 Daniel Drake + * Copyright 2010-2012 Peter Stuge + * Copyright 2008-2011 Nathan Hjelm + * Copyright 2009-2012 Pete Batard + * Copyright 2009-2012 Ludovic Rousseau + * Copyright 2010-2012 Michael Plante + * Copyright 2011-2012 Hans de Goede + * Copyright 2012 Martin Pieuchot + * Copyright 2012-2013 Toby Gray + */ + +package de.ailis.usb4java.libusb; + +/** + * Hotplug Callback Handle. + * + * Callback handles are generated by {@link LibUsb#hotplugRegisterCallback(Context, + * int, int, short, short, byte, HotplugCallback, Object, HotplugCallbackHandle)} + * and can be used to deregister callbacks. Callback handles are unique + * per {@link Context} and it is safe to call + * {@link LibUsb#hotplugDeregisterCallback(Context, HotplugCallbackHandle)} + * on an already deregistered callback. + * + * @author Luca Longinotti (l@longi.li) + */ +public final class HotplugCallbackHandle +{ + /** The hotplug callback handle, it's an integer (int) in C. */ + private long hotplugCallbackHandleValue; + + /** + * Constructs a new hotplug callback handle. Must be passed to + * {@link LibUsb#hotplugRegisterCallback(Context, int, int, short, short, + * byte, HotplugCallback, Object, HotplugCallbackHandle)} before passing it + * to any other method. + */ + public HotplugCallbackHandle() + { + // Empty + } + + /** + * Returns the hotplug callback handle value. + * + * @return The hotplug callback handle value. + */ + public long getValue() + { + return this.hotplugCallbackHandleValue; + } + + @Override + public int hashCode() + { + final int prime = 31; + int result = 1; + result = (prime * result) + + (int) (this.hotplugCallbackHandleValue ^ (this.hotplugCallbackHandleValue >>> 32)); + return result; + } + + @Override + public boolean equals(final Object obj) + { + if (this == obj) + { + return true; + } + if (obj == null) + { + return false; + } + if (this.getClass() != obj.getClass()) + { + return false; + } + final HotplugCallbackHandle other = (HotplugCallbackHandle) obj; + if (this.hotplugCallbackHandleValue != other.hotplugCallbackHandleValue) + { + return false; + } + return true; + } + + @Override + public String toString() + { + return String.format("libusb hotplug callback handle 0x%x", + this.hotplugCallbackHandleValue); + } +} diff --git a/src/main/java/de/ailis/usb4java/libusb/Interface.java b/src/main/java/de/ailis/usb4java/libusb/Interface.java index dc1659f..611abd0 100644 --- a/src/main/java/de/ailis/usb4java/libusb/Interface.java +++ b/src/main/java/de/ailis/usb4java/libusb/Interface.java @@ -1,9 +1,9 @@ /* * Copyright 2013 Klaus Reimer * See LICENSE.md for licensing information. - * - * Based on libusb : - * + * + * Based on libusb : + * * Copyright 2001 Johannes Erdfelt * Copyright 2007-2009 Daniel Drake * Copyright 2010-2012 Peter Stuge @@ -18,11 +18,12 @@ package de.ailis.usb4java.libusb; +import org.apache.commons.lang3.builder.EqualsBuilder; import org.apache.commons.lang3.builder.HashCodeBuilder; /** * A collection of alternate settings for a particular USB interface. - * + * * @author Klaus Reimer (k@ailis.de) */ public final class Interface @@ -31,35 +32,35 @@ 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. - * + * * @return The native pointer. */ public long getPointer() { return this.interfacePointer; } - + /** * Returns the array with interface descriptors. The length of this array is * determined by the {@link #numAltsetting()} field. - * + * * @return The array with interface descriptors. */ public native InterfaceDescriptor[] altsetting(); /** * Returns the number of alternate settings that belong to this interface. - * + * * @return The number of alternate settings. */ public native int numAltsetting(); @@ -70,46 +71,58 @@ 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", + this.numAltsetting())); + + for (final InterfaceDescriptor intDesc : this.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(this.altsetting()) + .append(this.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 (this.getClass() != obj.getClass()) + { + return false; + } + final Interface other = (Interface) obj; - return this.interfacePointer == other.interfacePointer; + + return new EqualsBuilder() + .append(this.altsetting(), other.altsetting()) + .append(this.numAltsetting(), other.numAltsetting()) + .isEquals(); } - + @Override public String toString() { - return dump(); + return this.dump(); } } diff --git a/src/main/java/de/ailis/usb4java/libusb/InterfaceDescriptor.java b/src/main/java/de/ailis/usb4java/libusb/InterfaceDescriptor.java index d781646..f9d7521 100644 --- a/src/main/java/de/ailis/usb4java/libusb/InterfaceDescriptor.java +++ b/src/main/java/de/ailis/usb4java/libusb/InterfaceDescriptor.java @@ -1,9 +1,9 @@ /* * Copyright 2013 Klaus Reimer * See LICENSE.md for licensing information. - * - * Based on libusb : - * + * + * Based on libusb : + * * Copyright 2001 Johannes Erdfelt * Copyright 2007-2009 Daniel Drake * Copyright 2010-2012 Peter Stuge @@ -29,10 +29,10 @@ import de.ailis.usb4java.utils.DescriptorUtils; /** * A structure representing the standard USB interface descriptor. - * + * * This descriptor is documented in section 9.6.5 of the USB 3.0 specification. * All multiple-byte fields are represented in host-endian format. - * + * * @author Klaus Reimer (k@ailis.de) */ public final class InterfaceDescriptor implements UsbInterfaceDescriptor @@ -41,17 +41,17 @@ 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. - * + * * @return The native pointer. */ public long getPointer() @@ -88,110 +88,110 @@ public final class InterfaceDescriptor implements UsbInterfaceDescriptor /** * Returns the array with endpoints. - * + * * @return The array with endpoints. */ public native EndpointDescriptor[] endpoint(); /** * Extra descriptors. - * + * * If libusb encounters unknown interface descriptors, it will store them * here, should you wish to parse them. - * + * * @return The extra descriptors. */ public native ByteBuffer extra(); /** * Length of the extra descriptors, in bytes. - * + * * @return The extra descriptors length. */ public native int extraLength(); /** * Returns a dump of this descriptor. - * + * * @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), + this.extraLength(), + DescriptorUtils.dump(this.extra()).replaceAll("(?m)^", " "))); + + for (final EndpointDescriptor epDesc : this.endpoint()) + { + builder.append("%n" + epDesc.dump()); + } + + return builder.toString(); } @Override public int hashCode() { return new HashCodeBuilder() - .append(bLength()) - .append(bDescriptorType()) - .append(bInterfaceNumber()) - .append(bAlternateSetting()) - .append(bNumEndpoints()) - .append(bInterfaceClass()) - .append(bInterfaceSubClass()) - .append(bInterfaceProtocol()) - .append(iInterface()) - .append(extra()) - .append(extraLength()) + .append(this.bLength()) + .append(this.bDescriptorType()) + .append(this.bInterfaceNumber()) + .append(this.bAlternateSetting()) + .append(this.bNumEndpoints()) + .append(this.bInterfaceClass()) + .append(this.bInterfaceSubClass()) + .append(this.bInterfaceProtocol()) + .append(this.iInterface()) + .append(this.endpoint()) + .append(this.extra()) + .append(this.extraLength()) .toHashCode(); } + @Override + public boolean equals(final Object obj) + { + if (this == obj) + { + return true; + } + if (obj == null) + { + return false; + } + if (this.getClass() != obj.getClass()) + { + return false; + } + + final InterfaceDescriptor other = (InterfaceDescriptor) obj; + + return new EqualsBuilder() + .append(this.bLength(), other.bLength()) + .append(this.bDescriptorType(), other.bDescriptorType()) + .append(this.bInterfaceNumber(), other.bInterfaceNumber()) + .append(this.bAlternateSetting(), other.bAlternateSetting()) + .append(this.bNumEndpoints(), other.bNumEndpoints()) + .append(this.bInterfaceClass(), other.bInterfaceClass()) + .append(this.bInterfaceSubClass(), other.bInterfaceSubClass()) + .append(this.bInterfaceProtocol(), other.bInterfaceProtocol()) + .append(this.iInterface(), other.iInterface()) + .append(this.endpoint(), other.endpoint()) + .append(this.extra(), other.extra()) + .append(this.extraLength(), other.extraLength()) + .isEquals(); + } + @Override public String toString() { - return dump(); + return this.dump(); } } 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..8c48dc4 --- /dev/null +++ b/src/main/java/de/ailis/usb4java/libusb/IsoPacketDescriptor.java @@ -0,0 +1,95 @@ +/* + * Copyright 2013 Luca Longinotti + * See LICENSE.md for licensing information. + * + * Based on libusb : + * + * Copyright 2001 Johannes Erdfelt + * Copyright 2007-2009 Daniel Drake + * Copyright 2010-2012 Peter Stuge + * Copyright 2008-2011 Nathan Hjelm + * Copyright 2009-2012 Pete Batard + * Copyright 2009-2012 Ludovic Rousseau + * Copyright 2010-2012 Michael Plante + * Copyright 2011-2012 Hans de Goede + * Copyright 2012 Martin Pieuchot + * Copyright 2012-2013 Toby Gray + */ + +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 this.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) (this.isoPacketDescriptorPointer ^ (this.isoPacketDescriptorPointer >>> 32)); + return result; + } + + @Override + public boolean equals(final Object obj) + { + if (this == obj) + { + return true; + } + if (obj == null) + { + return false; + } + if (this.getClass() != obj.getClass()) + { + return false; + } + final IsoPacketDescriptor other = (IsoPacketDescriptor) obj; + if (this.isoPacketDescriptorPointer != other.isoPacketDescriptorPointer) + { + return false; + } + return true; + } + + @Override + public String toString() + { + return String.format("libusb iso packet descriptor 0x%x", + this.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..d6a0549 100644 --- a/src/main/java/de/ailis/usb4java/libusb/LibUsb.java +++ b/src/main/java/de/ailis/usb4java/libusb/LibUsb.java @@ -1,9 +1,10 @@ /* * Copyright 2013 Klaus Reimer + * Copyright 2013 Luca Longinotti * See LICENSE.md for licensing information. - * - * Based on libusb : - * + * + * Based on libusb : + * * Copyright 2001 Johannes Erdfelt * Copyright 2007-2009 Daniel Drake * Copyright 2010-2012 Peter Stuge @@ -21,11 +22,19 @@ 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. - * + * * @author Klaus Reimer (k@ailis.de) + * @author Luca Longinotti (l@longi.li) */ public final class LibUsb { @@ -98,6 +107,9 @@ public final class LibUsb /** Other error. */ public static final int ERROR_OTHER = -99; + /** Total number of error codes */ + public static final int ERROR_COUNT = 14; + // Speed codes. Indicates the speed at which the device is operating. /** The OS doesn't report or know the device speed. */ @@ -119,16 +131,16 @@ public final class LibUsb // device supports. /** Low speed operation supported (1.5MBit/s). */ - public static final int LOW_SPEED_OPERATION = 1; + public static final short LOW_SPEED_OPERATION = 1; /** Full speed operation supported (12MBit/s). */ - public static final int FULL_SPEED_OPERATION = 2; + public static final short FULL_SPEED_OPERATION = 2; /** High speed operation supported (480MBit/s). */ - public static final int HIGH_SPEED_OPERATION = 4; + public static final short HIGH_SPEED_OPERATION = 4; /** Superspeed operation supported (5000MBit/s). */ - public static final int SUPER_SPEED_OPERATION = 8; + public static final short SUPER_SPEED_OPERATION = 8; // Masks for the bits of the bmAttributes field of the USB 2.0 Extension // descriptor. @@ -140,94 +152,94 @@ public final class LibUsb // Device Capability descriptor. /** Supports Latency Tolerance Messages (LTM). */ - public static final int BM_LTM_SUPPORT = 2; + public static final byte BM_LTM_SUPPORT = 2; // USB capability types. /** Wireless USB device capability. */ - public static final int BT_WIRELESS_USB_DEVICE_CAPABILITY = 1; + public static final byte BT_WIRELESS_USB_DEVICE_CAPABILITY = 1; /** USB 2.0 extensions. */ - public static final int BT_USB_2_0_EXTENSION = 2; + public static final byte BT_USB_2_0_EXTENSION = 2; /** SuperSpeed USB device capability. */ - public static final int BT_SS_USB_DEVICE_CAPABILITY = 3; + public static final byte BT_SS_USB_DEVICE_CAPABILITY = 3; /** Container ID type. */ - public static final int BT_CONTAINER_ID = 4; + public static final byte BT_CONTAINER_ID = 4; // 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 +266,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,257 +275,291 @@ 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. /** * Device descriptor. - * + * * @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; + /** Size of an endpoint descriptor. */ + public static final byte DT_ENDPOINT_SIZE = 7; - /** Size of an interface descriptor. */ - public static final int DT_ENDPOINT_AUDIO_SIZE = 9; + /** Size of an endpoint descriptor with audio extension. */ + public static final byte DT_ENDPOINT_AUDIO_SIZE = 9; - /** Size of an interface descriptor. */ - public static final int DT_HUB_NONVAR_SIZE = 7; + /** Size of a hub descriptor. */ + public static final byte DT_HUB_NONVAR_SIZE = 7; + + /** Size of a SuperSpeed endpoint companion descriptor. */ + public static final byte DT_SS_ENDPOINT_COMPANION_SIZE = 6; + + /** Size of a BOS descriptor. */ + public static final byte DT_BOS_SIZE = 5; + + /** Size of a device capability descriptor. */ + public static final byte DT_DEVICE_CAPABILITY_SIZE = 3; + + // BOS descriptor sizes + + /** Size of a BOS descriptor. */ + public static final byte BT_USB_2_0_EXTENSION_SIZE = 7; + + /** Size of a BOS descriptor. */ + public static final byte BT_SS_USB_DEVICE_CAPABILITY_SIZE = 10; + + /** Size of a BOS descriptor. */ + public static final byte BT_CONTAINER_ID_SIZE = 20; + + /** We unwrap the BOS => define its maximum size */ + public static final byte DT_BOS_MAX_SIZE = ((DT_BOS_SIZE) + + (BT_USB_2_0_EXTENSION_SIZE) + (BT_SS_USB_DEVICE_CAPABILITY_SIZE) + (BT_CONTAINER_ID_SIZE)); // 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 * returns. - * + * * If this flag is set, it is illegal to call * {@link #freeTransfer(Transfer)} from your transfer callback, as this will * result in a double-free when this flag is acted upon. */ - 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 * with an extra zero length packet. - * + * * This is useful when a device protocol mandates that each logical request * is terminated by an incomplete packet (i.e. the logical requests are not * separated by other means). - * + * * This flag only affects host-to-device transfers to bulk and interrupt * endpoints. In other situations, it is ignored. - * + * * This flag only affects transfers with a length that is a multiple of the * endpoint's wMaxPacketSize. On transfers of other lengths, this flag has * no effect. Therefore, if you are working with a device that needs a ZLP * whenever the end of the logical request falls on a packet boundary, then * it is sensible to set this flag on every transfer (you do not have to * worry about only setting it on transfers that end on the boundary). - * + * * This flag is currently only supported on Linux. On other systems, * libusb_submit_transfer() will return {@link #ERROR_NOT_SUPPORTED} for * every transfer where this flag is set. */ - public static final int TRANSFER_ADD_ZERO_PACKET = 8; + public static final byte TRANSFER_ADD_ZERO_PACKET = 8; // Transfer status codes @@ -542,14 +590,45 @@ 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; + // Flags for hotplug events - /** The currently set pollfd listener. */ - private static PollfdListener pollfdListener; + /** + * Arm the callback and fire it for all matching currently attached devices. + */ + public static final int HOTPLUG_ENUMERATE = 1; - /** The currently set pollfd listener user data. */ - private static Object pollfdListenerUserData; + // Hotplug events + + /** A device has been plugged in and is ready to use. */ + public static final int HOTPLUG_EVENT_DEVICE_ARRIVED = 0x01; + + /** + * A device has left and is no longer available. + * It is the user's responsibility to call {@link #close(DeviceHandle)} on + * any handle associated with a disconnected device. + * It is safe to call {@link #getDeviceDescriptor(Device, DeviceDescriptor)} + * on a device that has left. + */ + public static final int HOTPLUG_EVENT_DEVICE_LEFT = 0x02; + + // Wildcard matching for hotplug events + + /** Match any vendorId or productId or deviceClass. */ + public static final int HOTPLUG_MATCH_ANY = -1; + + /** + * Hotplug callbacks (to correctly manage calls and additional data). + */ + private static long globalHotplugId = 1; + + private static final ConcurrentMap> hotplugCallbacks = + new ConcurrentHashMap>(); + + /** + * Pollfd listeners (to support different listeners for different contexts). + */ + private static final ConcurrentMap> pollfdListeners = + new ConcurrentHashMap>(); static { @@ -567,90 +646,89 @@ public final class LibUsb /** * Returns the API version of the underlying libusb library. It is defined * as follows: (major << 24) | (minor << 16) | (16 bit incremental) - * + * * @return The API version of the underlying libusb library. */ public static native int getApiVersion(); /** * Initialize libusb. - * + * * This function must be called before calling any other libusb function. - * + * * If you do not provide an output location for a {@link Context}, a default * context will be created. If there was already a default context, it will * be reused (and nothing will be initialized/reinitialized). - * + * * @param context * Optional output location for context pointer. Null to use * default context. Only valid on return code 0. * @return 0 on success or a error code on failure. */ - public static native int init(final Context context); + public static synchronized native int init(final Context context); /** * Deinitialize libusb. - * + * * Should be called after closing all open devices and before your * application terminates. - * + * * @param context * The {@link Context} to deinitialize, or NULL for the default * context. */ - public static native void exit(final Context context); + public static synchronized native void exit(final Context context); /** * Set log message verbosity. - * + * * The default level is {@link #LOG_LEVEL_NONE}, which means no messages are * ever printed. If you choose to increase the message verbosity level, * ensure that your application does not close the stdout/stderr file * descriptors. - * + * * You are advised to use level {@link #LOG_LEVEL_WARNING}. libusb is * conservative with its message logging and most of the time, will only log * messages that explain error conditions and other oddities. This will help * you debug your software. - * + * * If the {@link #LOG_LEVEL_DEBUG} environment variable was set when libusb * was initialized, this function does nothing: the message verbosity is * fixed to the value in the environment variable. - * + * * If libusb was compiled without any message logging, this function does * nothing: you'll never get any messages. - * + * * If libusb was compiled with verbose debug message logging, this function * does nothing: you'll always get messages from all levels. - * + * * @param context * The {@link Context} to operate on, or NULL for the default * context. * @param level * The log level to set. */ - public static native void setDebug(final Context context, - final int level); + public static native void setDebug(final Context context, final int level); /** * Returns the version of the libusb runtime. - * + * * @return The version of the libusb runtime. */ public static native Version getVersion(); /** * Returns a list of USB devices currently attached to the system. - * + * * This is your entry point into finding a USB device to operate. - * + * * You are expected to unreference all the devices when you are done with * them, and then free the list with * {@link #freeDeviceList(DeviceList, boolean)}. Note that * {@link #freeDeviceList(DeviceList, boolean)} can unref all the devices * for you. Be careful not to unreference a device you are about to open * until after you have opened it. - * + * * @param context * The context to operate on, or NULL for the default context. * @param list @@ -665,10 +743,10 @@ public final class LibUsb /** * Frees a list of devices previously discovered using * {@link #getDeviceList(Context, DeviceList)}. - * + * * If the unref_devices parameter is set, the reference count of each device * in the list is decremented by 1. - * + * * @param list * The list to free. * @param unrefDevices @@ -679,7 +757,7 @@ public final class LibUsb /** * Get the number of the bus that a device is connected to. - * + * * @param device * A device. * @return The bus number @@ -688,7 +766,7 @@ public final class LibUsb /** * Get the number of the port that a device is connected to. - * + * * @param device * A device * @return The port number (0 if not available). @@ -697,7 +775,7 @@ public final class LibUsb /** * Get the list of all port numbers from root for the specified device. - * + * * @param device * A device. * @param path @@ -707,13 +785,14 @@ 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. * @param device @@ -725,15 +804,19 @@ 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(@SuppressWarnings("unused") final Context context, + final Device device, final ByteBuffer path) { return getPortNumbers(device, path); } - /** +/** * Get the the parent from the specified device [EXPERIMENTAL]. - * + * + * Please note that the reference count of the returned device is not + * increased. As such, do not *ever* call {@link #unrefDevice(Device)) + * directly on the returned Device. + * * @param device * A device * @return The device parent or NULL if not available. You should issue a @@ -750,7 +833,7 @@ public final class LibUsb /** * Get the address of the device on the bus it is connected to. - * + * * @param device * A device. * @return The device address @@ -759,7 +842,7 @@ public final class LibUsb /** * Get the negotiated connection speed for a device. - * + * * @param device * A device. * @return A SPEED code, where {@link #SPEED_UNKNOWN} means that the OS @@ -770,13 +853,13 @@ public final class LibUsb /** * Convenience function to retrieve the wMaxPacketSize value for a * particular endpoint in the active device configuration. - * + * * This function was originally intended to be of assistance when setting up * isochronous transfers, but a design mistake resulted in this function * instead. It simply returns the wMaxPacketSize value without considering * its contents. If you're dealing with isochronous transfers, you probably * want {@link #getMaxIsoPacketSize(Device, int)} instead. - * + * * @param device * A device. * @param endpoint @@ -785,28 +868,26 @@ 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 * sending or receiving in the duration of 1 microframe. - * + * * Only the active configuration is examined. The calculation is based on * the wMaxPacketSize field in the endpoint descriptor as described in * section 9.6.6 in the USB 2.0 specifications. - * + * * If acting on an isochronous or interrupt endpoint, this function will * multiply the value found in bits 0:10 by the number of transactions per * microframe (determined by bits 11:12). Otherwise, this function just * returns the numeric value found in bits 0:10. - * + * * This function is useful for setting up isochronous transfers, for example * you might pass the return value from this function to - * 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. * @param endpoint @@ -816,11 +897,11 @@ 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. - * + * * @param device * The device to reference. * @return The same device. @@ -829,10 +910,10 @@ public final class LibUsb /** * Decrement the reference count of a device. - * + * * If the decrement operation causes the reference count to reach zero, the * device shall be destroyed. - * + * * @param device * the device to unreference. */ @@ -840,15 +921,15 @@ public final class LibUsb /** * Open a device and obtain a device handle. - * + * * A handle allows you to perform I/O on the device in question. - * + * * Internally, this function adds a reference to the device and makes it * available to you through {@link #getDevice(DeviceHandle)}. This reference * is removed during {@link #close(DeviceHandle)}. - * + * * This is a non-blocking function; no requests are sent over the bus. - * + * * @param device * The device to open. * @param handle @@ -859,22 +940,21 @@ public final class LibUsb * {@link #ERROR_NO_DEVICE} if the device has been disconnected * another error on other failure */ - public static native int open(final Device device, - final DeviceHandle handle); + public static native int open(final Device device, final DeviceHandle handle); /** * Convenience function for finding a device with a particular * idVendor/idProduct combination. - * + * * This function is intended for those scenarios where you are using libusb * to knock up a quick test application - it allows you to avoid calling * {@link #getDeviceList(Context, DeviceList)} and worrying about * traversing/freeing the list. - * + * * This function has limitations and is hence not intended for use in real * applications: if multiple devices have the same IDs it will only give you * the first one, etc. - * + * * @param context * The context to operate on, or NULL for the default context. * @param vendorId @@ -885,29 +965,30 @@ 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. - * + * * Should be called on all open handles before your application exits. - * + * * Internally, this function destroys the reference that was added by * {@link #open(Device, DeviceHandle)} on the given device. - * + * * This is a non-blocking function; no requests are sent over the bus. - * + * * @param handle * The handle to close. */ public static native void close(final DeviceHandle handle); - /** +/** * 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. * @return The underlying device. @@ -916,17 +997,17 @@ public final class LibUsb /** * Determine the bConfigurationValue of the currently active configuration. - * + * * You could formulate your own control request to obtain this information, * but this function has the advantage that it may be able to retrieve the * information from operating system caches (no I/O involved). - * + * * If the OS does not cache this information, then this function will block * while a control transfer is submitted to retrieve the information. - * + * * This function will return a value of 0 in the config output parameter if * the device is in unconfigured state. - * + * * @param handle * a device handle. * @param config @@ -940,34 +1021,34 @@ public final class LibUsb /** * Set the active configuration for a device. - * + * * The operating system may or may not have already set an active * configuration on the device. It is up to your application to ensure the * correct configuration is selected before you attempt to claim interfaces * and perform other operations. - * + * * If you call this function on a device already configured with the * selected configuration, then this function will act as a lightweight * device reset: it will issue a SET_CONFIGURATION request using the current * configuration, causing most USB-related device state to be reset * (altsetting reset to zero, endpoint halts cleared, toggles reset). - * + * * You cannot change/reset configuration if your application has claimed * interfaces - you should free them with * {@link #releaseInterface(DeviceHandle, int)} first. You cannot * change/reset configuration if other applications or drivers have claimed * interfaces. - * + * * A configuration value of -1 will put the device in unconfigured state. * The USB specifications state that a configuration value of 0 does this, * however buggy devices exist which actually have a configuration 0. - * + * * You should always use this function rather than formulating your own * SET_CONFIGURATION control request. This is because the underlying * operating system needs to know when such changes happen. - * + * * This is a blocking function. - * + * * @param handle * a device handle. * @param config @@ -984,20 +1065,20 @@ public final class LibUsb /** * Claim an interface on a given device handle. - * + * * You must claim the interface you wish to use before you can perform I/O * on any of its endpoints. - * + * * It is legal to attempt to claim an already-claimed interface, in which * case libusb just returns 0 without doing anything. - * + * * Claiming of interfaces is a purely logical operation; it does not cause * any requests to be sent over the bus. Interface claiming is used to * instruct the underlying operating system that your application wishes to * take ownership of the interface. - * + * * This is a non-blocking function. - * + * * @param handle * A device handle. * @param iface @@ -1013,12 +1094,12 @@ public final class LibUsb /** * Release an interface previously claimed with * {@link #claimInterface(DeviceHandle, int)}. - * + * * You should release all claimed interfaces before closing a device handle. - * + * * This is a blocking function. A SET_INTERFACE control request will be sent * to the device, resetting interface state to the first alternate setting. - * + * * @param handle * a device handle. * @param iface @@ -1032,16 +1113,16 @@ public final class LibUsb /** * Activate an alternate setting for an interface. - * + * * The interface must have been previously claimed with * {@link #claimInterface(DeviceHandle, int)}. - * + * * You should always use this function rather than formulating your own * SET_INTERFACE control request. This is because the underlying operating * system needs to know when such changes happen. - * + * * This is a blocking function. - * + * * @param handle * A device handle. * @param interfaceNumber @@ -1058,15 +1139,15 @@ public final class LibUsb /** * Clear the halt/stall condition for an endpoint. - * + * * Endpoints with halt status are unable to receive or transmit data until * the halt condition is stalled. - * + * * You should cancel all pending transfers before attempting to clear the * halt condition. - * + * * This is a blocking function. - * + * * @param handle * A device handle. * @param endpoint @@ -1076,22 +1157,22 @@ 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. - * + * * The system will attempt to restore the previous configuration and * alternate settings after the reset has completed. - * + * * If the reset fails, the descriptors change, or the previous state cannot * be restored, the device will appear to be disconnected and reconnected. * This means that the device handle is no longer valid (you should close * it) and rediscover the device. A return code of {@link #ERROR_NOT_FOUND} * indicates when this is the case. - * + * * This is a blocking function which usually incurs a noticeable delay. - * + * * @param handle * a handle of the device to reset * @return 0 on success, {@link #ERROR_NOT_FOUND} if re-enumeration is @@ -1102,12 +1183,12 @@ public final class LibUsb /** * Determine if a kernel driver is active on an interface. - * + * * If a kernel driver is active, you cannot claim the interface, and libusb * will be unable to perform I/O. - * + * * This functionality is not available on Windows. - * + * * @param handle * A device handle. * @param interfaceNumber @@ -1116,7 +1197,7 @@ public final class LibUsb * {@link #ERROR_NO_DEVICE} if the device has been disconnected, * {@link #ERROR_NOT_SUPPORTED} on platforms where the functionality * is not available, another ERROR code on other failure - * + * * @see #detachKernelDriver(DeviceHandle, int) */ public static native int kernelDriverActive(final DeviceHandle handle, @@ -1124,16 +1205,16 @@ public final class LibUsb /** * Detach a kernel driver from an interface. - * + * * If successful, you will then be able to claim the interface and perform * I/O. - * + * * This functionality is not available on Darwin or Windows. - * + * * Note that libusb itself also talks to the device through a special * kernel driver, if this driver is already attached to the device, this * call will not detach it and return {@link #ERROR_NOT_FOUND}. - * + * * @param handle * a device handle * @param interfaceNumber @@ -1144,7 +1225,7 @@ public final class LibUsb * disconnected, {@link #ERROR_NOT_SUPPORTED} on platforms where the * functionality is not available, another ERROR code on other * failure - * + * * @see #kernelDriverActive(DeviceHandle, int) */ public static native int detachKernelDriver(final DeviceHandle handle, @@ -1153,12 +1234,12 @@ public final class LibUsb /** * Re-attach an interface's kernel driver, which was previously detached * using {@link #detachKernelDriver(DeviceHandle, int)}. - * + * * This call is only effective on Linux and returns * {@link #ERROR_NOT_SUPPORTED} on all other platforms. - * + * * This functionality is not available on Darwin or Windows. - * + * * @param handle * A device handle * @param interfaceNumber @@ -1170,7 +1251,7 @@ public final class LibUsb * functionality is not available, {@link #ERROR_BUSY} if the driver * cannot be attached because the interface is claimed by a program * or driver, anotherERROR code on other failure - * + * * @see #kernelDriverActive(DeviceHandle, int) */ public static native int attachKernelDriver(final DeviceHandle handle, @@ -1178,18 +1259,18 @@ public final class LibUsb /** * Enable/disable libusb's automatic kernel driver detachment. - * + * * When this is enabled libusb will automatically detach the kernel driver * on an interface when claiming the interface, and attach it when releasing * the interface. - * + * * Automatic kernel driver detachment is disabled on newly opened device * handles by default. - * + * * On platforms which do not have {@link #CAP_SUPPORTS_DETACH_KERNEL_DRIVER} * this function will return {@link #ERROR_NOT_SUPPORTED}, and libusb will * continue as if this function was never called. - * + * * @param handle * A device handle. * @param enable @@ -1202,7 +1283,7 @@ public final class LibUsb /** * Check at runtime if the loaded library has a given capability. - * + * * @param capability * The capability to check for. * @return True if the running library has the capability, false otherwise. @@ -1212,7 +1293,7 @@ public final class LibUsb /** * Returns a string with the ASCII name of a libusb error or transfer status * code. - * + * * @param errorCode * The libusb error or libusb transfer status code to return the * name of. @@ -1224,7 +1305,7 @@ public final class LibUsb /** * Set the language, and only the language, not the encoding! used for * translatable libusb messages. - * + * * This takes a locale string in the default setlocale format: lang[-region] * or lang[_country_region][.codeset]. Only the lang part of the string is * used, and only 2 letter ISO 639-1 codes are accepted for it, such as @@ -1232,15 +1313,15 @@ public final class LibUsb * This means that functions which return translatable strings will NOT * honor the specified encoding. All strings returned are encoded as UTF-8 * strings. - * + * * If {@link #setLocale(String)} is not called, all messages will be in * English. - * + * * The following functions return translatable strings: libusb_strerror(). * Note that the libusb log messages controlled through * {@link #setDebug(Context, int)} are not translated, they are always in * English. - * + * * @param locale * locale-string in the form of lang[_country_region][.codeset] * or lang[-region], where lang is a 2 letter ISO 639-1 code. @@ -1255,9 +1336,9 @@ public final class LibUsb * Returns a string with a short description of the given error code, this * description is intended for displaying to the end user and will be in the * language set by {@link #setLocale(String)}. - * + * * The messages always start with a capital letter and end without any dot. - * + * * @param errcode * The error code whose description is desired. * @return A short description of the error code. @@ -1266,34 +1347,34 @@ public final class LibUsb /** * Convert a 16-bit value from little-endian to host-endian format. - * + * * On little endian systems, this function does nothing. On big endian * systems, the bytes are swapped. - * + * * @param x * 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. - * + * * On little endian systems, this function does nothing. On big endian * systems, the bytes are swapped. - * + * * @param x * 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. - * + * * This is a non-blocking function; the device descriptor is cached in * memory. - * + * * @param device * the device * @param descriptor @@ -1303,32 +1384,46 @@ 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. - * + * * @param handle * A device handle. * @param index * 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. - * + * * This method is not part of libusb. - * + * * @param handle * The device handle. * @param index @@ -1336,25 +1431,30 @@ 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; } /** * Get the USB configuration descriptor for the currently active * configuration. - * + * * This is a non-blocking function which does not involve any requests being * sent to the device. - * + * * @param device * A device. * @param descriptor @@ -1363,7 +1463,7 @@ public final class LibUsb * {@link #freeConfigDescriptor(ConfigDescriptor)} after use. * @return 0 on success, {@link #ERROR_NOT_FOUND} if the device is in * unconfigured state another ERROR code on error - * + * * @see #getConfigDescriptor(Device, int, ConfigDescriptor) */ public static native int getActiveConfigDescriptor(final Device device, @@ -1371,10 +1471,10 @@ public final class LibUsb /** * Get a USB configuration descriptor based on its index. - * + * * This is a non-blocking function which does not involve any requests being * sent to the device. - * + * * @param device * A device. * @param index @@ -1385,19 +1485,19 @@ public final class LibUsb * {@link #freeConfigDescriptor(ConfigDescriptor)} after use. * @return 0 on success {@link #ERROR_NOT_FOUND} if the configuration does * not exist another ERROR code on error. - * + * * @see #getActiveConfigDescriptor(Device, ConfigDescriptor) * @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. - * + * * This is a non-blocking function which does not involve any requests being * sent to the device. - * + * * @param device * A device. * @param value @@ -1409,21 +1509,21 @@ public final class LibUsb * {@link #freeConfigDescriptor(ConfigDescriptor)} after use. * @return 0 on success {@link #ERROR_NOT_FOUND} if the configuration does * not exist another ERROR code on error See also: - * + * * @see #getActiveConfigDescriptor(Device, ConfigDescriptor) * @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 * {@link #getConfigDescriptor(Device, int, ConfigDescriptor)} or * {@link #getActiveConfigDescriptor(Device, ConfigDescriptor)}. - * + * * It is safe to call this function with a NULL config parameter, in which * case the function simply returns. - * + * * @param descriptor * The configuration descriptor to free */ @@ -1432,7 +1532,7 @@ public final class LibUsb /** * Get an endpoints superspeed endpoint companion descriptor (if any). - * + * * @param context * The context to operate on, or NULL for the default context. * @param endpointDescriptor @@ -1441,8 +1541,7 @@ public final class LibUsb * @param companionDescriptor * Output location for the superspeed endpoint companion * descriptor. Only valid if 0 was returned. Must be freed with - * {@link #freeSsEndpointCompanionDescriptor( - * SsEndpointCompanionDescriptor)} + * {@link #freeSsEndpointCompanionDescriptor(SsEndpointCompanionDescriptor)} * after use. * @return {@link #SUCCESS} on success, {@link #ERROR_NOT_FOUND} if the * descriptor does not exist, another error code on error @@ -1453,12 +1552,12 @@ public final class LibUsb /** * Free a superspeed endpoint companion descriptor obtained from - * {@link #getSsEndpointCompanionDescriptor(Context, EndpointDescriptor, - * SsEndpointCompanionDescriptor)}. - * + * {@link #getSsEndpointCompanionDescriptor(Context, EndpointDescriptor, SsEndpointCompanionDescriptor)} + * . + * * It is safe to call this function with a NULL parameter, in which case the * function simply returns. - * + * * @param companionDescriptor * The superspeed endpoint companion descriptor to free */ @@ -1468,7 +1567,7 @@ public final class LibUsb /** * Get a Binary Object Store (BOS) descriptor. This is a BLOCKING function, * which will send requests to the device. - * + * * @param handle * The handle of an open libusb device. * @param descriptor @@ -1484,19 +1583,18 @@ public final class LibUsb /** * Free a BOS descriptor obtained from * {@link #getBosDescriptor(DeviceHandle, BosDescriptor)}. - * + * * It is safe to call this function with a NULL parameter, in which case the * function simply returns. - * + * * @param descriptor * The BOS descriptor to free. */ - public static native void freeBosDescriptor(final BosDescriptor - descriptor); + public static native void freeBosDescriptor(final BosDescriptor descriptor); /** * Get an USB 2.0 Extension descriptor. - * + * * @param context * The context to operate on, or NULL for the default context. * @param devCapDescriptor @@ -1505,23 +1603,22 @@ public final class LibUsb * @param extensionDescriptor * Output location for the USB 2.0 Extension descriptor. Only * valid if 0 was returned. Must be freed with - * {@link #freeUsb20ExtensionDescriptor( - * Usb20ExtensionDescriptor)} after use. + * {@link #freeUsb20ExtensionDescriptor(Usb20ExtensionDescriptor)} + * after use. * @return 0 on success a LIBUSB_ERROR code on error */ - public static native int getUsb20ExtensionDescriptor( - final Context context, + public static native int getUsb20ExtensionDescriptor(final Context context, final BosDevCapabilityDescriptor devCapDescriptor, final Usb20ExtensionDescriptor extensionDescriptor); /** * Free a USB 2.0 Extension descriptor obtained from - * {@link #getUsb20ExtensionDescriptor(Context, BosDevCapabilityDescriptor, - * Usb20ExtensionDescriptor)}. - * - * It is safe to call this function with a NULL parameter, in which case + * {@link #getUsb20ExtensionDescriptor(Context, BosDevCapabilityDescriptor, Usb20ExtensionDescriptor)} + * . + * + * It is safe to call this function with a NULL parameter, in which case * the function simply returns. - * + * * @param extensionDescriptor * The USB 2.0 Extension descriptor to free. */ @@ -1530,7 +1627,7 @@ public final class LibUsb /** * Get a SuperSpeed USB Device Capability descriptor. - * + * * @param context * The context to operate on, or NULL for the default context. * @param devCapDescriptor @@ -1538,10 +1635,10 @@ public final class LibUsb * {@link #BT_SS_USB_DEVICE_CAPABILITY}. * @param ssUsbDeviceCapabilityDescriptor * Output location for the SuperSpeed USB Device Capability - * descriptor. Only valid if {@link #SUCCESS} was returned. + * descriptor. Only valid if {@link #SUCCESS} was returned. * Must be freed with - * {@link #freeSsUsbDeviceCapabilityDescriptor( - * SsUsbDeviceCapabilityDescriptor)} after use. + * {@link #freeSsUsbDeviceCapabilityDescriptor(SsUsbDeviceCapabilityDescriptor)} + * after use. * @return {@link #SUCCESS} on success, an error code on error. */ public static native int getSsUsbDeviceCapabilityDescriptor( @@ -1551,21 +1648,21 @@ public final class LibUsb /** * Free a SuperSpeed USB Device Capability descriptor obtained from - * {@link #getSsUsbDeviceCapabilityDescriptor(Context, - * BosDevCapabilityDescriptor, SsUsbDeviceCapabilityDescriptor)}. - * + * {@link #getSsUsbDeviceCapabilityDescriptor(Context, BosDevCapabilityDescriptor, SsUsbDeviceCapabilityDescriptor)} + * . + * * It is safe to call this function with a NULL parameter, * in which case the function simply returns. - * + * * @param ssUsbDeviceCapabilityDescriptor * The descriptor to free. */ public static native void freeSsUsbDeviceCapabilityDescriptor( final SsUsbDeviceCapabilityDescriptor ssUsbDeviceCapabilityDescriptor); - + /** * Get a Container ID descriptor. - * + * * @param context * The context to operate on, or NULL for the default context. * @param devCapDescriptor @@ -1578,31 +1675,30 @@ public final class LibUsb * after use. * @return {@link #SUCCESS} on success or an error code on error */ - public static native int getContainerIdDescriptor( - final Context context, + public static native int getContainerIdDescriptor(final Context context, final BosDevCapabilityDescriptor devCapDescriptor, final ContainerIdDescriptor containerIdDescriptor); /** * Free a Container ID descriptor obtained from - * {@link #getContainerIdDescriptor(Context, BosDevCapabilityDescriptor, - * ContainerIdDescriptor)}. - * - * It is safe to call this function with a NULL parameter, in which case + * {@link #getContainerIdDescriptor(Context, BosDevCapabilityDescriptor, ContainerIdDescriptor)} + * . + * + * It is safe to call this function with a NULL parameter, in which case * the function simply returns. - * + * * @param containerIdDescriptor * The descriptor to free. */ public static native void freeContainerIdDescriptor( final ContainerIdDescriptor containerIdDescriptor); - + /** * Retrieve a descriptor from the default control pipe. - * + * * This is a convenience function which formulates the appropriate control * message to retrieve the descriptor. - * + * * @param handle * A device handle. * @param type @@ -1612,18 +1708,22 @@ public final class LibUsb * @param data * Output buffer for descriptor * @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. - * + * * This is a convenience function which formulates the appropriate control * message to retrieve the descriptor. The string returned is Unicode, as * detailed in the USB specifications. - * + * * @param handle * A device handle. * @param index @@ -1633,20 +1733,24 @@ 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. - * + * * The direction of the transfer is inferred from the bmRequestType field of * the setup packet. - * + * * The wValue, wIndex and wLength fields values should be given in * host-endian byte order. - * + * * @param handle * A handle for the device to communicate with. * @param bmRequestType @@ -1671,30 +1775,30 @@ 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. - * + * * The direction of the transfer is inferred from the direction bits of the * endpoint address. - * + * * For bulk reads, the length field indicates the maximum length of data you * are expecting to receive. If less data arrives than expected, this * function will return that data, so be sure to check the transferred * output parameter. - * + * * You should also check the transferred parameter for bulk writes. Not all * of the data may have been written. - * + * * Also check transferred when dealing with a timeout error code. libusb * may have to split your transfer into a number of chunks to satisfy * underlying O/S requirements, meaning that the timeout may expire after * the first few chunks have completed. libusb is careful not to lose any * data that may have been transferred; do not assume that timeout * conditions indicate a complete lack of I/O. - * + * * @param handle * A handle for the device to communicate with. * @param endpoint @@ -1716,32 +1820,32 @@ 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. - * + * * The direction of the transfer is inferred from the direction bits of the * endpoint address. - * + * * For interrupt reads, the length field indicates the maximum length of * data you are expecting to receive. If less data arrives than expected, * this function will return that data, so be sure to check the transferred * output parameter. - * + * * You should also check the transferred parameter for interrupt writes. Not * all of the data may have been written. - * + * * Also check transferred when dealing with a timeout error code. libusb * may have to split your transfer into a number of chunks to satisfy * underlying O/S requirements, meaning that the timeout may expire after * the first few chunks have completed. libusb is careful not to lose any * data that may have been transferred; do not assume that timeout * conditions indicate a complete lack of I/O. - * + * * The default endpoint bInterval value is used as the polling interval. - * + * * @param handle * A handle for the device to communicate with. * @param endpoint @@ -1762,25 +1866,25 @@ 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. - * + * * This lock is used to ensure that only one thread is monitoring libusb * event sources at any one time. - * + * * You only need to use this lock if you are developing an application which * calls poll() or select() on libusb's file descriptors directly. If you * stick to libusb's event handling loop functions (e.g. * {@link #handleEvents(Context)}) then you do not need to be concerned with * this locking. - * + * * While holding this lock, you are trusted to actually be handling events. * If you are no longer handling events, you must call * {@link #unlockEvents(Context)} as soon as possible. - * + * * @param context * The context to operate on, or NULL for the default context. * @return 0 if the lock was obtained successfully, 1 if the lock was not @@ -1791,20 +1895,20 @@ public final class LibUsb /** * Acquire the event handling lock, blocking until successful acquisition if * it is contended. - * + * * This lock is used to ensure that only one thread is monitoring libusb * event sources at any one time. - * + * * You only need to use this lock if you are developing an application which * calls poll() or select() on libusb's file descriptors directly. If you * stick to libusb's event handling loop functions (e.g. * {@link #handleEvents(Context)}) then you do not need to be concerned with * this locking. - * + * * While holding this lock, you are trusted to actually be handling events. * If you are no longer handling events, you must call * {@link #unlockEvents(Context)} as soon as possible. - * + * * @param context * The context to operate on, or NULL for the default context. */ @@ -1813,10 +1917,10 @@ public final class LibUsb /** * Release the lock previously acquired with {@link #tryLockEvents(Context)} * or {@link #lockEvents(Context)}. - * + * * Releasing this lock will wake up any threads blocked on * {@link #waitForEvent(Context, long)}. - * + * * @param context * The context to operate on, or NULL for the default context */ @@ -1824,21 +1928,21 @@ public final class LibUsb /** * Determine if it is still OK for this thread to be doing event handling. - * + * * Sometimes, libusb needs to temporarily pause all event handlers, and * this is the function you should use before polling file descriptors to * see if this is the case. - * + * * If this function instructs your thread to give up the events lock, you * should just continue the usual logic that is documented in Multi-threaded * applications and asynchronous I/O. On the next iteration, your thread * will fail to obtain the events lock, and will hence become an event * waiter. - * + * * This function should be called while the events lock is held: you don't * need to worry about the results of this function if your thread is not * the current event handler. - * + * * @param context * The context to operate on, or NULL for the default context. * @return 1 if event handling can start or continue, 0 if this thread must @@ -1849,7 +1953,7 @@ public final class LibUsb /** * Determine if an active thread is handling events (i.e. if anyone is * holding the event handling lock). - * + * * @param context * The context to operate on, or NULL for the default context. * @return 1 if a thread is handling events, 0 if there are no threads @@ -1859,21 +1963,21 @@ public final class LibUsb /** * Acquire the event waiters lock. - * + * * This lock is designed to be obtained under the situation where you want * to be aware when events are completed, but some other thread is event * handling so calling {@link #handleEvents(Context)} is not allowed. - * + * * You then obtain this lock, re-check that another thread is still handling * events, then call {@link #waitForEvent(Context, long)}. - * + * * You only need to use this lock if you are developing an application which * calls poll() or select() on libusb's file descriptors directly, and may * potentially be handling events from 2 threads simultaenously. If you * stick to libusb's event handling loop functions (e.g. * {@link #handleEvents(Context)}) then you do not need to be concerned with * this locking. - * + * * @param context * The context to operate on, or NULL for the default context. */ @@ -1881,7 +1985,7 @@ public final class LibUsb /** * Release the event waiters lock. - * + * * @param context * The context to operate on, or NULL for the default context. */ @@ -1889,12 +1993,12 @@ public final class LibUsb /** * Wait for another thread to signal completion of an event. - * + * * Must be called with the event waiters lock held, see * {@link #lockEventWaiters(Context)}. - * + * * This function will block until any of the following conditions are met: - * + * * The timeout expires A transfer completes A thread releases the event * handling lock through {@link #unlockEvents(Context)} Condition 1 is * obvious. Condition 2 unblocks your thread after the callback for the @@ -1902,16 +2006,16 @@ public final class LibUsb * the thread that was previously handling events is no longer doing so, so * if any events are to complete, another thread needs to step up and start * event handling. - * + * * This function releases the event waiters lock before putting your thread * to sleep, and reacquires the lock as it is being woken up. - * + * * @param context * The context to operate on, or NULL for the default context. * @param timeout * Maximum timeout for this blocking function. A 0 value * indicates unlimited timeout. - * + * * @return 0 after a transfer completes or another thread stops event * handling, 1 if the timeout expired */ @@ -1920,23 +2024,28 @@ public final class LibUsb /** * Handle any pending events. - * + * * libusb determines "pending events" by checking if any timeouts have * expired and by checking the set of file descriptors for activity. - * + * * If a zero timeval is passed, this function will handle any * already-pending events and then immediately return in non-blocking style. - * + * * If a non-zero timeval is passed and no events are currently pending, this * function will block waiting for events to handle up until the specified * timeout. If an event arrives or a signal is raised, this function will * return early. - * + * * If the parameter completed is not NULL then after obtaining the event * handling lock this function will return immediately if the integer * pointed to is not 0. This allows for race free waiting for the completion * of a specific transfer. - * + * + * The only way to implement this in Java is by passing a direct buffer, and + * then accessing memory directly. IntBuffers can be direct, if they are + * created as a view of a direct ByteBuffer, by using BufferUtils: + * {@link BufferUtils#allocateIntBuffer()} + * * @param context * the context to operate on, or NULL for the default context * @param timeout @@ -1951,17 +2060,17 @@ public final class LibUsb /** * Handle any pending events. - * + * * Like {@link #handleEventsTimeoutCompleted(Context, long, IntBuffer)}, but * without the completed parameter, calling this function is equivalent to * calling {@link #handleEventsTimeoutCompleted(Context, long, IntBuffer)} * with a NULL completed parameter. - * + * * This function is kept primarily for backwards compatibility. All new code * should call {@link #handleEventsCompleted(Context, IntBuffer)} or * {@link #handleEventsTimeoutCompleted(Context, long, IntBuffer)} to avoid * race conditions. - * + * * @param context * The context to operate on, or NULL for the default context * @param timeout @@ -1974,17 +2083,17 @@ public final class LibUsb /** * Handle any pending events in blocking mode. - * + * * There is currently a timeout hardcoded at 60 seconds but we plan to make * it unlimited in future. For finer control over whether this function is * blocking or non-blocking, or for control over the timeout, use * {@link #handleEventsTimeoutCompleted(Context, long, IntBuffer)} instead. - * + * * This function is kept primarily for backwards compatibility. All new code * should call {@link #handleEventsCompleted(Context, IntBuffer)} or * {@link #handleEventsTimeoutCompleted(Context, long, IntBuffer)} to avoid * race conditions. - * + * * @param context * The context to operate on, or NULL for the default context. * @return 0 on success, or a ERROR code on failure. @@ -1993,14 +2102,14 @@ public final class LibUsb /** * Handle any pending events in blocking mode. - * + * * Like {@link #handleEvents(Context)}, with the addition of a completed * parameter to allow for race free waiting for the completion of a specific * transfer. - * + * * See {@link #handleEventsTimeoutCompleted(Context, long, IntBuffer)} for * details on the completed parameter. - * + * * @param context * The context to operate on, or NULL for the default context. * @param completed @@ -2013,17 +2122,17 @@ public final class LibUsb /** * Handle any pending events by polling file descriptors, without checking * if any other threads are already doing so. - * + * * Must be called with the event lock held, see {@link #lockEvents(Context)} * . - * + * * This function is designed to be called under the situation where you have * taken the event lock and are calling poll()/select() directly on * libusb's file descriptors (as opposed to using * {@link #handleEvents(Context)} or similar). You detect events on * libusb's descriptors, so you then call this function with a zero timeout * value (while still holding the event lock). - * + * * @param context * The context to operate on, or NULL for the default context. * @param timeout @@ -2037,24 +2146,24 @@ public final class LibUsb /** * Determines whether your application must apply special timing * considerations when monitoring libusb's file descriptors. - * + * * This function is only useful for applications which retrieve and poll * libusb's file descriptors in their own main loop (The more advanced * option). - * + * * Ordinarily, libusb's event handler needs to be called into at specific * moments in time (in addition to times when there is activity on the file * descriptor set). The usual approach is to use * {@link #getNextTimeout(Context, IntBuffer)} to learn about when the next * timeout occurs, and to adjust your poll()/select() timeout accordingly so * that you can make a call into the library at that time. - * + * * Some platforms supported by libusb do not come with this baggage - any * events relevant to timing will be represented by activity on the file * descriptor set, and {@link #getNextTimeout(Context, IntBuffer)} will * always return 0. This function allows you to detect whether you are * running on such a platform. - * + * * @param context * The context to operate on, or NULL for the default context * @return 0 if you must call into libusb at times determined by @@ -2066,30 +2175,30 @@ public final class LibUsb /** * Determine the next internal timeout that libusb needs to handle. - * + * * You only need to use this function if you are calling poll() or select() * or similar on libusb's file descriptors yourself - you do not need to * use it if you are calling {@link #handleEvents(Context)} or a variant * directly. - * + * * You should call this function in your main loop in order to determine how * long to wait for select() or poll() to return results. libusb needs to * be called into at this timeout, so you should use it as an upper bound on * your select() or poll() call. - * + * * When the timeout has expired, call into * {@link #handleEventsTimeout(Context, long)} (perhaps in non-blocking * mode) so that libusb can handle the timeout. - * + * * This function may return 1 (success) and an all-zero timeval. If this is * the case, it indicates that libusb has a timeout that has already * expired so you should call {@link #handleEventsTimeout(Context, long)} or * similar immediately. A return code of 0 indicates that there are no * pending timeouts. - * + * * On some platforms, this function will always returns 0 (no pending * timeouts). See Notes on time-based events. - * + * * @param context * The context to operate on, or NULL for the default context * @param timeout @@ -2100,25 +2209,25 @@ 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. - * + * * These functions will be invoked for every new or removed file descriptor * that libusb uses as an event source. - * + * * To remove notifiers, pass NULL values for the function pointers. - * + * * Note that file descriptors may have been added even before you register * these notifiers (e.g. at {@link #init(Context)} time). - * + * * Additionally, note that the removal notifier may be called during * {@link #exit(Context)} (e.g. when it is closing file descriptors that * were opened and added to the poll set at {@link #init(Context)} time). If * you don't want this, remove the notifiers immediately before calling * {@link #exit(Context)}. - * + * * @param context * The context to operate on, or NULL for the default context. * @param listener @@ -2127,83 +2236,134 @@ public final class LibUsb * User data to be passed back to callbacks (useful for passing * context information). */ - public static void setPollfdNotifiers(final Context context, + public static synchronized 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) + { + unsetPollfdNotifiersNative(context); + + pollfdListeners.remove(contextId); + } + else + { + setPollfdNotifiersNative(context, contextId); + + pollfdListeners.put(contextId, + new ImmutablePair(listener, userData)); + } } /** * Callback function, invoked when a new file descriptor should be added to * the set of file descriptors monitored for events. - * + * * @param fd * 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); + } } /** * Called internally from JNI when a pollfd was removed. - * + * * @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); + } } /** * Configures libusb to inform this class about pollfd additions and * removals. - * + * * @param context * The context to operate on, or NULL for the default context + * @param contextId + * A unique identifier for the given context. */ - static native void setPollfdNotifiers(final Context context); + static native void setPollfdNotifiersNative(final Context context, + final long contextId); /** * Tells libusb to stop informing this class about pollfd additions and * removals. - * + * * @param context * The context to operate on, or NULL for the default context */ - static native void unsetPollfdNotifiers(final Context context); + static native void unsetPollfdNotifiersNative(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. - * + * * The returned transfer is pre-initialized for you. When the new transfer * is no longer needed, it should be freed with * {@link #freeTransfer(Transfer)}. - * + * * Transfers intended for non-isochronous endpoints (e.g. control, bulk, * interrupt) should specify an iso_packets count of zero. - * + * * For transfers intended for isochronous endpoints, specify an appropriate * number of packet descriptors to be allocated as part of the transfer. The * returned transfer is not specially initialized for isochronous I/O; you * are still required to call the {@link Transfer#setNumIsoPackets(int)} a * {@link Transfer#setType(int)} methods accordingly. - * + * * It is safe to allocate a transfer with some isochronous packets and then * use it on a non-isochronous endpoint. If you do this, ensure that at time * of submission, numIsoPackets is 0 and that type is set appropriately. - * + * * @param isoPackets * Number of isochronous packet descriptors to allocate. * @return A newly allocated transfer, or NULL on error @@ -2212,22 +2372,312 @@ public final class LibUsb /** * Free a transfer structure. - * + * * 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. - * + * * It is not legal to free an active transfer (one which has been submitted * and has not yet completed). - * + * * @param transfer * The transfer to free */ 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()); + } + + static int hotplugCallback(final Context context, final Device device, + final int event, final long hotplugId) + { + final ImmutablePair callback = hotplugCallbacks + .get(hotplugId); + + int result = 0; + + if (callback != null) + { + result = callback.left.processEvent(context, device, event, + callback.right); + } + + // If callback indicates it is finished, it will get deregistered + // automatically. As such, we have to remove it from the Java + // map, like when deregistering manually. + if (result == 1) + { + hotplugCallbacks.remove(hotplugId); + } + + return result; + } + + /** + * Register a hotplug callback function. + * + * Register a callback with the {@link Context}. The callback will fire + * when a matching event occurs on a matching device. The callback is + * armed until either it is deregistered with + * {@link #hotplugDeregisterCallback(Context, HotplugCallbackHandle)} or the + * supplied callback returns 1 to indicate it is finished processing + * events. + * + * @param context + * context to register this callback with + * @param events + * bitwise or of events that will trigger this callback + * @param flags + * hotplug callback flags + * @param vendorId + * the vendor id to match or {@link #HOTPLUG_MATCH_ANY} + * @param productId + * the product id to match or {@link #HOTPLUG_MATCH_ANY} + * @param deviceClass + * the device class to match or {@link #HOTPLUG_MATCH_ANY} + * @param callback + * the function to be invoked on a matching event/device + * @param userData + * user data to pass to the callback function + * @param handle + * hotplug callback handle of the allocated callback. Only needed + * if you later want to deregister this callback, can be NULL. + * + * @return LIBUSB_SUCCESS on success LIBUSB_ERROR code on failure + */ + public static synchronized int hotplugRegisterCallback( + final Context context, final int events, final int flags, + final int vendorId, final int productId, final int deviceClass, + final HotplugCallback callback, final Object userData, + final HotplugCallbackHandle callbackHandle) + { + if (callback == null) + { + throw new IllegalArgumentException("callback must not be null"); + } + + // Mask the values for conversion to int in libusb API. + final int result = hotplugRegisterCallbackNative( + context, events, flags, + (vendorId == LibUsb.HOTPLUG_MATCH_ANY) ? (LibUsb.HOTPLUG_MATCH_ANY) + : (vendorId & 0xFFFF), + (productId == LibUsb.HOTPLUG_MATCH_ANY) ? (LibUsb.HOTPLUG_MATCH_ANY) + : (productId & 0xFFFF), + (deviceClass == LibUsb.HOTPLUG_MATCH_ANY) ? (LibUsb.HOTPLUG_MATCH_ANY) + : (deviceClass & 0xFF), + callbackHandle, globalHotplugId); + + if (result == LibUsb.SUCCESS) + { + hotplugCallbacks.put(globalHotplugId, + new ImmutablePair(callback, userData)); + + // Increment globalHotplugId by one, like the libusb handle. + globalHotplugId++; + } + + return result; + } + + static native int hotplugRegisterCallbackNative(final Context context, + final int events, final int flags, final int vendorId, + final int productId, final int deviceClass, + final HotplugCallbackHandle callbackHandle, final long hotplugId); + + /** + * Deregisters a hotplug callback. + * + * Deregister a callback from a {@link Context}. This function is safe to + * call from within a hotplug callback. + * + * @param context + * context this callback is registered with + * @param handle + * the handle of the callback to deregister + */ + public static void hotplugDeregisterCallback(final Context context, + final HotplugCallbackHandle callbackHandle) + { + final long handle = hotplugDeregisterCallbackNative(context, + callbackHandle); + + // When a handle is assigned by a register call, its value is the same + // as the one of globalHotplugId at that moment, which is what's used + // to identify data in the hotplugCallbacks map. + // This is because globalHotplugId pretty much mirrors the behavior of + // the handle: integer starting at 1, incremented each time by one. + // Problems could arise from concurrency, but are completely avoided by + // fully serializing register calls. + // As such, we can use the handle value from callbackHandle to + // correctly remove the data from the hotplugCallbacks map. + hotplugCallbacks.remove(handle); + } + + static native long hotplugDeregisterCallbackNative(final Context context, + final HotplugCallbackHandle callbackHandle); } diff --git a/src/main/java/de/ailis/usb4java/libusb/LibUsbException.java b/src/main/java/de/ailis/usb4java/libusb/LibUsbException.java index 528a369..eda5622 100644 --- a/src/main/java/de/ailis/usb4java/libusb/LibUsbException.java +++ b/src/main/java/de/ailis/usb4java/libusb/LibUsbException.java @@ -1,9 +1,9 @@ /* * Copyright 2013 Klaus Reimer * See LICENSE.md for licensing information. - * - * Based on libusb : - * + * + * Based on libusb : + * * Copyright 2001 Johannes Erdfelt * Copyright 2007-2009 Daniel Drake * Copyright 2010-2012 Peter Stuge diff --git a/src/main/java/de/ailis/usb4java/libusb/Loader.java b/src/main/java/de/ailis/usb4java/libusb/Loader.java index 3feda80..0cf08e9 100644 --- a/src/main/java/de/ailis/usb4java/libusb/Loader.java +++ b/src/main/java/de/ailis/usb4java/libusb/Loader.java @@ -14,7 +14,7 @@ import java.net.URL; /** * Utility class to load native libraries from classpath. - * + * * @author Klaus Reimer (k@ailis.de) */ public final class Loader @@ -80,15 +80,21 @@ public final class Loader * "osx" or (for any other non-supported platform) the value of the * "os.name" property converted to lower case and with removed space * characters. - * + * * @return The operating system name. */ private static String getOS() { final String os = System.getProperty("os.name").toLowerCase() .replace(" ", ""); - if (os.contains(OS_WINDOWS)) return OS_WINDOWS; - if (os.equals(OS_MACOSX)) return OS_OSX; + if (os.contains(OS_WINDOWS)) + { + return OS_WINDOWS; + } + if (os.equals(OS_MACOSX)) + { + return OS_OSX; + } return os; } @@ -97,20 +103,27 @@ public final class Loader * names i386 und amd64 are converted accordingly) or (when platform is * unsupported) the value of os.arch converted to lower-case and with * removed space characters. - * + * * @return The CPU architecture */ private static String getArch() { - final String arch = System.getProperty("os.arch"); - if (arch.equals(ARCH_I386)) return ARCH_X86; - if (arch.equals(ARCH_AMD64)) return ARCH_X86_64; - return arch.toLowerCase().replace(" ", ""); + final String arch = System.getProperty("os.arch").toLowerCase() + .replace(" ", ""); + if (arch.equals(ARCH_I386)) + { + return ARCH_X86; + } + if (arch.equals(ARCH_AMD64)) + { + return ARCH_X86_64; + } + return arch; } /** * Returns the shared library extension name. - * + * * @return The shared library extension name. */ private static String getExt() @@ -118,51 +131,67 @@ public final class Loader final String os = getOS(); final String key = "usb4java.libext." + getOS(); final String ext = System.getProperty(key); - if (ext != null) return ext; + if (ext != null) + { + return ext; + } if (os.equals(OS_LINUX) || os.equals(OS_FREEBSD) || os.equals(OS_SUNOS)) + { return EXT_SO; + } if (os.equals(OS_WINDOWS)) + { return EXT_DLL; + } if (os.equals(OS_OSX)) + { return EXT_DYLIB; - throw new LoaderException("Unable to determine the shared library " + - "file extension for operating system '" + os + - "'. Please specify Java parameter -D" + key + "="); + } + throw new LoaderException("Unable to determine the shared library " + + "file extension for operating system '" + os + + "'. Please specify Java parameter -D" + key + "="); } /** * Creates the temporary directory used for unpacking the native libraries. * This directory is marked for deletion on exit. - * + * * @return The temporary directory for native libraries. */ private static File createTempDirectory() { // Return cached tmp directory when already created - if (tmp != null) return tmp; + if (tmp != null) + { + return tmp; + } try { tmp = File.createTempFile("usb4java", null); if (!tmp.delete()) + { throw new IOException("Unable to delete temporary file " + tmp); + } if (!tmp.mkdirs()) + { throw new IOException("Unable to create temporary directory " + tmp); + } tmp.deleteOnExit(); return tmp; } catch (final IOException e) { - throw new LoaderException("Unable to create temporary directory " + - "for usb4java natives: " + e, e); + throw new LoaderException("Unable to create temporary directory " + + "for usb4java natives: " + e, e); } } /** * Returns the platform name. This could be for example "linux-x86" or * "windows-x86_64". - * + * * @return The architecture name. Never null. */ private static String getPlatform() @@ -173,7 +202,7 @@ public final class Loader /** * Returns the name of the usb4java native library. This could be * "libusb4java.dll" for example. - * + * * @return The usb4java native library name. Never null. */ private static String getLibName() @@ -185,19 +214,22 @@ public final class Loader * Returns the name of the libusb native library. This could be * "libusb0.dll" for example or null if this library is not needed on the * current platform (Because it is provided by the operating system). - * + * * @return The libusb native library name or null if not needed. */ private static String getExtraLibName() { final String os = getOS(); - if (os.equals(OS_WINDOWS)) return "libusb-1.0." + EXT_DLL; + if (os.equals(OS_WINDOWS)) + { + return "libusb-1.0." + EXT_DLL; + } return null; } /** * Copies the specified input stream to the specified output file. - * + * * @param input * The input stream. * @param output @@ -226,25 +258,27 @@ public final class Loader /** * Extracts a single library. - * + * * @param platform * The platform name (For example "linux-x86") * @param lib * The library name to extract (For example "libusb0.dll") * @return The absolute path to the extracted library. */ - private static String extractLibrary(final String platform, - final String lib) + private static String extractLibrary(final String platform, final String lib) { // Extract the usb4java library - final String source = '/' + - Loader.class.getPackage().getName().replace('.', '/') + - '/' + platform + "/" + lib; + final String source = '/' + + Loader.class.getPackage().getName().replace('.', '/') + '/' + + platform + "/" + lib; // Check if native library is present final URL url = Loader.class.getResource(source); - if (url == null) throw new LoaderException( - "Native library not found in classpath: " + source); + if (url == null) + { + throw new LoaderException("Native library not found in classpath: " + + source); + } // If native library was found in an already extracted form then // return this one without extracting it @@ -267,11 +301,12 @@ public final class Loader final File dest = new File(createTempDirectory(), lib); try { - final InputStream stream = - Loader.class.getResourceAsStream(source); + final InputStream stream = Loader.class.getResourceAsStream(source); if (stream == null) + { throw new LoaderException("Unable to find " + source + " in the classpath"); + } try { copy(stream, dest); @@ -283,9 +318,8 @@ public final class Loader } catch (final IOException e) { - throw new LoaderException( - "Unable to extract native library " + source + " to " + dest - + ": " + e, e); + throw new LoaderException("Unable to extract native library " + + source + " to " + dest + ": " + e, e); } // Mark usb4java library for deletion @@ -299,19 +333,24 @@ public final class Loader * times. Duplicate calls are ignored. This method is automatically called * when the {@link LibUsb} class is loaded. When you need to do it earlier * (To catch exceptions for example) then simply call this method manually. - * + * * @throws LoaderException * When loading the native wrapper libraries failed. */ public static void load() { - if (loaded) return; + if (loaded) + { + return; + } final String platform = getPlatform(); final String lib = getLibName(); final String extraLib = getExtraLibName(); if (extraLib != null) + { System.load(extractLibrary(platform, extraLib)); + } System.load(extractLibrary(platform, lib)); loaded = true; } diff --git a/src/main/java/de/ailis/usb4java/libusb/LoaderException.java b/src/main/java/de/ailis/usb4java/libusb/LoaderException.java index 7d23d06..0522915 100644 --- a/src/main/java/de/ailis/usb4java/libusb/LoaderException.java +++ b/src/main/java/de/ailis/usb4java/libusb/LoaderException.java @@ -7,7 +7,7 @@ package de.ailis.usb4java.libusb; /** * Thrown when JNI library could not be loaded. - * + * * @author Klaus Reimer (k@ailis.de) */ public final class LoaderException extends RuntimeException @@ -17,7 +17,7 @@ public final class LoaderException extends RuntimeException /** * Constructor. - * + * * @param message * The error message. */ @@ -28,7 +28,7 @@ public final class LoaderException extends RuntimeException /** * Constructor. - * + * * @param message * The error message. * @param cause diff --git a/src/main/java/de/ailis/usb4java/libusb/PollfdListener.java b/src/main/java/de/ailis/usb4java/libusb/PollfdListener.java index a54359b..6f3282c 100644 --- a/src/main/java/de/ailis/usb4java/libusb/PollfdListener.java +++ b/src/main/java/de/ailis/usb4java/libusb/PollfdListener.java @@ -1,9 +1,9 @@ /* * Copyright 2013 Klaus Reimer * See LICENSE.md for licensing information. - * - * Based on libusb : - * + * + * Based on libusb : + * * Copyright 2001 Johannes Erdfelt * Copyright 2007-2009 Daniel Drake * Copyright 2010-2012 Peter Stuge @@ -22,7 +22,7 @@ import java.io.FileDescriptor; /** * Listener interface for pollfd notifications. - * + * * @author Klaus Reimer (k@ailis.de) */ public interface PollfdListener @@ -30,7 +30,7 @@ public interface PollfdListener /** * Callback function, invoked when a new file descriptor should be added to * the set of file descriptors monitored for events. - * + * * @param fd * the new file descriptor. * @param events @@ -43,10 +43,10 @@ public interface PollfdListener /** * Callback function, invoked when a file descriptor should be removed from * the set of file descriptors being monitored for events. - * + * * After returning from this callback, do not use that file descriptor * again. - * + * * @param fd * The file descriptor to stop monitoring. * @param userData diff --git a/src/main/java/de/ailis/usb4java/libusb/SsEndpointCompanionDescriptor.java b/src/main/java/de/ailis/usb4java/libusb/SsEndpointCompanionDescriptor.java index 1f7e6da..7ddc043 100644 --- a/src/main/java/de/ailis/usb4java/libusb/SsEndpointCompanionDescriptor.java +++ b/src/main/java/de/ailis/usb4java/libusb/SsEndpointCompanionDescriptor.java @@ -1,9 +1,9 @@ /* * Copyright 2013 Klaus Reimer * See LICENSE.md for licensing information. - * - * Based on libusb : - * + * + * Based on libusb : + * * Copyright 2001 Johannes Erdfelt * Copyright 2007-2009 Daniel Drake * Copyright 2010-2012 Peter Stuge @@ -23,21 +23,20 @@ import org.apache.commons.lang3.builder.HashCodeBuilder; /** * A structure representing the superspeed endpoint companion descriptor. - * + * * This descriptor is documented in section 9.6.7 of the USB 3.0 specification. * All multiple-byte fields are represented in host-endian format. - * + * * @author Klaus Reimer (k@ailis.de) */ public final class SsEndpointCompanionDescriptor { /** The native pointer to the descriptor structure. */ - private long ssEndpointCompanionDescriptor; + private long ssEndpointCompanionDescriptorPointer; /** * Constructs a new descriptor which can be passed to the - * {@link LibUsb#getSsEndpointCompanionDescriptor(Context, - * EndpointDescriptor, SsEndpointCompanionDescriptor)} + * {@link LibUsb#getSsEndpointCompanionDescriptor(Context, EndpointDescriptor, SsEndpointCompanionDescriptor)} * method. */ public SsEndpointCompanionDescriptor() @@ -47,24 +46,24 @@ public final class SsEndpointCompanionDescriptor /** * Returns the native pointer. - * + * * @return The native pointer. */ public long getPointer() { - return this.ssEndpointCompanionDescriptor; + return this.ssEndpointCompanionDescriptorPointer; } /** * Returns the size of this descriptor (in bytes). - * + * * @return The descriptor size in bytes; */ public native byte bLength(); /** * Returns the descriptor type. - * + * * @return The descriptor type. */ public native byte bDescriptorType(); @@ -72,17 +71,17 @@ public final class SsEndpointCompanionDescriptor /** * Returns the maximum number of packets the endpoint can send or receive as * part of a burst. - * + * * @return The maximum number of packets as part of a burst. */ public native byte bMaxBurst(); /** - * Returns the attributes. In bulk endpoint: bits 4:0 represents the - * maximum number of streams the EP supports. In isochronous endpoint: - * bits 1:0 represents the Mult - a zero based value that determines the + * Returns the attributes. In bulk endpoint: bits 4:0 represents the + * maximum number of streams the EP supports. In isochronous endpoint: + * bits 1:0 represents the Mult - a zero based value that determines the * maximum number of packets within a service interval. - * + * * @return The attributes. */ public native byte bmAttributes(); @@ -90,62 +89,74 @@ public final class SsEndpointCompanionDescriptor /** * Returns the total number of bytes this endpoint will transfer every * service interval. Valid only for periodic endpoints. - * + * * @return The total number of bytes per service interval. */ public native short wBytesPerInterval(); /** * Returns a dump of this descriptor. - * + * * @return The descriptor dump. */ public String dump() { - return String.format("Device Descriptor:%n" - + " bLength %18d%n" - + " bDescriptorType %10d%n" - + " bMaxBurst %16s%n" - + " bmAttributes %13d%n" - + " wBytesPerInterval %8d%n", - bLength() & 0xff, - bDescriptorType() & 0xff, - bMaxBurst() & 0xff, - bmAttributes() & 0xff, - wBytesPerInterval() & 0xffff); - } - - @Override - public boolean equals(final Object obj) - { - if (obj == null) return false; - if (obj == this) return true; - if (obj.getClass() != getClass()) return false; - final SsEndpointCompanionDescriptor other = - (SsEndpointCompanionDescriptor) obj; - return new EqualsBuilder() - .append(bDescriptorType(), other.bDescriptorType()) - .append(bLength(), other.bLength()) - .append(bMaxBurst(), other.bMaxBurst()) - .append(bmAttributes(), other.bmAttributes()) - .append(wBytesPerInterval(), other.wBytesPerInterval()).isEquals(); + return String.format( + "SuperSpeed Endpoint Companion Descriptor:%n" + + " bLength %18d%n" + + " bDescriptorType %10d%n" + + " bMaxBurst %16s%n" + + " bmAttributes %13d%n" + + " wBytesPerInterval %8d%n", + this.bLength() & 0xFF, + this.bDescriptorType() & 0xFF, + this.bMaxBurst() & 0xFF, + this.bmAttributes() & 0xFF, + this.wBytesPerInterval() & 0xFFFF); } @Override public int hashCode() { return new HashCodeBuilder() - .append(bLength()) - .append(bDescriptorType()) - .append(bMaxBurst()) - .append(bmAttributes()) - .append(wBytesPerInterval()) + .append(this.bLength()) + .append(this.bDescriptorType()) + .append(this.bMaxBurst()) + .append(this.bmAttributes()) + .append(this.wBytesPerInterval()) .toHashCode(); } + @Override + public boolean equals(final Object obj) + { + if (obj == null) + { + return false; + } + if (obj == this) + { + return true; + } + if (obj.getClass() != this.getClass()) + { + return false; + } + + final SsEndpointCompanionDescriptor other = (SsEndpointCompanionDescriptor) obj; + + return new EqualsBuilder() + .append(this.bLength(), other.bLength()) + .append(this.bDescriptorType(), other.bDescriptorType()) + .append(this.bMaxBurst(), other.bMaxBurst()) + .append(this.bmAttributes(), other.bmAttributes()) + .append(this.wBytesPerInterval(), other.wBytesPerInterval()) + .isEquals(); + } + @Override public String toString() { - return dump(); + return this.dump(); } } diff --git a/src/main/java/de/ailis/usb4java/libusb/SsUsbDeviceCapabilityDescriptor.java b/src/main/java/de/ailis/usb4java/libusb/SsUsbDeviceCapabilityDescriptor.java index 57911df..4ca924f 100644 --- a/src/main/java/de/ailis/usb4java/libusb/SsUsbDeviceCapabilityDescriptor.java +++ b/src/main/java/de/ailis/usb4java/libusb/SsUsbDeviceCapabilityDescriptor.java @@ -1,9 +1,9 @@ /* * Copyright 2013 Klaus Reimer * See LICENSE.md for licensing information. - * - * Based on libusb : - * + * + * Based on libusb : + * * Copyright 2001 Johannes Erdfelt * Copyright 2007-2009 Daniel Drake * Copyright 2010-2012 Peter Stuge @@ -23,11 +23,11 @@ import org.apache.commons.lang3.builder.HashCodeBuilder; /** * A structure representing the SuperSpeed USB Device Capability descriptor. - * This descriptor is documented in section 9.6.2.2 of the USB 3.0 + * This descriptor is documented in section 9.6.2.2 of the USB 3.0 * specification. - * + * * All multiple-byte fields are represented in host-endian format. - * + * * @author Klaus Reimer (k@ailis.de) */ public final class SsUsbDeviceCapabilityDescriptor @@ -36,10 +36,10 @@ public final class SsUsbDeviceCapabilityDescriptor private long ssUsbDeviceCapabilityDescriptorPointer; /** - * Constructs a new SuperSpeed USB Device Capability descriptor which can + * Constructs a new SuperSpeed USB Device Capability descriptor which can * be passed to the - * {@link LibUsb#getSsUsbDeviceCapabilityDescriptor(Context, - * BosDevCapabilityDescriptor, SsUsbDeviceCapabilityDescriptor)} method. + * {@link LibUsb#getSsUsbDeviceCapabilityDescriptor(Context, BosDevCapabilityDescriptor, SsUsbDeviceCapabilityDescriptor)} + * method. */ public SsUsbDeviceCapabilityDescriptor() { @@ -48,7 +48,7 @@ public final class SsUsbDeviceCapabilityDescriptor /** * Returns the native pointer. - * + * * @return The native pointer. */ public long getPointer() @@ -58,126 +58,137 @@ public final class SsUsbDeviceCapabilityDescriptor /** * Returns the size of this descriptor (in bytes). - * + * * @return The descriptor size in bytes; */ public native byte bLength(); /** * Returns the descriptor type. - * + * * @return The descriptor type. */ public native byte bDescriptorType(); /** * Returns the device capability type. - * + * * @return The device capability type. */ public native byte bDevCapabilityType(); /** - * Returns the bitmap of supported device level features. - * + * Returns the bitmap of supported device level features. + * * @return The supported device level features. */ public native byte bmAttributes(); - + /** - * Returns the bitmap encoding of the speed supported by this device when + * Returns the bitmap encoding of the speed supported by this device when * operating in SuperSpeed mode. - * + * * @return The supported speed. */ public native short wSpeedSupported(); - + /** - * Returns the lowest speed at which all the functionality supported by the + * Returns the lowest speed at which all the functionality supported by the * device is available to the user. - * + * * @return The lowest speed. */ public native byte bFunctionalitySupport(); - + /** * Returns the U1 Device Exit Latency. - * + * * @return The U1 Device Exit Latency. */ public native byte bU1DevExitLat(); - + /** * Returns the U2 Device Exit Latency. - * + * * @return The U2 Device Exit Latency. */ public native short bU2DevExitLat(); /** * Returns a dump of this descriptor. - * + * * @return The descriptor dump. */ public String dump() { - return String.format("SuperSpeed USB Device Capability descriptor:%n" - + " bLength %18d%n" - + " bDescriptorType %10d%n" - + " bDevCapabilityType %7d%n" - + " bmAttributes %13s%n" - + " wSpeedSupported %10d%n" - + " bFunctionalitySupport %4d%n" - + " bU1DevExitLat %12d%n" - + " bU2DevExitLat %12d%n", - bLength() & 0xff, - bDescriptorType() & 0xff, - bDevCapabilityType() & 0xff, - String.format("0x%02x", bmAttributes() & 0xff), - wSpeedSupported() & 0xffff, - bFunctionalitySupport() & 0xff, - bU1DevExitLat() & 0xff, - bU2DevExitLat() & 0xffff); - } - - @Override - public boolean equals(final Object obj) - { - if (obj == null) return false; - if (obj == this) return true; - if (obj.getClass() != getClass()) return false; - final SsUsbDeviceCapabilityDescriptor other = - (SsUsbDeviceCapabilityDescriptor) obj; - return new EqualsBuilder() - .append(bDescriptorType(), other.bDescriptorType()) - .append(bLength(), other.bLength()) - .append(bDevCapabilityType(), other.bDevCapabilityType()) - .append(bmAttributes(), other.bmAttributes()) - .append(wSpeedSupported(), other.wSpeedSupported()) - .append(bFunctionalitySupport(), other.bFunctionalitySupport()) - .append(bU1DevExitLat(), other.bU1DevExitLat()) - .append(bU2DevExitLat(), other.bU2DevExitLat()) - .isEquals(); + return String.format( + "SuperSpeed USB Device Capability Descriptor:%n" + + " bLength %18d%n" + + " bDescriptorType %10d%n" + + " bDevCapabilityType %7d%n" + + " bmAttributes %13s%n" + + " wSpeedSupported %10d%n" + + " bFunctionalitySupport %4d%n" + + " bU1DevExitLat %12d%n" + + " bU2DevExitLat %12d%n", + this.bLength() & 0xFF, + this.bDescriptorType() & 0xFF, + this.bDevCapabilityType() & 0xFF, + String.format("0x%02x", this.bmAttributes() & 0xFF), + this.wSpeedSupported() & 0xFFFF, + this.bFunctionalitySupport() & 0xFF, + this.bU1DevExitLat() & 0xFF, + this.bU2DevExitLat() & 0xFFFF); } @Override public int hashCode() { return new HashCodeBuilder() - .append(bLength()) - .append(bDescriptorType()) - .append(bDevCapabilityType()) - .append(bmAttributes()) - .append(wSpeedSupported()) - .append(bFunctionalitySupport()) - .append(bU1DevExitLat()) - .append(bU2DevExitLat()) + .append(this.bLength()) + .append(this.bDescriptorType()) + .append(this.bDevCapabilityType()) + .append(this.bmAttributes()) + .append(this.wSpeedSupported()) + .append(this.bFunctionalitySupport()) + .append(this.bU1DevExitLat()) + .append(this.bU2DevExitLat()) .toHashCode(); } + @Override + public boolean equals(final Object obj) + { + if (obj == null) + { + return false; + } + if (obj == this) + { + return true; + } + if (obj.getClass() != this.getClass()) + { + return false; + } + + final SsUsbDeviceCapabilityDescriptor other = (SsUsbDeviceCapabilityDescriptor) obj; + + return new EqualsBuilder() + .append(this.bLength(), other.bLength()) + .append(this.bDescriptorType(), other.bDescriptorType()) + .append(this.bDevCapabilityType(), other.bDevCapabilityType()) + .append(this.bmAttributes(), other.bmAttributes()) + .append(this.wSpeedSupported(), other.wSpeedSupported()) + .append(this.bFunctionalitySupport(), other.bFunctionalitySupport()) + .append(this.bU1DevExitLat(), other.bU1DevExitLat()) + .append(this.bU2DevExitLat(), other.bU2DevExitLat()) + .isEquals(); + } + @Override public String toString() { - return dump(); + return this.dump(); } } diff --git a/src/main/java/de/ailis/usb4java/libusb/Transfer.java b/src/main/java/de/ailis/usb4java/libusb/Transfer.java index a4c56fb..4110a4d 100644 --- a/src/main/java/de/ailis/usb4java/libusb/Transfer.java +++ b/src/main/java/de/ailis/usb4java/libusb/Transfer.java @@ -1,9 +1,10 @@ /* * Copyright 2013 Klaus Reimer + * Copyright 2013 Luca Longinotti * See LICENSE.md for licensing information. - * - * Based on libusb : - * + * + * Based on libusb : + * * Copyright 2001 Johannes Erdfelt * Copyright 2007-2009 Daniel Drake * Copyright 2010-2012 Peter Stuge @@ -22,7 +23,7 @@ import java.nio.ByteBuffer; /** * The generic USB transfer structure. - * + * * The user populates this structure and then submits it in order to request a * transfer. After the transfer has completed, the library populates the * transfer with the results and passes it back to the user. @@ -32,36 +33,42 @@ 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 } /** * Returns the native pointer. - * + * * @return The native pointer. */ public long getPointer() { - return this.pointer; + return this.transferPointer; } /** * Returns the handle of the device that this transfer will be submitted to. - * + * * @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. - * + * * @param handle * The handle of the device. */ @@ -69,131 +76,258 @@ public final class Transfer /** * Returns the bitwise OR combination of libusb transfer flags. - * + * * @return The transfer flags. */ - public native int getFlags(); + public native byte flags(); /** * Sets the bitwise OR combination of libusb transfer flags. - * + * * @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. - * + * * @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. - * + * * @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 * indicates no timeout. - * + * * @return The timeout. */ - public native long getTimeout(); + public native long timeout(); /** * Sets the timeout for this transfer in milliseconds. A value of 0 * indicates no timeout. - * + * * @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 * transfer callback function. - * + * * If this is an isochronous transfer, this field may read * {@link LibUsb#TRANSFER_COMPLETED} even if there were errors in the * frames. Use the status field in each packet to determine if errors * occurred. - * + * * @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 (this.transferBuffer == null) + { + throw new IllegalArgumentException( + "buffer is null, only a length of 0 is allowed"); + } + + if (this.transferBuffer.capacity() < length) + { + throw new IllegalArgumentException( + "buffer too small for requested length"); + } + } + + // Native call. + this.setLengthNative(length); + } + + native void setLengthNative(final int length); /** * Returns the actual length of data that was transferred. Read-only, and * only for use within transfer callback function. Not valid for isochronous * endpoint transfers. - * + * * @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 this.transferBuffer; + } /** * Sets the data buffer. - * + * * @param buffer * The data buffer to set. */ - public native void setBuffer(final ByteBuffer buffer); + public void setBuffer(final ByteBuffer buffer) + { + // Native call. + this.setBufferNative(buffer); + + if (buffer != null) + { + // Set new length based on buffer's capacity. + this.setLengthNative(buffer.capacity()); + } + else + { + this.setLengthNative(0); + } + + // Once we know the native calls have gone through, update the + // reference. + this.transferBuffer = buffer; + } + + native void setBufferNative(final ByteBuffer buffer); /** * Returns the number of isochronous packets. Only used for I/O with * isochronous endpoints. - * + * * @return The number of isochronous packets. */ - public native int getNumIsoPackets(); + public native int numIsoPackets(); /** * Sets the number of isochronous packets. - * + * * @param numIsoPackets * 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) (this.transferPointer ^ (this.transferPointer >>> 32)); + return result; + } + + @Override + public boolean equals(final Object obj) + { + if (this == obj) + { + return true; + } + if (obj == null) + { + return false; + } + if (this.getClass() != obj.getClass()) + { + return false; + } + final Transfer other = (Transfer) obj; + if (this.transferPointer != other.transferPointer) + { + return false; + } + return true; + } + + @Override + public String toString() + { + return String.format("libusb transfer 0x%x", this.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..6d4fc65 --- /dev/null +++ b/src/main/java/de/ailis/usb4java/libusb/TransferCallback.java @@ -0,0 +1,11 @@ +/* + * Copyright 2013 Luca Longinotti + * See LICENSE.md for licensing information. + */ + +package de.ailis.usb4java.libusb; + +public interface TransferCallback +{ + void processTransfer(Transfer transfer); +} diff --git a/src/main/java/de/ailis/usb4java/libusb/Usb20ExtensionDescriptor.java b/src/main/java/de/ailis/usb4java/libusb/Usb20ExtensionDescriptor.java index 633fc6e..bd4eaf2 100644 --- a/src/main/java/de/ailis/usb4java/libusb/Usb20ExtensionDescriptor.java +++ b/src/main/java/de/ailis/usb4java/libusb/Usb20ExtensionDescriptor.java @@ -1,9 +1,9 @@ /* * Copyright 2013 Klaus Reimer * See LICENSE.md for licensing information. - * - * Based on libusb : - * + * + * Based on libusb : + * * Copyright 2001 Johannes Erdfelt * Copyright 2007-2009 Daniel Drake * Copyright 2010-2012 Peter Stuge @@ -24,9 +24,9 @@ import org.apache.commons.lang3.builder.HashCodeBuilder; /** * A structure representing the USB 2.0 Extension descriptor. This descriptor is * documented in section 9.6.2.1 of the USB 3.0 specification. - * + * * All multiple-byte fields are represented in host-endian format. - * + * * @author Klaus Reimer (k@ailis.de) */ public final class Usb20ExtensionDescriptor @@ -36,8 +36,8 @@ public final class Usb20ExtensionDescriptor /** * Constructs a new USB 2.0 Extension descriptor which can be passed to the - * {@link LibUsb#getUsb20ExtensionDescriptor(Context, - * BosDevCapabilityDescriptor, Usb20ExtensionDescriptor)} method. + * {@link LibUsb#getUsb20ExtensionDescriptor(Context, BosDevCapabilityDescriptor, Usb20ExtensionDescriptor)} + * method. */ public Usb20ExtensionDescriptor() { @@ -46,7 +46,7 @@ public final class Usb20ExtensionDescriptor /** * Returns the native pointer. - * + * * @return The native pointer. */ public long getPointer() @@ -56,79 +56,91 @@ public final class Usb20ExtensionDescriptor /** * Returns the size of this descriptor (in bytes). - * + * * @return The descriptor size in bytes; */ public native byte bLength(); /** * Returns the descriptor type. - * + * * @return The descriptor type. */ public native byte bDescriptorType(); /** * Returns the device capability type. - * + * * @return The device capability type. */ public native byte bDevCapabilityType(); /** - * Returns the bitmap of supported device level features. - * + * Returns the bitmap of supported device level features. + * * @return The supported device level features. */ public native int bmAttributes(); /** * Returns a dump of this descriptor. - * + * * @return The descriptor dump. */ public String dump() { - return String.format("USB 2.0 Extension Descriptor:%n" - + " bLength %18d%n" - + " bDescriptorType %10d%n" - + " bDevCapabilityType %7d%n" - + " bmAttributes %13s%n", - bLength() & 0xff, - bDescriptorType() & 0xff, - bDevCapabilityType() & 0xff, - String.format("0x%08x", bmAttributes())); - } - - @Override - public boolean equals(final Object obj) - { - if (obj == null) return false; - if (obj == this) return true; - if (obj.getClass() != getClass()) return false; - final Usb20ExtensionDescriptor other = - (Usb20ExtensionDescriptor) obj; - return new EqualsBuilder() - .append(bDescriptorType(), other.bDescriptorType()) - .append(bLength(), other.bLength()) - .append(bDevCapabilityType(), other.bDevCapabilityType()) - .append(bmAttributes(), other.bmAttributes()).isEquals(); + return String.format( + "USB 2.0 Extension Descriptor:%n" + + " bLength %18d%n" + + " bDescriptorType %10d%n" + + " bDevCapabilityType %7d%n" + + " bmAttributes %13s%n", + this.bLength() & 0xFF, + this.bDescriptorType() & 0xFF, + this.bDevCapabilityType() & 0xFF, + String.format("0x%08x", this.bmAttributes())); } @Override public int hashCode() { return new HashCodeBuilder() - .append(bLength()) - .append(bDescriptorType()) - .append(bDevCapabilityType()) - .append(bmAttributes()) + .append(this.bLength()) + .append(this.bDescriptorType()) + .append(this.bDevCapabilityType()) + .append(this.bmAttributes()) .toHashCode(); } + @Override + public boolean equals(final Object obj) + { + if (obj == null) + { + return false; + } + if (obj == this) + { + return true; + } + if (obj.getClass() != this.getClass()) + { + return false; + } + + final Usb20ExtensionDescriptor other = (Usb20ExtensionDescriptor) obj; + + return new EqualsBuilder() + .append(this.bLength(), other.bLength()) + .append(this.bDescriptorType(), other.bDescriptorType()) + .append(this.bDevCapabilityType(), other.bDevCapabilityType()) + .append(this.bmAttributes(), other.bmAttributes()) + .isEquals(); + } + @Override public String toString() { - return dump(); + return this.dump(); } } diff --git a/src/main/java/de/ailis/usb4java/libusb/Version.java b/src/main/java/de/ailis/usb4java/libusb/Version.java index 89b0452..e221109 100644 --- a/src/main/java/de/ailis/usb4java/libusb/Version.java +++ b/src/main/java/de/ailis/usb4java/libusb/Version.java @@ -1,9 +1,9 @@ /* * Copyright 2013 Klaus Reimer * See LICENSE.md for licensing information. - * - * Based on libusb : - * + * + * Based on libusb : + * * Copyright 2001 Johannes Erdfelt * Copyright 2007-2009 Daniel Drake * Copyright 2010-2012 Peter Stuge @@ -24,14 +24,14 @@ import org.apache.commons.lang3.builder.HashCodeBuilder; /** * Structure providing the version of the libusb runtime. - * + * * @author Klaus Reimer (k@ailis.de) */ 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()}. @@ -43,77 +43,113 @@ public final class Version implements Comparable /** * Returns the native pointer. - * + * * @return The native pointer. */ public long getPointer() { - return this.pointer; + return this.versionPointer; } /** * Returns the library major version. - * + * * @return The library major version. */ public native int major(); /** * Returns the library minor version. - * + * * @return The library minor version. */ public native int minor(); /** * Returns the library micro version. - * + * * @return The library micro version. */ 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". - * + * * @return The release candidate suffix string. */ 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(this.major()) + .append(this.minor()) + .append(this.micro()) + .append(this.nano()) + .append(this.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 (this.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(rc(), other.rc()) + .append(this.major(), other.major()) + .append(this.minor(), other.minor()) + .append(this.micro(), other.micro()) + .append(this.nano(), other.nano()) + .append(this.rc(), other.rc()) .isEquals(); } @Override public 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(rc(), other.rc()) + .append(this.major(), other.major()) + .append(this.minor(), other.minor()) + .append(this.micro(), other.micro()) + .append(this.nano(), other.nano()) + .append(this.rc(), other.rc()) .toComparison(); } + + @Override + public String toString() + { + return this.major() + "." + this.minor() + "." + this.micro() + "." + + this.nano() + this.rc(); + } } diff --git a/src/main/java/de/ailis/usb4java/libusb/package-info.java b/src/main/java/de/ailis/usb4java/libusb/package-info.java index a5e0d6e..57247fb 100644 --- a/src/main/java/de/ailis/usb4java/libusb/package-info.java +++ b/src/main/java/de/ailis/usb4java/libusb/package-info.java @@ -7,3 +7,4 @@ * Low-Level classes based on the native libusb library. */ package de.ailis.usb4java.libusb; + 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..e084444 --- /dev/null +++ b/src/main/java/de/ailis/usb4java/utils/BufferUtils.java @@ -0,0 +1,48 @@ +/* + * Copyright 2013 Luca Longinotti + * See LICENSE.md for licensing information. + */ + +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..ac2b07a 100644 --- a/src/main/java/de/ailis/usb4java/utils/DescriptorUtils.java +++ b/src/main/java/de/ailis/usb4java/utils/DescriptorUtils.java @@ -18,21 +18,21 @@ import de.ailis.usb4java.libusb.LibUsb; /** * Utility methods used for descriptor dumps. - * + * * @author Klaus Reimer (k@ailis.de) */ 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 +41,11 @@ 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_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"); } /** @@ -61,59 +59,70 @@ public final class DescriptorUtils /** * Returns the name of the specified USB class. "unknown" is returned for a * class which is unknown to libusb. - * + * * @param usbClass * 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; } /** * Decodes a binary-coded decimal into a string and returns it. - * + * * @param bcd * 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); } /** * Dumps the specified byte buffer into a hex string and returns it. - * + * * @param bytes * The bytes to dump. * @return The hex dump. */ 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. * @return The descriptor dump. @@ -124,9 +133,8 @@ 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. * @param manufacturer @@ -140,62 +148,64 @@ public final class DescriptorUtils public static String dump(final UsbDeviceDescriptor descriptor, final String manufacturer, final String product, final String serial) { - return String.format("Device Descriptor:%n" - + " bLength %18d%n" - + " bDescriptorType %10d%n" - + " bcdUSB %19s%n" - + " bDeviceClass %13d %s%n" - + " bDeviceSubClass %10d%n" - + " bDeviceProtocol %10d%n" - + " bMaxPacketSize0 %10d%n" - + " idVendor %17s%n" - + " idProduct %16s%n" - + " bcdDevice %16s%n" - + " iManufacturer %12d%s%n" - + " iProduct %17d%s%n" - + " iSerial %18d%s%n" - + " bNumConfigurations %7d%n", + return String.format( + "Device Descriptor:%n" + + " bLength %18d%n" + + " bDescriptorType %10d%n" + + " bcdUSB %19s%n" + + " bDeviceClass %13d %s%n" + + " bDeviceSubClass %10d%n" + + " bDeviceProtocol %10d%n" + + " bMaxPacketSize0 %10d%n" + + " idVendor %17s%n" + + " idProduct %16s%n" + + " bcdDevice %16s%n" + + " iManufacturer %12d%s%n" + + " iProduct %17d%s%n" + + " iSerial %18d%s%n" + + " bNumConfigurations %7d%n", descriptor.bLength(), 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); } /** * Dumps the specified USB configuration descriptor into a string and * returns it. - * + * * @param descriptor * The USB configuration descriptor to dump. * @return The descriptor dump. */ public static String dump(final UsbConfigurationDescriptor descriptor) { - return String.format("Configuration Descriptor:%n" - + " bLength %18d%n" - + " bDescriptorType %10d%n" - + " wTotalLength %13d%n" - + " bNumInterfaces %11d%n" - + " bConfigurationValue %6d%n" - + " iConfiguration %11d%n" - + " bmAttributes %13s%n" - + " %s%n" - + "%s" - + " bMaxPower %16smA%n", + return String.format( + "Configuration Descriptor:%n" + + " bLength %18d%n" + + " bDescriptorType %10d%n" + + " wTotalLength %13d%n" + + " bNumInterfaces %11d%n" + + " bConfigurationValue %6d%n" + + " iConfiguration %11d%n" + + " bmAttributes %13s%n" + + " %s%n" + + "%s" + + " bMaxPower %16smA%n", descriptor.bLength(), descriptor.bDescriptorType(), descriptor.wTotalLength() & 0xffff, @@ -203,74 +213,76 @@ 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. * @return The descriptor dump. */ public static String dump(final UsbInterfaceDescriptor descriptor) { - return String.format("Interface Descriptor:%n" - + " bLength %18d%n" - + " bDescriptorType %10d%n" - + " bInterfaceNumber %9d%n" - + " bAlternateSetting %8d%n" - + " bNumEndpoints %12d%n" - + " bInterfaceClass %10d %s%n" - + " bInterfaceSubClass %7d%n" - + " bInterfaceProtocol %7d%n" - + " iInterface %15d%n", + return String.format( + "Interface Descriptor:%n" + + " bLength %18d%n" + + " bDescriptorType %10d%n" + + " bInterfaceNumber %9d%n" + + " bAlternateSetting %8d%n" + + " bNumEndpoints %12d%n" + + " bInterfaceClass %10d %s%n" + + " bInterfaceSubClass %7d%n" + + " bInterfaceProtocol %7d%n" + + " iInterface %15d%n", descriptor.bLength(), descriptor.bDescriptorType(), descriptor.bInterfaceNumber() & 0xff, 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. * @return The descriptor dump. */ public static String dump(final UsbEndpointDescriptor descriptor) { - return String.format("Endpoint Descriptor:%n" - + " bLength %18d%n" - + " bDescriptorType %10d%n" - + " bEndpointAddress %9s EP %d %s%n" - + " bmAttributes %13d%n" - + " Transfer Type %s%n" - + " Synch Type %s%n" - + " Usage Type %s%n" - + " wMaxPacketSize %11d%n" - + " bInterval %16d%n", + return String.format( + "Endpoint Descriptor:%n" + + " bLength %18d%n" + + " bDescriptorType %10d%n" + + " bEndpointAddress %9s EP %d %s%n" + + " bmAttributes %13d%n" + + " Transfer Type %s%n" + + " Synch Type %s%n" + + " Usage Type %s%n" + + " wMaxPacketSize %11d%n" + + " bInterval %16d%n", descriptor.bLength(), descriptor.bDescriptorType(), String.format("0x%02x", descriptor.bEndpointAddress() & 0xff), - descriptor.bEndpointAddress() & 0xf, - (descriptor.bEndpointAddress() & 0x80) == 0 ? "OUT" : "IN", + descriptor.bEndpointAddress() & 0x0f, + ((descriptor.bEndpointAddress() & LibUsb.ENDPOINT_IN) == 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); } @@ -278,74 +290,80 @@ public final class DescriptorUtils /** * Returns the name for the transfer type in the specified endpoint * attributes. - * + * * @param bmAttributes * 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"; } } /** * Returns the name for the synchronization type in the specified endpoint * attributes. - * + * * @param bmAttributes * 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"; } } /** * Returns the name for the usage type in the specified endpoint attributes. - * + * * @param bmAttributes * 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"; } } /** * Returns the name for the specified speed number. - * + * * @param speed * The speed number. * @return The speed name. 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..efc2fa3 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/linux-x86/libusb4java.so b/src/main/resources/de/ailis/usb4java/libusb/linux-x86/libusb4java.so index bf05a40..55dd2b4 100644 Binary files a/src/main/resources/de/ailis/usb4java/libusb/linux-x86/libusb4java.so and b/src/main/resources/de/ailis/usb4java/libusb/linux-x86/libusb4java.so differ diff --git a/src/main/resources/de/ailis/usb4java/libusb/linux-x86_64/libusb4java.so b/src/main/resources/de/ailis/usb4java/libusb/linux-x86_64/libusb4java.so index 64e4b33..3b80aa2 100644 Binary files a/src/main/resources/de/ailis/usb4java/libusb/linux-x86_64/libusb4java.so and b/src/main/resources/de/ailis/usb4java/libusb/linux-x86_64/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..fcab4e9 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..78d837c 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..013b61c 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..fe28c43 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..3664569 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..d346aed 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/BosDescriptorTest.java b/src/test/java/de/ailis/usb4java/libusb/BosDescriptorTest.java index 70a164e..f15c55c 100644 --- a/src/test/java/de/ailis/usb4java/libusb/BosDescriptorTest.java +++ b/src/test/java/de/ailis/usb4java/libusb/BosDescriptorTest.java @@ -13,7 +13,7 @@ import org.junit.Test; /** * Tests the {@link BosDescriptor} class. - * + * * @author Klaus Reimer (k@ailis.de) */ public class BosDescriptorTest @@ -31,19 +31,18 @@ public class BosDescriptorTest LibUsb.init(null); this.descriptor = new BosDescriptor(); } - + /** * Tear down test. */ - @After + @After public void tearDown() { LibUsb.exit(null); } /** - * Tests uninitialized access to - * {@link BosDescriptor#bLength()} + * Tests uninitialized access to {@link BosDescriptor#bLength()} */ @Test(expected = IllegalStateException.class) public void testUninitializedLength() @@ -53,8 +52,7 @@ public class BosDescriptorTest } /** - * Tests uninitialized access to - * {@link BosDescriptor#bDescriptorType()} + * Tests uninitialized access to {@link BosDescriptor#bDescriptorType()} */ @Test(expected = IllegalStateException.class) public void testUninitializedDescriptorType() @@ -64,8 +62,7 @@ public class BosDescriptorTest } /** - * Tests uninitialized access to - * {@link BosDescriptor#wTotalLength()} + * Tests uninitialized access to {@link BosDescriptor#wTotalLength()} */ @Test(expected = IllegalStateException.class) public void testUninitializedTotalLength() @@ -75,8 +72,7 @@ public class BosDescriptorTest } /** - * Tests uninitialized access to - * {@link BosDescriptor#bNumDeviceCaps()} + * Tests uninitialized access to {@link BosDescriptor#bNumDeviceCaps()} */ @Test(expected = IllegalStateException.class) public void testUninitializedNumDeviceCaps() @@ -86,8 +82,7 @@ public class BosDescriptorTest } /** - * Tests uninitialized access to - * {@link BosDescriptor#devCapability()} + * Tests uninitialized access to {@link BosDescriptor#devCapability()} */ @Test(expected = IllegalStateException.class) public void testUninitializedDevCapability() diff --git a/src/test/java/de/ailis/usb4java/libusb/BosDevCapabilityDescriptorTest.java b/src/test/java/de/ailis/usb4java/libusb/BosDevCapabilityDescriptorTest.java index fbb01b6..3671db3 100644 --- a/src/test/java/de/ailis/usb4java/libusb/BosDevCapabilityDescriptorTest.java +++ b/src/test/java/de/ailis/usb4java/libusb/BosDevCapabilityDescriptorTest.java @@ -13,7 +13,7 @@ import org.junit.Test; /** * Tests the {@link BosDevCapabilityDescriptor} class. - * + * * @author Klaus Reimer (k@ailis.de) */ public class BosDevCapabilityDescriptorTest @@ -31,11 +31,11 @@ public class BosDevCapabilityDescriptorTest LibUsb.init(null); this.descriptor = new BosDevCapabilityDescriptor(); } - + /** * Tear down test. */ - @After + @After public void tearDown() { LibUsb.exit(null); diff --git a/src/test/java/de/ailis/usb4java/libusb/ConfigDescriptorTest.java b/src/test/java/de/ailis/usb4java/libusb/ConfigDescriptorTest.java index e7e9d0d..37712bd 100644 --- a/src/test/java/de/ailis/usb4java/libusb/ConfigDescriptorTest.java +++ b/src/test/java/de/ailis/usb4java/libusb/ConfigDescriptorTest.java @@ -13,7 +13,7 @@ import org.junit.Test; /** * Tests the {@link ConfigDescriptor} class. - * + * * @author Klaus Reimer (k@ailis.de) */ public class ConfigDescriptorTest @@ -31,19 +31,18 @@ public class ConfigDescriptorTest LibUsb.init(null); this.descriptor = new ConfigDescriptor(); } - + /** * Tear down test. */ - @After + @After public void tearDown() { LibUsb.exit(null); } /** - * Tests uninitialized access to - * {@link ConfigDescriptor#bLength()} + * Tests uninitialized access to {@link ConfigDescriptor#bLength()} */ @Test(expected = IllegalStateException.class) public void testUninitializedLength() @@ -53,8 +52,7 @@ public class ConfigDescriptorTest } /** - * Tests uninitialized access to - * {@link ConfigDescriptor#bDescriptorType()} + * Tests uninitialized access to {@link ConfigDescriptor#bDescriptorType()} */ @Test(expected = IllegalStateException.class) public void testUninitializedDescriptorType() @@ -64,8 +62,7 @@ public class ConfigDescriptorTest } /** - * Tests uninitialized access to - * {@link ConfigDescriptor#wTotalLength()} + * Tests uninitialized access to {@link ConfigDescriptor#wTotalLength()} */ @Test(expected = IllegalStateException.class) public void testUninitializedTotalLength() @@ -75,8 +72,7 @@ public class ConfigDescriptorTest } /** - * Tests uninitialized access to - * {@link ConfigDescriptor#bNumInterfaces()} + * Tests uninitialized access to {@link ConfigDescriptor#bNumInterfaces()} */ @Test(expected = IllegalStateException.class) public void testUninitializedNumInterfaces() @@ -97,8 +93,7 @@ public class ConfigDescriptorTest } /** - * Tests uninitialized access to - * {@link ConfigDescriptor#iConfiguration()} + * Tests uninitialized access to {@link ConfigDescriptor#iConfiguration()} */ @Test(expected = IllegalStateException.class) public void testUninitializedConfiguration() @@ -108,8 +103,7 @@ public class ConfigDescriptorTest } /** - * Tests uninitialized access to - * {@link ConfigDescriptor#bmAttributes()} + * Tests uninitialized access to {@link ConfigDescriptor#bmAttributes()} */ @Test(expected = IllegalStateException.class) public void testUninitializedDescriptorAttributes() @@ -119,8 +113,7 @@ public class ConfigDescriptorTest } /** - * Tests uninitialized access to - * {@link ConfigDescriptor#bMaxPower()} + * Tests uninitialized access to {@link ConfigDescriptor#bMaxPower()} */ @Test(expected = IllegalStateException.class) public void testUninitializedDescriptorMaxPower() @@ -130,8 +123,7 @@ public class ConfigDescriptorTest } /** - * Tests uninitialized access to - * {@link ConfigDescriptor#iface()} + * Tests uninitialized access to {@link ConfigDescriptor#iface()} */ @Test(expected = IllegalStateException.class) public void testUninitializedDescriptorIface() @@ -141,8 +133,7 @@ public class ConfigDescriptorTest } /** - * Tests uninitialized access to - * {@link ConfigDescriptor#extra()} + * Tests uninitialized access to {@link ConfigDescriptor#extra()} */ @Test(expected = IllegalStateException.class) public void testUninitializedDescriptorExtra() @@ -152,8 +143,7 @@ public class ConfigDescriptorTest } /** - * Tests uninitialized access to - * {@link ConfigDescriptor#extraLength()} + * Tests uninitialized access to {@link ConfigDescriptor#extraLength()} */ @Test(expected = IllegalStateException.class) public void testUninitializedDescriptorExtraLength() diff --git a/src/test/java/de/ailis/usb4java/libusb/ContainerIdDescriptorTest.java b/src/test/java/de/ailis/usb4java/libusb/ContainerIdDescriptorTest.java index 164cc79..08d84bd 100644 --- a/src/test/java/de/ailis/usb4java/libusb/ContainerIdDescriptorTest.java +++ b/src/test/java/de/ailis/usb4java/libusb/ContainerIdDescriptorTest.java @@ -13,7 +13,7 @@ import org.junit.Test; /** * Tests the {@link ContainerIdDescriptor} class. - * + * * @author Klaus Reimer (k@ailis.de) */ public class ContainerIdDescriptorTest @@ -31,19 +31,18 @@ public class ContainerIdDescriptorTest LibUsb.init(null); this.descriptor = new ContainerIdDescriptor(); } - + /** * Tear down test. */ - @After + @After public void tearDown() { LibUsb.exit(null); } /** - * Tests uninitialized access to - * {@link ContainerIdDescriptor#bLength()} + * Tests uninitialized access to {@link ContainerIdDescriptor#bLength()} */ @Test(expected = IllegalStateException.class) public void testUninitializedLength() @@ -75,8 +74,7 @@ public class ContainerIdDescriptorTest } /** - * Tests uninitialized access to - * {@link ContainerIdDescriptor#bReserved()} + * Tests uninitialized access to {@link ContainerIdDescriptor#bReserved()} */ @Test(expected = IllegalStateException.class) public void testUninitializedReserved() @@ -86,8 +84,7 @@ public class ContainerIdDescriptorTest } /** - * Tests uninitialized access to - * {@link ContainerIdDescriptor#containerId()} + * Tests uninitialized access to {@link ContainerIdDescriptor#containerId()} */ @Test(expected = IllegalStateException.class) public void testUninitializedContainerId() diff --git a/src/test/java/de/ailis/usb4java/libusb/DeviceDescriptorTest.java b/src/test/java/de/ailis/usb4java/libusb/DeviceDescriptorTest.java index 0480bba..083dd13 100644 --- a/src/test/java/de/ailis/usb4java/libusb/DeviceDescriptorTest.java +++ b/src/test/java/de/ailis/usb4java/libusb/DeviceDescriptorTest.java @@ -13,7 +13,7 @@ import org.junit.Test; /** * Tests the {@link DeviceDescriptor} class. - * + * * @author Klaus Reimer (k@ailis.de) */ public class DeviceDescriptorTest @@ -31,19 +31,18 @@ public class DeviceDescriptorTest LibUsb.init(null); this.descriptor = new DeviceDescriptor(); } - + /** * Tear down test. */ - @After + @After public void tearDown() { LibUsb.exit(null); } /** - * Tests uninitialized access to - * {@link DeviceDescriptor#bLength()} + * Tests uninitialized access to {@link DeviceDescriptor#bLength()} */ @Test(expected = IllegalStateException.class) public void testUninitializedLength() @@ -53,8 +52,7 @@ public class DeviceDescriptorTest } /** - * Tests uninitialized access to - * {@link DeviceDescriptor#bDescriptorType()} + * Tests uninitialized access to {@link DeviceDescriptor#bDescriptorType()} */ @Test(expected = IllegalStateException.class) public void testUninitializedDescriptorType() @@ -64,8 +62,7 @@ public class DeviceDescriptorTest } /** - * Tests uninitialized access to - * {@link DeviceDescriptor#bcdUSB()} + * Tests uninitialized access to {@link DeviceDescriptor#bcdUSB()} */ @Test(expected = IllegalStateException.class) public void testUninitializedBcdUSB() @@ -75,8 +72,7 @@ public class DeviceDescriptorTest } /** - * Tests uninitialized access to - * {@link DeviceDescriptor#bDeviceClass()} + * Tests uninitialized access to {@link DeviceDescriptor#bDeviceClass()} */ @Test(expected = IllegalStateException.class) public void testUninitializedDeviceClass() @@ -86,8 +82,7 @@ public class DeviceDescriptorTest } /** - * Tests uninitialized access to - * {@link DeviceDescriptor#bDeviceSubClass()} + * Tests uninitialized access to {@link DeviceDescriptor#bDeviceSubClass()} */ @Test(expected = IllegalStateException.class) public void testUninitializedDeviceSubClass() @@ -97,8 +92,7 @@ public class DeviceDescriptorTest } /** - * Tests uninitialized access to - * {@link DeviceDescriptor#bDeviceProtocol()} + * Tests uninitialized access to {@link DeviceDescriptor#bDeviceProtocol()} */ @Test(expected = IllegalStateException.class) public void testUninitializedDeviceProtocol() @@ -108,8 +102,7 @@ public class DeviceDescriptorTest } /** - * Tests uninitialized access to - * {@link DeviceDescriptor#bMaxPacketSize0()} + * Tests uninitialized access to {@link DeviceDescriptor#bMaxPacketSize0()} */ @Test(expected = IllegalStateException.class) public void testUninitializedMaxPacketSize0() @@ -119,8 +112,7 @@ public class DeviceDescriptorTest } /** - * Tests uninitialized access to - * {@link DeviceDescriptor#idVendor()} + * Tests uninitialized access to {@link DeviceDescriptor#idVendor()} */ @Test(expected = IllegalStateException.class) public void testUninitializedVendor() @@ -130,8 +122,7 @@ public class DeviceDescriptorTest } /** - * Tests uninitialized access to - * {@link DeviceDescriptor#idProduct()} + * Tests uninitialized access to {@link DeviceDescriptor#idProduct()} */ @Test(expected = IllegalStateException.class) public void testUninitializedProduct() @@ -141,8 +132,7 @@ public class DeviceDescriptorTest } /** - * Tests uninitialized access to - * {@link DeviceDescriptor#bcdDevice()} + * Tests uninitialized access to {@link DeviceDescriptor#bcdDevice()} */ @Test(expected = IllegalStateException.class) public void testUninitializedBcdDevice() @@ -152,8 +142,7 @@ public class DeviceDescriptorTest } /** - * Tests uninitialized access to - * {@link DeviceDescriptor#iManufacturer()} + * Tests uninitialized access to {@link DeviceDescriptor#iManufacturer()} */ @Test(expected = IllegalStateException.class) public void testUninitializedManufacturer() @@ -163,8 +152,7 @@ public class DeviceDescriptorTest } /** - * Tests uninitialized access to - * {@link DeviceDescriptor#iProduct()} + * Tests uninitialized access to {@link DeviceDescriptor#iProduct()} */ @Test(expected = IllegalStateException.class) public void testUninitializedIProduct() @@ -174,8 +162,7 @@ public class DeviceDescriptorTest } /** - * Tests uninitialized access to - * {@link DeviceDescriptor#iSerialNumber()} + * Tests uninitialized access to {@link DeviceDescriptor#iSerialNumber()} */ @Test(expected = IllegalStateException.class) public void testUninitializedSerialNumber() diff --git a/src/test/java/de/ailis/usb4java/libusb/EndpointDescriptorTest.java b/src/test/java/de/ailis/usb4java/libusb/EndpointDescriptorTest.java index f828754..9793b56 100644 --- a/src/test/java/de/ailis/usb4java/libusb/EndpointDescriptorTest.java +++ b/src/test/java/de/ailis/usb4java/libusb/EndpointDescriptorTest.java @@ -13,7 +13,7 @@ import org.junit.Test; /** * Tests the {@link EndpointDescriptor} class. - * + * * @author Klaus Reimer (k@ailis.de) */ public class EndpointDescriptorTest @@ -31,19 +31,18 @@ public class EndpointDescriptorTest LibUsb.init(null); this.descriptor = new EndpointDescriptor(); } - + /** * Tear down test. */ - @After + @After public void tearDown() { LibUsb.exit(null); } /** - * Tests uninitialized access to - * {@link EndpointDescriptor#bLength()} + * Tests uninitialized access to {@link EndpointDescriptor#bLength()} */ @Test(expected = IllegalStateException.class) public void testUninitializedLength() @@ -62,7 +61,7 @@ public class EndpointDescriptorTest assumeUsbTestsEnabled(); this.descriptor.bDescriptorType(); } - + /** * Tests uninitialized access to * {@link EndpointDescriptor#bEndpointAddress()} @@ -73,10 +72,9 @@ public class EndpointDescriptorTest assumeUsbTestsEnabled(); this.descriptor.bEndpointAddress(); } - + /** - * Tests uninitialized access to - * {@link EndpointDescriptor#bmAttributes()} + * Tests uninitialized access to {@link EndpointDescriptor#bmAttributes()} */ @Test(expected = IllegalStateException.class) public void testUninitializedAttributes() @@ -86,8 +84,7 @@ public class EndpointDescriptorTest } /** - * Tests uninitialized access to - * {@link EndpointDescriptor#wMaxPacketSize()} + * Tests uninitialized access to {@link EndpointDescriptor#wMaxPacketSize()} */ @Test(expected = IllegalStateException.class) public void testUninitializedMaxPacketSize() @@ -97,8 +94,7 @@ public class EndpointDescriptorTest } /** - * Tests uninitialized access to - * {@link EndpointDescriptor#bInterval()} + * Tests uninitialized access to {@link EndpointDescriptor#bInterval()} */ @Test(expected = IllegalStateException.class) public void testUninitializedInterval() @@ -106,10 +102,9 @@ public class EndpointDescriptorTest assumeUsbTestsEnabled(); this.descriptor.bInterval(); } - + /** - * Tests uninitialized access to - * {@link EndpointDescriptor#bRefresh()} + * Tests uninitialized access to {@link EndpointDescriptor#bRefresh()} */ @Test(expected = IllegalStateException.class) public void testUninitializedRefresh() @@ -117,10 +112,9 @@ public class EndpointDescriptorTest assumeUsbTestsEnabled(); this.descriptor.bRefresh(); } - + /** - * Tests uninitialized access to - * {@link EndpointDescriptor#bSynchAddress()} + * Tests uninitialized access to {@link EndpointDescriptor#bSynchAddress()} */ @Test(expected = IllegalStateException.class) public void testUninitializedSynchAddress() @@ -128,10 +122,9 @@ public class EndpointDescriptorTest assumeUsbTestsEnabled(); this.descriptor.bSynchAddress(); } - + /** - * Tests uninitialized access to - * {@link EndpointDescriptor#extra()} + * Tests uninitialized access to {@link EndpointDescriptor#extra()} */ @Test(expected = IllegalStateException.class) public void testUninitializedExtra() @@ -141,8 +134,7 @@ public class EndpointDescriptorTest } /** - * Tests uninitialized access to - * {@link EndpointDescriptor#extraLength()} + * Tests uninitialized access to {@link EndpointDescriptor#extraLength()} */ @Test(expected = IllegalStateException.class) public void testUninitializedExtraLength() diff --git a/src/test/java/de/ailis/usb4java/libusb/InterfaceDescriptorTest.java b/src/test/java/de/ailis/usb4java/libusb/InterfaceDescriptorTest.java index 5862c1b..ad08880 100644 --- a/src/test/java/de/ailis/usb4java/libusb/InterfaceDescriptorTest.java +++ b/src/test/java/de/ailis/usb4java/libusb/InterfaceDescriptorTest.java @@ -13,7 +13,7 @@ import org.junit.Test; /** * Tests the {@link InterfaceDescriptor} class. - * + * * @author Klaus Reimer (k@ailis.de) */ public class InterfaceDescriptorTest @@ -31,19 +31,18 @@ public class InterfaceDescriptorTest LibUsb.init(null); this.descriptor = new InterfaceDescriptor(); } - + /** * Tear down test. */ - @After + @After public void tearDown() { LibUsb.exit(null); } /** - * Tests uninitialized access to - * {@link InterfaceDescriptor#bLength()} + * Tests uninitialized access to {@link InterfaceDescriptor#bLength()} */ @Test(expected = IllegalStateException.class) public void testUninitializedLength() @@ -86,8 +85,7 @@ public class InterfaceDescriptorTest } /** - * Tests uninitialized access to - * {@link InterfaceDescriptor#bNumEndpoints()} + * Tests uninitialized access to {@link InterfaceDescriptor#bNumEndpoints()} */ @Test(expected = IllegalStateException.class) public void testUninitializedNumEndpoints() @@ -130,8 +128,7 @@ public class InterfaceDescriptorTest } /** - * Tests uninitialized access to - * {@link InterfaceDescriptor#iInterface()} + * Tests uninitialized access to {@link InterfaceDescriptor#iInterface()} */ @Test(expected = IllegalStateException.class) public void testUninitializedInterface() @@ -141,8 +138,7 @@ public class InterfaceDescriptorTest } /** - * Tests uninitialized access to - * {@link InterfaceDescriptor#endpoint()} + * Tests uninitialized access to {@link InterfaceDescriptor#endpoint()} */ @Test(expected = IllegalStateException.class) public void testUninitializedEndpoint() @@ -152,8 +148,7 @@ public class InterfaceDescriptorTest } /** - * Tests uninitialized access to - * {@link InterfaceDescriptor#extra()} + * Tests uninitialized access to {@link InterfaceDescriptor#extra()} */ @Test(expected = IllegalStateException.class) public void testUninitializedExtra() @@ -163,8 +158,7 @@ public class InterfaceDescriptorTest } /** - * Tests uninitialized access to - * {@link InterfaceDescriptor#extraLength()} + * Tests uninitialized access to {@link InterfaceDescriptor#extraLength()} */ @Test(expected = IllegalStateException.class) public void testUninitializedExtraLength() diff --git a/src/test/java/de/ailis/usb4java/libusb/InterfaceTest.java b/src/test/java/de/ailis/usb4java/libusb/InterfaceTest.java index 9fa5116..f84c265 100644 --- a/src/test/java/de/ailis/usb4java/libusb/InterfaceTest.java +++ b/src/test/java/de/ailis/usb4java/libusb/InterfaceTest.java @@ -13,7 +13,7 @@ import org.junit.Test; /** * Tests the {@link Interface} class. - * + * * @author Klaus Reimer (k@ailis.de) */ public class InterfaceTest @@ -31,19 +31,18 @@ public class InterfaceTest LibUsb.init(null); this.descriptor = new Interface(); } - + /** * Tear down test. */ - @After + @After public void tearDown() { LibUsb.exit(null); } /** - * Tests uninitialized access to - * {@link Interface#altsetting()} + * Tests uninitialized access to {@link Interface#altsetting()} */ @Test(expected = IllegalStateException.class) public void testUninitializedAltsetting() @@ -53,8 +52,7 @@ public class InterfaceTest } /** - * Tests uninitialized access to - * {@link Interface#numAltsetting()} + * Tests uninitialized access to {@link Interface#numAltsetting()} */ @Test(expected = IllegalStateException.class) public void testUninitializedDescriptorType() diff --git a/src/test/java/de/ailis/usb4java/libusb/LibUSBDeviceTest.java b/src/test/java/de/ailis/usb4java/libusb/LibUSBDeviceTest.java index 39c826f..155c6cb 100644 --- a/src/test/java/de/ailis/usb4java/libusb/LibUSBDeviceTest.java +++ b/src/test/java/de/ailis/usb4java/libusb/LibUSBDeviceTest.java @@ -19,10 +19,12 @@ import org.junit.After; import org.junit.Before; import org.junit.Test; +import de.ailis.usb4java.utils.BufferUtils; + /** * Tests the device-scope methods of the {@link LibUsb} class which need a open * USB context and a device to run the tests on. - * + * * @author Klaus Reimer (k@ailis.de) */ public class LibUSBDeviceTest @@ -34,16 +36,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. @@ -55,13 +57,14 @@ public class LibUSBDeviceTest LibUsb.init(this.context); try { - this.device = findTestDevice(); + this.device = this.findTestDevice(); if (this.device == null) + { throw new IllegalStateException("Need at least one USB device " - + - "with at least one endpoint to execute this test"); + + "with at least one endpoint to execute this test"); + } } - catch (Throwable e) + catch (final Throwable e) { this.device = null; } @@ -69,39 +72,46 @@ public class LibUSBDeviceTest /** * Finds a test device with at least one endpoint. - * + * * @return The test device or null if none. */ private Device findTestDevice() { - DeviceList list = new DeviceList(); - if (LibUsb.getDeviceList(this.context, list) <= 0) return null; + final DeviceList list = new DeviceList(); + if (LibUsb.getDeviceList(this.context, list) <= 0) + { + return null; + } try { - for (Device device: list) + for (final Device device : list) { - DeviceDescriptor descriptor = new DeviceDescriptor(); + final DeviceDescriptor descriptor = new DeviceDescriptor(); if (LibUsb.getDeviceDescriptor(device, descriptor) != 0) + { continue; + } this.vendorId = descriptor.idVendor(); this.productId = descriptor.idProduct(); - ConfigDescriptor config = new ConfigDescriptor(); + final ConfigDescriptor config = new ConfigDescriptor(); if (LibUsb.getActiveConfigDescriptor(device, config) < 0) + { return null; + } try { this.configValue = config.bConfigurationValue(); for (int j = 0; j < config.bNumInterfaces(); j++) { - Interface iface = config.iface()[j]; + final Interface iface = config.iface()[j]; for (int k = 0; k < iface.numAltsetting(); k++) { - InterfaceDescriptor ifaceDescriptor = - iface.altsetting()[k]; + final InterfaceDescriptor ifaceDescriptor = iface + .altsetting()[k]; if (ifaceDescriptor.bNumEndpoints() > 1) { - this.endpoint = ifaceDescriptor.endpoint()[0]. - bEndpointAddress(); + this.endpoint = ifaceDescriptor.endpoint()[0] + .bEndpointAddress(); return LibUsb.refDevice(device); } } @@ -126,8 +136,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 (this.device != null) + { + LibUsb.unrefDevice(this.device); + } + if (this.context != null) + { + LibUsb.exit(this.context); + } } /** @@ -153,21 +169,21 @@ public class LibUSBDeviceTest } /** - * Tests the {@link LibUsb#getPortNumbers(Device, byte[])} method. + * Tests the {@link LibUsb#getPortNumbers(Device, ByteBuffer)} method. */ @Test public void testGetPortNumbers() { assumeUsbTestsEnabled(); assumeNotNull(this.device); - byte[] path = new byte[8]; - int result = LibUsb.getPortNumbers(this.device, path); + final ByteBuffer path = BufferUtils.allocateByteBuffer(8); + final int result = LibUsb.getPortNumbers(this.device, path); assertTrue(result > 0); - assertTrue(result <= path.length); + assertTrue(result <= path.capacity()); } /** - * Tests the {@link LibUsb#getPortNumbers(Device, byte[])} method with + * Tests the {@link LibUsb#getPortNumbers(Device, ByteBuffer)} method with * 0-sized path buffer. */ @Test @@ -175,24 +191,24 @@ public class LibUSBDeviceTest { assumeUsbTestsEnabled(); assumeNotNull(this.device); - byte[] path = new byte[0]; - int result = LibUsb.getPortNumbers(this.device, path); + final ByteBuffer path = BufferUtils.allocateByteBuffer(0); + final int result = LibUsb.getPortNumbers(this.device, path); assertEquals(LibUsb.ERROR_OVERFLOW, result); } /** - * Tests the {@link LibUsb#getPortNumbers(Device, byte[])} method + * Tests the {@link LibUsb#getPortNumbers(Device, ByteBuffer)} method * without a device. */ @Test(expected = IllegalArgumentException.class) public void testGetPortNumbersWithoutDevice() { assumeUsbTestsEnabled(); - LibUsb.getPortNumbers(null, new byte[8]); + LibUsb.getPortNumbers(null, BufferUtils.allocateByteBuffer(8)); } /** - * Tests the {@link LibUsb#getPortNumbers(Device, byte[])} method + * Tests the {@link LibUsb#getPortNumbers(Device, ByteBuffer)} method * without a buffer. */ @Test(expected = IllegalArgumentException.class) @@ -203,14 +219,14 @@ public class LibUSBDeviceTest } /** - * Tests {@link LibUsb#getPortNumbers(Device, byte[])} method with + * Tests {@link LibUsb#getPortNumbers(Device, ByteBuffer)} method with * uninitialized device. */ @Test(expected = IllegalStateException.class) public void testGetPortNumbersWithUninitializedDevice() { assumeUsbTestsEnabled(); - LibUsb.getPortNumbers(new Device(), new byte[16]); + LibUsb.getPortNumbers(new Device(), BufferUtils.allocateByteBuffer(16)); } /** @@ -221,11 +237,11 @@ public class LibUSBDeviceTest { assumeUsbTestsEnabled(); assumeNotNull(this.device); - DeviceList list = new DeviceList(); + final DeviceList list = new DeviceList(); LibUsb.getDeviceList(this.context, list); try { - Device parent = LibUsb.getParent(this.device); + final Device parent = LibUsb.getParent(this.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 @@ -278,8 +294,9 @@ public class LibUSBDeviceTest { assumeUsbTestsEnabled(); assumeNotNull(this.device); - int speed = LibUsb.getDeviceSpeed(this.device); - assertTrue(speed >= LibUsb.SPEED_UNKNOWN && speed <= LibUsb.SPEED_SUPER); + final int speed = LibUsb.getDeviceSpeed(this.device); + assertTrue((speed >= LibUsb.SPEED_UNKNOWN) + && (speed <= LibUsb.SPEED_SUPER)); } /** @@ -293,7 +310,7 @@ public class LibUSBDeviceTest } /** - * Tests the {@link LibUsb#getMaxPacketSize(Device, int)} method. + * Tests the {@link LibUsb#getMaxPacketSize(Device, byte)} method. */ @Test public void testGetMaxPacketSizeWithInvalidEndpoint() @@ -301,11 +318,11 @@ public class LibUSBDeviceTest assumeUsbTestsEnabled(); assumeNotNull(this.device); assertEquals(LibUsb.ERROR_NOT_FOUND, - LibUsb.getMaxPacketSize(this.device, 0)); + LibUsb.getMaxPacketSize(this.device, (byte) 0)); } /** - * Tests the {@link LibUsb#getMaxPacketSize(Device, int)} method. + * Tests the {@link LibUsb#getMaxPacketSize(Device, byte)} method. */ @Test public void testGetMaxPacketSize() @@ -316,18 +333,18 @@ public class LibUSBDeviceTest } /** - * 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() @@ -335,11 +352,11 @@ public class LibUSBDeviceTest assumeUsbTestsEnabled(); assumeNotNull(this.device); assertEquals(LibUsb.ERROR_NOT_FOUND, - LibUsb.getMaxIsoPacketSize(this.device, 0)); + LibUsb.getMaxIsoPacketSize(this.device, (byte) 0)); } /** - * Tests the {@link LibUsb#getMaxIsoPacketSize(Device, int)} method. + * Tests the {@link LibUsb#getMaxIsoPacketSize(Device, byte)} method. */ @Test public void testGetMaxIsoPacketSize() @@ -350,14 +367,14 @@ public class LibUSBDeviceTest } /** - * 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); } /** @@ -369,7 +386,7 @@ public class LibUSBDeviceTest { assumeUsbTestsEnabled(); assumeNotNull(this.device); - Device device = LibUsb.refDevice(this.device); + final Device device = LibUsb.refDevice(this.device); try { assertEquals(this.device, device); @@ -412,9 +429,10 @@ public class LibUSBDeviceTest { assumeUsbTestsEnabled(); assumeNotNull(this.device); - DeviceHandle handle = new DeviceHandle(); - int result = LibUsb.open(this.device, handle); - assertTrue(result == LibUsb.SUCCESS || result == LibUsb.ERROR_ACCESS); + final DeviceHandle handle = new DeviceHandle(); + final int result = LibUsb.open(this.device, handle); + assertTrue((result == LibUsb.SUCCESS) + || (result == LibUsb.ERROR_ACCESS)); if (result == LibUsb.SUCCESS) { LibUsb.close(handle); @@ -424,7 +442,7 @@ public class LibUSBDeviceTest LibUsb.close(handle); fail("Double-close should throw IllegalStateException"); } - catch (IllegalStateException e) + catch (final IllegalStateException e) { // Expected behavior } @@ -439,7 +457,7 @@ public class LibUSBDeviceTest public void testOpenWithoutDevice() { assumeUsbTestsEnabled(); - DeviceHandle handle = new DeviceHandle(); + final DeviceHandle handle = new DeviceHandle(); LibUsb.open(null, handle); } @@ -465,7 +483,8 @@ public class LibUSBDeviceTest } /** - * Tests the {@link LibUsb#openDeviceWithVidPid(Context, int, int)} method. + * Tests the {@link LibUsb#openDeviceWithVidPid(Context, short, short)} + * method. * We can't test anything here because the device most likely can't be * opened anyway. We just make sure it does not crash. */ @@ -473,9 +492,12 @@ public class LibUSBDeviceTest public void testOpenDeviceWithVidPid() { assumeUsbTestsEnabled(); - DeviceHandle handle = LibUsb.openDeviceWithVidPid(this.context, + final DeviceHandle handle = LibUsb.openDeviceWithVidPid(this.context, this.vendorId, this.productId); - if (handle != null) LibUsb.close(handle); + if (handle != null) + { + LibUsb.close(handle); + } } /** @@ -497,7 +519,7 @@ public class LibUSBDeviceTest public void testGetConfigurationWithoutHandle() { assumeUsbTestsEnabled(); - LibUsb.getConfiguration(null, IntBuffer.allocate(1)); + LibUsb.getConfiguration(null, BufferUtils.allocateIntBuffer()); } /** @@ -557,14 +579,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); } /** @@ -636,7 +658,7 @@ public class LibUSBDeviceTest /** * Tests the {@link LibUsb#getDeviceDescriptor(Device, DeviceDescriptor)} * method. - * + * * Most descriptor fields can be anything because we are not testing a * specific device. We call each method anyway to make sure it is connected * to JNI and doesn't crash. @@ -646,7 +668,7 @@ public class LibUSBDeviceTest { assumeUsbTestsEnabled(); assumeNotNull(this.device); - DeviceDescriptor desc = new DeviceDescriptor(); + final DeviceDescriptor desc = new DeviceDescriptor(); LibUsb.getDeviceDescriptor(this.device, desc); desc.bcdDevice(); desc.bcdUSB(); @@ -654,7 +676,7 @@ public class LibUSBDeviceTest desc.bDeviceClass(); desc.bDeviceProtocol(); desc.bDeviceSubClass(); - assertEquals(desc.getData().limit(), desc.bLength()); + assertTrue(desc.bLength() > 0); desc.bMaxPacketSize0(); desc.bNumConfigurations(); } @@ -685,7 +707,7 @@ public class LibUSBDeviceTest /** * Validates the specified config descriptor. - * + * * @param desc * The config descriptor to validate. */ @@ -701,28 +723,30 @@ public class LibUSBDeviceTest assertEquals(desc.bNumInterfaces(), desc.iface().length); assertTrue(desc.wTotalLength() >= desc.bLength()); - for (Interface iface: desc.iface()) - validateInterface(iface); + for (final Interface iface : desc.iface()) + { + this.validateInterface(iface); + } } /** * Validates the specified interface. - * + * * @param iface * The interface to validate. */ private void validateInterface(final Interface iface) { assertEquals(iface.numAltsetting(), iface.altsetting().length); - for (InterfaceDescriptor desc: iface.altsetting()) + for (final InterfaceDescriptor desc : iface.altsetting()) { - validateInterfaceDescriptor(desc); + this.validateInterfaceDescriptor(desc); } } /** * Validates the specified interface descriptor. - * + * * @param desc * The interface descriptor to validate. */ @@ -739,15 +763,15 @@ public class LibUSBDeviceTest assertEquals(desc.extraLength(), desc.extra().limit()); desc.iInterface(); - for (EndpointDescriptor endDesc: desc.endpoint()) + for (final EndpointDescriptor endDesc : desc.endpoint()) { - validateEndpointDescriptor(endDesc); + this.validateEndpointDescriptor(endDesc); } } /** * Validates the specified endpoint desriptor. - * + * * @param desc * The endpoint descriptor to validate. */ @@ -774,11 +798,11 @@ public class LibUSBDeviceTest { assumeUsbTestsEnabled(); assumeNotNull(this.device); - ConfigDescriptor desc = new ConfigDescriptor(); + final ConfigDescriptor desc = new ConfigDescriptor(); LibUsb.getActiveConfigDescriptor(this.device, desc); try { - validateConfigDescriptor(desc); + this.validateConfigDescriptor(desc); } finally { @@ -788,42 +812,43 @@ 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(this.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); - ConfigDescriptor desc = new ConfigDescriptor(); - LibUsb.getConfigDescriptor(this.device, 0, desc); + final ConfigDescriptor desc = new ConfigDescriptor(); + LibUsb.getConfigDescriptor(this.device, (byte) 0, desc); try { - validateConfigDescriptor(desc); + this.validateConfigDescriptor(desc); } finally { @@ -833,31 +858,32 @@ 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(this.device, (byte) 0, null); } /** * Tests the - * {@link LibUsb#getConfigDescriptorByValue(Device, int, ConfigDescriptor)} + * {@link LibUsb#getConfigDescriptorByValue(Device, byte, ConfigDescriptor)} * method. */ @Test @@ -865,11 +891,11 @@ public class LibUSBDeviceTest { assumeUsbTestsEnabled(); assumeNotNull(this.device); - ConfigDescriptor desc = new ConfigDescriptor(); + final ConfigDescriptor desc = new ConfigDescriptor(); LibUsb.getConfigDescriptorByValue(this.device, this.configValue, desc); try { - validateConfigDescriptor(desc); + this.validateConfigDescriptor(desc); } finally { @@ -880,7 +906,7 @@ public class LibUSBDeviceTest LibUsb.freeConfigDescriptor(desc); fail("Double-free should throw IllegalStateException"); } - catch (IllegalStateException e) + catch (final IllegalStateException e) { // Expected behavior } @@ -891,7 +917,7 @@ public class LibUSBDeviceTest * Tests the {@link LibUsb#freeConfigDescriptor(ConfigDescriptor)} method * without a descriptor. */ - @Test(expected = IllegalArgumentException.class) + @Test public void testFreeConfigDescriptorWithoutDescriptor() { assumeUsbTestsEnabled(); @@ -900,215 +926,221 @@ 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, + BufferUtils.allocateByteBuffer(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, + BufferUtils.allocateByteBuffer(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, + BufferUtils.allocateByteBuffer(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, - ByteBuffer.allocate(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), - IntBuffer.allocate(1), 0); + LibUsb.bulkTransfer(null, (byte) 0, BufferUtils.allocateByteBuffer(0), + BufferUtils.allocateIntBuffer(), 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, - IntBuffer.allocate(1), 0); + LibUsb.bulkTransfer(new DeviceHandle(), (byte) 0, null, + BufferUtils.allocateIntBuffer(), 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), - IntBuffer.allocate(1), 0); + LibUsb.bulkTransfer(new DeviceHandle(), (byte) 0, + ByteBuffer.allocate(0), BufferUtils.allocateIntBuffer(), 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), - null, 0); + LibUsb.bulkTransfer(new DeviceHandle(), (byte) 0, + BufferUtils.allocateByteBuffer(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), - IntBuffer.allocate(1), 0); + LibUsb.interruptTransfer(null, (byte) 0, + BufferUtils.allocateByteBuffer(0), BufferUtils.allocateIntBuffer(), + 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, - IntBuffer.allocate(1), 0); + LibUsb.interruptTransfer(new DeviceHandle(), (byte) 0, null, + BufferUtils.allocateIntBuffer(), 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), - IntBuffer.allocate(1), 0); + LibUsb.interruptTransfer(new DeviceHandle(), (byte) 0, + ByteBuffer.allocate(0), BufferUtils.allocateIntBuffer(), 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), - null, 0); + LibUsb.interruptTransfer(new DeviceHandle(), (byte) 0, + BufferUtils.allocateByteBuffer(0), null, 0); } /** @@ -1119,16 +1151,16 @@ public class LibUSBDeviceTest public void testGetAndFreeDeviceList() { assumeUsbTestsEnabled(); - DeviceList list = new DeviceList(); + final DeviceList list = new DeviceList(); assertTrue(LibUsb.getDeviceList(this.context, list) >= 0); LibUsb.freeDeviceList(list, true); - + try { LibUsb.freeDeviceList(list, true); fail("Double-free should throw IllegalStateException"); } - catch (IllegalStateException e) + catch (final IllegalStateException e) { // Expected behavior } @@ -1143,19 +1175,19 @@ public class LibUSBDeviceTest public void testGetAndFreeDeviceListWithDefaultContext() { assumeUsbTestsEnabled(); - DeviceList list = new DeviceList(); + final DeviceList list = new DeviceList(); assertEquals(0, LibUsb.init(null)); try { assertTrue(LibUsb.getDeviceList(null, list) >= 0); LibUsb.freeDeviceList(list, true); - + try { LibUsb.freeDeviceList(list, true); fail("Double-free should throw IllegalStateException"); } - catch (IllegalStateException e) + catch (final IllegalStateException e) { // Expected behavior } diff --git a/src/test/java/de/ailis/usb4java/libusb/LibUSBGlobalTest.java b/src/test/java/de/ailis/usb4java/libusb/LibUSBGlobalTest.java index 1236b9c..67e0df2 100644 --- a/src/test/java/de/ailis/usb4java/libusb/LibUSBGlobalTest.java +++ b/src/test/java/de/ailis/usb4java/libusb/LibUSBGlobalTest.java @@ -16,9 +16,9 @@ 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) */ public class LibUSBGlobalTest @@ -37,7 +37,7 @@ public class LibUSBGlobalTest { LibUsb.init(this.context); } - catch (Throwable e) + catch (final Throwable e) { this.context = null; } @@ -49,7 +49,10 @@ public class LibUSBGlobalTest @After public void tearDown() { - if (this.context != null) LibUsb.exit(this.context); + if (this.context != null) + { + LibUsb.exit(this.context); + } } /** @@ -80,7 +83,7 @@ public class LibUSBGlobalTest result > 0); assertEquals(result, list.getSize()); int i = 0; - for (Device device: list) + for (final Device device : list) { assertNotNull(device); assertEquals(device, list.get(i)); @@ -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..64e39a7 100644 --- a/src/test/java/de/ailis/usb4java/libusb/LibUSBTest.java +++ b/src/test/java/de/ailis/usb4java/libusb/LibUSBTest.java @@ -16,14 +16,16 @@ 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. - * + * * @author Klaus Reimer (k@ailis.de) */ public class LibUSBTest @@ -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.")); } @@ -192,7 +194,7 @@ public class LibUSBTest LibUsb.exit(null); fail("Double-exit should throw IllegalStateException"); } - catch (IllegalStateException e) + catch (final IllegalStateException e) { // Expected behavior } @@ -206,7 +208,7 @@ public class LibUSBTest public void testInitDeinitWithContext() { assumeUsbTestsEnabled(); - Context context = new Context(); + final Context context = new Context(); assertEquals(LibUsb.SUCCESS, LibUsb.init(context)); LibUsb.exit(context); @@ -215,7 +217,7 @@ public class LibUSBTest LibUsb.exit(context); fail("Double-exit should throw IllegalStateException"); } - catch (IllegalStateException e) + catch (final IllegalStateException e) { // Expected behavior } @@ -271,7 +273,7 @@ public class LibUSBTest * Tests {@link LibUsb#freeDeviceList(DeviceList, boolean)} method without * list. */ - @Test(expected = IllegalArgumentException.class) + @Test public void testFreeDeviceListWithoutList() { assumeUsbTestsEnabled(); @@ -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); } /** @@ -438,7 +440,8 @@ public class LibUSBTest public void testGetConfigurationWithUninitializedHandle() { assumeUsbTestsEnabled(); - LibUsb.getConfiguration(new DeviceHandle(), IntBuffer.allocate(1)); + LibUsb.getConfiguration(new DeviceHandle(), + BufferUtils.allocateIntBuffer()); } /** @@ -486,14 +489,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 +578,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 +603,27 @@ 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()); } @@ -634,6 +638,17 @@ public class LibUSBTest LibUsb.freeConfigDescriptor(new ConfigDescriptor()); } + /** + * Tests the {@link LibUsb#freeConfigDescriptor(ConfigDescriptor)} method + * with null parameter. Must do nothing. + */ + @Test + public void testFreeConfigDescriptorWithNull() + { + assumeUsbTestsEnabled(); + LibUsb.freeConfigDescriptor(null); + } + /** * Tests the * {@link LibUsb#getSsEndpointCompanionDescriptor(Context, EndpointDescriptor, SsEndpointCompanionDescriptor)} @@ -643,7 +658,7 @@ public class LibUSBTest public void testGetSsEndpointCompanionDescriptorWithUninitializedEndpoint() { assumeUsbTestsEnabled(); - LibUsb.getSsEndpointCompanionDescriptor(null, new EndpointDescriptor(), + LibUsb.getSsEndpointCompanionDescriptor(null, new EndpointDescriptor(), new SsEndpointCompanionDescriptor()); } @@ -668,7 +683,8 @@ public class LibUSBTest public void testFreeSsEndpointCompanionDescriptorWithUninitializedDescriptor() { assumeUsbTestsEnabled(); - LibUsb.freeSsEndpointCompanionDescriptor(new SsEndpointCompanionDescriptor()); + LibUsb + .freeSsEndpointCompanionDescriptor(new SsEndpointCompanionDescriptor()); } /** @@ -682,10 +698,9 @@ public class LibUSBTest assumeUsbTestsEnabled(); LibUsb.freeSsEndpointCompanionDescriptor(null); } - + /** - * Tests the - * {@link LibUsb#getBosDescriptor(DeviceHandle, BosDescriptor)} + * Tests the {@link LibUsb#getBosDescriptor(DeviceHandle, BosDescriptor)} * method with uninitialized handled. */ @Test(expected = IllegalStateException.class) @@ -696,8 +711,7 @@ public class LibUSBTest } /** - * Tests the - * {@link LibUsb#getBosDescriptor(DeviceHandle, BosDescriptor)} + * Tests the {@link LibUsb#getBosDescriptor(DeviceHandle, BosDescriptor)} * method without handle. */ @Test(expected = IllegalArgumentException.class) @@ -708,9 +722,8 @@ public class LibUSBTest } /** - * Tests the - * {@link LibUsb#freeBosDescriptor(BosDescriptor)} - * method with uninitialized descriptor. + * Tests the {@link LibUsb#freeBosDescriptor(BosDescriptor)} method with + * uninitialized descriptor. */ @Test(expected = IllegalStateException.class) public void testFreeBosDescriptorWithUninitializedDescriptor() @@ -720,9 +733,8 @@ public class LibUSBTest } /** - * Tests the - * {@link LibUsb#freeBosDescriptor(BosDescriptor)} - * method with null parameter. Must do nothing. + * Tests the {@link LibUsb#freeBosDescriptor(BosDescriptor)} method with + * null parameter. Must do nothing. */ @Test public void testFreeBosDescriptorWithNull() @@ -730,26 +742,23 @@ public class LibUSBTest assumeUsbTestsEnabled(); LibUsb.freeBosDescriptor(null); } - + /** * Tests the - * {@link LibUsb#getUsb20ExtensionDescriptor(Context, - * BosDevCapabilityDescriptor, Usb20ExtensionDescriptor)} + * {@link LibUsb#getUsb20ExtensionDescriptor(Context, BosDevCapabilityDescriptor, Usb20ExtensionDescriptor)} * method with uninitialized device capability descriptor. */ @Test(expected = IllegalStateException.class) public void testGetUsb20ExtensionDescriptorWithUninitializedEndpoint() { assumeUsbTestsEnabled(); - LibUsb.getUsb20ExtensionDescriptor(null, - new BosDevCapabilityDescriptor(), - new Usb20ExtensionDescriptor()); + LibUsb.getUsb20ExtensionDescriptor(null, + new BosDevCapabilityDescriptor(), new Usb20ExtensionDescriptor()); } /** * Tests the - * {@link LibUsb#getUsb20ExtensionDescriptor(Context, - * BosDevCapabilityDescriptor, Usb20ExtensionDescriptor)} + * {@link LibUsb#getUsb20ExtensionDescriptor(Context, BosDevCapabilityDescriptor, Usb20ExtensionDescriptor)} * method without descriptors. */ @Test(expected = IllegalArgumentException.class) @@ -782,26 +791,24 @@ public class LibUSBTest assumeUsbTestsEnabled(); LibUsb.freeUsb20ExtensionDescriptor(null); } - + /** * Tests the - * {@link LibUsb#getSsUsbDeviceCapabilityDescriptor(Context, - * BosDevCapabilityDescriptor, SsUsbDeviceCapabilityDescriptor)} + * {@link LibUsb#getSsUsbDeviceCapabilityDescriptor(Context, BosDevCapabilityDescriptor, SsUsbDeviceCapabilityDescriptor)} * method with uninitialized device capability descriptor. */ @Test(expected = IllegalStateException.class) public void testGetSsUsbDeviceCapabilityDescriptorWithUninitializedEndpoint() { assumeUsbTestsEnabled(); - LibUsb.getSsUsbDeviceCapabilityDescriptor(null, - new BosDevCapabilityDescriptor(), + LibUsb.getSsUsbDeviceCapabilityDescriptor(null, + new BosDevCapabilityDescriptor(), new SsUsbDeviceCapabilityDescriptor()); } /** * Tests the - * {@link LibUsb#getSsUsbDeviceCapabilityDescriptor(Context, - * BosDevCapabilityDescriptor, SsUsbDeviceCapabilityDescriptor)} + * {@link LibUsb#getSsUsbDeviceCapabilityDescriptor(Context, BosDevCapabilityDescriptor, SsUsbDeviceCapabilityDescriptor)} * method without descriptors. */ @Test(expected = IllegalArgumentException.class) @@ -820,7 +827,8 @@ public class LibUSBTest public void testFreeSsUsbDeviceCapabilityDescriptorWithUninitializedDescriptor() { assumeUsbTestsEnabled(); - LibUsb.freeSsUsbDeviceCapabilityDescriptor(new SsUsbDeviceCapabilityDescriptor()); + LibUsb + .freeSsUsbDeviceCapabilityDescriptor(new SsUsbDeviceCapabilityDescriptor()); } /** @@ -834,26 +842,23 @@ public class LibUSBTest assumeUsbTestsEnabled(); LibUsb.freeSsUsbDeviceCapabilityDescriptor(null); } - + /** * Tests the - * {@link LibUsb#getContainerIdDescriptor(Context, - * BosDevCapabilityDescriptor, ContainerIdDescriptor)} + * {@link LibUsb#getContainerIdDescriptor(Context, BosDevCapabilityDescriptor, ContainerIdDescriptor)} * method with uninitialized device capability descriptor. */ @Test(expected = IllegalStateException.class) public void testGetContainerIdDescriptorWithUninitializedEndpoint() { assumeUsbTestsEnabled(); - LibUsb.getContainerIdDescriptor(null, - new BosDevCapabilityDescriptor(), + LibUsb.getContainerIdDescriptor(null, new BosDevCapabilityDescriptor(), new ContainerIdDescriptor()); } /** * Tests the - * {@link LibUsb#getContainerIdDescriptor(Context, - * BosDevCapabilityDescriptor, ContainerIdDescriptor)} + * {@link LibUsb#getContainerIdDescriptor(Context, BosDevCapabilityDescriptor, ContainerIdDescriptor)} * method without descriptors. */ @Test(expected = IllegalArgumentException.class) @@ -864,8 +869,7 @@ public class LibUSBTest } /** - * Tests the - * {@link LibUsb#freeContainerIdDescriptor(ContainerIdDescriptor)} + * Tests the {@link LibUsb#freeContainerIdDescriptor(ContainerIdDescriptor)} * method with uninitialized descriptor. */ @Test(expected = IllegalStateException.class) @@ -876,8 +880,7 @@ public class LibUSBTest } /** - * Tests the - * {@link LibUsb#freeContainerIdDescriptor(ContainerIdDescriptor)} + * Tests the {@link LibUsb#freeContainerIdDescriptor(ContainerIdDescriptor)} * method with null parameter. Must do nothing. */ @Test @@ -889,67 +892,67 @@ public class LibUSBTest /** * Tests the - * {@link LibUsb#getDescriptor(DeviceHandle, int, int, ByteBuffer)} method + * {@link LibUsb#getDescriptor(DeviceHandle, byte, byte, ByteBuffer)} method * 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, - ByteBuffer.allocateDirect(1), 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, - ByteBuffer.allocateDirect(1), IntBuffer.allocate(1), 0); + LibUsb.bulkTransfer(new DeviceHandle(), (byte) 0, + ByteBuffer.allocateDirect(1), BufferUtils.allocateIntBuffer(), 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, - ByteBuffer.allocateDirect(1), IntBuffer.allocate(1), 0); + LibUsb.interruptTransfer(new DeviceHandle(), (byte) 0, + ByteBuffer.allocateDirect(1), BufferUtils.allocateIntBuffer(), 0); } /** @@ -964,7 +967,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 +975,7 @@ public class LibUSBTest { assumeUsbTestsEnabled(); final Context context = new Context(); - LibUsb.openDeviceWithVidPid(context, 0, 0); + LibUsb.openDeviceWithVidPid(context, (short) 0, (short) 0); } /** @@ -1080,7 +1083,8 @@ public class LibUSBTest { assumeUsbTestsEnabled(); final Context context = new Context(); - LibUsb.handleEventsTimeoutCompleted(context, 53, IntBuffer.allocate(1)); + LibUsb.handleEventsTimeoutCompleted(context, 53, + BufferUtils.allocateIntBuffer()); } /** @@ -1116,7 +1120,7 @@ public class LibUSBTest { assumeUsbTestsEnabled(); final Context context = new Context(); - LibUsb.handleEventsCompleted(context, IntBuffer.allocate(1)); + LibUsb.handleEventsCompleted(context, BufferUtils.allocateIntBuffer()); } /** @@ -1144,7 +1148,7 @@ public class LibUSBTest } /** - * Tests {@link LibUsb#getNextTimeout(Context, IntBuffer)} with + * Tests {@link LibUsb#getNextTimeout(Context, LongBuffer)} with * uninitialized USB context. */ @Test(expected = IllegalStateException.class) @@ -1152,31 +1156,31 @@ public class LibUSBTest { assumeUsbTestsEnabled(); final Context context = new Context(); - LibUsb.getNextTimeout(context, IntBuffer.allocate(1)); + LibUsb.getNextTimeout(context, BufferUtils.allocateLongBuffer()); } /** - * Tests {@link LibUsb#setPollfdNotifiers(Context)} with uninitialized USB - * context. + * Tests {@link LibUsb#setPollfdNotifiersNative(Context, long)} + * with uninitialized USB context. */ @Test(expected = IllegalStateException.class) public void testSetPollfdNotifiersWithUninitializedContext() { assumeUsbTestsEnabled(); final Context context = new Context(); - LibUsb.setPollfdNotifiers(context); + LibUsb.setPollfdNotifiersNative(context, context.getPointer()); } /** - * Tests {@link LibUsb#unsetPollfdNotifiers(Context)} with uninitialized USB - * context. + * Tests {@link LibUsb#unsetPollfdNotifiersNative(Context)} with + * uninitialized USB context. */ @Test(expected = IllegalStateException.class) public void testUnsetPollfdNotifiersWithUninitializedContext() { assumeUsbTestsEnabled(); final Context context = new Context(); - LibUsb.unsetPollfdNotifiers(context); + LibUsb.unsetPollfdNotifiersNative(context); } /** @@ -1188,13 +1192,13 @@ public class LibUSBTest public void testPollFdNotifiers() { assumeUsbTestsEnabled(); - PollfdListenerMock listener = new PollfdListenerMock(); - Context context = new Context(); + final PollfdListenerMock listener = new PollfdListenerMock(); + final Context context = new Context(); LibUsb.init(context); LibUsb.setPollfdNotifiers(context, listener, "test"); FileDescriptor fd = new FileDescriptor(); - LibUsb.triggerPollfdAdded(fd, 53); + LibUsb.triggerPollfdAdded(fd, 53, context.getPointer()); assertEquals(53, listener.addedEvents); assertSame(fd, listener.addedFd); assertSame("test", listener.addedUserData); @@ -1204,7 +1208,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 +1219,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 +1229,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/SsEndpointCompanionDescriptorTest.java b/src/test/java/de/ailis/usb4java/libusb/SsEndpointCompanionDescriptorTest.java index bbdc84c..aa2cff5 100644 --- a/src/test/java/de/ailis/usb4java/libusb/SsEndpointCompanionDescriptorTest.java +++ b/src/test/java/de/ailis/usb4java/libusb/SsEndpointCompanionDescriptorTest.java @@ -13,7 +13,7 @@ import org.junit.Test; /** * Tests the {@link SsEndpointCompanionDescriptor} class. - * + * * @author Klaus Reimer (k@ailis.de) */ public class SsEndpointCompanionDescriptorTest @@ -31,11 +31,11 @@ public class SsEndpointCompanionDescriptorTest LibUsb.init(null); this.descriptor = new SsEndpointCompanionDescriptor(); } - + /** * Tear down test. */ - @After + @After public void tearDown() { LibUsb.exit(null); diff --git a/src/test/java/de/ailis/usb4java/libusb/SsUsbDeviceCapabilityDescriptorTest.java b/src/test/java/de/ailis/usb4java/libusb/SsUsbDeviceCapabilityDescriptorTest.java index 7638e3b..ab8b10f 100644 --- a/src/test/java/de/ailis/usb4java/libusb/SsUsbDeviceCapabilityDescriptorTest.java +++ b/src/test/java/de/ailis/usb4java/libusb/SsUsbDeviceCapabilityDescriptorTest.java @@ -13,7 +13,7 @@ import org.junit.Test; /** * Tests the {@link SsUsbDeviceCapabilityDescriptor} class. - * + * * @author Klaus Reimer (k@ailis.de) */ public class SsUsbDeviceCapabilityDescriptorTest @@ -31,11 +31,11 @@ public class SsUsbDeviceCapabilityDescriptorTest LibUsb.init(null); this.descriptor = new SsUsbDeviceCapabilityDescriptor(); } - + /** * Tear down test. */ - @After + @After public void tearDown() { LibUsb.exit(null); diff --git a/src/test/java/de/ailis/usb4java/libusb/TransferTest.java b/src/test/java/de/ailis/usb4java/libusb/TransferTest.java index 5bf6bde..e01b5a1 100644 --- a/src/test/java/de/ailis/usb4java/libusb/TransferTest.java +++ b/src/test/java/de/ailis/usb4java/libusb/TransferTest.java @@ -21,7 +21,7 @@ import org.junit.Test; /** * Tests the {@link Transfer} class. - * + * * @author Klaus Reimer (k@ailis.de) */ public class TransferTest @@ -40,7 +40,7 @@ public class TransferTest { LibUsb.init(this.context); } - catch (Throwable e) + catch (final Throwable e) { this.context = null; } @@ -52,7 +52,10 @@ public class TransferTest @After public void tearDown() { - if (this.context != null) LibUsb.exit(this.context); + if (this.context != null) + { + LibUsb.exit(this.context); + } } /** @@ -62,7 +65,7 @@ public class TransferTest public void testAllocAndFree() { assumeUsbTestsEnabled(); - Transfer transfer = LibUsb.allocTransfer(0); + final Transfer transfer = LibUsb.allocTransfer(0); assertNotNull(transfer); LibUsb.freeTransfer(transfer); @@ -71,7 +74,7 @@ public class TransferTest LibUsb.freeTransfer(transfer); fail("Double-free should throw IllegalStateException"); } - catch (IllegalStateException e) + catch (final IllegalStateException e) { // Expected behavior } @@ -79,22 +82,22 @@ public class TransferTest /** * Sets the device handle pointer via reflection. - * + * * @param handle * The device handle pointer. * @param pointer * The pointer to set. */ - private void setPointer(DeviceHandle handle, long pointer) + private void setPointer(final DeviceHandle handle, final long pointer) { try { - Field field = - DeviceHandle.class.getDeclaredField("deviceHandlePointer"); + final Field field = DeviceHandle.class + .getDeclaredField("deviceHandlePointer"); field.setAccessible(true); field.set(handle, pointer); } - catch (Exception e) + catch (final Exception e) { throw new RuntimeException(e.toString(), e); } @@ -108,70 +111,70 @@ public class TransferTest public void testDevHandle() { assumeUsbTestsEnabled(); - Transfer transfer = LibUsb.allocTransfer(0); - DeviceHandle handle = new DeviceHandle(); - setPointer(handle, 1); - DeviceHandle handle2 = new DeviceHandle(); - setPointer(handle2, 2); - assertNull(transfer.getDevHandle()); + final Transfer transfer = LibUsb.allocTransfer(0); + final DeviceHandle handle = new DeviceHandle(); + this.setPointer(handle, 1); + final DeviceHandle handle2 = new DeviceHandle(); + this.setPointer(handle2, 2); + 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 public void testFlags() { assumeUsbTestsEnabled(); - Transfer transfer = LibUsb.allocTransfer(0); - assertEquals(0, transfer.getFlags()); - transfer.setFlags(1); - assertEquals(1, transfer.getFlags()); - transfer.setFlags(0); - assertEquals(0, transfer.getFlags()); + final Transfer transfer = LibUsb.allocTransfer(0); + 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 public void testEndpoint() { assumeUsbTestsEnabled(); - Transfer transfer = LibUsb.allocTransfer(0); - assertEquals(0, transfer.getEndpoint()); - transfer.setEndpoint(1); - assertEquals(1, transfer.getEndpoint()); - transfer.setEndpoint(0); - assertEquals(0, transfer.getEndpoint()); + final Transfer transfer = LibUsb.allocTransfer(0); + 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 public void testType() { assumeUsbTestsEnabled(); - Transfer transfer = LibUsb.allocTransfer(0); - assertEquals(0, transfer.getType()); - transfer.setType(1); - assertEquals(1, transfer.getType()); - transfer.setType(0); - assertEquals(0, transfer.getType()); + final Transfer transfer = LibUsb.allocTransfer(0); + assertEquals(0, transfer.type()); + transfer.setType((byte) 1); + assertEquals(1, transfer.type()); + transfer.setType((byte) 0); + assertEquals(0, transfer.type()); LibUsb.freeTransfer(transfer); } @@ -183,12 +186,12 @@ public class TransferTest public void testTimeout() { assumeUsbTestsEnabled(); - Transfer transfer = LibUsb.allocTransfer(0); - assertEquals(0, transfer.getTimeout()); + final Transfer transfer = LibUsb.allocTransfer(0); + 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); } @@ -199,8 +202,8 @@ public class TransferTest public void testGetStatus() { assumeUsbTestsEnabled(); - Transfer transfer = LibUsb.allocTransfer(0); - assertEquals(0, transfer.getStatus()); + final Transfer transfer = LibUsb.allocTransfer(0); + assertEquals(0, transfer.status()); LibUsb.freeTransfer(transfer); } } diff --git a/src/test/java/de/ailis/usb4java/libusb/Usb20ExtensionDescriptorTest.java b/src/test/java/de/ailis/usb4java/libusb/Usb20ExtensionDescriptorTest.java index 5366863..716ca27 100644 --- a/src/test/java/de/ailis/usb4java/libusb/Usb20ExtensionDescriptorTest.java +++ b/src/test/java/de/ailis/usb4java/libusb/Usb20ExtensionDescriptorTest.java @@ -13,7 +13,7 @@ import org.junit.Test; /** * Tests the {@link Usb20ExtensionDescriptor} class. - * + * * @author Klaus Reimer (k@ailis.de) */ public class Usb20ExtensionDescriptorTest @@ -31,19 +31,18 @@ public class Usb20ExtensionDescriptorTest LibUsb.init(null); this.descriptor = new Usb20ExtensionDescriptor(); } - + /** * Tear down test. */ - @After + @After public void tearDown() { LibUsb.exit(null); } /** - * Tests uninitialized access to - * {@link Usb20ExtensionDescriptor#bLength()} + * Tests uninitialized access to {@link Usb20ExtensionDescriptor#bLength()} */ @Test(expected = IllegalStateException.class) public void testUninitializedLength() diff --git a/src/test/java/de/ailis/usb4java/libusb/VersionTest.java b/src/test/java/de/ailis/usb4java/libusb/VersionTest.java index 3ec5659..53d8d8e 100644 --- a/src/test/java/de/ailis/usb4java/libusb/VersionTest.java +++ b/src/test/java/de/ailis/usb4java/libusb/VersionTest.java @@ -13,7 +13,7 @@ import org.junit.Test; /** * Tests the {@link Version} class. - * + * * @author Klaus Reimer (k@ailis.de) */ public class VersionTest @@ -31,19 +31,18 @@ public class VersionTest LibUsb.init(null); this.version = new Version(); } - + /** * Tear down test. */ - @After + @After public void tearDown() { LibUsb.exit(null); } /** - * Tests uninitialized access to - * {@link Version#major()} + * Tests uninitialized access to {@link Version#major()} */ @Test(expected = IllegalStateException.class) public void testUninitializedMajor() @@ -53,8 +52,7 @@ public class VersionTest } /** - * Tests uninitialized access to - * {@link Version#minor()} + * Tests uninitialized access to {@link Version#minor()} */ @Test(expected = IllegalStateException.class) public void testUninitializedMinor() @@ -64,8 +62,7 @@ public class VersionTest } /** - * Tests uninitialized access to - * {@link Version#micro()} + * Tests uninitialized access to {@link Version#micro()} */ @Test(expected = IllegalStateException.class) public void testUninitializedMicro() @@ -75,8 +72,7 @@ public class VersionTest } /** - * Tests uninitialized access to - * {@link Version#rc()} + * Tests uninitialized access to {@link Version#rc()} */ @Test(expected = IllegalStateException.class) public void testUninitializedRc() 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. *