diff --git a/LibusbJava/LibusbJava.cpp b/LibusbJava/LibusbJava.cpp index 85b4694..f224d66 100644 --- a/LibusbJava/LibusbJava.cpp +++ b/LibusbJava/LibusbJava.cpp @@ -1,9 +1,23 @@ -/******************************************************************************************** - * Java libusb1.0 wrapper - * Copyright (c) 2010-2011 Roger Millischer +/*! \file + * \brief Java libusb1.0 wrapper * - * This libary is covered by the LGPL, read LGPL.txt for details - *******************************************************************************************/ + * \copyright 2010-2012 NTB Interstate University of Applied Sciences of Technology Buchs + * This libary is covered by the LGPL, read LGPL.txt for details + * + * \author Roger Millischer (original author) + * \author Ueli Niederer (modifications and enhancements) + * + * \todo Currently all the pointers and handles passed to and received from libusb are coded + * in long values to get them in JVM. + * Clebert Suconic ( http://planet.jboss.org/post/pointers_in_jni_c ) suggests a + * possibly more elegant way to deal with this issue: + * Make use of the ByteBuffer-Class delivered by with the native IO package. + * (java.nio). As this class is made to store the start pointer to native buffers + * we could create a "ByteBuffer" of length 0 where the start address represents + * e.g. the handle. This can be done using the following JNI Call: + * env->NewDirectByteBuffer(myPointer, 0); // size = 0, you don't want anyone to change it + */ + /******************************************************************************************** * * Includes @@ -59,6 +73,8 @@ static void LIBUSB_CALL fd_removed_callback(int fd, void *user_data); * *******************************************************************************************/ static __inline jbyteArray JNICALL to_byteArray(JNIEnv *env, const void *data, size_t len); +static __inline void JNICALL ThrowIfUnsuccessful(JNIEnv *env, int libusb_result); +static __inline void JNICALL ThrowLibusbError(JNIEnv *env, jint code); /******************************************************************************************** * @@ -695,13 +711,17 @@ JNIEXPORT void JNICALL Java_ch_ntb_inf_libusbJava_LibusbJava1_libusb_1unref_1dev ********************************************************************************************/ JNIEXPORT jlong JNICALL Java_ch_ntb_inf_libusbJava_LibusbJava1_libusb_1open( JNIEnv *env, jclass obj, jobject dev) { clearLibusbJavaError(); - libusb_device_handle *handle; + libusb_device_handle *handle = NULL; libusb_device *libusb_dev = (libusb_device *) (unsigned long) env->GetLongField(dev, usb_devFID_devStructAddr); int res = libusb_open(libusb_dev, &handle); - if(!res){ - return (jlong) handle; + + if(res != 0) + { + ThrowLibusbError(env, res); + handle = NULL; } - return (jlong)res; + + return (jlong)handle; } /******************************************************************************************** @@ -940,76 +960,82 @@ JNIEXPORT jobject JNICALL Java_ch_ntb_inf_libusbJava_LibusbJava1_libusb_1get_1de /******************************************************************************************** * Class: ch_ntb_inf_libusbJava_LibusbJava1 * Method: libusb_get_configuration - * Signature: (J)B + * Signature: (J)I ********************************************************************************************/ -JNIEXPORT jbyte JNICALL Java_ch_ntb_inf_libusbJava_LibusbJava1_libusb_1get_1configuration(JNIEnv *env, jclass obj, jlong handle) { - int config; +JNIEXPORT jint JNICALL Java_ch_ntb_inf_libusbJava_LibusbJava1_libusb_1get_1configuration(JNIEnv *env, jclass obj, jlong handle) { + int config = 0; + int libusb_result = 0; + clearLibusbJavaError(); - if (libusb_get_configuration((libusb_device_handle*) (unsigned long) handle, &config)) { + libusb_result = libusb_get_configuration((libusb_device_handle*) (unsigned long) handle, &config); + + if (libusb_result != 0) { setLibusbJavaError("shared library error: get_configuration failed"); - return -1; + ThrowLibusbError(env, libusb_result); + config = 0; } + return config; } /******************************************************************************************** * Class: ch_ntb_inf_libusbJava_LibusbJava1 * Method: libusb_set_configuration - * Signature: (JI)I + * Signature: (JI)V ********************************************************************************************/ -JNIEXPORT jint JNICALL Java_ch_ntb_inf_libusbJava_LibusbJava1_libusb_1set_1configuration(JNIEnv *env, jclass obj, jlong handle, jint config) { +JNIEXPORT void JNICALL Java_ch_ntb_inf_libusbJava_LibusbJava1_libusb_1set_1configuration(JNIEnv *env, jclass obj, jlong handle, jint config) { clearLibusbJavaError(); - return libusb_set_configuration((libusb_device_handle*) (unsigned long) handle, config); + ThrowIfUnsuccessful(env, libusb_set_configuration((libusb_device_handle*) (unsigned long) handle, config)); } /******************************************************************************************** * Class: ch_ntb_inf_libusbJava_LibusbJava1 * Method: libusb_claim_interface - * Signature: (JI)I + * Signature: (JI)V ********************************************************************************************/ -JNIEXPORT jint JNICALL Java_ch_ntb_inf_libusbJava_LibusbJava1_libusb_1claim_1interface(JNIEnv *env, jclass obj, jlong handle, jint iNumber) { +JNIEXPORT void JNICALL Java_ch_ntb_inf_libusbJava_LibusbJava1_libusb_1claim_1interface(JNIEnv *env, jclass obj, jlong handle, jint iNumber) { clearLibusbJavaError(); - return libusb_claim_interface((libusb_device_handle*) (unsigned long) handle, iNumber); + ThrowIfUnsuccessful(env, libusb_claim_interface((libusb_device_handle*) (unsigned long) handle, iNumber)); } /******************************************************************************************** * Class: ch_ntb_inf_libusbJava_LibusbJava1 * Method: libusb_release_interface - * Signature: (JI)I + * Signature: (JI)V ********************************************************************************************/ -JNIEXPORT jint JNICALL Java_ch_ntb_inf_libusbJava_LibusbJava1_libusb_1release_1interface(JNIEnv *env, jclass obj, jlong handle, jint iNumber) { +JNIEXPORT void JNICALL Java_ch_ntb_inf_libusbJava_LibusbJava1_libusb_1release_1interface(JNIEnv *env, jclass obj, jlong handle, jint iNumber) { clearLibusbJavaError(); - return libusb_release_interface((libusb_device_handle*) (unsigned long) handle, iNumber); + ThrowIfUnsuccessful(env, libusb_release_interface((libusb_device_handle*) (unsigned long) handle, iNumber)); } /******************************************************************************************** * Class: ch_ntb_inf_libusbJava_LibusbJava1 * Method: libusb_set_interface_alt_setting - * Signature: (JII)I + * Signature: (JII)V ********************************************************************************************/ -JNIEXPORT jint JNICALL Java_ch_ntb_inf_libusbJava_LibusbJava1_libusb_1set_1interface_1alt_1setting(JNIEnv *env, jclass obj, jlong handle, jint iNumber, jint altSet) { +JNIEXPORT void JNICALL Java_ch_ntb_inf_libusbJava_LibusbJava1_libusb_1set_1interface_1alt_1setting(JNIEnv *env, jclass obj, jlong handle, jint iNumber, jint altSet) { clearLibusbJavaError(); - return libusb_set_interface_alt_setting((libusb_device_handle*) (unsigned long) handle, iNumber, altSet); + ThrowIfUnsuccessful(env, libusb_set_interface_alt_setting((libusb_device_handle*) (unsigned long) handle, iNumber, altSet)); } /******************************************************************************************** * Class: ch_ntb_inf_libusbJava_LibusbJava1 * Method: libusb_clear_halt - * Signature: (JS)I + * Signature: (JS)V ********************************************************************************************/ -JNIEXPORT jint JNICALL Java_ch_ntb_inf_libusbJava_LibusbJava1_libusb_1clear_1halt(JNIEnv *env, jclass obj, jlong handle, jshort ep) { +JNIEXPORT void JNICALL Java_ch_ntb_inf_libusbJava_LibusbJava1_libusb_1clear_1halt(JNIEnv *env, jclass obj, jlong handle, jshort ep) { clearLibusbJavaError(); - return libusb_clear_halt((libusb_device_handle*) (unsigned long) handle, ep); + ThrowIfUnsuccessful(env, libusb_clear_halt((libusb_device_handle*) (unsigned long) handle, ep)); } /******************************************************************************************** * Class: ch_ntb_inf_libusbJava_LibusbJava1 * Method: libusb_reset_device - * Signature: (J)I + * Signature: (J)V ********************************************************************************************/ -JNIEXPORT jint JNICALL Java_ch_ntb_inf_libusbJava_LibusbJava1_libusb_1reset_1device(JNIEnv *env, jclass obj, jlong handle) { +JNIEXPORT void JNICALL Java_ch_ntb_inf_libusbJava_LibusbJava1_libusb_1reset_1device(JNIEnv *env, jclass obj, jlong handle) { clearLibusbJavaError(); - return libusb_reset_device((libusb_device_handle*) (unsigned long) handle); + ThrowIfUnsuccessful(env, libusb_reset_device((libusb_device_handle*) (unsigned long) handle)); } /******************************************************************************************** @@ -1018,28 +1044,38 @@ JNIEXPORT jint JNICALL Java_ch_ntb_inf_libusbJava_LibusbJava1_libusb_1reset_1dev * Signature: (JI)I ********************************************************************************************/ JNIEXPORT jint JNICALL Java_ch_ntb_inf_libusbJava_LibusbJava1_libusb_1kernel_1driver_1active(JNIEnv *env, jclass obj, jlong handle, jint iNumber) { + int libusb_result = 0; + clearLibusbJavaError(); - return libusb_kernel_driver_active((libusb_device_handle*) (unsigned long) handle, iNumber); + libusb_result = libusb_kernel_driver_active((libusb_device_handle*) (unsigned long) handle, iNumber); + + if (libusb_result < 0) + { + ThrowLibusbError(env, libusb_result); + libusb_result = 0; + } + + return libusb_result; } /******************************************************************************************** * Class: ch_ntb_inf_libusbJava_LibusbJava1 * Method: libusb_detach_kernel_driver - * Signature: (JI)I + * Signature: (JI)V ********************************************************************************************/ -JNIEXPORT jint JNICALL Java_ch_ntb_inf_libusbJava_LibusbJava1_libusb_1detach_1kernel_1driver(JNIEnv *env, jclass obj, jlong handle, jint iNumber) { +JNIEXPORT void JNICALL Java_ch_ntb_inf_libusbJava_LibusbJava1_libusb_1detach_1kernel_1driver(JNIEnv *env, jclass obj, jlong handle, jint iNumber) { clearLibusbJavaError(); - return libusb_detach_kernel_driver((libusb_device_handle*) (unsigned long) handle, iNumber); + ThrowIfUnsuccessful(env, libusb_detach_kernel_driver((libusb_device_handle*) (unsigned long) handle, iNumber)); } /******************************************************************************************** * Class: ch_ntb_inf_libusbJava_LibusbJava1 * Method: libusb_attach_kernel_driver - * Signature: (JI)I + * Signature: (JI)V ********************************************************************************************/ -JNIEXPORT jint JNICALL Java_ch_ntb_inf_libusbJava_LibusbJava1_libusb_1attach_1kernel_1driver(JNIEnv *env, jclass obj, jlong handle, jint iNumber) { +JNIEXPORT void JNICALL Java_ch_ntb_inf_libusbJava_LibusbJava1_libusb_1attach_1kernel_1driver(JNIEnv *env, jclass obj, jlong handle, jint iNumber) { clearLibusbJavaError(); - return libusb_attach_kernel_driver((libusb_device_handle*) (unsigned long) handle, iNumber); + ThrowIfUnsuccessful(env, libusb_attach_kernel_driver((libusb_device_handle*) (unsigned long) handle, iNumber)); } /******************************************************************************************** @@ -1196,13 +1232,20 @@ JNIEXPORT jstring JNICALL Java_ch_ntb_inf_libusbJava_LibusbJava1_libusb_1get_1st jstring string; int res = 0; clearLibusbJavaError(); - unsigned char data[(int)length]; + unsigned char data[(int)length + 1]; + res = libusb_get_string_descriptor_ascii((libusb_device_handle*) (unsigned long) handle, desc_index, data, (int)length); - if (res > 0) { + + if (res >= 0) + { + data[res] = '\0'; string = env->NewStringUTF((const char*)data); - } else { + } + else + { setLibusbJavaError("get_string_descriptor_ascii: retrieve String failed"); string = NULL; + ThrowLibusbError(env, res); } return string; } @@ -1223,6 +1266,7 @@ JNIEXPORT jbyteArray JNICALL Java_ch_ntb_inf_libusbJava_LibusbJava1_libusb_1get_ res = libusb_get_descriptor((libusb_device_handle*) (unsigned long) handle, desc_type, desc_index, data, size); if (res < 0) { setLibusbJavaError("libusb_get_descriptor: retrieve data failed"); + ThrowLibusbError(env, res); return NULL; } @@ -1238,16 +1282,19 @@ JNICALL Java_ch_ntb_inf_libusbJava_LibusbJava1_libusb_1get_1string_1descriptor(J clearLibusbJavaError(); int res; jstring string; - unsigned char data[(int)size]; + unsigned char data[(int)size + 1]; res = libusb_get_string_descriptor((libusb_device_handle*) (unsigned long) handle, desc_index, langid, data, size); - res = 0; - if (res > 0) { + + if (res >= 0) { + data[res] = '\0'; string = env->NewStringUTF((const char*) data); } else { setLibusbJavaError("get_string_descriptor: retrieve String failed"); string = NULL; + ThrowLibusbError(env, res); } + return string; } @@ -1274,21 +1321,21 @@ JNIEXPORT void JNICALL Java_ch_ntb_inf_libusbJava_LibusbJava1_libusb_1free_1tran /******************************************************************************************** * Class: ch_ntb_inf_libusbJava_LibusbJava1 * Method: libusb_submit_transfer - * Signature: (J)I + * Signature: (J)V ********************************************************************************************/ -JNIEXPORT jint JNICALL Java_ch_ntb_inf_libusbJava_LibusbJava1_libusb_1submit_1transfer(JNIEnv *env, jclass obj, jlong transfernumber) { +JNIEXPORT void JNICALL Java_ch_ntb_inf_libusbJava_LibusbJava1_libusb_1submit_1transfer(JNIEnv *env, jclass obj, jlong transfernumber) { clearLibusbJavaError(); - return libusb_submit_transfer((libusb_transfer*) (unsigned long) transfernumber); + ThrowIfUnsuccessful(env, libusb_submit_transfer((libusb_transfer*) (unsigned long) transfernumber)); } /******************************************************************************************** * Class: ch_ntb_inf_libusbJava_LibusbJava1 * Method: libusb_cancel_transfer - * Signature: (J)I + * Signature: (J)V ********************************************************************************************/ -JNIEXPORT jint JNICALL Java_ch_ntb_inf_libusbJava_LibusbJava1_libusb_1cancel_1transfer(JNIEnv *env, jclass obj, jlong transfernumber) { +JNIEXPORT void JNICALL Java_ch_ntb_inf_libusbJava_LibusbJava1_libusb_1cancel_1transfer(JNIEnv *env, jclass obj, jlong transfernumber) { clearLibusbJavaError(); - return libusb_cancel_transfer((libusb_transfer*) (unsigned long) transfernumber); + ThrowIfUnsuccessful(env, libusb_cancel_transfer((libusb_transfer*) (unsigned long) transfernumber)); } /******************************************************************************************** * Class: ch_ntb_inf_libusbJava_LibusbJava1 @@ -1304,7 +1351,7 @@ JNIEXPORT jbyteArray JNICALL Java_ch_ntb_inf_libusbJava_LibusbJava1_libusb_1cont return NULL; data = libusb_control_transfer_get_data(trans); - return to_byteArray(env, data, trans->actual_length - 8); + return to_byteArray(env, data, trans->actual_length - LIBUSB_CONTROL_SETUP_SIZE ); } /********************************************************************************************* @@ -1547,43 +1594,50 @@ JNIEXPORT jint JNICALL Java_ch_ntb_inf_libusbJava_LibusbJava1_libusb_1wait_1for_ /******************************************************************************************** * Class: ch_ntb_inf_libusbJava_LibusbJava1 * Method: libusb_handle_events_timeout - * Signature: (JJ)I + * Signature: (JJ)V ********************************************************************************************/ -JNIEXPORT jint JNICALL Java_ch_ntb_inf_libusbJava_LibusbJava1_libusb_1handle_1events_1timeout(JNIEnv *env, jclass obj, jlong ctx, jlong timevalue) { +JNIEXPORT void JNICALL Java_ch_ntb_inf_libusbJava_LibusbJava1_libusb_1handle_1events_1timeout(JNIEnv *env, jclass obj, jlong ctx, jlong timevalue) { clearLibusbJavaError(); - if (timevalue) { + if (timevalue != 0) + { timeval tv; tv.tv_sec = timevalue; tv.tv_usec = 0; - return libusb_handle_events_timeout((libusb_context*) (unsigned long) ctx, &tv); + ThrowIfUnsuccessful(env, libusb_handle_events_timeout((libusb_context*) (unsigned long) ctx, &tv)); + } + else + { + ThrowIfUnsuccessful(env, libusb_handle_events_timeout((libusb_context*) (unsigned long) ctx, NULL)); } - return libusb_handle_events_timeout((libusb_context*) (unsigned long) ctx, NULL); } /******************************************************************************************** * Class: ch_ntb_inf_libusbJava_LibusbJava1 * Method: libusb_handle_events - * Signature: (J)I + * Signature: (J)V ********************************************************************************************/ -JNIEXPORT jint JNICALL Java_ch_ntb_inf_libusbJava_LibusbJava1_libusb_1handle_1events(JNIEnv *env, jclass obj, jlong ctx) { +JNIEXPORT void JNICALL Java_ch_ntb_inf_libusbJava_LibusbJava1_libusb_1handle_1events(JNIEnv *env, jclass obj, jlong ctx) { clearLibusbJavaError(); - return libusb_handle_events((libusb_context*) (unsigned long) ctx); + ThrowIfUnsuccessful(env, libusb_handle_events((libusb_context*) (unsigned long) ctx)); } /******************************************************************************************** * Class: ch_ntb_inf_libusbJava_LibusbJava1 * Method: libusb_handle_events_locked - * Signature: (JJ)I + * Signature: (JJ)V ********************************************************************************************/ -JNIEXPORT jint JNICALL Java_ch_ntb_inf_libusbJava_LibusbJava1_libusb_1handle_1events_1locked(JNIEnv *env, jclass obj, jlong ctx, jlong timevalue) { +JNIEXPORT void JNICALL Java_ch_ntb_inf_libusbJava_LibusbJava1_libusb_1handle_1events_1locked(JNIEnv *env, jclass obj, jlong ctx, jlong timevalue) { clearLibusbJavaError(); if (timevalue) { timeval tv; tv.tv_sec = timevalue; tv.tv_usec = 0; - return libusb_handle_events_locked((libusb_context*) (unsigned long) ctx, &tv); + ThrowIfUnsuccessful(env, libusb_handle_events_locked((libusb_context*) (unsigned long) ctx, &tv)); + } + else + { + ThrowIfUnsuccessful(env, libusb_handle_events_locked((libusb_context*) (unsigned long) ctx, NULL)); } - return libusb_handle_events_locked((libusb_context*) (unsigned long) ctx, NULL); } /******************************************************************************************** @@ -1604,20 +1658,26 @@ JNIEXPORT jint JNICALL Java_ch_ntb_inf_libusbJava_LibusbJava1_libusb_1pollfds_1h JNIEXPORT jint JNICALL Java_ch_ntb_inf_libusbJava_LibusbJava1_libusb_1get_1next_1timeout(JNIEnv *env, jclass obj, jlong ctx) { clearLibusbJavaError(); int res; - long time; - timeval* tv = (timeval*) malloc(sizeof(struct timeval)); + timeval tv; - res = libusb_get_next_timeout((libusb_context*) (unsigned long) ctx, tv); + /*! \todo Is this code working correctly if we use it in a 64-Bit environment? Actually + * it's unlikely to have a timeout of more than 2^(31)-1 seconds. But it is a + * possible value. */ + res = libusb_get_next_timeout((libusb_context*) (unsigned long) ctx, &tv); - if (res > 0) { - time = tv->tv_sec; - free(tv); - return time; + if (res > 0) + { + res = tv.tv_sec; } - free(tv); - if (res == 0) { - return -999; + else if (res == 0) { + res = -1; } + else + { + ThrowLibusbError(env, res); + res = -2; + } + return res; } @@ -1628,11 +1688,14 @@ JNIEXPORT jint JNICALL Java_ch_ntb_inf_libusbJava_LibusbJava1_libusb_1get_1next_ ********************************************************************************************/ JNIEXPORT void JNICALL Java_ch_ntb_inf_libusbJava_LibusbJava1_libusb_1set_1pollfd_1notifiers(JNIEnv *env, jclass obj, jlong ctx, jboolean remove) { clearLibusbJavaError(); - if (remove) { + if (remove) + { libusb_set_pollfd_notifiers((libusb_context*) (unsigned long) ctx, NULL, NULL, env); - return; } - libusb_set_pollfd_notifiers((libusb_context*) (unsigned long) ctx, fd_added_callback, fd_removed_callback, env); + else + { + libusb_set_pollfd_notifiers((libusb_context*) (unsigned long) ctx, fd_added_callback, fd_removed_callback, env); + } } /******************************************************************************************** @@ -1697,16 +1760,20 @@ JNIEXPORT jint JNICALL Java_ch_ntb_inf_libusbJava_LibusbJava1_libusb_1control_1t ********************************************************************************************/ JNIEXPORT jint JNICALL Java_ch_ntb_inf_libusbJava_LibusbJava1_libusb_1bulk_1transfer(JNIEnv *env, jclass obj, jlong handle, jbyte endpoint, jbyteArray buffer, jint length, jint timeout) { clearLibusbJavaError(); - int res, actual_length; - unsigned char* data; + int libusb_result = 0; + int bytes_transferred = 0; + unsigned char* data = (unsigned char*) env->GetByteArrayElements(buffer, NULL); - data = (unsigned char*) env->GetByteArrayElements(buffer, NULL); - res = libusb_bulk_transfer((libusb_device_handle*) (unsigned long) handle, endpoint, data, length, &actual_length, timeout); + libusb_result = libusb_bulk_transfer((libusb_device_handle*) (unsigned long) handle, endpoint, data, length, &bytes_transferred, timeout); env->ReleaseByteArrayElements(buffer, (jbyte*) data, 0); - if (res) { - return res; + + if (libusb_result != 0) + { + ThrowLibusbError(env, libusb_result); + bytes_transferred = 0; } - return actual_length; + + return bytes_transferred; } /******************************************************************************************** @@ -1716,16 +1783,19 @@ JNIEXPORT jint JNICALL Java_ch_ntb_inf_libusbJava_LibusbJava1_libusb_1bulk_1tran ********************************************************************************************/ JNIEXPORT jint JNICALL Java_ch_ntb_inf_libusbJava_LibusbJava1_libusb_1interrupt_1transfer(JNIEnv *env, jclass obj, jlong handle, jbyte endpoint, jbyteArray buffer, jint length, jint timeout) { clearLibusbJavaError(); - int res, actual_length; - unsigned char* data; - - data = (unsigned char*) env->GetByteArrayElements(buffer, NULL); - res = libusb_interrupt_transfer((libusb_device_handle*) (unsigned long) handle, endpoint, data, length, &actual_length, timeout); + int libusb_result; + int bytes_transferred = 0; + unsigned char* data = (unsigned char*) env->GetByteArrayElements(buffer, NULL); + libusb_result = libusb_interrupt_transfer((libusb_device_handle*) (unsigned long) handle, endpoint, data, length, &bytes_transferred, timeout); env->ReleaseByteArrayElements(buffer, (jbyte*) data, 0); - if (res) { - return res; + + if (libusb_result != 0) + { + ThrowLibusbError(env, libusb_result); + bytes_transferred = 0; } - return actual_length; + + return bytes_transferred; } /******************************************************************************************** @@ -1734,17 +1804,27 @@ JNIEXPORT jint JNICALL Java_ch_ntb_inf_libusbJava_LibusbJava1_libusb_1interrupt_ * Signature: ()Ljava/lang/String; ********************************************************************************************/ JNIEXPORT jstring JNICALL Java_ch_ntb_inf_libusbJava_LibusbJava1_libusb_1strerror(JNIEnv *env, jclass obj) { - char *str; + char *str = "Libusb-1.0 Error"; + /* check for LibusbJava specific errors first*/ if (libusbJavaError != NULL) { str = libusbJavaError; clearLibusbJavaError(); - } else { - str = "Libusb-1.0 Error"; } + return env->NewStringUTF(str); } +/* + * Class: ch_ntb_inf_libusbJava_LibusbJava1 + * Method: libusb_exceptionTest + * Signature: (I)V + */ +JNIEXPORT void JNICALL Java_ch_ntb_inf_libusbJava_LibusbJava1_libusb_1exceptionTest(JNIEnv *env, jclass obj, jint code) +{ + ThrowLibusbError(env, code); +} + /******************************************************************************************** * Class: LibusbJava_1_0.cpp * Method: transfer_callback @@ -1814,3 +1894,74 @@ static __inline jbyteArray JNICALL to_byteArray(JNIEnv *env, const void *data, s return result; } +/*! \brief Convenience function that throws an exception in the callers environment if + * the given result is not "success" + * + * This function can be used to wrap calls to the libusb if no further reaction + * on a unsuccessful result is needed, than throwing an exception in the java + * environment. + * + * \param env Java environment of the caller + * \param libusb_result Result code of the libusb call + */ +static __inline void JNICALL ThrowIfUnsuccessful(JNIEnv *env, int libusb_result) +{ + if (libusb_result != 0) + { + ThrowLibusbError(env, libusb_result); + } +} + +/*! \brief Throws an exception of type LibusbError in the calling Java environment. + * + * \param env Environment to throw the exception in + * \param code Error code that represents the cause of the exception + */ +static __inline void JNICALL ThrowLibusbError(JNIEnv *env, jint code) +{ + jmethodID constructor = NULL; + jthrowable exception = NULL; + + jclass clazz = env->FindClass("ch/ntb/inf/libusbJava/exceptions/LibusbError"); + if (clazz == NULL) + { + goto no_class; + } + + constructor = env->GetMethodID(clazz, "", "(I)V"); + if (constructor == NULL) + { + goto no_constructor; + } + + exception = (jthrowable)env->NewObject(clazz, constructor, code); + if (exception == NULL) + { + goto no_object; + } + + if (env->Throw(exception) != 0) + { + goto throw_failed; + } + + env->DeleteLocalRef(exception); + env->DeleteLocalRef(clazz); + + return; + +/* Error Handling. All errors covered here are caused by JNI callbacks and have + * therefore already thrown appropriate exceptions in the Java environment. + * Therefore we only have to cleanup what we constructed. */ +throw_failed: + env->DeleteLocalRef(exception); + +no_object: + +no_constructor: + env->DeleteLocalRef(clazz); + +no_class: + + return; +} diff --git a/LibusbJava/LibusbJava.h b/LibusbJava/LibusbJava.h index 91ee071..fe3348a 100644 --- a/LibusbJava/LibusbJava.h +++ b/LibusbJava/LibusbJava.h @@ -106,57 +106,57 @@ JNIEXPORT jobject JNICALL Java_ch_ntb_inf_libusbJava_LibusbJava1_libusb_1get_1de /* * Class: ch_ntb_inf_libusbJava_LibusbJava1 * Method: libusb_get_configuration - * Signature: (J)B + * Signature: (J)I */ -JNIEXPORT jbyte JNICALL Java_ch_ntb_inf_libusbJava_LibusbJava1_libusb_1get_1configuration +JNIEXPORT jint JNICALL Java_ch_ntb_inf_libusbJava_LibusbJava1_libusb_1get_1configuration (JNIEnv *, jclass, jlong); /* * Class: ch_ntb_inf_libusbJava_LibusbJava1 * Method: libusb_set_configuration - * Signature: (JI)I + * Signature: (JI)V */ -JNIEXPORT jint JNICALL Java_ch_ntb_inf_libusbJava_LibusbJava1_libusb_1set_1configuration +JNIEXPORT void JNICALL Java_ch_ntb_inf_libusbJava_LibusbJava1_libusb_1set_1configuration (JNIEnv *, jclass, jlong, jint); /* * Class: ch_ntb_inf_libusbJava_LibusbJava1 * Method: libusb_claim_interface - * Signature: (JI)I + * Signature: (JI)V */ -JNIEXPORT jint JNICALL Java_ch_ntb_inf_libusbJava_LibusbJava1_libusb_1claim_1interface +JNIEXPORT void JNICALL Java_ch_ntb_inf_libusbJava_LibusbJava1_libusb_1claim_1interface (JNIEnv *, jclass, jlong, jint); /* * Class: ch_ntb_inf_libusbJava_LibusbJava1 * Method: libusb_release_interface - * Signature: (JI)I + * Signature: (JI)V */ -JNIEXPORT jint JNICALL Java_ch_ntb_inf_libusbJava_LibusbJava1_libusb_1release_1interface +JNIEXPORT void JNICALL Java_ch_ntb_inf_libusbJava_LibusbJava1_libusb_1release_1interface (JNIEnv *, jclass, jlong, jint); /* * Class: ch_ntb_inf_libusbJava_LibusbJava1 * Method: libusb_set_interface_alt_setting - * Signature: (JII)I + * Signature: (JII)V */ -JNIEXPORT jint JNICALL Java_ch_ntb_inf_libusbJava_LibusbJava1_libusb_1set_1interface_1alt_1setting +JNIEXPORT void JNICALL Java_ch_ntb_inf_libusbJava_LibusbJava1_libusb_1set_1interface_1alt_1setting (JNIEnv *, jclass, jlong, jint, jint); /* * Class: ch_ntb_inf_libusbJava_LibusbJava1 * Method: libusb_clear_halt - * Signature: (JS)I + * Signature: (JS)V */ -JNIEXPORT jint JNICALL Java_ch_ntb_inf_libusbJava_LibusbJava1_libusb_1clear_1halt +JNIEXPORT void JNICALL Java_ch_ntb_inf_libusbJava_LibusbJava1_libusb_1clear_1halt (JNIEnv *, jclass, jlong, jshort); /* * Class: ch_ntb_inf_libusbJava_LibusbJava1 * Method: libusb_reset_device - * Signature: (J)I + * Signature: (J)V */ -JNIEXPORT jint JNICALL Java_ch_ntb_inf_libusbJava_LibusbJava1_libusb_1reset_1device +JNIEXPORT void JNICALL Java_ch_ntb_inf_libusbJava_LibusbJava1_libusb_1reset_1device (JNIEnv *, jclass, jlong); /* @@ -170,17 +170,17 @@ JNIEXPORT jint JNICALL Java_ch_ntb_inf_libusbJava_LibusbJava1_libusb_1kernel_1dr /* * Class: ch_ntb_inf_libusbJava_LibusbJava1 * Method: libusb_detach_kernel_driver - * Signature: (JI)I + * Signature: (JI)V */ -JNIEXPORT jint JNICALL Java_ch_ntb_inf_libusbJava_LibusbJava1_libusb_1detach_1kernel_1driver +JNIEXPORT void JNICALL Java_ch_ntb_inf_libusbJava_LibusbJava1_libusb_1detach_1kernel_1driver (JNIEnv *, jclass, jlong, jint); /* * Class: ch_ntb_inf_libusbJava_LibusbJava1 * Method: libusb_attach_kernel_driver - * Signature: (JI)I + * Signature: (JI)V */ -JNIEXPORT jint JNICALL Java_ch_ntb_inf_libusbJava_LibusbJava1_libusb_1attach_1kernel_1driver +JNIEXPORT void JNICALL Java_ch_ntb_inf_libusbJava_LibusbJava1_libusb_1attach_1kernel_1driver (JNIEnv *, jclass, jlong, jint); /* @@ -234,17 +234,17 @@ JNIEXPORT void JNICALL Java_ch_ntb_inf_libusbJava_LibusbJava1_libusb_1free_1tran /* * Class: ch_ntb_inf_libusbJava_LibusbJava1 * Method: libusb_submit_transfer - * Signature: (J)I + * Signature: (J)V */ -JNIEXPORT jint JNICALL Java_ch_ntb_inf_libusbJava_LibusbJava1_libusb_1submit_1transfer +JNIEXPORT void JNICALL Java_ch_ntb_inf_libusbJava_LibusbJava1_libusb_1submit_1transfer (JNIEnv *, jclass, jlong); /* * Class: ch_ntb_inf_libusbJava_LibusbJava1 * Method: libusb_cancel_transfer - * Signature: (J)I + * Signature: (J)V */ -JNIEXPORT jint JNICALL Java_ch_ntb_inf_libusbJava_LibusbJava1_libusb_1cancel_1transfer +JNIEXPORT void JNICALL Java_ch_ntb_inf_libusbJava_LibusbJava1_libusb_1cancel_1transfer (JNIEnv *, jclass, jlong); /* @@ -394,25 +394,25 @@ JNIEXPORT jint JNICALL Java_ch_ntb_inf_libusbJava_LibusbJava1_libusb_1wait_1for_ /* * Class: ch_ntb_inf_libusbJava_LibusbJava1 * Method: libusb_handle_events_timeout - * Signature: (JJ)I + * Signature: (JJ)V */ -JNIEXPORT jint JNICALL Java_ch_ntb_inf_libusbJava_LibusbJava1_libusb_1handle_1events_1timeout +JNIEXPORT void JNICALL Java_ch_ntb_inf_libusbJava_LibusbJava1_libusb_1handle_1events_1timeout (JNIEnv *, jclass, jlong, jlong); /* * Class: ch_ntb_inf_libusbJava_LibusbJava1 * Method: libusb_handle_events - * Signature: (J)I + * Signature: (J)V */ -JNIEXPORT jint JNICALL Java_ch_ntb_inf_libusbJava_LibusbJava1_libusb_1handle_1events +JNIEXPORT void JNICALL Java_ch_ntb_inf_libusbJava_LibusbJava1_libusb_1handle_1events (JNIEnv *, jclass, jlong); /* * Class: ch_ntb_inf_libusbJava_LibusbJava1 * Method: libusb_handle_events_locked - * Signature: (JJ)I + * Signature: (JJ)V */ -JNIEXPORT jint JNICALL Java_ch_ntb_inf_libusbJava_LibusbJava1_libusb_1handle_1events_1locked +JNIEXPORT void JNICALL Java_ch_ntb_inf_libusbJava_LibusbJava1_libusb_1handle_1events_1locked (JNIEnv *, jclass, jlong, jlong); /* @@ -479,6 +479,14 @@ JNIEXPORT jint JNICALL Java_ch_ntb_inf_libusbJava_LibusbJava1_libusb_1interrupt_ JNIEXPORT jstring JNICALL Java_ch_ntb_inf_libusbJava_LibusbJava1_libusb_1strerror (JNIEnv *, jclass); +/* + * Class: ch_ntb_inf_libusbJava_LibusbJava1 + * Method: libusb_exceptionTest + * Signature: (I)V + */ +JNIEXPORT void JNICALL Java_ch_ntb_inf_libusbJava_LibusbJava1_libusb_1exceptionTest + (JNIEnv *, jclass, jint); + #ifdef __cplusplus } #endif diff --git a/java/src/ch/ntb/inf/libusbJava/Device.java b/java/src/ch/ntb/inf/libusbJava/Device.java index 8979a14..6315937 100644 --- a/java/src/ch/ntb/inf/libusbJava/Device.java +++ b/java/src/ch/ntb/inf/libusbJava/Device.java @@ -223,9 +223,9 @@ public class Device { if (dev != null) { long res = LibusbJava.usb_open(dev); - if (res <= 0) { + if (res == 0) { throw new USBException("LibusbJava.usb_open: " - + LibusbJava.usb_strerror() + " (" + res + ")"); + + LibusbJava.usb_strerror()); } usbDevHandle = res; } diff --git a/java/src/ch/ntb/inf/libusbJava/LibusbJava.java b/java/src/ch/ntb/inf/libusbJava/LibusbJava.java index 0e6f398..e86cfcd 100644 --- a/java/src/ch/ntb/inf/libusbJava/LibusbJava.java +++ b/java/src/ch/ntb/inf/libusbJava/LibusbJava.java @@ -6,11 +6,14 @@ * This library is covered by the LGPL, read LGPL.txt for details. * * Changes: + * 12.04.2012 NTB / Ueli Niederer implemented exception handling * 18.10.2010 NTB / Roger Millischer change from native interface to compatibility layer * */ package ch.ntb.inf.libusbJava; +import ch.ntb.inf.libusbJava.exceptions.LibusbError; + /** * This class is used as compatibility layer for libusb 0.1 projects. For new * projects use {@link LibusbJava1} @@ -26,10 +29,12 @@ public class LibusbJava { * This list is not complete! For more error codes see the file 'errorno.h' * on your system. */ - public static int ERROR_SUCCESS, ERROR_BAD_FILE_DESCRIPTOR, - ERROR_NO_SUCH_DEVICE_OR_ADDRESS, ERROR_BUSY, - ERROR_INVALID_PARAMETER, ERROR_TIMEDOUT, ERROR_IO_ERROR, - ERROR_NOT_ENOUGH_MEMORY;; + public static final int ERROR_SUCCESS = LibusbError.ERROR_NONE; + public static final int ERROR_BUSY = LibusbError.ERROR_BUSY; + public static final int ERROR_INVALID_PARAMETER = LibusbError.ERROR_INVALID_PARAM; + public static final int ERROR_TIMEDOUT = LibusbError.ERROR_TIMEOUT; + public static final int ERROR_IO_ERROR = LibusbError.ERROR_IO; + public static final int ERROR_NOT_ENOUGH_MEMORY = LibusbError.ERROR_NO_MEM; /** * Sets the debugging level of libusb.
@@ -51,17 +56,18 @@ public class LibusbJava { * functions. */ public static void usb_init() { - if (defaultCTX > 0) { + if (defaultCTX != 0) { return; } - defaultCTX = LibusbJava1.libusb_init(); + try { + defaultCTX = LibusbJava1.libusb_init(); + } catch (LibusbError e) { + System.err.println("LibusbJava-1.0 init failed with errorcode: " + + e.getMessage()); + e.printStackTrace(); + defaultCTX = 0; + } LibusbJava1.libusb_set_debug(0, 0); - if (defaultCTX < 0) { - System.out.println("LibusbJava-1.0 init failed with errorcode: " - + defaultCTX); - return; - } - } /** @@ -78,7 +84,7 @@ public class LibusbJava { boolean found = false; Usb_Device devices = null; devices = LibusbJava1.libusb_get_device_list(0); - + // no busses if (devices.getDevnum() == -1) { while (busses != null) { @@ -286,8 +292,19 @@ public class LibusbJava { * error has occurred. */ public static long usb_open(Usb_Device dev) { -// return LibusbJava1.libusb_open_device_with_vid_pid(defaultCTX, dev.getDescriptor().getIdVendor(), dev.getDescriptor().getIdProduct()); - return LibusbJava1.libusb_open(dev); + long handle = 0; + + try { + handle = LibusbJava1.libusb_open(dev); + } + catch (LibusbError e) { + System.err.println("LibusbJava-1.0 init failed with errorcode: " + + e.getMessage()); + e.printStackTrace(); + handle = 0; + } + + return handle; } /** @@ -313,7 +330,15 @@ public class LibusbJava { * @return 0 on success or < 0 on error. */ public static int usb_set_configuration(long dev_handle, int configuration) { - return LibusbJava1.libusb_set_configuration(dev_handle, configuration); + int result = 0; + + try { + LibusbJava1.libusb_set_configuration(dev_handle, configuration); + } catch (LibusbError e) { + result = -1; + } + + return result; } /** @@ -330,21 +355,37 @@ public class LibusbJava { Usb_Device dev = LibusbJava1.libusb_get_device(dev_handle); int nofInterfaces = LibusbJava1 .libusb_get_active_config_descriptor(dev).getBNumInterfaces(); - int interface_number, success = -1; + int interface_number, success = 0; for (interface_number = 0; interface_number < nofInterfaces; interface_number++) { - success = LibusbJava1.libusb_release_interface(dev_handle, - interface_number); - if (success >= 0) { - success = LibusbJava1.libusb_claim_interface(dev_handle, - interface_number); - if (success < 0) { - return success; + try + { + LibusbJava1.libusb_release_interface(dev_handle, interface_number); + + try + { + LibusbJava1.libusb_claim_interface(dev_handle, interface_number); + } + catch (LibusbError e) + { + return e.getErrorCode(); } break; } + catch (LibusbError e) + { + /* Move ahead. */ + } } - return LibusbJava1.libusb_set_interface_alt_setting(dev_handle, - interface_number, alternate); + + try { + LibusbJava1.libusb_set_interface_alt_setting(dev_handle, interface_number, alternate); + success = 0; + } + catch (LibusbError e) { + success = -1; + } + + return success; } /** @@ -357,8 +398,15 @@ public class LibusbJava { * @return 0 on success or < 0 on error. */ public static int usb_clear_halt(long dev_handle, int ep) { - - return LibusbJava1.libusb_clear_halt(dev_handle, (short) ep); + int result = 0; + + try { + LibusbJava1.libusb_clear_halt(dev_handle, (short) ep); + } catch (LibusbError e) { + result = e.getErrorCode(); + } + + return result; } /** @@ -374,10 +422,22 @@ public class LibusbJava { * @return 0 on success or < 0 on error. */ public static int usb_reset(long dev_handle) { - LibusbJava1.libusb_claim_interface(dev_handle, 0); - int res = LibusbJava1.libusb_reset_device(dev_handle); - LibusbJava1.libusb_release_interface(dev_handle, 0); - LibusbJava1.libusb_close(dev_handle); + int res = 0; + + try { + LibusbJava1.libusb_claim_interface(dev_handle, 0); + try { + LibusbJava1.libusb_reset_device(dev_handle); + } + catch (LibusbError e) { + res = e.getErrorCode(); + } + LibusbJava1.libusb_release_interface(dev_handle, 0); + LibusbJava1.libusb_close(dev_handle); + } catch (LibusbError e) { + /* Ignore all errors of these calls */ + } + return res; } @@ -397,7 +457,15 @@ public class LibusbJava { * @return 0 on success or < 0 on error. */ public static int usb_claim_interface(long dev_handle, int interface_) { - return LibusbJava1.libusb_claim_interface(dev_handle, interface_); + int result = 0; + + try { + LibusbJava1.libusb_claim_interface(dev_handle, interface_); + } catch (LibusbError e) { + result = e.getErrorCode(); + } + + return result; } /** @@ -411,7 +479,15 @@ public class LibusbJava { * @return 0 on success or < 0 on error. */ public static int usb_release_interface(long dev_handle, int interface_) { - return LibusbJava1.libusb_release_interface(dev_handle, interface_); + int result = 0; + + try { + LibusbJava1.libusb_release_interface(dev_handle, interface_); + } catch (LibusbError e) { + result = e.getErrorCode(); + } + + return result; } // Control Transfers @@ -448,8 +524,15 @@ public class LibusbJava { * @return the descriptor String or null */ public static String usb_get_string(long dev_handle, int index, int langid) { - - return LibusbJava1.libusb_get_string_descriptor(dev_handle, (short) index, langid, 255); + String result; + + try { + result = LibusbJava1.libusb_get_string_descriptor(dev_handle, (short) index, langid, 255); + } catch (LibusbError e) { + result = null; + } + + return result; } /** @@ -463,7 +546,15 @@ public class LibusbJava { * @return the descriptor String or null */ public static String usb_get_string_simple(long dev_handle, int index) { - return LibusbJava1.libusb_get_string_descriptor_ascii(dev_handle,(short) index, 255); + String result = null; + + try { + result = LibusbJava1.libusb_get_string_descriptor_ascii(dev_handle,(short) index, 255); + } catch (LibusbError e) { + result = null; + } + + return result; } /** @@ -484,7 +575,14 @@ public class LibusbJava { */ public static byte[] usb_get_descriptor(long dev_handle, byte type, byte index, int size) { - return LibusbJava1.libusb_get_descriptor(dev_handle, type, index, size); + byte[] result = null; + + try { + result = LibusbJava1.libusb_get_descriptor(dev_handle, type, index, size); + } catch (LibusbError e) { + } + + return result; } /** @@ -534,8 +632,16 @@ public class LibusbJava { */ public static int usb_bulk_write(long dev_handle, int ep, byte[] bytes, int size, int timeout) { - return LibusbJava1.libusb_bulk_transfer(dev_handle, (byte) ep, bytes, - size, timeout); + int result = LibusbError.ERROR_OTHER; + + try { + result = LibusbJava1.libusb_bulk_transfer(dev_handle, (byte) ep, + bytes, size, timeout); + } catch (LibusbError e) { + result = e.getErrorCode(); + } + + return result; } /** @@ -551,8 +657,16 @@ public class LibusbJava { */ public static int usb_bulk_read(long dev_handle, int ep, byte[] bytes, int size, int timeout) { - return LibusbJava1.libusb_bulk_transfer(dev_handle, (byte) ep, bytes, - size, timeout); + int result = LibusbError.ERROR_OTHER; + + try { + result = LibusbJava1.libusb_bulk_transfer(dev_handle, (byte) ep, + bytes, size, timeout); + } catch (LibusbError e) { + result = e.getErrorCode(); + } + + return result; } // Interrupt Transfers @@ -569,8 +683,16 @@ public class LibusbJava { */ public static int usb_interrupt_write(long dev_handle, int ep, byte[] bytes, int size, int timeout) { - return LibusbJava1.libusb_interrupt_transfer(dev_handle, (byte) ep, - bytes, size, timeout); + int result = LibusbError.ERROR_OTHER; + + try { + result = LibusbJava1.libusb_interrupt_transfer(dev_handle, (byte) ep, + bytes, size, timeout); + } catch (LibusbError e) { + result = e.getErrorCode(); + } + + return result; } /** @@ -586,8 +708,16 @@ public class LibusbJava { */ public static int usb_interrupt_read(long dev_handle, int ep, byte[] bytes, int size, int timeout) { - return LibusbJava1.libusb_interrupt_transfer(dev_handle, (byte) ep, - bytes, size, timeout); + int result = LibusbError.ERROR_OTHER; + + try { + result = LibusbJava1.libusb_interrupt_transfer(dev_handle, (byte) ep, + bytes, size, timeout); + } catch (LibusbError e) { + result = e.getErrorCode(); + } + + return result; } /** diff --git a/java/src/ch/ntb/inf/libusbJava/LibusbJava1.java b/java/src/ch/ntb/inf/libusbJava/LibusbJava1.java index b463f93..d4e9de3 100644 --- a/java/src/ch/ntb/inf/libusbJava/LibusbJava1.java +++ b/java/src/ch/ntb/inf/libusbJava/LibusbJava1.java @@ -6,6 +6,8 @@ */ package ch.ntb.inf.libusbJava; +import ch.ntb.inf.libusbJava.exceptions.LibusbError; + /** * This class represents the Java Native Interface to the shared library which * is (with some exceptions) a one-to-one representation of the libusb1.0 API.
@@ -28,27 +30,6 @@ package ch.ntb.inf.libusbJava; * */ public class LibusbJava1 { - - /** - * System error codes.
- * This list is not complete! For more error codes see the file 'errorno.h' - * on your system. - */ - public static final int LIBUSB_SUCCESS = 0; - public static final int LIBUSB_ERROR_IO = -1; - public static final int LIBUSB_ERROR_INVALID_PARAM = -2; - public static final int LIBUSB_ERROR_ACCESS = -3; - public static final int LIBUSB_ERROR_NO_DEVICE = -4; - public static final int LIBUSB_ERROR_NOT_FOUND = -5; - public static final int LIBUSB_ERROR_BUSY = -6; - public static final int LIBUSB_ERROR_TIMEOUT = -7; - public static final int LIBUSB_ERROR_OVERFLOW = -8; - public static final int LIBUSB_ERROR_PIPE = -9; - public static final int LIBUSB_ERROR_INTERRUPTED = -10; - public static final int LIBUSB_ERROR_NO_MEM = -11; - public static final int LIBUSB_ERROR_NOT_SUPPORTED = -12; - public static final int LIBUSB_ERROR_OTHER = -99; - /** * Set message verbosity. *
    @@ -95,7 +76,7 @@ public class LibusbJava1 { * @return a context to operate on
    * or a LIBUSB_ERROR code on failure */ - public static native long libusb_init(); + public static native long libusb_init() throws LibusbError; /** * Deinitialize libusb.
    @@ -126,9 +107,10 @@ public class LibusbJava1 { public static native Usb_Device libusb_get_device_list(long ctx); /** - * Get the number of the bus that a device is connected to. + * Get the number of the bus that a device is connected to. * - * @param dev a device + * @param dev + * a device * @return the bus number */ public static native short libusb_get_bus_number(Usb_Device dev); @@ -210,9 +192,17 @@ public class LibusbJava1 { * * @return a device handler * + * @throws LibusbError + * in case of an error
    + * Possible causes are:
    + * - ERROR_NO_MEM on memory allocation failure - ERROR_ACCESS if + * the user has insufficient permissions - ERROR_NO_DEVICE if + * the device has been disconnected - another ERROR code on + * other failure + * * @see #libusb_get_device(long) */ - public static native long libusb_open(Usb_Device dev); + public static native long libusb_open(Usb_Device dev) throws LibusbError; /** * Convenience function for finding a device with a particular @@ -286,9 +276,14 @@ public class LibusbJava1 { * @param dev_handle * a device handle * @return bConfigurationValue of the currently active configuration - * + * @throws LibusbError + * in case of an error
    + * Possible error causes are:
    + * - ERROR_NO_DEVICE if the device has been disconnected - + * another ERROR code on other failure */ - public static native byte libusb_get_configuration(long dev_handle); + public static native int libusb_get_configuration(long dev_handle) + throws LibusbError; /** * Set the active configuration for a device.
    @@ -327,15 +322,17 @@ public class LibusbJava1 { * the bConfigurationValue of the configuration you wish to * activate, or -1 if you wish to put the device in unconfigured * state - * @return 0 on success
    - * LIBUSB_ERROR_NOT_FOUND if the requested configuration does not - * exist
    - * LIBUSB_ERROR_BUSY if interfaces are currently claimed
    - * LIBUSB_ERROR_NO_DEVICE if the device has been disconnected
    - * another LIBUSB_ERROR code on other failure
    + * @throws LibusbError + * in case of an error
    + * Possible error causes are:
    + * - ERROR_NOT_FOUND if the requested configuration does not + * exist
    + * - ERROR_BUSY if interfaces are currently claimed
    + * - ERROR_NO_DEVICE if the device has been disconnected
    + * - another LIBUSB_ERROR code on other failure
    */ - public static native int libusb_set_configuration(long dev_handle, - int configuration); + public static native void libusb_set_configuration(long dev_handle, + int configuration) throws LibusbError; /** * Claim an interface on a given device handle.
    @@ -358,15 +355,15 @@ public class LibusbJava1 { * a device handle * @param interface_number * the bInterfaceNumber of the interface you wish to claim - * @return 0 on success
    - * LIBUSB_ERROR_NOT_FOUND if the interface was not claimed
    - * LIBUSB_ERROR_NO_DEVICE if the device has been disconnected
    - * LIBUSB_ERROR_BUSY if another program or driver has claimed the - * interface
    - * another LIBUSB_ERROR code on other failure
    + * @throws LibusbError in case of an error
    + * Possible causes for errors are:
    + * - ERROR_NOT_FOUND if the interface was not claimed
    + * - ERROR_NO_DEVICE if the device has been disconnected
    + * - ERROR_BUSY if another program or driver has claimed the interface
    + * - another LIBUSB_ERROR code on other failure
    */ - public static native int libusb_claim_interface(long dev_handle, - int interface_number); + public static native void libusb_claim_interface(long dev_handle, + int interface_number) throws LibusbError; /** * Release an interface previously claimed with @@ -382,19 +379,20 @@ public class LibusbJava1 { * a device handle * @param interface_number * the bInterfaceNumber of the previously-claimed interface - * @return 0 on success
    - * LIBUSB_ERROR_NOT_FOUND if the interface was not claimed
    - * LIBUSB_ERROR_NO_DEVICE if the device has been disconnected
    - * another LIBUSB_ERROR code on other failure
    + * @throws LibusbError in case of an error
    + * Possible causes for errors are:
    + * - ERROR_NOT_FOUND if the interface was not claimed
    + * - ERROR_NO_DEVICE if the device has been disconnected
    + * - another ERROR code on other failure
    */ - public static native int libusb_release_interface(long dev_handle, - int interface_number); + public static native void libusb_release_interface(long dev_handle, + int interface_number) throws LibusbError; /** * Activate an alternate setting for an interface.
    *
    * The interface must have been previously claimed with - *{@link #libusb_claim_interface(long, int)}.
    + * {@link #libusb_claim_interface(long, int)}.
    *
    * You should always use this function rather than formulating your own * SET_INTERFACE control request. This is because the underlying operating @@ -409,14 +407,14 @@ public class LibusbJava1 { * the bInterfaceNumber of the previously-claimed interface * @param alternate_setting * the bAlternateSetting of the alternate setting to activate - * @return 0 on success
    - * LIBUSB_ERROR_NOT_FOUND if the interface was not claimed, or the - * requested alternate setting does not exist
    - * LIBUSB_ERROR_NO_DEVICE if the device has been disconnected
    - * another LIBUSB_ERROR code on other failure
    + * @throws LibusbError in case of an error
    + * Possible causes for errors are:
    + * - ERROR_NOT_FOUND if the interface was not claimed, or the requested alternate setting does not exist
    + * - ERROR_NO_DEVICE if the device has been disconnected
    + * - another LIBUSB_ERROR code on other failure
    */ - public static native int libusb_set_interface_alt_setting(long dev_handle, - int interface_number, int alternate_setting); + public static native void libusb_set_interface_alt_setting(long dev_handle, + int interface_number, int alternate_setting) throws LibusbError; /** * Clear the halt/stall condition for an endpoint.
    @@ -434,12 +432,13 @@ public class LibusbJava1 { * a device handle * @param endpoint * the endpoint to clear halt status - * @return 0 on success
    - * LIBUSB_ERROR_NOT_FOUND if the endpoint does not exist
    - * LIBUSB_ERROR_NO_DEVICE if the device has been disconnected
    - * another LIBUSB_ERROR code on other failure
    + * @throws LibusbError in case of an error
    + * Possible causes for errors are:
    + * - ERROR_NOT_FOUND if the endpoint does not exist
    + * - ERROR_NO_DEVICE if the device has been disconnected
    + * - another LIBUSB_ERROR code on other failure
    */ - public static native int libusb_clear_halt(long dev_handle, short endpoint); + public static native void libusb_clear_halt(long dev_handle, short endpoint) throws LibusbError; /** * Perform a USB port reset to reinitialize a device.
    @@ -458,12 +457,12 @@ public class LibusbJava1 { * * @param dev_handle * a handle of the device to reset - * @return 0 on success
    - * LIBUSB_ERROR_NOT_FOUND if re-enumeration is required, or if the - * device has been disconnected
    - * another LIBUSB_ERROR code on other failure
    + * @throws LibusbError in case of an error
    + * Possible causes for errors are:
    + * - ERROR_NOT_FOUND if re-enumeration is required, or if the device has been disconnected
    + * - another LIBUSB_ERROR code on other failure
    */ - public static native int libusb_reset_device(long dev_handle); + public static native void libusb_reset_device(long dev_handle) throws LibusbError; /** * Determine if a kernel driver is active on an interface.
    @@ -478,12 +477,14 @@ public class LibusbJava1 { * the interface to check * @return 0 if no kernel driver is active
    * 1 if a kernel driver is active
    - * LIBUSB_ERROR_NO_DEVICE if the device has been disconnected
    - * another LIBUSB_ERROR code on other failure
    + * @throws LibusbError in case of an error
    + * Possible causes for errors are:
    + * - ERROR_NO_DEVICE if the device has been disconnected
    + * - another LIBUSB_ERROR code on other failure
    * @see #libusb_detach_kernel_driver(long, int) */ public static native int libusb_kernel_driver_active(long dev_handle, - int interface_number); + int interface_number)throws LibusbError; /** * Detach a kernel driver from an interface.
    @@ -496,15 +497,16 @@ public class LibusbJava1 { * a device handle * @param interface_number * the interface to detach the driver from - * @return 0 on success
    - * LIBUSB_ERROR_NOT_FOUND if no kernel driver was active
    - * LIBUSB_ERROR_INVALID_PARAM if the interface does not exist
    - * LIBUSB_ERROR_NO_DEVICE if the device has been disconnected
    - * another LIBUSB_ERROR code on other failure
    + * @throws LibusbError in case of an error
    + * Possible causes for errors are:
    + * - ERROR_NOT_FOUND if no kernel driver was active
    + * - ERROR_INVALID_PARAM if the interface does not exist
    + * - ERROR_NO_DEVICE if the device has been disconnected
    + * - another ERROR code on other failure
    * @see #libusb_kernel_driver_active(long, int) */ - public static native int libusb_detach_kernel_driver(long dev_handle, - int interface_number); + public static native void libusb_detach_kernel_driver(long dev_handle, + int interface_number) throws LibusbError; /** * Re-attach an interface's kernel driver, which was previously detached @@ -514,17 +516,17 @@ public class LibusbJava1 { * a device handle * @param interface_number * the interface to attach the driver from - * @return 0 on success
    - * LIBUSB_ERROR_NOT_FOUND if no kernel driver was active
    - * LIBUSB_ERROR_INVALID_PARAM if the interface does not exist
    - * LIBUSB_ERROR_NO_DEVICE if the device has been disconnected
    - * LIBUSB_ERROR_BUSY if the driver cannot be attached because the - * interface is claimed by a program or driver
    - * another LIBUSB_ERROR code on other failure
    + * @throws LibusbError in case of an error
    + * Possible causes for errors are:
    + * - ERROR_NOT_FOUND if no kernel driver was active
    + * - ERROR_INVALID_PARAM if the interface does not exist
    + * - ERROR_NO_DEVICE if the device has been disconnected
    + * - ERROR_BUSY if the driver cannot be attached because the interface is claimed by a program or driver
    + * - another ERROR code on other failure
    * @see #libusb_kernel_driver_active(long, int) */ - public static native int libusb_attach_kernel_driver(long dev_handle, - int interface_number); + public static native void libusb_attach_kernel_driver(long dev_handle, + int interface_number) throws LibusbError; /** * Get the USB configuration descriptor for the currently active @@ -556,9 +558,10 @@ public class LibusbJava1 { * number of charactes which will be retrieved (the length of the * resulting String) * @return a string which contains the string descriptor + * @throws LibusbError in case of an error
    */ public static native String libusb_get_string_descriptor_ascii( - long dev_handle, short desc_index, int size); + long dev_handle, short desc_index, int size) throws LibusbError; /** * Retrieve a descriptor from the default control pipe.
    @@ -576,10 +579,11 @@ public class LibusbJava1 { * number of bytes which will be retrieved (the length of the * resulting byte[]) * @return a byte[] which contains the descriptor or null on failure + * @throws LibusbError in case of an error
    * */ public static native byte[] libusb_get_descriptor(long dev_handle, - int desc_type, short desc_index, int size); + int desc_type, short desc_index, int size) throws LibusbError; /** * Retrieve a descriptor from a device.
    @@ -598,10 +602,11 @@ public class LibusbJava1 { * number of charactes which will be retrieved (the length of the * resulting String) * @return a string which contains the string descriptor + * @throws LibusbError in case of an error
    * @see #libusb_get_string_descriptor_ascii(long, short, int) */ public static native String libusb_get_string_descriptor(long dev_handle, - short desc_index, int langid, int size); + short desc_index, int langid, int size) throws LibusbError; /** * Allocate a libusb transfer with a specified number of isochronous packet @@ -656,12 +661,13 @@ public class LibusbJava1 { * * @param transfernumber * the transfer to submit - * @return 0 on success
    - * LIBUSB_ERROR_NO_DEVICE if the device has been disconnected
    - * LIBUSB_ERROR_BUSY if the transfer has already been submitted.
    - * another LIBUSB_ERROR code on other failure
    + * @throws LibusbError in case of an error
    + * Possible causes for errors are:
    + * - ERROR_NO_DEVICE if the device has been disconnected
    + * - ERROR_BUSY if the transfer has already been submitted.
    + * - another LIBUSB_ERROR code on other failure
    */ - public static native int libusb_submit_transfer(long transfernumber); + public static native void libusb_submit_transfer(long transfernumber) throws LibusbError; /** * Asynchronously cancel a previously submitted transfer.
    @@ -672,12 +678,12 @@ public class LibusbJava1 { * * @param transfernumber * a transfer - * @return 0 on success
    - * LIBUSB_ERROR_NOT_FOUND if the transfer is already complete or - * cancelled.
    - * a LIBUSB_ERROR code on failure
    + * @throws LibusbError in case of an error
    + * Possible causes for errors are:
    + * - ERROR_NOT_FOUND if the transfer is already complete or cancelled.
    + * - a LIBUSB_ERROR code on failure
    */ - public static native int libusb_cancel_transfer(long transfernumber); + public static native void libusb_cancel_transfer(long transfernumber) throws LibusbError; /** * Get the data section of a control transfer.
    @@ -691,7 +697,7 @@ public class LibusbJava1 { * * @param transfernumber * a transfer - * @return the data section from the transfer + * @return the data section from the transfer, null if the transfer number was invalid. */ public static native byte[] libusb_control_transfer_get_data( long transfernumber); @@ -708,7 +714,7 @@ public class LibusbJava1 { * * @param transfernumber * a transfer - * @return the setup packet from the transfer + * @return the setup packet from the transfer, null if the transfer number was invalid. */ public static native byte[] libusb_control_transfer_get_setup( long transfernumber); @@ -1060,9 +1066,9 @@ public class LibusbJava1 { * @param timeval * the maximum time to block waiting for events, or zero for * non-blocking mode - * @return 0 on success, or a LIBUSB_ERROR code on failure + * @throws LibusbError in case of an error
    */ - public static native int libusb_handle_events_timeout(long ctx, long timeval); + public static native void libusb_handle_events_timeout(long ctx, long timeval) throws LibusbError; /** * Handle any pending events in blocking mode with a sensible timeout.
    @@ -1074,9 +1080,9 @@ public class LibusbJava1 { * * @param ctx * the context to operate on, or NULL for the default context - * @return 0 on success, or a LIBUSB_ERROR code on failure + * @throws LibusbError in case of an error
    */ - public static native int libusb_handle_events(long ctx); + public static native void libusb_handle_events(long ctx) throws LibusbError; /** * Handle any pending events by polling file descriptors, without checking @@ -1097,9 +1103,9 @@ public class LibusbJava1 { * @param timeval * the maximum time in seconds to block waiting for events, or * zero for non-blocking mode - * @return 0 on success, or a LIBUSB_ERROR code on failure + * @throws LibusbError in case of an error
    */ - public static native int libusb_handle_events_locked(long ctx, long timeval); + public static native void libusb_handle_events_locked(long ctx, long timeval) throws LibusbError; /** * Determines whether your application must apply special timing @@ -1151,18 +1157,20 @@ public class LibusbJava1 { * This function may return an zero timevalue. If this is the case, it * indicates that libusb has a timeout that has already expired so you * should call libusb_handle_events_timeout() or similar immediately. A - * return code of -999 indicates that there are no pending timeouts.
    + * return code of -1 indicates that there are no pending timeouts.
    *
    - * On some platforms, this function will always returns -999 (no pending + * On some platforms, this function will always returns -1 (no pending * timeouts). * * @param ctx * the context to operate on, or NULL for the default context - * @return -999 if there are no pending timeouts
    - * time to next timeout
    - * LIBUSB_ERROR_OTHER on failure + * @return time to next timeout
    + * -1 if there are no pending timeouts
    + * @throws LibusbError + * If an error is occured in libusb */ - public static native int libusb_get_next_timeout(long ctx); + public static native int libusb_get_next_timeout(long ctx) + throws LibusbError; /** * Register notification functions for file descriptor additions/removals.
    @@ -1271,15 +1279,20 @@ public class LibusbJava1 { * timeout (in millseconds) that this function should wait before * giving up due to no response being received. For an unlimited * timeout, use value 0. - * @return on success, the number of bytes actually transferred
    - * LIBUSB_ERROR_TIMEOUT if the transfer timed out
    - * LIBUSB_ERROR_PIPE if the control request was not supported by the - * device
    - * LIBUSB_ERROR_NO_DEVICE if the device has been disconnected
    - * another LIBUSB_ERROR code on other failures. + * @return The number of bytes actually transferred + * @throws LibusbError + * in case an error occured
    + * Possible causes are:
    + * - ERROR_TIMEOUT if the transfer timed out
    + * - ERROR_PIPE if the control request was not supported by the + * device
    + * - ERROR_OVERFLOW if the device offered more data
    + * - ERROR_NO_DEVICE if the device has been disconnected
    + * - another code on other failures. */ public static native int libusb_bulk_transfer(long dev_handle, - byte endpoint, byte[] data, int length, int timeout); + byte endpoint, byte[] data, int length, int timeout) + throws LibusbError; /** * Perform a USB interrupt transfer.
    @@ -1311,15 +1324,20 @@ public class LibusbJava1 { * timeout (in millseconds) that this function should wait before * giving up due to no response being received. For an unlimited * timeout, use value 0. - * @return on success, the number of bytes actually transferred
    - * LIBUSB_ERROR_TIMEOUT if the transfer timed out
    - * LIBUSB_ERROR_PIPE if the control request was not supported by the - * device
    - * LIBUSB_ERROR_NO_DEVICE if the device has been disconnected
    - * another LIBUSB_ERROR code on other failures + * @return The number of bytes actually transferred
    + * @throws LibusbError + * in case an error occured
    + * Possible causes are:
    + * - ERROR_TIMEOUT if the transfer timed out
    + * - ERROR_PIPE if the control request was not supported by the + * device
    + * - ERROR_OVERFLOW if the device offered more data
    + * - ERROR_NO_DEVICE if the device has been disconnected
    + * - another ERROR code on other failures */ public static native int libusb_interrupt_transfer(long dev_handle, - byte endpoint, byte[] data, int length, int timeout); + byte endpoint, byte[] data, int length, int timeout) + throws LibusbError; /** * Returns the error string after an error occured. @@ -1332,8 +1350,20 @@ public class LibusbJava1 { String os = System.getProperty("os.name"); if (os.contains("Windows")) { System.loadLibrary("LibusbJava-1_0"); - } else { + } else { System.loadLibrary("usbJava-1.0"); } } + + /** + * This method is only used for testing the DLL-code that throws exceptions + * in the java environment. + * + * @param code + * Code of the error to be simulated and hence the code of the + * exception that shall be thrown. + * + * @throws LibusbError + */ + public static native void libusb_exceptionTest(int code) throws LibusbError; } diff --git a/java/src/ch/ntb/inf/libusbJava/exceptions/LibusbError.java b/java/src/ch/ntb/inf/libusbJava/exceptions/LibusbError.java new file mode 100644 index 0000000..907e47d --- /dev/null +++ b/java/src/ch/ntb/inf/libusbJava/exceptions/LibusbError.java @@ -0,0 +1,129 @@ +package ch.ntb.inf.libusbJava.exceptions; + +public class LibusbError extends Exception { + private static final long serialVersionUID = 9096323614080207236L; + + /** + * libusb error codes + */ + public static final int ERROR_NONE = 0; + public static final int ERROR_IO = -1; + public static final int ERROR_INVALID_PARAM = -2; + public static final int ERROR_ACCESS = -3; + public static final int ERROR_NO_DEVICE = -4; + public static final int ERROR_NOT_FOUND = -5; + public static final int ERROR_BUSY = -6; + public static final int ERROR_TIMEOUT = -7; + public static final int ERROR_OVERFLOW = -8; + public static final int ERROR_PIPE = -9; + public static final int ERROR_INTERRUPTED = -10; + public static final int ERROR_NO_MEM = -11; + public static final int ERROR_NOT_SUPPORTED = -12; + public static final int ERROR_OTHER = -99; + + private int code = ERROR_NONE; + + public LibusbError(int code) + { + super("libusb result: " + getStringFromCode(code)); + this.code = code; + } + + public int getErrorCode() + { + return code; + } + + public static String getStringFromCode(int code) + { + String result; + + switch (code) + { + case ERROR_IO: + { + result = "ERROR_IO"; + break; + } + case ERROR_INVALID_PARAM: + { + result = "ERROR_INVALID_PARAM"; + break; + } + case ERROR_ACCESS: + { + result = "ERROR_ACCESS"; + break; + } + case ERROR_NO_DEVICE: + { + result = "ERROR_NO_DEVICE"; + break; + } + case ERROR_NOT_FOUND: + { + result = "ERROR_NOT_FOUND"; + break; + } + case ERROR_BUSY: + { + result = "ERROR_BUSY"; + break; + } + + case ERROR_TIMEOUT: + { + result = "ERROR_TIMEOUT"; + break; + } + + case ERROR_OVERFLOW: + { + result = "ERROR_OVERFLOW"; + break; + } + + case ERROR_PIPE: + { + result = "ERROR_PIPE"; + break; + } + + case ERROR_INTERRUPTED: + { + result = "ERROR_INTERRUPTED"; + break; + } + + case ERROR_NO_MEM: + { + result = "ERROR_NO_MEM"; + break; + } + + case ERROR_NOT_SUPPORTED: + { + result = "ERROR_NOT_SUPPORTED"; + break; + } + + case ERROR_OTHER: + { + result = "ERROR_OTHER"; + break; + } + + default: + { + result = "ERROR_UNKNWON (" + code + ")"; + break; + } + } + + return result; + } + + public String getErrorString() { + return getStringFromCode(getErrorCode()); + } +} diff --git a/java/src/ch/ntb/inf/libusbJava/usbView/UsbTreeModel.java b/java/src/ch/ntb/inf/libusbJava/usbView/UsbTreeModel.java index 2ed0bec..90e5e29 100644 --- a/java/src/ch/ntb/inf/libusbJava/usbView/UsbTreeModel.java +++ b/java/src/ch/ntb/inf/libusbJava/usbView/UsbTreeModel.java @@ -274,7 +274,7 @@ public class UsbTreeModel implements TreeModel, TreeSelectionListener { if (tmpDevDesc.equals(devDesc)) { long handle = LibusbJava.usb_open(dev); sb.append("\nString descriptors\n"); - if (handle <= 0) { + if (handle == 0) { sb.append("\terror opening the device\n"); break; } @@ -348,7 +348,7 @@ public class UsbTreeModel implements TreeModel, TreeSelectionListener { && (confDesc.getIConfiguration() > 0)) { long handle = LibusbJava.usb_open(dev); sb.append("\nString descriptors\n"); - if (handle <= 0) { + if (handle == 0) { sb.append("\terror opening the device\n"); break; } @@ -426,7 +426,7 @@ public class UsbTreeModel implements TreeModel, TreeSelectionListener { && (intDesc.getIInterface() > 0)) { long handle = LibusbJava.usb_open(dev); sb.append("\nString descriptors\n"); - if (handle <= 0) { + if (handle == 0) { sb .append("\terror opening the device\n"); break; diff --git a/java/test/ch/ntb/inf/libusbJava/test/TestLibUsbJava.java b/java/test/ch/ntb/inf/libusbJava/test/TestLibUsbJava.java index 2b4184f..a495590 100644 --- a/java/test/ch/ntb/inf/libusbJava/test/TestLibUsbJava.java +++ b/java/test/ch/ntb/inf/libusbJava/test/TestLibUsbJava.java @@ -120,7 +120,7 @@ public class TestLibUsbJava { udev = LibusbJava.usb_open(dev); - if (udev <= 0) { + if (udev != 0) { if (dev.getDescriptor().getIManufacturer() != 0) { mfr = LibusbJava.usb_get_string_simple(udev, dev .getDescriptor().getIManufacturer()); diff --git a/java/test/ch/ntb/inf/libusbJava/test/exceptions/LibusbErrorTest.java b/java/test/ch/ntb/inf/libusbJava/test/exceptions/LibusbErrorTest.java new file mode 100644 index 0000000..4011ae0 --- /dev/null +++ b/java/test/ch/ntb/inf/libusbJava/test/exceptions/LibusbErrorTest.java @@ -0,0 +1,75 @@ +package ch.ntb.inf.libusbJava.test.exceptions; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.util.Arrays; +import java.util.Collection; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.junit.runners.Parameterized.Parameters; + +import ch.ntb.inf.libusbJava.exceptions.LibusbError; + +@RunWith(Parameterized.class) +public class LibusbErrorTest { + @Parameters + public static Collection codesToTest() { + return Arrays.asList(new Object[][] { {"ERROR_UNKNWON (0)", 0 }, + {"ERROR_IO", -1 }, + {"ERROR_INVALID_PARAM", -2}, + {"ERROR_ACCESS", -3}, + {"ERROR_NO_DEVICE", -4}, + {"ERROR_NOT_FOUND", -5}, + {"ERROR_BUSY", -6}, + {"ERROR_TIMEOUT", -7}, + {"ERROR_OVERFLOW", -8}, + {"ERROR_PIPE", -9}, + {"ERROR_INTERRUPTED", -10}, + {"ERROR_NO_MEM", -11}, + {"ERROR_NOT_SUPPORTED", -12}, + {"ERROR_UNKNWON (-13)", -13}, + {"ERROR_UNKNWON (-98)", -98}, + {"ERROR_UNKNWON (-100)", -100}, + {"ERROR_OTHER", -99} }); + } + + private String exp_desc; + private int code; + private LibusbError e; + + public LibusbErrorTest(String exp_desc, int code) { + this.exp_desc = exp_desc; + this.code = code; + try { + throw new LibusbError(code); + } catch (LibusbError e) { + this.e = e; + } + } + + @Test + public void testGetErrorCode() { + assertEquals("Error code is correct", e.getErrorCode(), code); + } + + @Test + public void testGetStringFromCode() { + String gen_desc = LibusbError.getStringFromCode(code); + assertEquals("Correct error description for " + code, exp_desc, gen_desc); + } + + @Test + public void testGetErrorString() { + assertEquals("Correct error string for " + code, e.getErrorString(), exp_desc); + } + + + @Test + public void testGetMessage() { + assertEquals("Correct error string for " + code, e.getMessage(), "libusb result: " + exp_desc); + } +}