From 321b1c9e20eb5bf31934a3e64133878b80142c65 Mon Sep 17 00:00:00 2001 From: Klaus Reimer Date: Fri, 21 Jan 2011 21:59:55 +0100 Subject: [PATCH] First commit. --- .hgignore | 5 + src/main/c/AUTHORS | 1 + src/main/c/COPYING | 165 ++++++++ src/main/c/ChangeLog | 4 + src/main/c/Makefile.am | 2 + src/main/c/Makefile.scm | 36 ++ src/main/c/NEWS | 1 + src/main/c/README | 1 + src/main/c/acinclude.m4 | 12 + src/main/c/configure.ac | 16 + src/main/c/src/Makefile.am | 12 + src/main/c/src/USB.c | 198 ++++++++++ src/main/c/src/USBBus.c | 136 +++++++ src/main/c/src/USBBus.h | 10 + src/main/c/src/USBConfigDescriptor.c | 195 ++++++++++ src/main/c/src/USBConfigDescriptor.h | 10 + src/main/c/src/USBDevHandle.c | 56 +++ src/main/c/src/USBDevHandle.h | 10 + src/main/c/src/USBDevice.c | 219 +++++++++++ src/main/c/src/USBDevice.h | 10 + src/main/c/src/USBDeviceDescriptor.c | 243 ++++++++++++ src/main/c/src/USBDeviceDescriptor.h | 10 + src/main/java/Test.java | 168 +++++++++ .../de/ailis/usb4java/EventListenerList.java | 68 ++++ .../UsbConfigurationDescriptorImpl.java | 125 +++++++ .../ailis/usb4java/UsbConfigurationImpl.java | 137 +++++++ .../java/de/ailis/usb4java/UsbDeviceImpl.java | 351 ++++++++++++++++++ .../java/de/ailis/usb4java/UsbHubImpl.java | 98 +++++ .../usb4java/UsbInterfaceDescriptorImpl.java | 135 +++++++ .../de/ailis/usb4java/UsbInterfaceImpl.java | 250 +++++++++++++ .../de/ailis/usb4java/UsbServicesImpl.java | 271 ++++++++++++++ .../usb4java/UsbServicesListenerList.java | 22 ++ .../de/ailis/usb4java/VirtualRootUsbHub.java | 18 + src/main/java/de/ailis/usb4java/jni/USB.java | 195 ++++++++++ .../java/de/ailis/usb4java/jni/USBBus.java | 96 +++++ .../usb4java/jni/USBConfigDescriptor.java | 54 +++ .../de/ailis/usb4java/jni/USBDevHandle.java | 32 ++ .../java/de/ailis/usb4java/jni/USBDevice.java | 124 +++++++ .../usb4java/jni/USBDeviceDescriptor.java | 60 +++ .../usb4java/jni/USBEndpointDescriptor.java | 52 +++ .../de/ailis/usb4java/jni/USBInterface.java | 36 ++ .../usb4java/jni/USBInterfaceDescriptor.java | 56 +++ src/main/resources/javax.usb.properties | 165 ++++++++ src/test/comparison/Makefile | 5 + src/test/comparison/dump.c | 212 +++++++++++ src/test/java/de/ailis/usb4java/Dump.java | 243 ++++++++++++ 46 files changed, 4325 insertions(+) create mode 100644 .hgignore create mode 100644 src/main/c/AUTHORS create mode 100644 src/main/c/COPYING create mode 100644 src/main/c/ChangeLog create mode 100644 src/main/c/Makefile.am create mode 100644 src/main/c/Makefile.scm create mode 100644 src/main/c/NEWS create mode 100644 src/main/c/README create mode 100644 src/main/c/acinclude.m4 create mode 100644 src/main/c/configure.ac create mode 100644 src/main/c/src/Makefile.am create mode 100644 src/main/c/src/USB.c create mode 100644 src/main/c/src/USBBus.c create mode 100644 src/main/c/src/USBBus.h create mode 100644 src/main/c/src/USBConfigDescriptor.c create mode 100644 src/main/c/src/USBConfigDescriptor.h create mode 100644 src/main/c/src/USBDevHandle.c create mode 100644 src/main/c/src/USBDevHandle.h create mode 100644 src/main/c/src/USBDevice.c create mode 100644 src/main/c/src/USBDevice.h create mode 100644 src/main/c/src/USBDeviceDescriptor.c create mode 100644 src/main/c/src/USBDeviceDescriptor.h create mode 100644 src/main/java/Test.java create mode 100644 src/main/java/de/ailis/usb4java/EventListenerList.java create mode 100644 src/main/java/de/ailis/usb4java/UsbConfigurationDescriptorImpl.java create mode 100644 src/main/java/de/ailis/usb4java/UsbConfigurationImpl.java create mode 100644 src/main/java/de/ailis/usb4java/UsbDeviceImpl.java create mode 100644 src/main/java/de/ailis/usb4java/UsbHubImpl.java create mode 100644 src/main/java/de/ailis/usb4java/UsbInterfaceDescriptorImpl.java create mode 100644 src/main/java/de/ailis/usb4java/UsbInterfaceImpl.java create mode 100644 src/main/java/de/ailis/usb4java/UsbServicesImpl.java create mode 100644 src/main/java/de/ailis/usb4java/UsbServicesListenerList.java create mode 100644 src/main/java/de/ailis/usb4java/VirtualRootUsbHub.java create mode 100644 src/main/java/de/ailis/usb4java/jni/USB.java create mode 100644 src/main/java/de/ailis/usb4java/jni/USBBus.java create mode 100644 src/main/java/de/ailis/usb4java/jni/USBConfigDescriptor.java create mode 100644 src/main/java/de/ailis/usb4java/jni/USBDevHandle.java create mode 100644 src/main/java/de/ailis/usb4java/jni/USBDevice.java create mode 100644 src/main/java/de/ailis/usb4java/jni/USBDeviceDescriptor.java create mode 100644 src/main/java/de/ailis/usb4java/jni/USBEndpointDescriptor.java create mode 100644 src/main/java/de/ailis/usb4java/jni/USBInterface.java create mode 100644 src/main/java/de/ailis/usb4java/jni/USBInterfaceDescriptor.java create mode 100644 src/main/resources/javax.usb.properties create mode 100644 src/test/comparison/Makefile create mode 100644 src/test/comparison/dump.c create mode 100644 src/test/java/de/ailis/usb4java/Dump.java diff --git a/.hgignore b/.hgignore new file mode 100644 index 0000000..63a965c --- /dev/null +++ b/.hgignore @@ -0,0 +1,5 @@ +syntax: glob +target +.settings +.classpath +.project diff --git a/src/main/c/AUTHORS b/src/main/c/AUTHORS new file mode 100644 index 0000000..1f18bbf --- /dev/null +++ b/src/main/c/AUTHORS @@ -0,0 +1 @@ +Klaus Reimer diff --git a/src/main/c/COPYING b/src/main/c/COPYING new file mode 100644 index 0000000..fc8a5de --- /dev/null +++ b/src/main/c/COPYING @@ -0,0 +1,165 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + + This version of the GNU Lesser General Public License incorporates +the terms and conditions of version 3 of the GNU General Public +License, supplemented by the additional permissions listed below. + + 0. Additional Definitions. + + As used herein, "this License" refers to version 3 of the GNU Lesser +General Public License, and the "GNU GPL" refers to version 3 of the GNU +General Public License. + + "The Library" refers to a covered work governed by this License, +other than an Application or a Combined Work as defined below. + + An "Application" is any work that makes use of an interface provided +by the Library, but which is not otherwise based on the Library. +Defining a subclass of a class defined by the Library is deemed a mode +of using an interface provided by the Library. + + A "Combined Work" is a work produced by combining or linking an +Application with the Library. The particular version of the Library +with which the Combined Work was made is also called the "Linked +Version". + + The "Minimal Corresponding Source" for a Combined Work means the +Corresponding Source for the Combined Work, excluding any source code +for portions of the Combined Work that, considered in isolation, are +based on the Application, and not on the Linked Version. + + The "Corresponding Application Code" for a Combined Work means the +object code and/or source code for the Application, including any data +and utility programs needed for reproducing the Combined Work from the +Application, but excluding the System Libraries of the Combined Work. + + 1. Exception to Section 3 of the GNU GPL. + + You may convey a covered work under sections 3 and 4 of this License +without being bound by section 3 of the GNU GPL. + + 2. Conveying Modified Versions. + + If you modify a copy of the Library, and, in your modifications, a +facility refers to a function or data to be supplied by an Application +that uses the facility (other than as an argument passed when the +facility is invoked), then you may convey a copy of the modified +version: + + a) under this License, provided that you make a good faith effort to + ensure that, in the event an Application does not supply the + function or data, the facility still operates, and performs + whatever part of its purpose remains meaningful, or + + b) under the GNU GPL, with none of the additional permissions of + this License applicable to that copy. + + 3. Object Code Incorporating Material from Library Header Files. + + The object code form of an Application may incorporate material from +a header file that is part of the Library. You may convey such object +code under terms of your choice, provided that, if the incorporated +material is not limited to numerical parameters, data structure +layouts and accessors, or small macros, inline functions and templates +(ten or fewer lines in length), you do both of the following: + + a) Give prominent notice with each copy of the object code that the + Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the object code with a copy of the GNU GPL and this license + document. + + 4. Combined Works. + + You may convey a Combined Work under terms of your choice that, +taken together, effectively do not restrict modification of the +portions of the Library contained in the Combined Work and reverse +engineering for debugging such modifications, if you also do each of +the following: + + a) Give prominent notice with each copy of the Combined Work that + the Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the Combined Work with a copy of the GNU GPL and this license + document. + + c) For a Combined Work that displays copyright notices during + execution, include the copyright notice for the Library among + these notices, as well as a reference directing the user to the + copies of the GNU GPL and this license document. + + d) Do one of the following: + + 0) Convey the Minimal Corresponding Source under the terms of this + License, and the Corresponding Application Code in a form + suitable for, and under terms that permit, the user to + recombine or relink the Application with a modified version of + the Linked Version to produce a modified Combined Work, in the + manner specified by section 6 of the GNU GPL for conveying + Corresponding Source. + + 1) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (a) uses at run time + a copy of the Library already present on the user's computer + system, and (b) will operate properly with a modified version + of the Library that is interface-compatible with the Linked + Version. + + e) Provide Installation Information, but only if you would otherwise + be required to provide such information under section 6 of the + GNU GPL, and only to the extent that such information is + necessary to install and execute a modified version of the + Combined Work produced by recombining or relinking the + Application with a modified version of the Linked Version. (If + you use option 4d0, the Installation Information must accompany + the Minimal Corresponding Source and Corresponding Application + Code. If you use option 4d1, you must provide the Installation + Information in the manner specified by section 6 of the GNU GPL + for conveying Corresponding Source.) + + 5. Combined Libraries. + + You may place library facilities that are a work based on the +Library side by side in a single library together with other library +facilities that are not Applications and are not covered by this +License, and convey such a combined library under terms of your +choice, if you do both of the following: + + a) Accompany the combined library with a copy of the same work based + on the Library, uncombined with any other library facilities, + conveyed under the terms of this License. + + b) Give prominent notice with the combined library that part of it + is a work based on the Library, and explaining where to find the + accompanying uncombined form of the same work. + + 6. Revised Versions of the GNU Lesser General Public License. + + The Free Software Foundation may publish revised and/or new versions +of the GNU Lesser General Public License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. + + Each version is given a distinguishing version number. If the +Library as you received it specifies that a certain numbered version +of the GNU Lesser General Public License "or any later version" +applies to it, you have the option of following the terms and +conditions either of that published version or of any later version +published by the Free Software Foundation. If the Library as you +received it does not specify a version number of the GNU Lesser +General Public License, you may choose any version of the GNU Lesser +General Public License ever published by the Free Software Foundation. + + If the Library as you received it specifies that a proxy can decide +whether future versions of the GNU Lesser General Public License shall +apply, that proxy's public statement of acceptance of any version is +permanent authorization for you to choose that version for the +Library. diff --git a/src/main/c/ChangeLog b/src/main/c/ChangeLog new file mode 100644 index 0000000..d8a1b74 --- /dev/null +++ b/src/main/c/ChangeLog @@ -0,0 +1,4 @@ +2010-01-18 -- Version 1.0.0 +=========================== + +* Initial release diff --git a/src/main/c/Makefile.am b/src/main/c/Makefile.am new file mode 100644 index 0000000..87d3040 --- /dev/null +++ b/src/main/c/Makefile.am @@ -0,0 +1,2 @@ +ACLOCAL_AMFLAGS=-I m4 +SUBDIRS = src diff --git a/src/main/c/Makefile.scm b/src/main/c/Makefile.scm new file mode 100644 index 0000000..3789c08 --- /dev/null +++ b/src/main/c/Makefile.scm @@ -0,0 +1,36 @@ +all: + mkdir -p m4 + autoreconf --install --force + +clean: + rm -rf \ + autom4te.cache \ + m4 \ + aclocal.m4 \ + config.guess \ + config.h \ + config.h.in \ + config.log \ + config.status \ + config.sub \ + configure \ + depcomp \ + install-sh \ + INSTALL \ + libtool \ + ltmain.sh \ + Makefile \ + Makefile.in \ + missing \ + stamp-h1 \ + src/Makefile.in \ + src/.deps \ + src/.libs \ + src/*.lo \ + src/*.la \ + src/*.o \ + src/Makefile \ + *.tar.gz \ + *.tar.bz2 \ + *~ + diff --git a/src/main/c/NEWS b/src/main/c/NEWS new file mode 100644 index 0000000..4a39bdf --- /dev/null +++ b/src/main/c/NEWS @@ -0,0 +1 @@ +Nothing new right now. \ No newline at end of file diff --git a/src/main/c/README b/src/main/c/README new file mode 100644 index 0000000..c81f453 --- /dev/null +++ b/src/main/c/README @@ -0,0 +1 @@ +libusb 0.x Java-Wrapper diff --git a/src/main/c/acinclude.m4 b/src/main/c/acinclude.m4 new file mode 100644 index 0000000..01f2fff --- /dev/null +++ b/src/main/c/acinclude.m4 @@ -0,0 +1,12 @@ +AC_DEFUN([AC_CHECK_JAVA],[ + AC_ARG_WITH( + java-home, + [ --with-java-home=DIR Java home directory ], + [ + JAVA_HOME=`echo $withval` + ] + ) + CFLAGS="$CFLAGS -I$JAVA_HOME/include -I$JAVA_HOME/include/linux -I$JAVA_HOME/include/win32" + CPPFLAGS="$CPPFLAGS -I$JAVA_HOME/include -I$JAVA_HOME/include/linux -I$JAVA_HOME/include/win32" + AC_CHECK_HEADERS(jni.h,,echo "ERROR: jni.h not found. JAVA_HOME is $JAVA_HOME. Use --with-java-home option to specify an other Java home directory."; exit 1;) +]) diff --git a/src/main/c/configure.ac b/src/main/c/configure.ac new file mode 100644 index 0000000..1beba27 --- /dev/null +++ b/src/main/c/configure.ac @@ -0,0 +1,16 @@ +AC_INIT(configure.ac) +AM_INIT_AUTOMAKE(usb4java, 1.0.0) +AM_CONFIG_HEADER(config.h) +AC_CONFIG_MACRO_DIR([m4]) + +AC_LANG_C +AC_PROG_CC +AM_PROG_LIBTOOL +AC_CHECK_JAVA +AC_CHECK_HEADERS(usb.h,,echo "ERROR: usb.h not found. Please install libusb"; exit 1;) + +AC_CONFIG_FILES( + Makefile + src/Makefile +) +AC_OUTPUT diff --git a/src/main/c/src/Makefile.am b/src/main/c/src/Makefile.am new file mode 100644 index 0000000..b6a2540 --- /dev/null +++ b/src/main/c/src/Makefile.am @@ -0,0 +1,12 @@ +lib_LTLIBRARIES = usb4java.la +libusb4java_la_CFLAGS = -fPIC -Wall -Werror -O2 -ansi +libusb4java_la_LIBADD = -lusb +libusb4java_la_LDFLAGS = -version-info 1:0:0 -no-undefined -lusb +libusb4java_la_SOURCES = \ + USB.c \ + USBBus.c \ + USBDevice.c \ + USBDeviceDescriptor.c \ + USBConfigDescriptor.c \ + USBDevHandle.c + \ No newline at end of file diff --git a/src/main/c/src/USB.c b/src/main/c/src/USB.c new file mode 100644 index 0000000..b836e13 --- /dev/null +++ b/src/main/c/src/USB.c @@ -0,0 +1,198 @@ +/* + * $Id$ + * Copyright (C) 2011 Klaus Reimer (k@ailis.de) + * See COPYING file for copying conditions + */ + +/** + * @name USB + * + * Native methods for the USB class. + * + * @author Klaus Reimer + * @version 0.1 + */ + +#include +#include +#include "USBBus.h" +#include "USBDevice.h" +#include "USBDevHandle.h" + + +/** + * Initialize libusb. + * + * Just like the name implies, usb_init sets up some internal structures. + * usb_init must be called before any other libusb functions. + */ + +JNIEXPORT void JNICALL Java_de_ailis_usb4java_jni_USB_usb_1init( + JNIEnv *env, jobject jobj) +{ + usb_init(); +} + + +/** + * Finds all USB busses on system. + * + * usb_find_busses will find all of the busses on the system. Returns the + * number of changes since previous call to this function (total of new + * busses and busses removed). + * + * @return The number of of changes since previous call. + */ + +JNIEXPORT jint JNICALL Java_de_ailis_usb4java_jni_USB_usb_1find_1busses( + JNIEnv *env, jobject jobj) +{ + return usb_find_busses(); +} + + +/** + * Find all devices on all USB devices. + * + * usb_find_devices will find all of the devices on each bus. This should be + * called after usb_find_busses. Returns the number of changes since the + * previous call to this function (total of new device and devices removed). + * + * @return The number of changes since previous call. + */ + +JNIEXPORT jint JNICALL Java_de_ailis_usb4java_jni_USB_usb_1find_1devices( + JNIEnv *env, jobject jobj) +{ + return usb_find_devices(); +} + + +/** + * Return the list of USB busses found + * + * usb_get_busses simply returns the value of the global variable + * usb_busses. This was implemented for those languages that support C + * calling convention and can use shared libraries, but don't support C + * global variables (like Delphi). + * + * @return The list of USB busses found. + */ + +JNIEXPORT jobject JNICALL Java_de_ailis_usb4java_jni_USB_usb_1get_1busses( + JNIEnv *env, jclass jcls) +{ + return wrap_usb_bus(env, usb_get_busses()); +} + + +/** + * Opens a USB device. + * + * usb_open is to be used to open up a device for use. usb_open must be + * called before attempting to perform any operations to the device. Returns + * a handle used in future communication with the device. + * + * @param device + * The USB device. + * @return The USB device handle. + */ + +JNIEXPORT jobject JNICALL Java_de_ailis_usb4java_jni_USB_usb_1open( + JNIEnv *env, jclass jcls, jobject device) +{ + return wrap_usb_dev_handle(env, usb_open(unwrap_usb_device(env, device))); +} + + +/** + * Closes a USB device. + * + * usb_close closes a device opened with usb_open. No further operations may + * be performed on the handle after usb_close is called. Returns 0 on + * success or < 0 on error. + * + * @param handle + * The USB device handle. + * @return 0 on success or < 0 on error. + */ + +JNIEXPORT jint JNICALL Java_de_ailis_usb4java_jni_USB_usb_1close( + JNIEnv *env, jclass jcls, jobject handle) +{ + return usb_close(unwrap_usb_dev_handle(env, handle)); +} + + +/** + * Retrieves a string descriptor from a device using the first language. + * + * usb_get_string_simple is a wrapper around usb_get_string that retrieves + * the string description specified by index in the first language for the + * descriptor and converts it into C style ASCII. Returns number of bytes + * returned in buf or < 0 on error. + + * @param handle + * The USB device handle. + * @param index + * The string description index. + * @param langid + * The language id. + * @param buffer + * The buffer to write the string to. + * @param buflen + * The maximum number of bytes to read. + * @return The number of bytes read or < 0 on error. + */ + +JNIEXPORT jint JNICALL Java_de_ailis_usb4java_jni_USB_usb_1get_1string( + JNIEnv *env, jclass cls, jobject handle, jint index, jint langid, + jbyteArray buffer, jint buflen) +{ + char *buf = (char*) malloc(buflen); + int result = usb_get_string(unwrap_usb_dev_handle(env, handle), + index, langid, buf, buflen); + if (result >= 0) + { + (*env)->SetByteArrayRegion(env, buffer, 0, result, + (const jbyte *) buf); + } + free(buf); + return result; +} + + +/** + * Retrieves a string descriptor from a device using the first language. + * + * usb_get_string_simple is a wrapper around usb_get_string that retrieves + * the string description specified by index in the first language for the + * descriptor and converts it into C style ASCII. Returns number of bytes + * returned in buf or < 0 on error. + * + * @param handle + * The USB device handle. + * @param index + * The string description index. + * @param buffer + * The buffer to write the string to. + * @param buflen + * The maximum number of bytes to read. + * @return The number of bytes read or < 0 on error. + */ + +JNIEXPORT jint JNICALL Java_de_ailis_usb4java_jni_USB_usb_1get_1string_1simple( + JNIEnv *env, jclass cls, jobject handle, jint index, jbyteArray buffer, + jint buflen) +{ + char *buf = (char*) malloc(buflen); + int result = usb_get_string_simple(unwrap_usb_dev_handle(env, handle), + index, buf, buflen); + if (result >= 0) + { + (*env)->SetByteArrayRegion(env, buffer, 0, result, + (const jbyte *) buf); + } + free(buf); + return result; +} diff --git a/src/main/c/src/USBBus.c b/src/main/c/src/USBBus.c new file mode 100644 index 0000000..32a9a87 --- /dev/null +++ b/src/main/c/src/USBBus.c @@ -0,0 +1,136 @@ +/* + * $Id$ + * Copyright (C) 2011 Klaus Reimer (k@ailis.de) + * See COPYING file for copying conditions + */ + +/** + * @name USBBus + * + * Native methods for the USBBus class. + * + * @author Klaus Reimer + * @version 0.1 + */ + +#include +#include +#include "USBDevice.h" + + +/** + * Creates and returns a new USB bus wrapper object. + * + * @param env + * The JNI environment. + * @param bus + * The USB bus. + * @return The USB bus wrapper object. + */ + +jobject wrap_usb_bus(JNIEnv *env, struct usb_bus *bus) +{ + if (!bus) return NULL; + jclass cls = (*env)->FindClass(env, "de/ailis/libusb/jni/USBBus"); + if (cls == NULL) return NULL; + jmethodID constructor = (*env)->GetMethodID(env, cls, "", "(J)V"); + if (constructor == NULL) return NULL; + return (*env)->NewObject(env, cls, constructor, (long) bus); +} + + +/** + * Returns the wrapped USB bus object from the specified wrapper object. + * + * @param env + * The JNI environment. + * @param obj + * The USB bus wrapper object. + * @return The USB bus object. + */ + +struct usb_bus *unwrap_usb_bus(JNIEnv *env, jobject obj) +{ + jclass cls = (*env)->GetObjectClass(env, obj); + jfieldID field = (*env)->GetFieldID(env, cls, "pointer", "J"); + return (struct usb_bus *) ((*env)->GetLongField(env, obj, field)); +} + + +/** + * Returns the usb bus dirname. + * + * @return The usb bus dirname. + */ + +JNIEXPORT jstring JNICALL Java_de_ailis_usb4java_jni_USBBus_dirname( + JNIEnv *env, jobject this) +{ + return (*env)->NewStringUTF(env, unwrap_usb_bus(env, this)->dirname); +} + + +/** + * Returns the next usb bus. + * + * @return The next usb bus. + */ + +JNIEXPORT jobject JNICALL Java_de_ailis_usb4java_jni_USBBus_next( + JNIEnv *env, jobject this) +{ + return wrap_usb_bus(env, unwrap_usb_bus(env, this)->next); +} + + +/** + * Returns the previous usb bus. + * + * @return The previous usb bus. + */ + +JNIEXPORT jobject JNICALL Java_de_ailis_usb4java_jni_USBBus_prev( + JNIEnv *env, jobject this) +{ + return wrap_usb_bus(env, unwrap_usb_bus(env, this)->prev); +} + + +/** + * Returns the usb bus location. + * + * @return The usb bus location. + */ + +JNIEXPORT jlong JNICALL Java_de_ailis_usb4java_jni_USBBus_location( + JNIEnv *env, jobject this) +{ + return unwrap_usb_bus(env, this)->location; +} + + +/** + * Returns the usb devices. + * + * @return The usb devices. + */ + +JNIEXPORT jobject JNICALL Java_de_ailis_usb4java_jni_USBBus_devices( + JNIEnv *env, jobject this) +{ + return wrap_usb_device(env, unwrap_usb_bus(env, this)->devices); +} + + +/** + * Returns the usb root device. + * + * @return The usb root device. + */ + +JNIEXPORT jobject JNICALL Java_de_ailis_usb4java_jni_USBBus_root_1dev( + JNIEnv *env, jobject this) +{ + return wrap_usb_device(env, unwrap_usb_bus(env, this)->root_dev); +} + diff --git a/src/main/c/src/USBBus.h b/src/main/c/src/USBBus.h new file mode 100644 index 0000000..57db4ca --- /dev/null +++ b/src/main/c/src/USBBus.h @@ -0,0 +1,10 @@ +#ifndef USB_BUS_H +#define USB_BUS_H + +#include +#include + +extern jobject wrap_usb_bus(JNIEnv *env, struct usb_bus *bus); +extern struct usb_bus *unwrap_usb_bus(JNIEnv *env, jobject obj); + +#endif \ No newline at end of file diff --git a/src/main/c/src/USBConfigDescriptor.c b/src/main/c/src/USBConfigDescriptor.c new file mode 100644 index 0000000..cdfa3b2 --- /dev/null +++ b/src/main/c/src/USBConfigDescriptor.c @@ -0,0 +1,195 @@ +/* + * $Id$ + * Copyright (C) 2011 Klaus Reimer (k@ailis.de) + * See COPYING file for copying conditions + */ + +/** + * @name USBConfigDescriptor + * + * Native methods for the USBConfigDescriptor class. + * + * @author Klaus Reimer + * @version 0.1 + */ + +#include +#include + + +/** + * Creates and returns a new USB config descriptor wrapper object. + * + * @param env + * The JNI environment. + * @param device + * The USB config descriptor. + * @return The USB config descriptor wrapper object. + */ + +jobject wrap_usb_config_descriptor(JNIEnv *env, + struct usb_config_descriptor *descriptor) +{ + if (!descriptor) return NULL; + jclass cls = (*env)->FindClass(env, + "de/ailis/libusb/jni/USBConfigDescriptor"); + if (cls == NULL) return NULL; + jmethodID constructor = (*env)->GetMethodID(env, cls, "", "(J)V"); + if (constructor == NULL) return NULL; + return (*env)->NewObject(env, cls, constructor, (long) descriptor); +} + + +/** + * Returns the wrapped USB config descriptor object from the specified + * wrapper object. + * + * @param env + * The JNI environment. + * @param obj + * The USB config descriptor wrapper object. + * @return The USB config descriptor object. + */ + +struct usb_config_descriptor *unwrap_usb_config_descriptor(JNIEnv *env, + jobject obj) +{ + jclass cls = (*env)->GetObjectClass(env, obj); + jfieldID field = (*env)->GetFieldID(env, cls, "pointer", "J"); + return (struct usb_config_descriptor *) ((*env)->GetLongField(env, + obj, field)); +} + + +/** + * Returns the bLength. + * + * @return The bLength. + */ + +JNIEXPORT jbyte JNICALL Java_de_ailis_usb4java_jni_USBConfigDescriptor_bLength( + JNIEnv *env, jobject this) +{ + return unwrap_usb_config_descriptor(env, this)->bLength; +} + + +/** + * Returns the bDescriptorType. + * + * @return The bDescriptorType. + */ + +JNIEXPORT jbyte JNICALL Java_de_ailis_usb4java_jni_USBConfigDescriptor_bDescriptorType( + JNIEnv *env, jobject this) +{ + return unwrap_usb_config_descriptor(env, this)->bDescriptorType; +} + + +/** + * Returns the wTotalLength. + * + * @return The wTotalLength. + */ + +JNIEXPORT jshort JNICALL Java_de_ailis_usb4java_jni_USBConfigDescriptor_wTotalLength( + JNIEnv *env, jobject this) +{ + return unwrap_usb_config_descriptor(env, this)->wTotalLength; +} + + +/** + * Returns the bNumInterfaces. + * + * @return The bNumInterfaces. + */ + +JNIEXPORT jbyte JNICALL Java_de_ailis_usb4java_jni_USBConfigDescriptor_bNumInterfaces( + JNIEnv *env, jobject this) +{ + return unwrap_usb_config_descriptor(env, this)->bNumInterfaces; +} + + +/** + * Returns the bConfigurationValue. + * + * @return The bConfigurationValue. + */ + +JNIEXPORT jbyte JNICALL Java_de_ailis_usb4java_jni_USBConfigDescriptor_bConfigurationValue( + JNIEnv *env, jobject this) +{ + return unwrap_usb_config_descriptor(env, this)->bConfigurationValue; +} + + +/** + * Returns the iConfiguration. + * + * @return The iConfiguration. + */ + +JNIEXPORT jbyte JNICALL Java_de_ailis_usb4java_jni_USBConfigDescriptor_iConfiguration( + JNIEnv *env, jobject this) +{ + return unwrap_usb_config_descriptor(env, this)->iConfiguration; +} + + +/** + * Returns the bmAttributes. + * + * @return The bmAttributes. + */ + +JNIEXPORT jbyte JNICALL Java_de_ailis_usb4java_jni_USBConfigDescriptor_bmAttributes( + JNIEnv *env, jobject this) +{ + return unwrap_usb_config_descriptor(env, this)->bmAttributes; +} + + +/** + * Returns the MaxPower. + * + * @return The MaxPower. + */ + +JNIEXPORT jbyte JNICALL Java_de_ailis_usb4java_jni_USBConfigDescriptor_MaxPower( + JNIEnv *env, jobject this) +{ + return unwrap_usb_config_descriptor(env, this)->MaxPower; +} + + +/** + * Returns the extralen. + * + * @return The idProduct. + */ + +JNIEXPORT jshort JNICALL Java_de_ailis_usb4java_jni_USBConfigDescriptor_extralen( + JNIEnv *env, jobject this) +{ + return unwrap_usb_config_descriptor(env, this)->extralen; +} + + +/** + * Returns the extra descriptors. + * + * @return The extra descriptors. + */ + +JNIEXPORT jbyteArray JNICALL Java_de_ailis_usb4java_jni_USBConfigDescriptor_extra( + JNIEnv *env, jobject this) +{ + struct usb_config_descriptor *descriptor = unwrap_usb_config_descriptor(env, this); + jbyteArray array = (*env)->NewByteArray(env, descriptor->extralen); + (*env)->SetByteArrayRegion(env, array, 0, descriptor->extralen, + (const jbyte *) descriptor->extra); + return array; +} diff --git a/src/main/c/src/USBConfigDescriptor.h b/src/main/c/src/USBConfigDescriptor.h new file mode 100644 index 0000000..9edd83d --- /dev/null +++ b/src/main/c/src/USBConfigDescriptor.h @@ -0,0 +1,10 @@ +#ifndef USB_CONFIG_DESCRIPTOR_H +#define USB_CONFIG_DESCRIPTOR_H + +#include +#include + +extern jobject wrap_usb_config_descriptor(JNIEnv *env, struct usb_config_descriptor *device); +extern struct usb_config_descriptor *unwrap_usb_config_descriptor(JNIEnv *env, jobject obj); + +#endif diff --git a/src/main/c/src/USBDevHandle.c b/src/main/c/src/USBDevHandle.c new file mode 100644 index 0000000..5c4c452 --- /dev/null +++ b/src/main/c/src/USBDevHandle.c @@ -0,0 +1,56 @@ +/* + * $Id$ + * Copyright (C) 2011 Klaus Reimer (k@ailis.de) + * See COPYING file for copying conditions + */ + +/** + * @name USBDevHandle + * + * Native methods for the USBDevHandle class. + * + * @author Klaus Reimer + * @version 0.1 + */ + +#include +#include + + +/** + * Creates and returns a new USB device wrapper object. + * + * @param env + * The JNI environment. + * @param device + * The USB device. + * @return The USB device wrapper object. + */ + +jobject wrap_usb_dev_handle(JNIEnv *env, struct usb_dev_handle *device) +{ + if (!device) return NULL; + jclass cls = (*env)->FindClass(env, "de/ailis/libusb/jni/USBDevHandle"); + if (cls == NULL) return NULL; + jmethodID constructor = (*env)->GetMethodID(env, cls, "", "(J)V"); + if (constructor == NULL) return NULL; + return (*env)->NewObject(env, cls, constructor, (long) device); +} + + +/** + * Returns the wrapped USB device object from the specified wrapper object. + * + * @param env + * The JNI environment. + * @param obj + * The USB device wrapper object. + * @return The USB device object. + */ + +struct usb_dev_handle *unwrap_usb_dev_handle(JNIEnv *env, jobject obj) +{ + jclass cls = (*env)->GetObjectClass(env, obj); + jfieldID field = (*env)->GetFieldID(env, cls, "pointer", "J"); + return (struct usb_dev_handle *) ((*env)->GetLongField(env, obj, field)); +} diff --git a/src/main/c/src/USBDevHandle.h b/src/main/c/src/USBDevHandle.h new file mode 100644 index 0000000..ea503fc --- /dev/null +++ b/src/main/c/src/USBDevHandle.h @@ -0,0 +1,10 @@ +#ifndef USB_DEV_HANDLE_H +#define USB_DEV_HANDLE_H + +#include +#include + +extern jobject wrap_usb_dev_handle(JNIEnv *env, struct usb_dev_handle *device); +extern struct usb_dev_handle *unwrap_usb_dev_handle(JNIEnv *env, jobject obj); + +#endif diff --git a/src/main/c/src/USBDevice.c b/src/main/c/src/USBDevice.c new file mode 100644 index 0000000..48f5308 --- /dev/null +++ b/src/main/c/src/USBDevice.c @@ -0,0 +1,219 @@ +/* + * $Id$ + * Copyright (C) 2011 Klaus Reimer (k@ailis.de) + * See COPYING file for copying conditions + */ + +/** + * @name USBDevice + * + * Native methods for the USBDevice class. + * + * @author Klaus Reimer + * @version 0.1 + */ + +#include +#include +#include "USBBus.h" +#include "USBDeviceDescriptor.h" +#include "USBConfigDescriptor.h" + + +/** + * Creates and returns a new USB device wrapper object. + * + * @param env + * The JNI environment. + * @param device + * The USB device. + * @return The USB device wrapper object. + */ + +jobject wrap_usb_device(JNIEnv *env, struct usb_device *device) +{ + if (!device) return NULL; + jclass cls = (*env)->FindClass(env, "de/ailis/libusb/jni/USBDevice"); + if (cls == NULL) return NULL; + jmethodID constructor = (*env)->GetMethodID(env, cls, "", "(J)V"); + if (constructor == NULL) return NULL; + return (*env)->NewObject(env, cls, constructor, (long) device); +} + + + +/** + * Creates and returns an array with device wrapper objects. + * + * @param env + * The JNI environment + * @param num_devices + * The number of devices + * @param devices + * The devices to wrap. + * @return The array with the USB device wrappers. + */ + +static jobjectArray wrap_usb_devices(JNIEnv *env, uint8_t num_children, + struct usb_device **children) +{ + int i; + + jobjectArray array = (jobjectArray) (*env)->NewObjectArray(env, num_children, + (*env)->FindClass(env, "de/ailis/libusb/jni/USBDevice"), NULL); + for (i = 0; i < num_children; i++) + (*env)->SetObjectArrayElement(env, array, i, + wrap_usb_device(env, children[i])); + return array; +} + + +/** + * Returns the wrapped USB device object from the specified wrapper object. + * + * @param env + * The JNI environment. + * @param obj + * The USB device wrapper object. + * @return The USB device object. + */ + +struct usb_device *unwrap_usb_device(JNIEnv *env, jobject obj) +{ + jclass cls = (*env)->GetObjectClass(env, obj); + jfieldID field = (*env)->GetFieldID(env, cls, "pointer", "J"); + return (struct usb_device *) ((*env)->GetLongField(env, obj, field)); +} + + +/** + * Returns the usb device filename. + * + * @return The usb device filename. + */ + +JNIEXPORT jstring JNICALL Java_de_ailis_usb4java_jni_USBDevice_filename( + JNIEnv *env, jobject this) +{ + return (*env)->NewStringUTF(env, unwrap_usb_device(env, this)->filename); +} + + +/** + * Returns the next usb device. + * + * @return The next usb device. + */ + +JNIEXPORT jobject JNICALL Java_de_ailis_usb4java_jni_USBDevice_next( + JNIEnv *env, jobject this) +{ + return wrap_usb_device(env, unwrap_usb_device(env, this)->next); +} + + +/** + * Returns the previous usb device. + * + * @return The previous usb device. + */ + +JNIEXPORT jobject JNICALL Java_de_ailis_usb4java_jni_USBDevice_prev( + JNIEnv *env, jobject this) +{ + return wrap_usb_device(env, unwrap_usb_device(env, this)->prev); +} + + +/** + * Returns the USB bus. + * + * @return The USB bus. + */ + +JNIEXPORT jobject JNICALL Java_de_ailis_usb4java_jni_USBDevice_bus( + JNIEnv *env, jobject this) +{ + return wrap_usb_bus(env, unwrap_usb_device(env, this)->bus); +} + + +/** + * Returns the device number. + * + * @return The device number. + */ + +JNIEXPORT jshort JNICALL Java_de_ailis_usb4java_jni_USBDevice_devnum( + JNIEnv *env, jobject this) +{ + return (jshort) unwrap_usb_device(env, this)->devnum; +} + + +/** + * Returns the number of child devices. + * + * @return The number of child devices.. + */ + +JNIEXPORT jshort JNICALL Java_de_ailis_usb4java_jni_USBDevice_num_1children( + JNIEnv *env, jobject this) +{ + return (jshort) unwrap_usb_device(env, this)->num_children; +} + + +/** + * Returns the child devices. + * + * @return The child devices. + */ + +JNIEXPORT jobject JNICALL Java_de_ailis_usb4java_jni_USBDevice_children( + JNIEnv *env, jobject this) +{ + struct usb_device *device = unwrap_usb_device(env, this); + return wrap_usb_devices(env, device->num_children, device->children); +} + + +/** + * Returns the configuration descriptors. + * + * @return The configuration descriptors. + */ + +JNIEXPORT jobjectArray JNICALL Java_de_ailis_usb4java_jni_USBDevice_config( + JNIEnv *env, jobject this) +{ + int i; + + struct usb_device *device = unwrap_usb_device(env, this); + struct usb_config_descriptor *descriptors = device->config; + unsigned char config_count = device->descriptor.bNumConfigurations; + jclass cls = (*env)->FindClass(env, "de/ailis/libusb/jni/USBConfigDescriptor"); + jobjectArray configs = (*env)->NewObjectArray(env, config_count, cls, 0); + for (i = 0; i < config_count; i++) + { + (*env)->SetObjectArrayElement(env, configs, i, + wrap_usb_config_descriptor(env, &descriptors[i])); + } + return configs; +} + + +/** + * Returns the USB device descriptor. + * + * @return The USB device descriptor. + */ + +JNIEXPORT jobject JNICALL Java_de_ailis_usb4java_jni_USBDevice_descriptor( + JNIEnv *env, jobject this) +{ + return wrap_usb_device_descriptor(env, &(unwrap_usb_device(env, + this)->descriptor)); +} + + diff --git a/src/main/c/src/USBDevice.h b/src/main/c/src/USBDevice.h new file mode 100644 index 0000000..179dc0f --- /dev/null +++ b/src/main/c/src/USBDevice.h @@ -0,0 +1,10 @@ +#ifndef USB_DEVICE_H +#define USB_DEVICE_H + +#include +#include + +extern jobject wrap_usb_device(JNIEnv *env, struct usb_device *device); +extern struct usb_device *unwrap_usb_device(JNIEnv *env, jobject obj); + +#endif diff --git a/src/main/c/src/USBDeviceDescriptor.c b/src/main/c/src/USBDeviceDescriptor.c new file mode 100644 index 0000000..9c012d5 --- /dev/null +++ b/src/main/c/src/USBDeviceDescriptor.c @@ -0,0 +1,243 @@ +/* + * $Id$ + * Copyright (C) 2011 Klaus Reimer (k@ailis.de) + * See COPYING file for copying conditions + */ + +/** + * @name USBDeviceDescriptor + * + * Native methods for the USBDeviceDescriptor class. + * + * @author Klaus Reimer + * @version 0.1 + */ + +#include +#include +#include "USBBus.h" + + +/** + * Creates and returns a new USB device descriptor wrapper object. + * + * @param env + * The JNI environment. + * @param device + * The USB device descriptor. + * @return The USB device descriptor wrapper object. + */ + +jobject wrap_usb_device_descriptor(JNIEnv *env, + struct usb_device_descriptor *descriptor) +{ + if (!descriptor) return NULL; + jclass cls = (*env)->FindClass(env, + "de/ailis/libusb/jni/USBDeviceDescriptor"); + if (cls == NULL) return NULL; + jmethodID constructor = (*env)->GetMethodID(env, cls, "", "(J)V"); + if (constructor == NULL) return NULL; + return (*env)->NewObject(env, cls, constructor, (long) descriptor); +} + + +/** + * Returns the wrapped USB device descriptor object from the specified + * wrapper object. + * + * @param env + * The JNI environment. + * @param obj + * The USB device descriptor wrapper object. + * @return The USB device descriptor object. + */ + +struct usb_device_descriptor *unwrap_usb_device_descriptor(JNIEnv *env, + jobject obj) +{ + jclass cls = (*env)->GetObjectClass(env, obj); + jfieldID field = (*env)->GetFieldID(env, cls, "pointer", "J"); + return (struct usb_device_descriptor *) ((*env)->GetLongField(env, + obj, field)); +} + + +/** + * Returns the bLength. + * + * @return The bLength. + */ + +JNIEXPORT jshort JNICALL Java_de_ailis_usb4java_jni_USBDeviceDescriptor_bLength( + JNIEnv *env, jobject this) +{ + return (jshort) unwrap_usb_device_descriptor(env, this)->bLength; +} + + +/** + * Returns the bDescriptorType. + * + * @return The bDescriptorType. + */ + +JNIEXPORT jshort JNICALL Java_de_ailis_usb4java_jni_USBDeviceDescriptor_bDescriptorType( + JNIEnv *env, jobject this) +{ + return (jshort) unwrap_usb_device_descriptor(env, this)->bDescriptorType; +} + + +/** + * Returns the bcdUSB. + * + * @return The bcdUSB. + */ + +JNIEXPORT jint JNICALL Java_de_ailis_usb4java_jni_USBDeviceDescriptor_bcdUSB( + JNIEnv *env, jobject this) +{ + return (jint) unwrap_usb_device_descriptor(env, this)->bcdUSB; +} + + +/** + * Returns the bDeviceClass. + * + * @return The bDeviceClass. + */ + +JNIEXPORT jshort JNICALL Java_de_ailis_usb4java_jni_USBDeviceDescriptor_bDeviceClass( + JNIEnv *env, jobject this) +{ + return (jshort) unwrap_usb_device_descriptor(env, this)->bDeviceClass; +} + + +/** + * Returns the bDeviceSubClass. + * + * @return The bDeviceSubClass. + */ + +JNIEXPORT jshort JNICALL Java_de_ailis_usb4java_jni_USBDeviceDescriptor_bDeviceSubClass( + JNIEnv *env, jobject this) +{ + return (jshort) unwrap_usb_device_descriptor(env, this)->bDeviceSubClass; +} + + +/** + * Returns the bDeviceProtocol. + * + * @return The bDeviceProtocol. + */ + +JNIEXPORT jshort JNICALL Java_de_ailis_usb4java_jni_USBDeviceDescriptor_bDeviceProtocol( + JNIEnv *env, jobject this) +{ + return (jshort) unwrap_usb_device_descriptor(env, this)->bDeviceProtocol; +} + + +/** + * Returns the bMaxPacketSize0. + * + * @return The bMaxPacketSize0. + */ + +JNIEXPORT jshort JNICALL Java_de_ailis_usb4java_jni_USBDeviceDescriptor_bMaxPacketSize0( + JNIEnv *env, jobject this) +{ + return (jshort) unwrap_usb_device_descriptor(env, this)->bMaxPacketSize0; +} + + +/** + * Returns the idVendor. + * + * @return The idVendor. + */ + +JNIEXPORT jint JNICALL Java_de_ailis_usb4java_jni_USBDeviceDescriptor_idVendor( + JNIEnv *env, jobject this) +{ + return (jint) unwrap_usb_device_descriptor(env, this)->idVendor; +} + +/** + * Returns the idProduct. + * + * @return The idProduct. + */ + +JNIEXPORT jint JNICALL Java_de_ailis_usb4java_jni_USBDeviceDescriptor_idProduct( + JNIEnv *env, jobject this) +{ + return (jint) unwrap_usb_device_descriptor(env, this)->idProduct; +} + + +/** + * Returns the bcdDevice. + * + * @return The bcdDevice. + */ + +JNIEXPORT jint JNICALL Java_de_ailis_usb4java_jni_USBDeviceDescriptor_bcdDevice( + JNIEnv *env, jobject this) +{ + return (jint) unwrap_usb_device_descriptor(env, this)->bcdDevice; +} + + +/** + * Returns the iManufacturer. + * + * @return The iManufacturer. + */ + +JNIEXPORT jshort JNICALL Java_de_ailis_usb4java_jni_USBDeviceDescriptor_iManufacturer( + JNIEnv *env, jobject this) +{ + return (jshort) unwrap_usb_device_descriptor(env, this)->iManufacturer; +} + + +/** + * Returns the iProduct. + * + * @return The iProduct. + */ + +JNIEXPORT jshort JNICALL Java_de_ailis_usb4java_jni_USBDeviceDescriptor_iProduct( + JNIEnv *env, jobject this) +{ + return (jshort) unwrap_usb_device_descriptor(env, this)->iProduct; +} + + +/** + * Returns the iSerialNumber. + * + * @return The iSerialNumber. + */ + +JNIEXPORT jshort JNICALL Java_de_ailis_usb4java_jni_USBDeviceDescriptor_iSerialNumber( + JNIEnv *env, jobject this) +{ + return (jshort) unwrap_usb_device_descriptor(env, this)->iSerialNumber; +} + + +/** + * Returns the bNumConfigurations. + * + * @return The bNumConfigurations. + */ + +JNIEXPORT jshort JNICALL Java_de_ailis_usb4java_jni_USBDeviceDescriptor_bNumConfigurations( + JNIEnv *env, jobject this) +{ + return (jshort) unwrap_usb_device_descriptor(env, this)->bNumConfigurations; +} diff --git a/src/main/c/src/USBDeviceDescriptor.h b/src/main/c/src/USBDeviceDescriptor.h new file mode 100644 index 0000000..c4abbc6 --- /dev/null +++ b/src/main/c/src/USBDeviceDescriptor.h @@ -0,0 +1,10 @@ +#ifndef USB_DEVICE_DESCRIPTOR_H +#define USB_DEVICE_DESCRIPTOR_H + +#include +#include + +extern jobject wrap_usb_device_descriptor(JNIEnv *env, struct usb_device_descriptor *device); +extern struct usb_device_descriptor *unwrap_usb_device_descriptor(JNIEnv *env, jobject obj); + +#endif diff --git a/src/main/java/Test.java b/src/main/java/Test.java new file mode 100644 index 0000000..74e5f52 --- /dev/null +++ b/src/main/java/Test.java @@ -0,0 +1,168 @@ +import javax.usb.UsbConst; +import javax.usb.UsbDevice; +import javax.usb.UsbDeviceDescriptor; +import javax.usb.UsbHostManager; +import javax.usb.UsbHub; +import javax.usb.UsbPort; +import javax.usb.UsbServices; + +/* + * Copyright (C) 2011 Klaus Reimer + * See LICENSE.txt for licensing information. + */ + + +/** + * Test + * + * @author k + */ + +public class Test +{ + private static int indentLevel = 0; + + public static String indent() + { + final StringBuilder str = new StringBuilder(); + for (int i = 0; i < indentLevel; i++) str.append(" "); + return str.toString(); + } + + public static String getSpeedString(final Object speed) + { + if (speed == UsbConst.DEVICE_SPEED_FULL) + return "Full"; + else if (speed == UsbConst.DEVICE_SPEED_LOW) + return "Low"; + else if (speed == UsbConst.DEVICE_SPEED_UNKNOWN) + return "Unknown"; + else + throw new RuntimeException("Unknown speed object: " + speed); + } + + public static void dumpHub(final UsbHub hub) throws Exception + { + System.out.println(indent() + "Manufacturer: " + hub.getManufacturerString()); + System.out.println(indent() + "Product: " + hub.getProductString()); + System.out.println(indent() + "Serial number: " + hub.getSerialNumberString()); + System.out.println(indent() + "Speed: " + getSpeedString(hub.getSpeed())); + System.out.println(indent() + "Devices: " + hub.getAttachedUsbDevices().size()); + System.exit(1); + + indentLevel++; + for (byte i = 0; i < hub.getAttachedUsbDevices().size(); i++) + { + System.out.println(indent() + "Device " + i + ":"); + indentLevel++; + final UsbDevice device = (UsbDevice) hub.getAttachedUsbDevices().get(i); + dumpDevice(device); + indentLevel--; + } + indentLevel--; + + /* + System.out.println(indent() + "Ports: " + hub.getUsbPorts().size()); + + indentLevel++; + for (byte i = 1; i <= hub.getNumberOfPorts(); i++) + { + System.out.println(indent() + "Port " + i + ":"); + indentLevel++; + final UsbPort port = hub.getUsbPort(i); + dumpPort(port); + indentLevel--; + } + indentLevel--; + */ + } + + public static void dumpPort(final UsbPort port) throws Exception + { + System.out.println(indent() + "Port number: " + port.getPortNumber()); + final UsbDevice device = port.getUsbDevice(); + if (device != null) dumpDevice(device); + } + + public static void dumpDevice(final UsbDevice device) throws Exception + { + System.out.println(indent() + "Configured: " + device.isConfigured()); + System.out.println(indent() + "Is Hub: " + device.isUsbHub()); + if (device.isUsbHub()) + { + // dumpHub((UsbHub) device); + } + else + { + System.out.println(indent() + "Manufacturer: " + device.getManufacturerString()); + System.out.println(indent() + "Product: " + device.getProductString()); + System.out.println(indent() + "Serial number: " + device.getSerialNumberString()); + System.out.println(indent() + "Speed: " + getSpeedString(device.getSpeed())); + } + final UsbDeviceDescriptor descriptor = device.getUsbDeviceDescriptor(); + System.out.println(indent() + "VendorId: " + String.format("%04x", descriptor.idVendor())); + System.out.println(indent() + "ProductId: " + String.format("%04x", descriptor.idProduct())); + } + + public static void main(final String args[]) throws Exception + { + final UsbServices services = UsbHostManager.getUsbServices(); + +// System.out.println("Implementation Description: "); +// System.out.println(services.getImpDescription()); +// System.out.println("Implementation version: " + services.getImpVersion()); +// System.out.println("API version: " + services.getApiVersion()); + final UsbHub rootUsbHub = services.getRootUsbHub(); + if (rootUsbHub != null) + { + System.out.println("Root hub:"); + //indentLevel++; + System.out.println("POrts:" + rootUsbHub.getNumberOfPorts()); + for (final Object item: rootUsbHub.getUsbPorts()) + { + final UsbPort port = (UsbPort) item; + System.out.println(port.getUsbDevice().getSerialNumberString()); + System.out.println(port.getPortNumber()); + } + //dumpHub(rootUsbHub); + //indentLevel--; + } + + /* + services.addUsbServicesListener(new UsbServicesListener() + { + + @Override + public void usbDeviceDetached(final UsbServicesEvent event) + { + try + { + System.out.println("Detached: " +event.getUsbDevice().getProductString()); + } + catch (final Exception e) + { + throw new RuntimeException(e); + } + } + + @Override + public void usbDeviceAttached(final UsbServicesEvent event) + { + try + { + System.out.println("Attached: " +event.getUsbDevice().getProductString()); + } + catch (final Exception e) + { + throw new RuntimeException(e); + } + } + }); + */ + +// while (true) +// { +// Thread.sleep(100); +// } + } +} diff --git a/src/main/java/de/ailis/usb4java/EventListenerList.java b/src/main/java/de/ailis/usb4java/EventListenerList.java new file mode 100644 index 0000000..f1129f4 --- /dev/null +++ b/src/main/java/de/ailis/usb4java/EventListenerList.java @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2011 Klaus Reimer + * See LICENSE.txt for licensing information. + */ + +package de.ailis.usb4java; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Collections; +import java.util.EventListener; +import java.util.List; + + +/** + * Manages event listeners in a list. + * + * @author Klaus Reimer (k@ailis.de) + * @param + * The event listener class. + */ + +public class EventListenerList implements Serializable +{ + /** Serial version UID. */ + private static final long serialVersionUID = 1L; + + /** The list of listeners. */ + protected final List listeners = Collections + .synchronizedList(new ArrayList()); + + + /** + * Adds a listener to the list. + * + * @param listener + * The listener to add. Must not be null. + * @throws IllegalStateException + * If listener can't be added because it is already registered. + */ + + public void addListener(final T listener) + { + if (listener == null) + throw new IllegalArgumentException("listener must not be null"); + if (this.listeners.contains(listener)) + throw new IllegalStateException("listener is already registered"); + this.listeners.add(listener); + } + + + /** + * Removes the specified listener from the list. + * + * @param listener + * The listener to remove. + * @throws IllegalStateException + * If listener can't be removed because it is not registered. + */ + + public void removeListener(final T listener) + { + if (listener == null) + throw new IllegalArgumentException("listener must not be null"); + if (!this.listeners.remove(listener)) + throw new IllegalStateException("listener is not registered"); + } +} diff --git a/src/main/java/de/ailis/usb4java/UsbConfigurationDescriptorImpl.java b/src/main/java/de/ailis/usb4java/UsbConfigurationDescriptorImpl.java new file mode 100644 index 0000000..cf52fa9 --- /dev/null +++ b/src/main/java/de/ailis/usb4java/UsbConfigurationDescriptorImpl.java @@ -0,0 +1,125 @@ +/* + * Copyright (C) 2011 Klaus Reimer + * See LICENSE.txt for licensing information. + */ + +package de.ailis.usb4java; + +import javax.usb.UsbConfigurationDescriptor; + +import de.ailis.usb4java.jni.USBConfigDescriptor; + + +/** + * UsbConfigurationDescriptor implementation of usb4java. + * + * @author Klaus Reimer (k@ailis.de) + */ + +public class UsbConfigurationDescriptorImpl implements + UsbConfigurationDescriptor +{ + /** The low-level USB config desciptor. */ + private final USBConfigDescriptor configDescriptor; + + + /** + * Constructor. + * + * @param configDescriptor + * The low-level config descriptor. + */ + + UsbConfigurationDescriptorImpl(final USBConfigDescriptor configDescriptor) + { + this.configDescriptor = configDescriptor; + } + + + /** + * @see javax.usb.UsbDescriptor#bLength() + */ + + @Override + public byte bLength() + { + return this.configDescriptor.bLength(); + } + + + /** + * @see javax.usb.UsbDescriptor#bDescriptorType() + */ + + @Override + public byte bDescriptorType() + { + return this.configDescriptor.bDescriptorType(); + } + + + /** + * @see javax.usb.UsbConfigurationDescriptor#wTotalLength() + */ + + @Override + public short wTotalLength() + { + return this.configDescriptor.wTotalLength(); + } + + + /** + * @see javax.usb.UsbConfigurationDescriptor#bNumInterfaces() + */ + + @Override + public byte bNumInterfaces() + { + return this.configDescriptor.bNumInterfaces(); + } + + + /** + * @see javax.usb.UsbConfigurationDescriptor#bConfigurationValue() + */ + + @Override + public byte bConfigurationValue() + { + return this.configDescriptor.bConfigurationValue(); + } + + + /** + * @see javax.usb.UsbConfigurationDescriptor#iConfiguration() + */ + + @Override + public byte iConfiguration() + { + return this.configDescriptor.iConfiguration(); + } + + + /** + * @see javax.usb.UsbConfigurationDescriptor#bmAttributes() + */ + + @Override + public byte bmAttributes() + { + return this.configDescriptor.bmAttributes(); + } + + + /** + * @see javax.usb.UsbConfigurationDescriptor#bMaxPower() + */ + + @Override + public byte bMaxPower() + { + return this.configDescriptor.MaxPower(); + } +} diff --git a/src/main/java/de/ailis/usb4java/UsbConfigurationImpl.java b/src/main/java/de/ailis/usb4java/UsbConfigurationImpl.java new file mode 100644 index 0000000..1537d46 --- /dev/null +++ b/src/main/java/de/ailis/usb4java/UsbConfigurationImpl.java @@ -0,0 +1,137 @@ +/* + * Copyright (C) 2011 Klaus Reimer + * See LICENSE.txt for licensing information. + */ + +package de.ailis.usb4java; + +import java.io.UnsupportedEncodingException; +import java.util.List; + +import javax.usb.UsbConfiguration; +import javax.usb.UsbConfigurationDescriptor; +import javax.usb.UsbDevice; +import javax.usb.UsbDisconnectedException; +import javax.usb.UsbException; +import javax.usb.UsbInterface; + + +/** + * UsbConfiguration implementation of usb4java. + * + * @author Klaus Reimer (k@ailis.de) + */ + +public class UsbConfigurationImpl implements UsbConfiguration +{ + /** + * Constructor. + * + * @param descriptor + * The USB configuration descriptor. + */ + + public UsbConfigurationImpl(final UsbConfigurationDescriptor descriptor) + { + // TODO Implement me! + } + + + /** + * @see javax.usb.UsbConfiguration#isActive() + */ + + @Override + public boolean isActive() + { + // TODO Implement me! + throw new UnsupportedOperationException(); + } + + + /** + * @see javax.usb.UsbConfiguration#getUsbInterfaces() + */ + + @Override + public List getUsbInterfaces() + { + // TODO Implement me! + throw new UnsupportedOperationException(); + } + + + /** + * @see javax.usb.UsbConfiguration#getUsbInterface(byte) + */ + + @Override + public UsbInterface getUsbInterface(final byte number) + { + // TODO Implement me! + throw new UnsupportedOperationException(); + } + + + /** + * @see javax.usb.UsbConfiguration#containsUsbInterface(byte) + */ + + @Override + public boolean containsUsbInterface(final byte number) + { + // TODO Implement me! + throw new UnsupportedOperationException(); + } + + + /** + * Adds a USB interface. + * + * @param iface + * The interface to add. + */ + + void addUsbInterface(final UsbInterface iface) + { + // TODO Implement me! + throw new UnsupportedOperationException(); + } + + + /** + * @see javax.usb.UsbConfiguration#getUsbDevice() + */ + + @Override + public UsbDevice getUsbDevice() + { + // TODO Implement me! + throw new UnsupportedOperationException(); + } + + + /** + * @see javax.usb.UsbConfiguration#getUsbConfigurationDescriptor() + */ + + @Override + public UsbConfigurationDescriptor getUsbConfigurationDescriptor() + { + // TODO Implement me! + throw new UnsupportedOperationException(); + } + + + /** + * @see javax.usb.UsbConfiguration#getConfigurationString() + */ + + @Override + public String getConfigurationString() throws UsbException, + UnsupportedEncodingException, UsbDisconnectedException + { + // TODO Implement me! + throw new UnsupportedOperationException(); + } +} diff --git a/src/main/java/de/ailis/usb4java/UsbDeviceImpl.java b/src/main/java/de/ailis/usb4java/UsbDeviceImpl.java new file mode 100644 index 0000000..07b388c --- /dev/null +++ b/src/main/java/de/ailis/usb4java/UsbDeviceImpl.java @@ -0,0 +1,351 @@ +/* + * Copyright (C) 2011 Klaus Reimer + * See LICENSE.txt for licensing information. + */ + +package de.ailis.usb4java; + +import java.io.UnsupportedEncodingException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import javax.usb.UsbConfiguration; +import javax.usb.UsbControlIrp; +import javax.usb.UsbDevice; +import javax.usb.UsbDeviceDescriptor; +import javax.usb.UsbDisconnectedException; +import javax.usb.UsbException; +import javax.usb.UsbPort; +import javax.usb.UsbStringDescriptor; +import javax.usb.event.UsbDeviceListener; + +import de.ailis.usb4java.jni.USBDevice; + + +/** + * UsbDevice implementation of usb4java. + * + * @author Klaus Reimer (k@ailis.de) + */ + +public class UsbDeviceImpl implements UsbDevice +{ + /** The USB configurations. */ + private final List configurations = new ArrayList(); + + /** The currently active USB configuration. */ + private byte activeConfigurationNumber = 0; + + + /** + * Constructor. + * + * @param device + * The low-level USB device. + */ + + public UsbDeviceImpl(final USBDevice device) + { + // TODO Implement me! + } + + + /** + * @see javax.usb.UsbDevice#getParentUsbPort() + */ + + @Override + public UsbPort getParentUsbPort() throws UsbDisconnectedException + { + // TODO Implement me! + throw new UnsupportedOperationException(); + } + + + /** + * @see javax.usb.UsbDevice#isUsbHub() + */ + + @Override + public boolean isUsbHub() + { + // TODO Implement me! + throw new UnsupportedOperationException(); + } + + + /** + * @see javax.usb.UsbDevice#getManufacturerString() + */ + + @Override + public String getManufacturerString() throws UsbException, + UnsupportedEncodingException, UsbDisconnectedException + { + // TODO Implement me! + throw new UnsupportedOperationException(); + } + + + /** + * @see javax.usb.UsbDevice#getSerialNumberString() + */ + + @Override + public String getSerialNumberString() throws UsbException, + UnsupportedEncodingException, UsbDisconnectedException + { + // TODO Implement me! + throw new UnsupportedOperationException(); + } + + + /** + * @see javax.usb.UsbDevice#getProductString() + */ + + @Override + public String getProductString() throws UsbException, + UnsupportedEncodingException, UsbDisconnectedException + { + // TODO Implement me! + throw new UnsupportedOperationException(); + } + + + /** + * @see javax.usb.UsbDevice#getSpeed() + */ + + @Override + public Object getSpeed() + { + // TODO Implement me! + throw new UnsupportedOperationException(); + } + + + /** + * @see javax.usb.UsbDevice#getUsbConfigurations() + */ + + @Override + public List getUsbConfigurations() + { + return Collections.unmodifiableList(this.configurations); + } + + + /** + * @see javax.usb.UsbDevice#getUsbConfiguration(byte) + */ + + @Override + public UsbConfiguration getUsbConfiguration(final byte number) + { + for (final UsbConfiguration configuration : this.configurations) + if (configuration.getUsbConfigurationDescriptor() + .bConfigurationValue() == number) + return configuration; + return null; + } + + + /** + * @see javax.usb.UsbDevice#containsUsbConfiguration(byte) + */ + + @Override + public boolean containsUsbConfiguration(final byte number) + { + for (final UsbConfiguration configuration : this.configurations) + if (configuration.getUsbConfigurationDescriptor() + .bConfigurationValue() == number) + return true; + return false; + } + + + /** + * Adds a USB configuration. + * + * @param configuration + * The USB configuration to add. + */ + + void addUsbConfiguration(final UsbConfiguration configuration) + { + if (this.configurations.contains(configuration)) + throw new IllegalStateException("configuration already added"); + this.configurations.add(configuration); + + // Use the first added configuration is the active one. + // FIXME This may be wrong. Find out how this really works. + if (this.activeConfigurationNumber == 0) + this.activeConfigurationNumber = configuration + .getUsbConfigurationDescriptor().bConfigurationValue(); + } + + + /** + * @see javax.usb.UsbDevice#getActiveUsbConfigurationNumber() + */ + + @Override + public byte getActiveUsbConfigurationNumber() + { + return this.activeConfigurationNumber; + } + + + /** + * @see javax.usb.UsbDevice#getActiveUsbConfiguration() + */ + + @Override + public UsbConfiguration getActiveUsbConfiguration() + { + return getUsbConfiguration(this.activeConfigurationNumber); + } + + + /** + * @see javax.usb.UsbDevice#isConfigured() + */ + + @Override + public boolean isConfigured() + { + // TODO Implement me! + throw new UnsupportedOperationException(); + } + + + /** + * @see javax.usb.UsbDevice#getUsbDeviceDescriptor() + */ + + @Override + public UsbDeviceDescriptor getUsbDeviceDescriptor() + { + // TODO Implement me! + throw new UnsupportedOperationException(); + } + + + /** + * @see javax.usb.UsbDevice#getUsbStringDescriptor(byte) + */ + + @Override + public UsbStringDescriptor getUsbStringDescriptor(final byte index) + throws UsbException, UsbDisconnectedException + { + // TODO Implement me! + throw new UnsupportedOperationException(); + } + + + /** + * @see javax.usb.UsbDevice#getString(byte) + */ + + @Override + public String getString(final byte index) throws UsbException, + UnsupportedEncodingException, UsbDisconnectedException + { + // TODO Implement me! + throw new UnsupportedOperationException(); + } + + + /** + * @see javax.usb.UsbDevice#syncSubmit(javax.usb.UsbControlIrp) + */ + + @Override + public void syncSubmit(final UsbControlIrp irp) throws UsbException, + IllegalArgumentException, UsbDisconnectedException + { + // TODO Implement me! + throw new UnsupportedOperationException(); + } + + + /** + * @see javax.usb.UsbDevice#asyncSubmit(javax.usb.UsbControlIrp) + */ + + @Override + public void asyncSubmit(final UsbControlIrp irp) throws UsbException, + IllegalArgumentException, UsbDisconnectedException + { + // TODO Implement me! + throw new UnsupportedOperationException(); + } + + + /** + * @see javax.usb.UsbDevice#syncSubmit(java.util.List) + */ + + @Override + public void syncSubmit(@SuppressWarnings("rawtypes") final List list) + throws UsbException, IllegalArgumentException, UsbDisconnectedException + { + // TODO Implement me! + throw new UnsupportedOperationException(); + } + + + /** + * @see javax.usb.UsbDevice#asyncSubmit(java.util.List) + */ + + @Override + public void asyncSubmit(@SuppressWarnings("rawtypes") final List list) + throws UsbException, IllegalArgumentException, UsbDisconnectedException + { + // TODO Implement me! + throw new UnsupportedOperationException(); + } + + + /** + * @see javax.usb.UsbDevice#createUsbControlIrp(byte, byte, short, short) + */ + + @Override + public UsbControlIrp createUsbControlIrp(final byte bmRequestType, + final byte bRequest, + final short wValue, final short wIndex) + { + // TODO Implement me! + throw new UnsupportedOperationException(); + } + + + /** + * @see javax.usb.UsbDevice#addUsbDeviceListener(javax.usb.event.UsbDeviceListener) + */ + + @Override + public void addUsbDeviceListener(final UsbDeviceListener listener) + { + // TODO Implement me! + throw new UnsupportedOperationException(); + } + + + /** + * @see javax.usb.UsbDevice#removeUsbDeviceListener(javax.usb.event.UsbDeviceListener) + */ + + @Override + public void removeUsbDeviceListener(final UsbDeviceListener listener) + { + // TODO Implement me! + throw new UnsupportedOperationException(); + } +} diff --git a/src/main/java/de/ailis/usb4java/UsbHubImpl.java b/src/main/java/de/ailis/usb4java/UsbHubImpl.java new file mode 100644 index 0000000..b1ec6f1 --- /dev/null +++ b/src/main/java/de/ailis/usb4java/UsbHubImpl.java @@ -0,0 +1,98 @@ +/* + * Copyright (C) 2011 Klaus Reimer + * See LICENSE.txt for licensing information. + */ + +package de.ailis.usb4java; + +import java.util.List; + +import javax.usb.UsbDevice; +import javax.usb.UsbHub; +import javax.usb.UsbPort; + +import de.ailis.usb4java.jni.USBDevice; + + +/** + * UsbHub implementation of usb4java. + * + * @author Klaus Reimer (k@ailis.de) + */ + +public class UsbHubImpl extends UsbDeviceImpl implements UsbHub +{ + /** + * Constructor. + * + * @param device + * The low-level USB device. + */ + + public UsbHubImpl(final USBDevice device) + { + super(device); + + // TODO Implement me! + } + + + /** + * @see javax.usb.UsbHub#getNumberOfPorts() + */ + + @Override + public byte getNumberOfPorts() + { + // TODO Implement me! + throw new UnsupportedOperationException(); + } + + + /** + * @see javax.usb.UsbHub#getUsbPorts() + */ + + @Override + public List getUsbPorts() + { + // TODO Implement me! + throw new UnsupportedOperationException(); + } + + + /** + * @see javax.usb.UsbHub#getUsbPort(byte) + */ + + @Override + public UsbPort getUsbPort(final byte number) + { + // TODO Implement me! + throw new UnsupportedOperationException(); + } + + + /** + * @see javax.usb.UsbHub#getAttachedUsbDevices() + */ + + @Override + public List getAttachedUsbDevices() + { + // TODO Implement me! + throw new UnsupportedOperationException(); + } + + + /** + * @see javax.usb.UsbHub#isRootUsbHub() + */ + + @Override + public boolean isRootUsbHub() + { + // TODO Implement me! + throw new UnsupportedOperationException(); + } +} diff --git a/src/main/java/de/ailis/usb4java/UsbInterfaceDescriptorImpl.java b/src/main/java/de/ailis/usb4java/UsbInterfaceDescriptorImpl.java new file mode 100644 index 0000000..16f8e8e --- /dev/null +++ b/src/main/java/de/ailis/usb4java/UsbInterfaceDescriptorImpl.java @@ -0,0 +1,135 @@ +/* + * Copyright (C) 2011 Klaus Reimer + * See LICENSE.txt for licensing information. + */ + +package de.ailis.usb4java; + +import javax.usb.UsbInterfaceDescriptor; + +import de.ailis.usb4java.jni.USBInterfaceDescriptor; + + +/** + * UsbInterfaceDescriptor implementation of usb4java. + * + * @author Klaus Reimer (k@ailis.de) + */ + +public class UsbInterfaceDescriptorImpl implements UsbInterfaceDescriptor +{ + /** The low-level USB interface descriptor. */ + private final USBInterfaceDescriptor descriptor; + + + /** + * Constructor. + * + * @param descriptor + * The low-level USB interface descriptor. + */ + + UsbInterfaceDescriptorImpl(final USBInterfaceDescriptor descriptor) + { + this.descriptor = descriptor; + } + + + /** + * @see javax.usb.UsbDescriptor#bLength() + */ + + @Override + public byte bLength() + { + return this.descriptor.bLength(); + } + + + /** + * @see javax.usb.UsbDescriptor#bDescriptorType() + */ + + @Override + public byte bDescriptorType() + { + return this.descriptor.bDescriptorType(); + } + + + /** + * @see javax.usb.UsbInterfaceDescriptor#bInterfaceNumber() + */ + + @Override + public byte bInterfaceNumber() + { + return this.descriptor.bInterfaceNumber(); + } + + + /** + * @see javax.usb.UsbInterfaceDescriptor#bAlternateSetting() + */ + + @Override + public byte bAlternateSetting() + { + return this.descriptor.bAlternateSetting(); + } + + + /** + * @see javax.usb.UsbInterfaceDescriptor#bNumEndpoints() + */ + + @Override + public byte bNumEndpoints() + { + return this.descriptor.bNumEndpoints(); + } + + + /** + * @see javax.usb.UsbInterfaceDescriptor#bInterfaceClass() + */ + + @Override + public byte bInterfaceClass() + { + return this.descriptor.bInterfaceClass(); + } + + + /** + * @see javax.usb.UsbInterfaceDescriptor#bInterfaceSubClass() + */ + + @Override + public byte bInterfaceSubClass() + { + return this.descriptor.bInterfaceSubClass(); + } + + + /** + * @see javax.usb.UsbInterfaceDescriptor#bInterfaceProtocol() + */ + + @Override + public byte bInterfaceProtocol() + { + return this.descriptor.bInterfaceProtocol(); + } + + + /** + * @see javax.usb.UsbInterfaceDescriptor#iInterface() + */ + + @Override + public byte iInterface() + { + return this.descriptor.iInterface(); + } +} diff --git a/src/main/java/de/ailis/usb4java/UsbInterfaceImpl.java b/src/main/java/de/ailis/usb4java/UsbInterfaceImpl.java new file mode 100644 index 0000000..d031601 --- /dev/null +++ b/src/main/java/de/ailis/usb4java/UsbInterfaceImpl.java @@ -0,0 +1,250 @@ +/* + * Copyright (C) 2011 Klaus Reimer + * See LICENSE.txt for licensing information. + */ + +package de.ailis.usb4java; + +import java.io.UnsupportedEncodingException; +import java.util.List; + +import javax.usb.UsbClaimException; +import javax.usb.UsbConfiguration; +import javax.usb.UsbDisconnectedException; +import javax.usb.UsbEndpoint; +import javax.usb.UsbException; +import javax.usb.UsbInterface; +import javax.usb.UsbInterfaceDescriptor; +import javax.usb.UsbInterfacePolicy; +import javax.usb.UsbNotActiveException; + + +/** + * UsbInterface implementation of usb4java. + * + * @author Klaus Reimer (k@ailis.de) + */ + +public class UsbInterfaceImpl implements UsbInterface +{ + /** + * Constructor. + * + * @param descriptor + * . The USB interface descriptor. + */ + + public UsbInterfaceImpl(final UsbInterfaceDescriptor descriptor) + { + // TODO Implement me! + throw new UnsupportedOperationException(); + } + + + /** + * @see javax.usb.UsbInterface#claim() + */ + + @Override + public void claim() throws UsbClaimException, UsbException, + UsbNotActiveException, UsbDisconnectedException + { + // TODO Implement me! + throw new UnsupportedOperationException(); + } + + + /** + * @see javax.usb.UsbInterface#claim(javax.usb.UsbInterfacePolicy) + */ + + @Override + public void claim(final UsbInterfacePolicy policy) throws UsbClaimException, + UsbException, UsbNotActiveException, UsbDisconnectedException + { + // TODO Implement me! + throw new UnsupportedOperationException(); + } + + + /** + * @see javax.usb.UsbInterface#release() + */ + + @Override + public void release() throws UsbClaimException, UsbException, + UsbNotActiveException, UsbDisconnectedException + { + // TODO Implement me! + throw new UnsupportedOperationException(); + } + + + /** + * @see javax.usb.UsbInterface#isClaimed() + */ + + @Override + public boolean isClaimed() + { + // TODO Implement me! + throw new UnsupportedOperationException(); + } + + + /** + * @see javax.usb.UsbInterface#isActive() + */ + + @Override + public boolean isActive() + { + // TODO Implement me! + throw new UnsupportedOperationException(); + } + + + /** + * @see javax.usb.UsbInterface#getNumSettings() + */ + + @Override + public int getNumSettings() + { + // TODO Implement me! + throw new UnsupportedOperationException(); + } + + + /** + * @see javax.usb.UsbInterface#getActiveSettingNumber() + */ + + @Override + public byte getActiveSettingNumber() throws UsbNotActiveException + { + // TODO Implement me! + throw new UnsupportedOperationException(); + } + + + /** + * @see javax.usb.UsbInterface#getActiveSetting() + */ + + @Override + public UsbInterface getActiveSetting() throws UsbNotActiveException + { + // TODO Implement me! + throw new UnsupportedOperationException(); + } + + + /** + * @see javax.usb.UsbInterface#getSetting(byte) + */ + + @Override + public UsbInterface getSetting(final byte number) + { + // TODO Implement me! + throw new UnsupportedOperationException(); + } + + + /** + * @see javax.usb.UsbInterface#containsSetting(byte) + */ + + @Override + public boolean containsSetting(final byte number) + { + // TODO Implement me! + throw new UnsupportedOperationException(); + } + + + /** + * @see javax.usb.UsbInterface#getSettings() + */ + + @Override + public List getSettings() + { + // TODO Implement me! + throw new UnsupportedOperationException(); + } + + + /** + * @see javax.usb.UsbInterface#getUsbEndpoints() + */ + + @Override + public List getUsbEndpoints() + { + // TODO Implement me! + throw new UnsupportedOperationException(); + } + + + /** + * @see javax.usb.UsbInterface#getUsbEndpoint(byte) + */ + + @Override + public UsbEndpoint getUsbEndpoint(final byte address) + { + // TODO Implement me! + throw new UnsupportedOperationException(); + } + + + /** + * @see javax.usb.UsbInterface#containsUsbEndpoint(byte) + */ + + @Override + public boolean containsUsbEndpoint(final byte address) + { + // TODO Implement me! + throw new UnsupportedOperationException(); + } + + + /** + * @see javax.usb.UsbInterface#getUsbConfiguration() + */ + + @Override + public UsbConfiguration getUsbConfiguration() + { + // TODO Implement me! + throw new UnsupportedOperationException(); + } + + + /** + * @see javax.usb.UsbInterface#getUsbInterfaceDescriptor() + */ + + @Override + public UsbInterfaceDescriptor getUsbInterfaceDescriptor() + { + // TODO Implement me! + throw new UnsupportedOperationException(); + } + + + /** + * @see javax.usb.UsbInterface#getInterfaceString() + */ + + @Override + public String getInterfaceString() throws UsbException, + UnsupportedEncodingException, UsbDisconnectedException + { + // TODO Implement me! + throw new UnsupportedOperationException(); + } +} diff --git a/src/main/java/de/ailis/usb4java/UsbServicesImpl.java b/src/main/java/de/ailis/usb4java/UsbServicesImpl.java new file mode 100644 index 0000000..2cfc905 --- /dev/null +++ b/src/main/java/de/ailis/usb4java/UsbServicesImpl.java @@ -0,0 +1,271 @@ +/* + * Copyright (C) 2011 Klaus Reimer + * See LICENSE.txt for licensing information. + */ + +package de.ailis.usb4java; + +import javax.usb.UsbConfiguration; +import javax.usb.UsbConfigurationDescriptor; +import javax.usb.UsbDevice; +import javax.usb.UsbException; +import javax.usb.UsbHub; +import javax.usb.UsbInterface; +import javax.usb.UsbInterfaceDescriptor; +import javax.usb.UsbServices; +import javax.usb.event.UsbServicesListener; + +import de.ailis.usb4java.jni.USB; +import de.ailis.usb4java.jni.USBBus; +import de.ailis.usb4java.jni.USBConfigDescriptor; +import de.ailis.usb4java.jni.USBDevice; +import de.ailis.usb4java.jni.USBDeviceDescriptor; +import de.ailis.usb4java.jni.USBInterface; +import de.ailis.usb4java.jni.USBInterfaceDescriptor; + + +/** + * UsbServices implementation of usb4java. + * + * @author Klaus Reimer (k@ailis.de) + */ + +public class UsbServicesImpl implements UsbServices +{ + /** The minimum implemented API version. */ + private final static String API_VERSION = "1.0.0"; + + /** The implementation description. */ + private final static String IMPL_DESCRIPTION = + "de.ailis.libusb JSR80 Implementation"; + + /** The implementation version. */ + private final static String IMPL_VERSION = "1.0.0"; + + /** The virtual root USB hub. */ + private final UsbHubImpl rootUsbHub = new VirtualRootUsbHub(); + + /** The list of registered USB services listeners. */ + private final UsbServicesListenerList usbServicesListeners = new UsbServicesListenerList(); + + + /** + * Constructor. + */ + + public UsbServicesImpl() + { + USB.usb_init(); + startUsbPolling(); + } + + + /** + * Starts the thread which polls for USB changes in regular intervals. + */ + + private void startUsbPolling() + { + final Runnable runnable = new Runnable() + { + @Override + public void run() + { + while (true) + { + pollUsb(); + try + { + Thread.sleep(500); + } + catch (final InterruptedException e) + { + // Ignored + } + } + } + }; + + final Thread pollThread = new Thread(runnable); + pollThread.setDaemon(true); + pollThread.setName("usb4java USB Polling"); + pollThread.start(); + } + + + /** + * Polls USB for changes. + */ + + void pollUsb() + { + // Poll for USB changes + final int busCount = USB.usb_find_busses(); + final int deviceCount = USB.usb_find_devices(); + + // If nothing was changed then exit immediately + if (busCount + deviceCount == 0) return; + + // Iterate over all USB busses + USBBus bus = USB.usb_get_busses(); + while (bus != null) + { + // Iterate over all USB devices of current bus + USBDevice device = bus.devices(); + while (device != null) + { + if (device.config() != null) + { + final UsbDevice usbDevice = createDevice(device); + } + device = device.next(); + } + bus = bus.next(); + } + } + + + /** + * Creates the JSR80 USB device from the specified low-level USB device. + * + * @param device + * The low-level USB device + * @return The JSR80 USB device. + */ + + private UsbDevice createDevice(final USBDevice device) + { + final USBDeviceDescriptor descriptor = device.descriptor(); + if (descriptor.bDeviceClass() == USB.USB_CLASS_HUB) + { + return new UsbHubImpl(device); + } + else + { + final UsbDeviceImpl usbDevice = new UsbDeviceImpl(device); + for (int i = 0; i < descriptor.bNumConfigurations(); i++) + { + usbDevice.addUsbConfiguration(createConfig(device.config()[i])); + } + return usbDevice; + } + } + + /** + * Creates the JSR80 USB configuration from the specified low-level USB + * configuration descriptor. + * + * @param config + * The low-level configuration descriptor. + * @return The JSR80 USB configuration. + */ + + private UsbConfiguration createConfig(final USBConfigDescriptor config) + { + final UsbConfigurationDescriptor descriptor = new UsbConfigurationDescriptorImpl( + config); + final UsbConfigurationImpl usbConfig = new UsbConfigurationImpl( + descriptor); + + for (int i = 0, iMax = config.bNumInterfaces(); i < iMax; i++) + { + final USBInterface iface = config.interface_()[i]; + for (int j = 0, jMax = iface.num_altsetting(); j < jMax; j++) + { + final USBInterfaceDescriptor ifaceDescriptor = iface + .altsetting()[j]; + usbConfig.addUsbInterface(createInterface(ifaceDescriptor)); + } + } + + return usbConfig; + } + + + /** + * Creates the JSR80 USB interface for the specified low-level USB interface + * descriptor. + * + * @param descriptor + * The low-level USB interface descriptor. + * @return The JSR80 USB interface. + */ + + private UsbInterface createInterface(final USBInterfaceDescriptor descriptor) + { + final UsbInterfaceDescriptor ifaceDescriptor = new UsbInterfaceDescriptorImpl( + descriptor); + final UsbInterface iface = new UsbInterfaceImpl(ifaceDescriptor); + + // TODO Implement me! + throw new UnsupportedOperationException(); + + // return iface; + } + + + /** + * @see javax.usb.UsbServices#getRootUsbHub() + */ + + @Override + public UsbHub getRootUsbHub() throws UsbException, SecurityException + { + return this.rootUsbHub; + } + + + /** + * @see javax.usb.UsbServices#addUsbServicesListener(javax.usb.event.UsbServicesListener) + */ + + @Override + public void addUsbServicesListener(final UsbServicesListener listener) + { + this.usbServicesListeners.addListener(listener); + } + + + /** + * @see javax.usb.UsbServices#removeUsbServicesListener(javax.usb.event.UsbServicesListener) + */ + + @Override + public void removeUsbServicesListener(final UsbServicesListener listener) + { + this.usbServicesListeners.removeListener(listener); + } + + + /** + * @see javax.usb.UsbServices#getApiVersion() + */ + + @Override + public String getApiVersion() + { + return API_VERSION; + } + + + /** + * @see javax.usb.UsbServices#getImpVersion() + */ + + @Override + public String getImpVersion() + { + return IMPL_VERSION; + } + + + /** + * @see javax.usb.UsbServices#getImpDescription() + */ + + @Override + public String getImpDescription() + { + return IMPL_DESCRIPTION; + } +} diff --git a/src/main/java/de/ailis/usb4java/UsbServicesListenerList.java b/src/main/java/de/ailis/usb4java/UsbServicesListenerList.java new file mode 100644 index 0000000..91442fe --- /dev/null +++ b/src/main/java/de/ailis/usb4java/UsbServicesListenerList.java @@ -0,0 +1,22 @@ +/* + * Copyright (C) 2011 Klaus Reimer + * See LICENSE.txt for licensing information. + */ + +package de.ailis.usb4java; + +import javax.usb.event.UsbServicesListener; + + + +/** + * Manages USB services listeners in a list. + * + * @author Klaus Reimer (k@ailis.de) + */ + +public class UsbServicesListenerList extends EventListenerList +{ + /** Serial version UID. */ + private static final long serialVersionUID = 1L; +} diff --git a/src/main/java/de/ailis/usb4java/VirtualRootUsbHub.java b/src/main/java/de/ailis/usb4java/VirtualRootUsbHub.java new file mode 100644 index 0000000..a23590b --- /dev/null +++ b/src/main/java/de/ailis/usb4java/VirtualRootUsbHub.java @@ -0,0 +1,18 @@ +/* + * Copyright (C) 2011 Klaus Reimer + * See LICENSE.txt for licensing information. + */ + +package de.ailis.usb4java; + + +/** + * The virtual root USB hub. + * + * @author Klaus Reimer (k@ailis.de) + */ + +public class VirtualRootUsbHub extends UsbHubImpl +{ + // TODO Implement me +} diff --git a/src/main/java/de/ailis/usb4java/jni/USB.java b/src/main/java/de/ailis/usb4java/jni/USB.java new file mode 100644 index 0000000..da78baa --- /dev/null +++ b/src/main/java/de/ailis/usb4java/jni/USB.java @@ -0,0 +1,195 @@ +/* + * Copyright (C) 2011 Klaus Reimer + * See LICENSE.txt for licensing information. + */ + +package de.ailis.usb4java.jni; + + +/** + * This is the main class of the usb4java JNI wrapper. It wraps the necessary + * global functions of libusb 0.x as static methods. Usage is the same as + * documented by libusb. + * + * You can use these classes to access USB at a low level but it is recommended + * to use javax.usb (JSR80) instead which usb4java implements. To do this put + * the file javax.usb.resources into the classpath with the following content: + * + * javax.usb.services = de.ailis.usb4java.UsbServicesImpl + * + * @author Klaus Reimer (k@ailis.de) + */ + +public class USB +{ + /** USB_CLASS_PER_INTERFACE constant. */ + public static final short USB_CLASS_PER_INTERFACE = 0; + + /** USB_CLASS_AUDIO constant. */ + public static final short USB_CLASS_AUDIO = 1; + + /** USB_CLASS_COMM constant. */ + public static final short USB_CLASS_COMM = 2; + + /** USB_CLASS_HID constant. */ + public static final short USB_CLASS_HID = 3; + + /** USB_CLASS_PRINTER constant. */ + public static final short USB_CLASS_PRINTER = 7; + + /** USB_CLASS_PTP constant. */ + public static final short USB_CLASS_PTP = 6; + + /** USB_CLASS_MASS_STORAGE constant. */ + public static final short USB_CLASS_MASS_STORAGE = 8; + + /** USB_CLASS_HUB constant. */ + public static final short USB_CLASS_HUB = 9; + + /** USB_CLASS_DATA constant. */ + public static final short USB_CLASS_DATA = 10; + + /** USB_CLASS_VENDOR_SPEC constant. */ + public static final short USB_CLASS_VENDOR_SPEC = 0xff; + + + static + { + try + { + System.loadLibrary("libusb-java"); + } + catch (final UnsatisfiedLinkError e) + { + System.loadLibrary("usb-java"); + } + } + + + /** + * Initialize libusb. + * + * Just like the name implies, usb_init sets up some internal structures. + * usb_init must be called before any other libusb functions. + */ + + public static native void usb_init(); + + + /** + * Finds all USB busses on system. + * + * usb_find_busses will find all of the busses on the system. Returns the + * number of changes since previous call to this function (total of new + * busses and busses removed). + * + * @return The number of changes since previous call. + */ + + public static native int usb_find_busses(); + + + /** + * Find all devices on all USB devices. + * + * usb_find_devices will find all of the devices on each bus. This should be + * called after usb_find_busses. Returns the number of changes since the + * previous call to this function (total of new device and devices removed). + * + * @return The number of changes since previous call. + */ + + public static native int usb_find_devices(); + + + /** + * Return the list of USB busses found. + * + * usb_get_busses simply returns the value of the global variable + * usb_busses. This was implemented for those languages that support C + * calling convention and can use shared libraries, but don't support C + * global variables (like Delphi). + * + * @return The list of USB busses found. + */ + + public static native USBBus usb_get_busses(); + + + /** + * Opens a USB device. + * + * usb_open is to be used to open up a device for use. usb_open must be + * called before attempting to perform any operations to the device. Returns + * a handle used in future communication with the device. + * + * @param device + * The USB device. + * @return The USB device handle. + */ + + public static native USBDevHandle usb_open(USBDevice device); + + + /** + * Closes a USB device. + * + * usb_close closes a device opened with usb_open. No further operations may + * be performed on the handle after usb_close is called. Returns 0 on + * success or < 0 on error. + * + * @param handle + * The USB device handle. + * @return 0 on success or < 0 on error. + */ + + public static native int usb_close(USBDevHandle handle); + + + /** + * Retrieves a string descriptor from a device. + * + * usb_get_string retrieves the string descriptor specified by index and + * langid from a device. The string will be returned in Unicode as specified + * by the USB specification. Returns the number of bytes returned in buf or + * < 0 on error. + * + * @param handle + * The USB device handle. + * @param index + * The string description index. + * @param langid + * The language id. + * @param buffer + * The buffer to write the string to. + * @param buflen + * The maximum number of bytes to read. + * @return The number of bytes read or < 0 on error. + */ + + public static native int usb_get_string(USBDevHandle handle, + int index, int langid, byte[] buffer, int buflen); + + + /** + * Retrieves a string descriptor from a device using the first language. + * + * usb_get_string_simple is a wrapper around usb_get_string that retrieves + * the string description specified by index in the first language for the + * descriptor and converts it into C style ASCII. Returns number of bytes + * returned in buf or < 0 on error. + * + * @param handle + * The USB device handle. + * @param index + * The string description index. + * @param buffer + * The buffer to write the string to. + * @param buflen + * The maximum number of bytes to read. + * @return The number of bytes read or < 0 on error. + */ + + public static native int usb_get_string_simple(USBDevHandle handle, + int index, byte[] buffer, int buflen); +} diff --git a/src/main/java/de/ailis/usb4java/jni/USBBus.java b/src/main/java/de/ailis/usb4java/jni/USBBus.java new file mode 100644 index 0000000..f59fc27 --- /dev/null +++ b/src/main/java/de/ailis/usb4java/jni/USBBus.java @@ -0,0 +1,96 @@ +/* + * Copyright (C) 2011 Klaus Reimer + * See LICENSE.txt for licensing information. + */ + +package de.ailis.usb4java.jni; + + +/** + * USB Bus. + * + * @author Klaus Reimer (k@ailis.de) + */ + +public class USBBus +{ + /** Pointer to low-level C structure. */ + final long pointer; + + /** + * Constructor. + * + * @param pointer + * The low-level C structure pointer. + */ + + USBBus(final long pointer) + { + this.pointer = pointer; + } + + + /** + * Returns the dirname. + * + * @return The dirname. + */ + + public native String dirname(); + + + /** + * Returns the next USB bus or null if none. + * + * @return The next USB bus or null if none. + */ + + public native USBBus next(); + + + /** + * Returns the previous USB bus or null if none. + * + * @return The previous USB bus or null if none. + */ + + public native USBBus prev(); + + + /** + * Returns the location. + * + * @return The location. + */ + + public native long location(); + + + /** + * Returns the USB devices. + * + * @return The USB devices or null if none. + */ + + public native USBDevice devices(); + + + /** + * Returns the USB root device. + * + * @return The USB root device or null if none. + */ + + public native USBDevice root_dev(); + + + /** + * @see java.lang.Object#toString() + */ + + @Override + public String toString() + { + return dirname(); + } +} diff --git a/src/main/java/de/ailis/usb4java/jni/USBConfigDescriptor.java b/src/main/java/de/ailis/usb4java/jni/USBConfigDescriptor.java new file mode 100644 index 0000000..506ed38 --- /dev/null +++ b/src/main/java/de/ailis/usb4java/jni/USBConfigDescriptor.java @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2011 Klaus Reimer + * See LICENSE.txt for licensing information. + */ + +package de.ailis.usb4java.jni; + + +/** + * USB config descriptor. + * + * @author Klaus Reimer (k@ailis.de) + */ + +public class USBConfigDescriptor +{ + /** The low-level pointer to the C structure. */ + final long pointer; + + + /** + * Constructor. + * + * @param pointer + * The low-level pointer to the C structure. + */ + + USBConfigDescriptor(final long pointer) + { + this.pointer = pointer; + } + + public native byte bLength(); + + public native byte bDescriptorType(); + + public native short wTotalLength(); + + public native byte bNumInterfaces(); + + public native byte bConfigurationValue(); + + public native byte iConfiguration(); + + public native byte bmAttributes(); + + public native byte MaxPower(); + + public native short extralen(); + + public native byte[] extra(); + + public native USBInterface[] interface_(); +} diff --git a/src/main/java/de/ailis/usb4java/jni/USBDevHandle.java b/src/main/java/de/ailis/usb4java/jni/USBDevHandle.java new file mode 100644 index 0000000..e338a1c --- /dev/null +++ b/src/main/java/de/ailis/usb4java/jni/USBDevHandle.java @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2011 Klaus Reimer + * See LICENSE.txt for licensing information. + */ + +package de.ailis.usb4java.jni; + + +/** + * USB Device handle. + * + * @author Klaus Reimer (k@ailis.de) + */ + +public class USBDevHandle +{ + /** The low-level pointer to the C structure. */ + final long pointer; + + + /** + * Constructor. + * + * @param pointer + * The low-level pointer to the C structure. + */ + + USBDevHandle(final long pointer) + { + this.pointer = pointer; + } +} diff --git a/src/main/java/de/ailis/usb4java/jni/USBDevice.java b/src/main/java/de/ailis/usb4java/jni/USBDevice.java new file mode 100644 index 0000000..d84a365 --- /dev/null +++ b/src/main/java/de/ailis/usb4java/jni/USBDevice.java @@ -0,0 +1,124 @@ +/* + * Copyright (C) 2011 Klaus Reimer + * See LICENSE.txt for licensing information. + */ + +package de.ailis.usb4java.jni; + + +/** + * USB Device. + * + * @author Klaus Reimer (k@ailis.de) + */ + +public class USBDevice +{ + /** The low-level pointer to the C structure. */ + final long pointer; + + + /** + * Constructor. + * + * @param pointer + * The low-level pointer to the C structure. + */ + + USBDevice(final long pointer) + { + this.pointer = pointer; + } + + + /** + * Returns the filename. + * + * @return The filename. + */ + + public native String filename(); + + + /** + * Returns the next USB device or null if none. + * + * @return The next USB device or null if none. + */ + + public native USBDevice next(); + + + /** + * Returns the child devices. + * + * @return The child devices. + */ + + public native USBDevice[] children(); + + + /** + * Returns the previous USB device or null if none. + * + * @return The previous USB device or null if none. + */ + + public native USBDevice prev(); + + + /** + * Returns the device number. + * + * @return The device number. + */ + + public native short devnum(); + + + /** + * Returns the number of child devices. + * + * @return The number of child devices. + */ + + public native short num_children(); + + + /** + * Returns the USB bus. + * + * @return The USB bus. + */ + + public native USBBus bus(); + + + /** + * Returns the USB device descriptor. + * + * @return The USB device descriptor. + */ + + public native USBDeviceDescriptor descriptor(); + + + /** + * Returns the USB config descriptor. + * + * @return The USB config descriptor. + */ + + public native USBConfigDescriptor[] config(); + + + /** + * @see java.lang.Object#toString() + */ + + @Override + public String toString() + { + return filename(); + } +} diff --git a/src/main/java/de/ailis/usb4java/jni/USBDeviceDescriptor.java b/src/main/java/de/ailis/usb4java/jni/USBDeviceDescriptor.java new file mode 100644 index 0000000..7ca55be --- /dev/null +++ b/src/main/java/de/ailis/usb4java/jni/USBDeviceDescriptor.java @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2011 Klaus Reimer + * See LICENSE.txt for licensing information. + */ + +package de.ailis.usb4java.jni; + + +/** + * USB device descriptor. + * + * @author Klaus Reimer (k@ailis.de) + */ + +public class USBDeviceDescriptor +{ + /** The low-level pointer to the C structure. */ + final long pointer; + + + /** + * Constructor. + * + * @param pointer + * The low-level pointer to the C structure. + */ + + USBDeviceDescriptor(final long pointer) + { + this.pointer = pointer; + } + + public native short bLength(); + + public native short bDescriptorType(); + + public native int bcdUSB(); + + public native short bDeviceClass(); + + public native short bDeviceSubClass(); + + public native short bDeviceProtocol(); + + public native short bMaxPacketSize0(); + + public native int idVendor(); + + public native int idProduct(); + + public native int bcdDevice(); + + public native short iManufacturer(); + + public native short iProduct(); + + public native short iSerialNumber(); + + public native short bNumConfigurations(); +} diff --git a/src/main/java/de/ailis/usb4java/jni/USBEndpointDescriptor.java b/src/main/java/de/ailis/usb4java/jni/USBEndpointDescriptor.java new file mode 100644 index 0000000..d16caa6 --- /dev/null +++ b/src/main/java/de/ailis/usb4java/jni/USBEndpointDescriptor.java @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2011 Klaus Reimer + * See LICENSE.txt for licensing information. + */ + +package de.ailis.usb4java.jni; + + +/** + * USB endport descriptor. + * + * @author Klaus Reimer (k@ailis.de) + */ + +public class USBEndpointDescriptor +{ + /** The low-level pointer to the C structure. */ + final long pointer; + + + /** + * Constructor. + * + * @param pointer + * The low-level pointer to the C structure. + */ + + USBEndpointDescriptor(final long pointer) + { + this.pointer = pointer; + } + + public native byte bLength(); + + public native byte bDescriptorType(); + + public native byte bEndpointAddress(); + + public native byte bmAttributes(); + + public native short wMaxPacketSize(); + + public native byte bInterval(); + + public native byte bRefresh(); + + public native byte bSynchAddress(); + + public native byte[] extra(); + + public native int extralen(); +} diff --git a/src/main/java/de/ailis/usb4java/jni/USBInterface.java b/src/main/java/de/ailis/usb4java/jni/USBInterface.java new file mode 100644 index 0000000..6be8471 --- /dev/null +++ b/src/main/java/de/ailis/usb4java/jni/USBInterface.java @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2011 Klaus Reimer + * See LICENSE.txt for licensing information. + */ + +package de.ailis.usb4java.jni; + + +/** + * USB interface. + * + * @author Klaus Reimer (k@ailis.de) + */ + +public class USBInterface +{ + /** The low-level pointer to the C structure. */ + final long pointer; + + + /** + * Constructor. + * + * @param pointer + * The low-level pointer to the C structure. + */ + + USBInterface(final long pointer) + { + this.pointer = pointer; + } + + public native USBInterfaceDescriptor[] altsetting(); + + public native int num_altsetting(); +} diff --git a/src/main/java/de/ailis/usb4java/jni/USBInterfaceDescriptor.java b/src/main/java/de/ailis/usb4java/jni/USBInterfaceDescriptor.java new file mode 100644 index 0000000..7af7001 --- /dev/null +++ b/src/main/java/de/ailis/usb4java/jni/USBInterfaceDescriptor.java @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2011 Klaus Reimer + * See LICENSE.txt for licensing information. + */ + +package de.ailis.usb4java.jni; + + +/** + * USB interface descriptor. + * + * @author Klaus Reimer (k@ailis.de) + */ + +public class USBInterfaceDescriptor +{ + /** The low-level pointer to the C structure. */ + final long pointer; + + + /** + * Constructor. + * + * @param pointer + * The low-level pointer to the C structure. + */ + + USBInterfaceDescriptor(final long pointer) + { + this.pointer = pointer; + } + + public native byte bLength(); + + public native byte bDescriptorType(); + + public native byte bInterfaceNumber(); + + public native byte bAlternateSetting(); + + public native byte bNumEndpoints(); + + public native byte bInterfaceClass(); + + public native byte bInterfaceSubClass(); + + public native byte bInterfaceProtocol(); + + public native byte iInterface(); + + public native USBEndpointDescriptor[] endpoint(); + + public native byte[] extra(); + + public native int extralen(); +} diff --git a/src/main/resources/javax.usb.properties b/src/main/resources/javax.usb.properties new file mode 100644 index 0000000..963f899 --- /dev/null +++ b/src/main/resources/javax.usb.properties @@ -0,0 +1,165 @@ +# +# Properties file for javax.usb +# +# This file is provided by the Linux implementation of javax.usb. +# +# The 2.4 kernel does not support control-type queueing nor interrupt-type +# queueing (see below to enable javax.usb internal queueing). +# +# Some 2.4 kernels do not properly handle hotplug notification, specifically +# those somewhere after 2.4.19. See below to enable polling instead. +# + +################################################################################ +# Properties required/used by javax.usb API +################################################################################ + +# This is required by the API, this is the class that the API will create +# to implement UsbServices. +#javax.usb.services = com.ibm.jusb.os.linux.LinuxUsbServices +javax.usb.services = de.ailis.usb4java.UsbServicesImpl + +################################################################################ +# Properties required/used by javax.usb Common Reference Implementation +################################################################################ + +# These properties enable queueing for different pipe types. If the operating +# system does not support queueing for a particular pipe type (or at all), +# enable queueing here. This queueing is most likely much slower than OS-level +# queueing, so if the OS supports queueing, these should not be enabled. +com.ibm.jusb.UsbPipeImp.queueSubmissions.control = true +#com.ibm.jusb.UsbPipeImp.queueSubmissions.interrupt = false +#com.ibm.jusb.UsbPipeImp.queueSubmissions.isochronous = false +#com.ibm.jusb.UsbPipeImp.queueSubmissions.bulk = false + +# This property is similar to the UsbPipe-specific queueing properties, but +# this applies only to the Default Control Pipe queueing. +com.ibm.jusb.UsbDeviceImp.queueSubmissions = true + +# This property causes the common implementation to enforce short packet error conditions. +# If set, it checks each UsbIrp for a short packet condition upon completion, and if +# one is detected with no exception (and the accept short packet flag set to false), +# it creates a UsbShortPacketException and sets it on the UsbIrp. +# This should only be set to true for platform implementations that do not support/create +# short packet exceptions. +#com.ibm.jusb.UsbIrpImp.createShortPacketException = false + +# This property sets the default UsbTracer implementation. The default is the NullUsbTracer, +# which does no tracing at all. These implementations are provided, or you can create your own: +# com.ibm.jusb.util.NullUsbTracer +# com.ibm.jusb.util.StandardOutUsbTracer +# com.ibm.jusb.util.StandardErrorUsbTracer +#com.ibm.jusb.util.UsbTracer=com.ibm.jusb.util.NullUsbTracer + +# These set the default name and level of the "global" UsbTracer object. The level may be specified +# as any of these defines: +# TRACE_CRITICAL +# TRACE_ERROR +# TRACE_WARN +# TRACE_NOTICE +# TRACE_INFO +# TRACE_DEBUG +#com.ibm.jusb.util.UsbTracer.global.name=Main UsbTracer +#com.ibm.jusb.util.UsbTracer.global.level=TRACE_DEBUG + +# This sets the level of messages that the StandardOutUsbTracer prints. Trace messages with +# lower priority than this will not be printed. This may be specified as any of the +# level defines listed above. +#com.ibm.jusb.util.StandardOutUsbTracer.currentLevel=TRACE_DEBUG + +# This sets the level of messages that the StandardErrorUsbTracer prints. Trace messages with +# lower priority than this will not be printed. This may be specified as any of the +# level defines listed above. +#com.ibm.jusb.util.StandardErrorUsbTracer.currentLevel=TRACE_DEBUG + +################################################################################ +# Properties required/used by javax.usb Linux Implementation +################################################################################ + +# If polling should be used instead of waiting for a hotplug notification. +# Some kernel versions have a bug, and don't update the device node(s) until +# many seconds after waking up threads waiting on the devices file. +# If you are not getting hotplug events on a moderately to heavily loaded system, +# use polling. +# Note that since the new (buggy?) kernel behavior breaks javax.usb, this defaults to true! +# If you know your kernel isn't broken you can set this to false. +#com.ibm.jusb.os.linux.LinuxUsbServices.topologyUpdateUsePolling = true + +# If polling is disabled, this is how long in ms to delay after a +# hotplug event is signalled to re-enumerate the USB bus. +# If polling is enabled, this is how often to poll. +#com.ibm.jusb.os.linux.LinuxUsbServices.topologyUpdateDelay = 5000 + +# After new device(s) are detected, the device's driver is probably taking its +# sweet time talking to them. This delay lets the Linux driver (if any) have some time to +# talk before we send a device connection event, which may cause an application +# to immediately start talking to the device. +#com.ibm.jusb.os.linux.LinuxUsbServices.topologyUpdateNewDeviceDelay = 500 + +################################################################################ +# Tracing properties used by javax.usb Linux Implementation +################################################################################ + +# These rest apply to JNI tracing levels. This is a little better than it used to be, +# but it needs more improvement as far as controlling the tracers and levels. + +# This either disables tracing entirely, or enables some amount of tracing. +#com.ibm.jusb.os.linux.LinuxUsbServices.JNI.tracing = true + +# This defines where the JNI tracing output is sent. +# The default is stderr. Note that if append mode is used, the trace file will +# grow ever-larger every time javax.usb is run, and its size should be managed +# somehow. In file mode, the file size will not be managed/limited by javax.usb. +# 1 - stdout +# 2 - stderr +# 3 - file (truncate mode) +# 4 - file (append mode) +#com.ibm.jusb.os.linux.LinuxUsbServices.JNI.trace_output = 2 + +# This is the filename to trace to, if trace_output is set to file tracing. +# There is NO DEFAULT to this, it must be set if trace_output is set to file tracing. +#com.ibm.jusb.os.linux.LinuxUsbServices.JNI.trace_filename = + +# This sets the tracing level. Higher levels mean more tracing. +# This level applies to ALL tracers. See each tracer for their levels. +#com.ibm.jusb.os.linux.LinuxUsbServices.JNI.trace_level = 0 + +# This enables or disables default tracing. This is the most used tracer. +# The trace_data must also be enabled. +# These are the levels for this tracer. +# 0 - CRITICAL +# 1 - ERROR +# 2 - INFO +# 3 - FUNCTION +# 4 - DEBUG +# 5 - OTHER +#com.ibm.jusb.os.linux.LinuxUsbServices.JNI.trace_default = true + +# This enables or disables hotplug tracing. +# The trace_data must also be enabled. +# These are the levels for this tracer. +# 0 - CRITICAL +# 1 - ERROR +# 2 - CHANGE +# 3 - DEVICE +# 4 - OTHER +#com.ibm.jusb.os.linux.LinuxUsbServices.JNI.trace_hotplug = true + +# This enables or disables xfer tracing. +# The trace_data must also be enabled. +# These are the levels for this tracer. +# 0 - CRITICAL +# 1 - ERROR +# 2 - REQUEST +# 3 - METADATA +# 4 - DATA +# 5 - OTHER +#com.ibm.jusb.os.linux.LinuxUsbServices.JNI.trace_xfer = true + +# This enables or disables urb tracing. +# The trace_data must also be enabled. +# WARNING! DATA-level tracing will generate a LOT of output. +# These are the levels for this tracer. +# 2 - METADATA +# 3 - DATA +#com.ibm.jusb.os.linux.LinuxUsbServices.JNI.trace_urb = false diff --git a/src/test/comparison/Makefile b/src/test/comparison/Makefile new file mode 100644 index 0000000..6dbe7dc --- /dev/null +++ b/src/test/comparison/Makefile @@ -0,0 +1,5 @@ +all: dump + +dump: dump.c + gcc -lusb -o dump dump.c + \ No newline at end of file diff --git a/src/test/comparison/dump.c b/src/test/comparison/dump.c new file mode 100644 index 0000000..8a85097 --- /dev/null +++ b/src/test/comparison/dump.c @@ -0,0 +1,212 @@ +#include +#include + +int level = 0; + +void indent() +{ + int i; + + for (i = 0; i < level; i++) printf(" "); +} + +void dump_device_descriptor(struct usb_device_descriptor descriptor) +{ + indent(); printf("bLength: 0x%02x\n", descriptor.bLength); + indent(); printf("bDescriptorType: 0x%02x\n", descriptor.bDescriptorType); + indent(); printf("bcdUSB: 0x%04x\n", descriptor.bcdUSB); + indent(); printf("bDeviceClass: 0x%02x\n", descriptor.bDeviceClass); + indent(); printf("bDeviceSubClass: 0x%02x\n", descriptor.bDeviceSubClass); + indent(); printf("bDeviceProtocol: 0x%02x\n", descriptor.bDeviceProtocol); + indent(); printf("bMaxPacketSize0: 0x%02x\n", descriptor.bMaxPacketSize0); + indent(); printf("idVendor: 0x%04x\n", descriptor.idVendor); + indent(); printf("idProduct: 0x%04x\n", descriptor.idProduct); + indent(); printf("bcdDevice: 0x%04x\n", descriptor.bcdDevice); + indent(); printf("iManufacturer: 0x%02x\n", descriptor.iManufacturer); + indent(); printf("iProduct: 0x%02x\n", descriptor.iProduct); + indent(); printf("iSerialNumber: 0x%02x\n", descriptor.iSerialNumber); + indent(); printf("bNumConfigurations: 0x%02x\n", descriptor.bNumConfigurations); +} + +void dump_endpoint_descriptor(struct usb_endpoint_descriptor descriptor) +{ + int i; + + indent(); printf("Endpoint\n"); + level++; + indent(); printf("bLength: 0x%02x\n", descriptor.bLength); + indent(); printf("bDescriptorType: 0x%02x\n", descriptor.bDescriptorType); + indent(); printf("bEndpointAddress: 0x%02x\n", descriptor.bEndpointAddress); + indent(); printf("bmAttributes: 0x%02x\n", descriptor.bmAttributes); + indent(); printf("wMaxPacketSize: 0x%04x\n", descriptor.wMaxPacketSize); + indent(); printf("bInterval: 0x%02x\n", descriptor.bInterval); + indent(); printf("bRefresh: 0x%02x\n", descriptor.bRefresh); + indent(); printf("bSynchAddress: 0x%02x\n", descriptor.bSynchAddress); + indent(); printf("extralen: 0x%04x\n", descriptor.extralen); + indent(); printf("extra:"); + for (i = 0; i < descriptor.extralen; i++) + printf(" %02x", descriptor.extra[i]); + printf("\n"); + level--; +} + +void dump_interface_descriptor(struct usb_interface_descriptor descriptor) +{ + int i; + + indent(); printf("Interface descriptor:\n"); + level++; + indent(); printf("bLength: 0x%02x\n", descriptor.bLength); + indent(); printf("bDescriptorType: 0x%02x\n", descriptor.bDescriptorType); + indent(); printf("bInterfaceNumber: 0x%02x\n", descriptor.bInterfaceNumber); + indent(); printf("bAlternateSetting: 0x%02x\n", descriptor.bAlternateSetting); + indent(); printf("bNumEndpoints: 0x%02x\n", descriptor.bNumEndpoints); + indent(); printf("bInterfaceClass: 0x%02x\n", descriptor.bInterfaceClass); + indent(); printf("bInterfaceSubClass: 0x%02x\n", descriptor.bInterfaceSubClass); + indent(); printf("bInterfaceProtocol: 0x%02x\n", descriptor.bInterfaceProtocol); + indent(); printf("iInterface: 0x%02x\n", descriptor.iInterface); + indent(); printf("extralen: 0x%04x\n", descriptor.extralen); + indent(); printf("extra:"); + for (i = 0; i < descriptor.extralen; i++) + printf(" %02x", descriptor.extra[i]); + printf("\n"); + indent(); printf("Endpoints:\n"); + level++; + for (i = 0; i < descriptor.bNumEndpoints; i++) + dump_endpoint_descriptor(descriptor.endpoint[i]); + level--; + level--; +} + +void dump_interface(struct usb_interface iface) +{ + int i; + + indent(); printf("Interface:\n"); + level++; + indent(); printf("num_altsetting: 0x%04x\n", iface.num_altsetting); + indent(); printf("altsetting:\n"); + level++; + for (i = 0; i < iface.num_altsetting; i++) + dump_interface_descriptor(iface.altsetting[i]); + level--; + level--; +} + +void dump_config_descriptor(struct usb_config_descriptor config) +{ + int i, max; + + indent(); printf("Config Descriptor:\n"); + level++; + indent(); printf("bLength: 0x%02x\n", config.bLength); + indent(); printf("bDescriptorType: 0x%02x\n", config.bDescriptorType); + indent(); printf("wTotalLength: 0x%04x\n", config.wTotalLength); + indent(); printf("bNumInterfaces: 0x%02x\n", config.bNumInterfaces); + indent(); printf("bConfigurationValue: 0x%02x\n", config.bConfigurationValue); + indent(); printf("iConfiguration: 0x%02x\n", config.iConfiguration); + indent(); printf("bmAttributes: 0x%02x\n", config.bmAttributes); + indent(); printf("MaxPower: 0x%02x\n", config.MaxPower); + indent(); printf("extralen: 0x%04x\n", config.extralen); + indent(); printf("extra:"); + for (i = 0; i < config.extralen; i++) + printf(" %02x", config.extra[i]); + printf("\n"); + indent(); printf("Interfaces:\n"); + level++; + for (i = 0; i < config.bNumInterfaces; i++) + dump_interface(config.interface[i]); + level--; + level--; +} + +void dump_device(struct usb_device *device) +{ + int i, buffer[256]; + + indent(); printf("Device:\n"); + level++; + indent(); printf("filename: %s\n", device->filename); + indent(); printf("bus: %s\n", device->bus->dirname); + indent(); printf("devnum: %i\n", device->devnum); + indent(); printf("num_children: %i\n", device->num_children); + indent(); printf("descriptor:\n"); + level++; + dump_device_descriptor(device->descriptor); + level--; + struct usb_handle *handle = usb_open(device); + i = usb_get_string_simple(handle, device->descriptor.iManufacturer, buffer, 255); + indent(); printf("Manufacturer: %s\n", i > 0 ? buffer : "Unknown"); + i = usb_get_string_simple(handle, device->descriptor.iProduct, buffer, 255); + indent(); printf("Product: %s\n", i > 0 ? buffer : "Unknown"); + i = usb_get_string_simple(handle, device->descriptor.iSerialNumber, buffer, 255); + indent(); printf("Serial: %s\n", i > 0 ? buffer : "Unknown"); + usb_close(handle); + indent(); printf("config descriptors:\n"); + level++; + int max = device->descriptor.bNumConfigurations; + if (max == 0) + { + indent(); printf("None\n"); + } + else + { + for (i = 0; i < max; i++) + { + dump_config_descriptor(device->config[i]); + } + } + level--; + indent(); printf("children:\n"); + level++; + if (device->num_children == 0) + { + indent(); printf("None\n"); + } + else + { + for (i = 0; i< device->num_children; i++) + dump_device(device->children[i]); + } + level--; + level--; +} + +int main(int argc, char *argv[]) +{ + usb_init(); + int bus_count = usb_find_busses(); + printf("Found %i busses\n", bus_count); + int dev_count = usb_find_devices(); + printf("Found %i devices\n", dev_count); + + struct usb_bus *bus = usb_get_busses(); + while (bus) + { + printf("Bus:\n"); + level++; + indent(); printf("dirname: %s\n", bus->dirname); + indent(); printf("location: %i\n", bus->location); + indent(); printf("Root device: "); + level++; + if (bus->root_dev) + printf("%s/%s\n", bus->root_dev->bus->dirname, + bus->root_dev->filename); + else + printf("None\n"); + level--; + indent(); printf("devices: \n"); + level++; + struct usb_device *device = bus->devices; + while (device) + { + dump_device(device); + device = device->next; + } + level--; + level--; + + printf("\n"); + bus = bus->next; + } +} diff --git a/src/test/java/de/ailis/usb4java/Dump.java b/src/test/java/de/ailis/usb4java/Dump.java new file mode 100644 index 0000000..f60cdaf --- /dev/null +++ b/src/test/java/de/ailis/usb4java/Dump.java @@ -0,0 +1,243 @@ +/* + * Copyright (C) 2011 Klaus Reimer + * See LICENSE.txt for licensing information. + */ + +package de.ailis.usb4java; + +import de.ailis.usb4java.jni.USB; +import de.ailis.usb4java.jni.USBBus; +import de.ailis.usb4java.jni.USBConfigDescriptor; +import de.ailis.usb4java.jni.USBDevHandle; +import de.ailis.usb4java.jni.USBDevice; +import de.ailis.usb4java.jni.USBDeviceDescriptor; +import de.ailis.usb4java.jni.USBEndpointDescriptor; +import de.ailis.usb4java.jni.USBInterface; +import de.ailis.usb4java.jni.USBInterfaceDescriptor; + + +/** + * Dump + * + * @author Klaus Reimer (k@ailis.de) + */ + +public class Dump +{ + private static int level = 0; + + private static void indent() + { + int i; + + for (i = 0; i < level; i++) System.out.format(" "); + } + + private static void dump_device_descriptor(final USBDeviceDescriptor descriptor) + { + indent(); System.out.format("bLength: 0x%02x\n", descriptor.bLength()); + indent(); System.out.format("bDescriptorType: 0x%02x\n", descriptor.bDescriptorType()); + indent(); System.out.format("bcdUSB: 0x%04x\n", descriptor.bcdUSB()); + indent(); System.out.format("bDeviceClass: 0x%02x\n", descriptor.bDeviceClass()); + indent(); System.out.format("bDeviceSubClass: 0x%02x\n", descriptor.bDeviceSubClass()); + indent(); System.out.format("bDeviceProtocol: 0x%02x\n", descriptor.bDeviceProtocol()); + indent(); System.out.format("bMaxPacketSize0: 0x%02x\n", descriptor.bMaxPacketSize0()); + indent(); System.out.format("idVendor: 0x%04x\n", descriptor.idVendor()); + indent(); System.out.format("idProduct: 0x%04x\n", descriptor.idProduct()); + indent(); System.out.format("bcdDevice: 0x%04x\n", descriptor.bcdDevice()); + indent(); System.out.format("iManufacturer: 0x%02x\n", descriptor.iManufacturer()); + indent(); System.out.format("iProduct: 0x%02x\n", descriptor.iProduct()); + indent(); System.out.format("iSerialNumber: 0x%02x\n", descriptor.iSerialNumber()); + indent(); System.out.format("bNumConfigurations: 0x%02x\n", descriptor.bNumConfigurations()); + } + + private static void dump_endpoint_descriptor(final USBEndpointDescriptor descriptor) + { + int i; + + indent(); System.out.format("Endpoint\n"); + level++; + indent(); System.out.format("bLength: 0x%02x\n", descriptor.bLength()); + indent(); System.out.format("bDescriptorType: 0x%02x\n", descriptor.bDescriptorType()); + indent(); System.out.format("bEndpointAddress: 0x%02x\n", descriptor.bEndpointAddress()); + indent(); System.out.format("bmAttributes: 0x%02x\n", descriptor.bmAttributes()); + indent(); System.out.format("wMaxPacketSize: 0x%04x\n", descriptor.wMaxPacketSize()); + indent(); System.out.format("bInterval: 0x%02x\n", descriptor.bInterval()); + indent(); System.out.format("bRefresh: 0x%02x\n", descriptor.bRefresh()); + indent(); System.out.format("bSynchAddress: 0x%02x\n", descriptor.bSynchAddress()); + indent(); System.out.format("extralen: 0x%04x\n", descriptor.extralen()); + indent(); System.out.format("extra:"); + for (i = 0; i < descriptor.extralen(); i++) + System.out.format(" %02x", descriptor.extra()[i]); + System.out.format("\n"); + level--; + } + + private static void dump_interface_descriptor(final USBInterfaceDescriptor descriptor) + { + int i; + + indent(); System.out.format("Interface descriptor:\n"); + level++; + indent(); System.out.format("bLength: 0x%02x\n", descriptor.bLength()); + indent(); System.out.format("bDescriptorType: 0x%02x\n", descriptor.bDescriptorType()); + indent(); System.out.format("bInterfaceNumber: 0x%02x\n", descriptor.bInterfaceNumber()); + indent(); System.out.format("bAlternateSetting: 0x%02x\n", descriptor.bAlternateSetting()); + indent(); System.out.format("bNumEndpoints: 0x%02x\n", descriptor.bNumEndpoints()); + indent(); System.out.format("bInterfaceClass: 0x%02x\n", descriptor.bInterfaceClass()); + indent(); System.out.format("bInterfaceSubClass: 0x%02x\n", descriptor.bInterfaceSubClass()); + indent(); System.out.format("bInterfaceProtocol: 0x%02x\n", descriptor.bInterfaceProtocol()); + indent(); System.out.format("iInterface: 0x%02x\n", descriptor.iInterface()); + indent(); System.out.format("extralen: 0x%04x\n", descriptor.extralen()); + indent(); System.out.format("extra:"); + for (i = 0; i < descriptor.extralen(); i++) + System.out.format(" %02x", descriptor.extra()[i]); + System.out.format("\n"); + indent(); System.out.format("Endpoints:\n"); + level++; + for (i = 0; i < descriptor.bNumEndpoints(); i++) + dump_endpoint_descriptor(descriptor.endpoint()[i]); + level--; + level--; + } + + private static void dump_interface(final USBInterface iface) + { + int i; + + indent(); System.out.format("Interface:\n"); + level++; + indent(); System.out.format("num_altsetting: 0x%04x\n", iface.num_altsetting()); + indent(); System.out.format("altsetting:\n"); + level++; + for (i = 0; i < iface.num_altsetting(); i++) + dump_interface_descriptor(iface.altsetting()[i]); + level--; + level--; + } + + private static void dump_config_descriptor(final USBConfigDescriptor config) + { + int i; + final int max; + + indent(); System.out.format("Config Descriptor:\n"); + level++; + indent(); System.out.format("bLength: 0x%02x\n", config.bLength()); + indent(); System.out.format("bDescriptorType: 0x%02x\n", config.bDescriptorType()); + indent(); System.out.format("wTotalLength: 0x%04x\n", config.wTotalLength()); + indent(); System.out.format("bNumInterfaces: 0x%02x\n", config.bNumInterfaces()); + indent(); System.out.format("bConfigurationValue: 0x%02x\n", config.bConfigurationValue()); + indent(); System.out.format("iConfiguration: 0x%02x\n", config.iConfiguration()); + indent(); System.out.format("bmAttributes: 0x%02x\n", config.bmAttributes()); + indent(); System.out.format("MaxPower: 0x%02x\n", config.MaxPower()); + indent(); System.out.format("extralen: 0x%04x\n", config.extralen()); + indent(); System.out.format("extra:"); + for (i = 0; i < config.extralen(); i++) + System.out.format(" %02x", config.extra()[i]); + System.out.format("\n"); + indent(); System.out.format("Interfaces:\n"); + level++; + for (i = 0; i < config.bNumInterfaces(); i++) + dump_interface(config.interface_()[i]); + level--; + level--; + } + + private static void dump_device(final USBDevice device) + { + int i; + final byte[] buffer = new byte[256]; + + indent(); System.out.format("Device:\n"); + level++; + indent(); System.out.format("filename: %s\n", device.filename()); + indent(); System.out.format("bus: %s\n", device.bus().dirname()); + indent(); System.out.format("devnum: %i\n", device.devnum()); + indent(); System.out.format("num_children: %i\n", device.num_children()); + indent(); System.out.format("descriptor:\n"); + level++; + dump_device_descriptor(device.descriptor()); + level--; + // Rename me to USBHandle + final USBDevHandle handle = USB.usb_open(device); + i = USB.usb_get_string_simple(handle, device.descriptor().iManufacturer(), buffer, 255); + indent(); System.out.format("Manufacturer: %s\n", i > 0 ? buffer : "Unknown"); + i = USB.usb_get_string_simple(handle, device.descriptor().iProduct(), buffer, 255); + indent(); System.out.format("Product: %s\n", i > 0 ? buffer : "Unknown"); + i = USB.usb_get_string_simple(handle, device.descriptor().iSerialNumber(), buffer, 255); + indent(); System.out.format("Serial: %s\n", i > 0 ? buffer : "Unknown"); + USB.usb_close(handle); + indent(); System.out.format("config descriptors:\n"); + level++; + final int max = device.descriptor().bNumConfigurations(); + if (max == 0) + { + indent(); System.out.format("None\n"); + } + else + { + for (i = 0; i < max; i++) + { + dump_config_descriptor(device.config()[i]); + } + } + level--; + indent(); System.out.format("children:\n"); + level++; + if (device.num_children() == 0) + { + indent(); System.out.format("None\n"); + } + else + { + for (i = 0; i< device.num_children(); i++) + dump_device(device.children()[i]); + } + level--; + level--; + } + + /** + * Main method. + */ + + public static void main(final String[] args) + { + USB.usb_init(); + final int bus_count = USB.usb_find_busses(); + System.out.format("Found %i busses\n", bus_count); + final int dev_count = USB.usb_find_devices(); + System.out.format("Found %i devices\n", dev_count); + + USBBus bus = USB.usb_get_busses(); + while (bus != null) + { + System.out.format("Bus:\n"); + level++; + indent(); System.out.format("dirname: %s\n", bus.dirname()); + indent(); System.out.format("location: %i\n", bus.location()); + indent(); System.out.format("Root device: "); + level++; + if (bus.root_dev() != null) + System.out.format("%s/%s\n", bus.root_dev().bus().dirname(), + bus.root_dev().filename()); + else + System.out.format("None\n"); + level--; + indent(); System.out.format("devices: \n"); + level++; + USBDevice device = bus.devices(); + while (device != null) + { + dump_device(device); + device = device.next(); + } + level--; + level--; + + System.out.format("\n"); + bus = bus.next(); + } + } +}