- Bugfix: Guaranteeing '\0'-Termination of the retrieved C-Strings for all libusb_get_string_descriptor* calls - Change: The whole interface makes now use of exceptions to pass errors into the java environment instead encoding them into return values. - Change: Allowing Descriptor strings to have a length of 0 git-svn-id: https://svn.code.sf.net/p/libusbjava/code/trunk@292 94ad28fe-ef68-46b1-9651-e7ae4fcf1c4c
1968 lines
94 KiB
C++
1968 lines
94 KiB
C++
/*! \file
|
|
* \brief Java libusb1.0 wrapper
|
|
*
|
|
* \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 <roger.millischer at ntb.ch> (original author)
|
|
* \author Ueli Niederer <ueli.niederer at ntb.ch> (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
|
|
*
|
|
*******************************************************************************************/
|
|
#include <jni.h>
|
|
#include <cstddef>
|
|
#include <string>
|
|
#include <cstdlib>
|
|
#include <ctime>
|
|
|
|
#include <string.h>
|
|
|
|
#include "libusb.h"
|
|
#include "LibusbJava.h"
|
|
|
|
//#define DEBUGON
|
|
|
|
/********************************************************************************************
|
|
*
|
|
* Globals
|
|
*
|
|
*******************************************************************************************/
|
|
/* global flag for loading all class, method and field ID references*/
|
|
int java_references_loaded = 0;
|
|
|
|
/* if > 0 an LibusbJava specific error string is set*/
|
|
char *libusbJavaError = NULL;
|
|
/********************************************************************************************
|
|
*
|
|
* Macros
|
|
*
|
|
*******************************************************************************************/
|
|
/* to set and clear LibusbJava specific errors*/
|
|
#define setLibusbJavaError(error) libusbJavaError = error
|
|
#define clearLibusbJavaError() libusbJavaError = NULL
|
|
|
|
/********************************************************************************************
|
|
*
|
|
* Prototyp and define for callback-function
|
|
*
|
|
*******************************************************************************************/
|
|
static void LIBUSB_CALL transfer_callback(struct libusb_transfer *transfer);
|
|
|
|
static void
|
|
LIBUSB_CALL fd_added_callback(int fd, short events, void *user_data);
|
|
|
|
static void LIBUSB_CALL fd_removed_callback(int fd, void *user_data);
|
|
|
|
/********************************************************************************************
|
|
*
|
|
* Local helper functions
|
|
*
|
|
*******************************************************************************************/
|
|
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);
|
|
|
|
/********************************************************************************************
|
|
*
|
|
* References
|
|
*
|
|
*******************************************************************************************/
|
|
/* class references*/
|
|
static jclass usb_devClazz, usb_devDescClazz, usb_confDescClazz, usb_intClazz,
|
|
usb_intDescClazz, usb_epDescClazz, usb_cb_clazz, usb_pollfd_clazz;
|
|
|
|
/* method ID references*/
|
|
static jmethodID usb_devMid, usb_devDescMid, usb_confDescMid, usb_intMid,
|
|
usb_intDescMid, usb_epDescMid, usb_transfer_cb_Mid,
|
|
usb_fd_added_cb_Mid, usb_fd_removed_cb_Mid, usb_pollfd_Mid;
|
|
|
|
/* field ID references*/
|
|
/* usb_device*/
|
|
static jfieldID usb_devFID_next, usb_devFID_prev, usb_devFID_filename, usb_devFID_bus,
|
|
usb_devFID_descriptor, usb_devFID_config, usb_devFID_devnum,
|
|
usb_devFID_num_children, usb_devFID_children, usb_devFID_devStructAddr;
|
|
/* usb_deviceDescriptor */
|
|
static jfieldID usb_devDescFID_bLength, usb_devDescFID_bDescriptorType,
|
|
usb_devDescFID_bcdUSB, usb_devDescFID_bDeviceClass,
|
|
usb_devDescFID_bDeviceSubClass, usb_devDescFID_bDeviceProtocol,
|
|
usb_devDescFID_bMaxPacketSize0, usb_devDescFID_idVendor,
|
|
usb_devDescFID_idProduct, usb_devDescFID_bcdDevice,
|
|
usb_devDescFID_iManufacturer, usb_devDescFID_iProduct,
|
|
usb_devDescFID_iSerialNumber, usb_devDescFID_bNumConfigurations;
|
|
/* usb_configurationDescriptor*/
|
|
static jfieldID usb_confDescFID_bLength, usb_confDescFID_bDescriptorType,
|
|
usb_confDescFID_wTotalLength, usb_confDescFID_bNumInterfaces,
|
|
usb_confDescFID_bConfigurationValue, usb_confDescFID_iConfiguration,
|
|
usb_confDescFID_bmAttributes, usb_confDescFID_MaxPower,
|
|
usb_confDescFID_interface_, usb_confDescFID_extra,
|
|
usb_confDescFID_extralen;
|
|
/* usb_interface*/
|
|
static jfieldID usb_intFID_altsetting, usb_intFID_num_altsetting;
|
|
/* usb_intDesc*/
|
|
static jfieldID usb_intDescFID_bLength, usb_intDescFID_bDescriptorType,
|
|
usb_intDescFID_bInterfaceNumber, usb_intDescFID_bAlternateSetting,
|
|
usb_intDescFID_bNumEndpoints, usb_intDescFID_bInterfaceClass,
|
|
usb_intDescFID_bInterfaceSubClass, usb_intDescFID_bInterfaceProtocol,
|
|
usb_intDescFID_iInterface, usb_intDescFID_endpoint,
|
|
usb_intDescFID_extra, usb_intDescFID_extralen;
|
|
/* usb_endpointDescriptor*/
|
|
static jfieldID usb_epDescFID_bLength, usb_epDescFID_bDescriptorType,
|
|
usb_epDescFID_bEndpointAddress, usb_epDescFID_bmAttributes,
|
|
usb_epDescFID_wMaxPacketSize, usb_epDescFID_bInterval,
|
|
usb_epDescFID_bRefresh, usb_epDescFID_bSynchAddress,
|
|
usb_epDescFID_extra, usb_epDescFID_extralen;
|
|
/*Libusb_pollfd*/
|
|
static jfieldID usb_pollfdFID_fd, usb_pollfdFID_events;
|
|
|
|
/********************************************************************************************
|
|
*
|
|
* Methods
|
|
*
|
|
*******************************************************************************************/
|
|
|
|
/********************************************************************************************
|
|
* Class: ch_ntb_inf_libusbJava_LibusbJava1
|
|
* Method: libusb_set_debug
|
|
* Signature: (JI)V
|
|
********************************************************************************************/
|
|
JNIEXPORT void JNICALL Java_ch_ntb_inf_libusbJava_LibusbJava1_libusb_1set_1debug( JNIEnv *env, jclass obj, jlong ctx, jint level) {
|
|
clearLibusbJavaError();
|
|
libusb_context *context = NULL;
|
|
if (ctx) {
|
|
context = (libusb_context*) ((unsigned long) ctx);
|
|
}
|
|
libusb_set_debug(context, level);
|
|
}
|
|
|
|
/********************************************************************************************
|
|
* Class: ch_ntb_inf_libusbJava_LibusbJava1
|
|
* Method: libusb_init
|
|
* Signature: ()J
|
|
********************************************************************************************/
|
|
JNIEXPORT jlong JNICALL Java_ch_ntb_inf_libusbJava_LibusbJava1_libusb_1init( JNIEnv *env, jclass obj) {
|
|
int res;
|
|
libusb_context *context;
|
|
clearLibusbJavaError();
|
|
|
|
res = libusb_init(&context);
|
|
|
|
#ifdef DEBUGON
|
|
printf("res = %i \n", res);
|
|
printf("env = %p\n", env);
|
|
printf("context = %p\n", &context);
|
|
#endif
|
|
|
|
if (!res) {
|
|
return (jlong) context;
|
|
} else {
|
|
return (jlong) res;
|
|
}
|
|
}
|
|
|
|
/********************************************************************************************
|
|
* Class: ch_ntb_inf_libusbJava_LibusbJava1
|
|
* Method: libusb_exit
|
|
* Signature: (J)V
|
|
*******************************************************************************************/
|
|
JNIEXPORT void JNICALL Java_ch_ntb_inf_libusbJava_LibusbJava1_libusb_1exit(JNIEnv *env, jclass obj, jlong ctx) {
|
|
libusb_context *context = NULL;
|
|
clearLibusbJavaError();
|
|
if (ctx) {
|
|
context = (libusb_context*) ((unsigned long) ctx);
|
|
}
|
|
libusb_exit(context);
|
|
}
|
|
|
|
/********************************************************************************************
|
|
* Class: ch_ntb_inf_libusbJava_LibusbJava1
|
|
* Method: libusb_get_device_list
|
|
* Signature: (J)Lch/ntb/inf/libusbJava/Usb_Device;
|
|
********************************************************************************************/
|
|
JNIEXPORT jobject JNICALL Java_ch_ntb_inf_libusbJava_LibusbJava1_libusb_1get_1device_1list( JNIEnv *env, jclass obj, jlong ctx) {
|
|
libusb_device **devs;
|
|
libusb_context *context = NULL;
|
|
ssize_t cnt;
|
|
int res, a, i;
|
|
uint8_t c, h, e;
|
|
|
|
/* only load class references, method and field ID once*/
|
|
if (!java_references_loaded) {
|
|
/* find classes and field ids*/
|
|
#ifdef DEBUGON
|
|
printf("load references starts\n");
|
|
#endif
|
|
|
|
/*usb_device*/
|
|
jobject devClazz = env->FindClass("ch/ntb/inf/libusbJava/Usb_Device");//returns a local reference
|
|
usb_devClazz = (jclass)env->NewGlobalRef(devClazz);//make it global
|
|
if (usb_devClazz == NULL) {
|
|
return NULL; /* exception thrown */
|
|
}
|
|
usb_devMid = env->GetMethodID(usb_devClazz, "<init>", "()V");
|
|
if (usb_devMid == NULL) {
|
|
return NULL;
|
|
}
|
|
|
|
usb_devFID_next = env->GetFieldID(usb_devClazz, "next", "Lch/ntb/inf/libusbJava/Usb_Device;");
|
|
usb_devFID_prev = env->GetFieldID(usb_devClazz, "prev", "Lch/ntb/inf/libusbJava/Usb_Device;");
|
|
usb_devFID_filename = env->GetFieldID(usb_devClazz, "filename", "Ljava/lang/String;");
|
|
usb_devFID_bus = env->GetFieldID(usb_devClazz, "bus", "Lch/ntb/inf/libusbJava/Usb_Bus;");
|
|
usb_devFID_descriptor = env->GetFieldID(usb_devClazz, "descriptor", "Lch/ntb/inf/libusbJava/Usb_Device_Descriptor;");
|
|
usb_devFID_config = env->GetFieldID(usb_devClazz, "config", "[Lch/ntb/inf/libusbJava/Usb_Config_Descriptor;");
|
|
usb_devFID_devnum = env->GetFieldID(usb_devClazz, "devnum", "B");
|
|
usb_devFID_num_children = env->GetFieldID(usb_devClazz, "num_children", "B");
|
|
usb_devFID_children = env->GetFieldID(usb_devClazz, "children", "Lch/ntb/inf/libusbJava/Usb_Device;");
|
|
usb_devFID_devStructAddr = env->GetFieldID(usb_devClazz, "devStructAddr", "J");
|
|
|
|
#ifdef DEBUGON
|
|
printf("usb_device references loaded\n");
|
|
#endif
|
|
/* usb_device_descriptor*/
|
|
jobject devDescClazz = env->FindClass("ch/ntb/inf/libusbJava/Usb_Device_Descriptor");//returns a local reference
|
|
usb_devDescClazz = (jclass)env->NewGlobalRef(devDescClazz);//make it global
|
|
if (usb_devDescClazz == NULL) {
|
|
return NULL; /* exception thrown */
|
|
}
|
|
usb_devDescMid = env->GetMethodID(usb_devDescClazz, "<init>", "()V");
|
|
if (usb_devDescMid == NULL) {
|
|
return NULL;
|
|
}
|
|
usb_devDescFID_bLength = env->GetFieldID(usb_devDescClazz, "bLength", "B");
|
|
usb_devDescFID_bDescriptorType = env->GetFieldID(usb_devDescClazz, "bDescriptorType", "B");
|
|
usb_devDescFID_bcdUSB = env->GetFieldID(usb_devDescClazz, "bcdUSB", "S");
|
|
usb_devDescFID_bDeviceClass = env->GetFieldID(usb_devDescClazz, "bDeviceClass", "B");
|
|
usb_devDescFID_bDeviceSubClass = env->GetFieldID(usb_devDescClazz, "bDeviceSubClass", "B");
|
|
usb_devDescFID_bDeviceProtocol = env->GetFieldID(usb_devDescClazz, "bDeviceProtocol", "B");
|
|
usb_devDescFID_bMaxPacketSize0 = env->GetFieldID(usb_devDescClazz, "bMaxPacketSize0", "B");
|
|
usb_devDescFID_idVendor = env->GetFieldID(usb_devDescClazz, "idVendor", "S");
|
|
usb_devDescFID_idProduct = env->GetFieldID(usb_devDescClazz, "idProduct", "S");
|
|
usb_devDescFID_bcdDevice = env->GetFieldID(usb_devDescClazz, "bcdDevice", "S");
|
|
usb_devDescFID_iManufacturer = env->GetFieldID(usb_devDescClazz, "iManufacturer", "B");
|
|
usb_devDescFID_iProduct = env->GetFieldID(usb_devDescClazz, "iProduct", "B");
|
|
usb_devDescFID_iSerialNumber = env->GetFieldID(usb_devDescClazz, "iSerialNumber", "B");
|
|
usb_devDescFID_bNumConfigurations = env->GetFieldID(usb_devDescClazz, "bNumConfigurations", "B");
|
|
|
|
|
|
#ifdef DEBUGON
|
|
printf("usb_device_descriptor references loaded\n");
|
|
#endif
|
|
/* usb_configuration_descriptor*/
|
|
jobject confDescClazz = env->FindClass("ch/ntb/inf/libusbJava/Usb_Config_Descriptor");//returns a local reference
|
|
usb_confDescClazz = (jclass)env->NewGlobalRef(confDescClazz);//make it global
|
|
if (usb_confDescClazz == NULL) {
|
|
return NULL; /* exception thrown */
|
|
}
|
|
usb_confDescMid = env->GetMethodID(usb_confDescClazz, "<init>", "()V");
|
|
if (usb_confDescMid == NULL) {
|
|
return NULL;
|
|
}
|
|
|
|
usb_confDescFID_bLength = env->GetFieldID(usb_confDescClazz, "bLength", "B");
|
|
usb_confDescFID_bDescriptorType = env->GetFieldID(usb_confDescClazz, "bDescriptorType", "B");
|
|
usb_confDescFID_wTotalLength = env->GetFieldID(usb_confDescClazz, "wTotalLength", "S");
|
|
usb_confDescFID_bNumInterfaces = env->GetFieldID(usb_confDescClazz, "bNumInterfaces", "B");
|
|
usb_confDescFID_bConfigurationValue = env->GetFieldID(usb_confDescClazz, "bConfigurationValue", "B");
|
|
usb_confDescFID_iConfiguration = env->GetFieldID(usb_confDescClazz, "iConfiguration", "B");
|
|
usb_confDescFID_bmAttributes = env->GetFieldID(usb_confDescClazz, "bmAttributes", "B");
|
|
usb_confDescFID_MaxPower = env->GetFieldID(usb_confDescClazz, "MaxPower", "B");
|
|
usb_confDescFID_interface_ = env->GetFieldID(usb_confDescClazz, "interface_", "[Lch/ntb/inf/libusbJava/Usb_Interface;");
|
|
usb_confDescFID_extra = env->GetFieldID(usb_confDescClazz, "extra", "[B");
|
|
usb_confDescFID_extralen = env->GetFieldID(usb_confDescClazz, "extralen", "I");
|
|
#ifdef DEBUGON
|
|
printf("usb_configuration_descriptor references loaded\n");
|
|
#endif
|
|
/* usb_interface*/
|
|
jobject intClazz = env->FindClass("ch/ntb/inf/libusbJava/Usb_Interface");//returns a local reference
|
|
usb_intClazz = (jclass)env->NewGlobalRef(intClazz);//make it global
|
|
if (usb_intClazz == NULL) {
|
|
return NULL; /* exception thrown */
|
|
}
|
|
usb_intMid = env->GetMethodID(usb_intClazz, "<init>", "()V");
|
|
if (usb_intMid == NULL) {
|
|
return NULL;
|
|
}
|
|
usb_intFID_altsetting = env->GetFieldID(usb_intClazz, "altsetting", "[Lch/ntb/inf/libusbJava/Usb_Interface_Descriptor;");
|
|
usb_intFID_num_altsetting = env->GetFieldID(usb_intClazz, "num_altsetting", "I");
|
|
#ifdef DEBUGON
|
|
printf("usb_interface references loaded\n");
|
|
#endif
|
|
/* usb_interface_descriptor*/
|
|
jobject intDescClazz = env->FindClass( "ch/ntb/inf/libusbJava/Usb_Interface_Descriptor");//returns a local reference
|
|
usb_intDescClazz = (jclass)env->NewGlobalRef(intDescClazz);//make it global
|
|
if (usb_intDescClazz == NULL) {
|
|
return NULL; /* exception thrown */
|
|
}
|
|
usb_intDescMid = env->GetMethodID(usb_intDescClazz, "<init>", "()V");
|
|
if (usb_intDescMid == NULL) {
|
|
return NULL;
|
|
}
|
|
usb_intDescFID_bLength = env->GetFieldID(usb_intDescClazz, "bLength", "B");
|
|
usb_intDescFID_bDescriptorType = env->GetFieldID(usb_intDescClazz, "bDescriptorType", "B");
|
|
usb_intDescFID_bInterfaceNumber = env->GetFieldID(usb_intDescClazz, "bInterfaceNumber", "B");
|
|
usb_intDescFID_bAlternateSetting = env->GetFieldID(usb_intDescClazz, "bAlternateSetting", "B");
|
|
usb_intDescFID_bNumEndpoints = env->GetFieldID(usb_intDescClazz, "bNumEndpoints", "B");
|
|
usb_intDescFID_bInterfaceClass = env->GetFieldID(usb_intDescClazz, "bInterfaceClass", "B");
|
|
usb_intDescFID_bInterfaceSubClass = env->GetFieldID(usb_intDescClazz, "bInterfaceSubClass", "B");
|
|
usb_intDescFID_bInterfaceProtocol = env->GetFieldID(usb_intDescClazz, "bInterfaceProtocol", "B");
|
|
usb_intDescFID_iInterface = env->GetFieldID(usb_intDescClazz, "iInterface", "B");
|
|
usb_intDescFID_endpoint = env->GetFieldID(usb_intDescClazz, "endpoint", "[Lch/ntb/inf/libusbJava/Usb_Endpoint_Descriptor;");
|
|
usb_intDescFID_extra = env->GetFieldID(usb_intDescClazz, "extra", "[B");
|
|
usb_intDescFID_extralen = env->GetFieldID(usb_intDescClazz, "extralen", "I");
|
|
#ifdef DEBUGON
|
|
printf("usb_interface_descriptor references loaded\n");
|
|
#endif
|
|
/* usb_endpoint_descriptor*/
|
|
jobject epDescClazz = env->FindClass("ch/ntb/inf/libusbJava/Usb_Endpoint_Descriptor");//returns a local reference
|
|
usb_epDescClazz = (jclass)env->NewGlobalRef(epDescClazz);//make it global
|
|
if (usb_epDescClazz == NULL) {
|
|
return NULL; /* exception thrown */
|
|
}
|
|
usb_epDescMid = env->GetMethodID(usb_epDescClazz, "<init>", "()V");
|
|
if (usb_epDescMid == NULL) {
|
|
return NULL;
|
|
}
|
|
usb_epDescFID_bLength = env->GetFieldID(usb_epDescClazz, "bLength", "B");
|
|
usb_epDescFID_bDescriptorType = env->GetFieldID(usb_epDescClazz, "bDescriptorType", "B");
|
|
usb_epDescFID_bEndpointAddress = env->GetFieldID(usb_epDescClazz, "bEndpointAddress", "B");
|
|
usb_epDescFID_bmAttributes = env->GetFieldID(usb_epDescClazz, "bmAttributes", "B");
|
|
usb_epDescFID_wMaxPacketSize = env->GetFieldID(usb_epDescClazz, "wMaxPacketSize", "S");
|
|
usb_epDescFID_bInterval = env->GetFieldID(usb_epDescClazz, "bInterval", "B");
|
|
usb_epDescFID_bRefresh = env->GetFieldID(usb_epDescClazz, "bRefresh", "B");
|
|
usb_epDescFID_bSynchAddress = env->GetFieldID(usb_epDescClazz, "bSynchAddress", "B");
|
|
usb_epDescFID_extra = env->GetFieldID(usb_epDescClazz, "extra", "[B");
|
|
usb_epDescFID_extralen = env->GetFieldID(usb_epDescClazz, "extralen", "I");
|
|
#ifdef DEBUGON
|
|
printf("usb_endpoint_descriptor references loaded\n");
|
|
#endif
|
|
/*libusb_event*/
|
|
jobject cb_clazz = env->FindClass("ch/ntb/inf/libusbJava/Libusb_event");//returns a local reference
|
|
usb_cb_clazz = (jclass)env->NewGlobalRef(cb_clazz);//make it global
|
|
if (usb_cb_clazz == NULL) {
|
|
printf("load Clazz failed\n");
|
|
return NULL; /*exception thrown*/
|
|
}
|
|
usb_transfer_cb_Mid = env->GetMethodID(usb_cb_clazz, "transferCallback", "()V");
|
|
if (usb_transfer_cb_Mid == NULL) {
|
|
printf("load method transferCallback failed\n");
|
|
return NULL; /* exception thrown */
|
|
}
|
|
usb_fd_added_cb_Mid = env->GetMethodID(usb_cb_clazz, "fdAddedCallback", "(I)V");
|
|
if (usb_fd_added_cb_Mid == NULL) {
|
|
printf("load method fdAddedCallback failed\n");
|
|
return NULL;/* exception thrown */
|
|
}
|
|
usb_fd_removed_cb_Mid = env->GetMethodID(usb_cb_clazz, "fdRemovedCallback", "(I)V");
|
|
if (usb_fd_removed_cb_Mid == NULL) {
|
|
printf("load method fdRemovedCallback failed\n");
|
|
return NULL;/* exception thrown */
|
|
}
|
|
#ifdef DEBUGON
|
|
printf("usb_event_descriptor references loaded\n");
|
|
#endif
|
|
/*Libusb_pollfd*/
|
|
jobject pollfd_clazz = env->FindClass("ch/ntb/inf/libusbJava/Libusb_pollfd");//returns a local reference
|
|
usb_pollfd_clazz = (jclass)env->NewGlobalRef(pollfd_clazz);//make it global
|
|
if (usb_pollfd_clazz == NULL) {
|
|
return NULL; /*exception thrown*/
|
|
}
|
|
usb_pollfd_Mid = env->GetMethodID(usb_pollfd_clazz, "<init>", "()V");
|
|
if (usb_devMid == NULL) {
|
|
return NULL; /*exception thrown*/
|
|
}
|
|
usb_pollfdFID_fd = env->GetFieldID(usb_pollfd_clazz, "fd", "I");
|
|
usb_pollfdFID_events = env->GetFieldID(usb_pollfd_clazz, "events", "B");
|
|
#ifdef DEBUGON
|
|
printf("Libusb_pollfd_descriptor references loaded\n");
|
|
#endif
|
|
java_references_loaded = 1;
|
|
|
|
#ifdef DEBUGON
|
|
printf("libusb_init: Field initialization done \n");
|
|
#endif
|
|
}
|
|
|
|
/* objects*/
|
|
jobject root_usb_devObj, usb_devObj, usb_devObj_next, usb_devObj_prev,
|
|
usb_devDescObj, usb_confDescObj, usb_intObj, usb_intDescObj,
|
|
usb_epDescObj;
|
|
|
|
jobjectArray usb_confDescObjArray, usb_intObjArray, usb_intDescObjArray,
|
|
usb_epDescObjArray;
|
|
clearLibusbJavaError();
|
|
|
|
libusb_config_descriptor *conf_desc;
|
|
if (ctx > 0) {
|
|
context = (libusb_context*) ((unsigned long) ctx);
|
|
cnt = libusb_get_device_list(context, &devs);
|
|
} else {
|
|
cnt = libusb_get_device_list(NULL, &devs);
|
|
}
|
|
if (cnt < 0) {
|
|
setLibusbJavaError("libusb_get_device_list: Error on Memory allocation");
|
|
libusb_free_device_list(devs, 1);
|
|
return NULL;
|
|
}
|
|
|
|
/*empty list*/
|
|
if (!cnt) {
|
|
libusb_free_device_list(devs, 1);
|
|
usb_devObj = env->NewObject(usb_devClazz, usb_devMid);
|
|
env->SetByteField(usb_devObj, usb_devFID_devnum, -1);
|
|
}
|
|
usb_devObj = NULL;
|
|
usb_devObj_next = NULL;
|
|
usb_devObj_prev = NULL;
|
|
/* create a new object for every device*/
|
|
for (i = 0; i < cnt; i++) {
|
|
#ifdef DEBUGON
|
|
printf("libusb_get_device_list: dev %u \n", i);
|
|
#endif
|
|
char filename[3];
|
|
|
|
libusb_device_descriptor dev_desc;
|
|
res = libusb_get_device_descriptor(devs[i], &dev_desc);
|
|
|
|
if (res) {
|
|
/* this shouldn't happen*/
|
|
printf("\t libusb_get _device_list: dev %u coudn't read Devicedescriptor\n",i);
|
|
continue;
|
|
}
|
|
if (dev_desc.bLength != 18) {
|
|
printf("Corrupt Devicedescriptor dev %d\n", i);
|
|
continue;
|
|
}
|
|
|
|
if (!usb_devObj) {
|
|
usb_devObj = env->NewObject(usb_devClazz, usb_devMid);
|
|
if (!usb_devObj) {
|
|
setLibusbJavaError("shared library error: Error NewObject (usb_devObj)");
|
|
return NULL;
|
|
}
|
|
root_usb_devObj = usb_devObj;
|
|
}
|
|
usb_devObj_next = NULL;
|
|
if (i < cnt - 1) {
|
|
usb_devObj_next = env->NewObject(usb_devClazz, usb_devMid);
|
|
if (!usb_devObj_next) {
|
|
setLibusbJavaError("shared library error: Error NewObject (usb_devObj_next)");
|
|
return NULL;
|
|
}
|
|
}
|
|
/*fill the fields of the object*/
|
|
env->SetObjectField(usb_devObj, usb_devFID_next, usb_devObj_next);
|
|
env->SetObjectField(usb_devObj, usb_devFID_prev, usb_devObj_prev);
|
|
sprintf(filename, "%03d", libusb_get_device_address(devs[i]));
|
|
env->SetObjectField(usb_devObj, usb_devFID_filename, env->NewStringUTF(filename));/*like the compatibility Layer*/
|
|
env->SetByteField(usb_devObj, usb_devFID_devnum, libusb_get_device_address(devs[i]));
|
|
env->SetByteField(usb_devObj, usb_devFID_num_children, 0);/*Hardcoded to 0, like the compatibility Layer*/
|
|
env->SetObjectField(usb_devObj, usb_devFID_children, NULL);/*Hardcoded to NULL, like the compatibility Layer*/
|
|
env->SetLongField(usb_devObj, usb_devFID_devStructAddr, (jlong) devs[i]);
|
|
|
|
/*device Descriptor*/
|
|
usb_devDescObj = env->NewObject(usb_devDescClazz, usb_devDescMid);
|
|
if (!usb_devDescObj) {
|
|
setLibusbJavaError("shared library error: Error NewObject (usb_devDescObj)");
|
|
return NULL;
|
|
}
|
|
env->SetByteField(usb_devDescObj, usb_devDescFID_bLength, dev_desc.bLength);
|
|
env->SetByteField(usb_devDescObj, usb_devDescFID_bDescriptorType, dev_desc.bDescriptorType);
|
|
env->SetShortField(usb_devDescObj, usb_devDescFID_bcdUSB, dev_desc.bcdUSB);
|
|
env->SetByteField(usb_devDescObj, usb_devDescFID_bDeviceClass, dev_desc.bDeviceClass);
|
|
env->SetByteField(usb_devDescObj, usb_devDescFID_bDeviceSubClass, dev_desc.bDeviceSubClass);
|
|
env->SetByteField(usb_devDescObj, usb_devDescFID_bDeviceProtocol, dev_desc.bDeviceProtocol);
|
|
env->SetByteField(usb_devDescObj, usb_devDescFID_bMaxPacketSize0, dev_desc.bMaxPacketSize0);
|
|
env->SetShortField(usb_devDescObj, usb_devDescFID_idVendor, dev_desc.idVendor);
|
|
env->SetShortField(usb_devDescObj, usb_devDescFID_idProduct, dev_desc.idProduct);
|
|
env->SetShortField(usb_devDescObj, usb_devDescFID_bcdDevice, dev_desc.bcdDevice);
|
|
env->SetByteField(usb_devDescObj, usb_devDescFID_iManufacturer, dev_desc.iManufacturer);
|
|
env->SetByteField(usb_devDescObj, usb_devDescFID_iProduct, dev_desc.iProduct);
|
|
env->SetByteField(usb_devDescObj, usb_devDescFID_iSerialNumber, dev_desc.iSerialNumber);
|
|
env->SetByteField(usb_devDescObj, usb_devDescFID_bNumConfigurations, dev_desc.bNumConfigurations);
|
|
env->SetObjectField(usb_devDescObj, usb_devFID_descriptor, usb_devDescObj);
|
|
env->SetObjectField(usb_devObj, usb_devFID_descriptor, usb_devDescObj);
|
|
|
|
/*configuration descriptor*/
|
|
/*Loop through all of the configurations*/
|
|
usb_confDescObjArray = (jobjectArray) env->NewObjectArray(dev_desc.bNumConfigurations, usb_confDescClazz, NULL);
|
|
if (!usb_confDescObjArray) {
|
|
setLibusbJavaError("shared library error: Error NewOjectArray");
|
|
return NULL;
|
|
}
|
|
for (c = 0; c < dev_desc.bNumConfigurations; c++) {
|
|
#ifdef DEBUGON
|
|
printf("\t\tlibusb_get_device_list: configuration %u, Dev: %d \n", c, i);
|
|
#endif
|
|
res = libusb_get_config_descriptor(devs[i], c, &conf_desc);
|
|
if (res) {
|
|
continue;
|
|
}
|
|
usb_confDescObj = env->NewObject(usb_confDescClazz, usb_confDescMid);
|
|
if (!usb_confDescObj) {
|
|
setLibusbJavaError("shared library error: Error NewObject (usb_confDescObj)");
|
|
return NULL;
|
|
}
|
|
env->SetObjectArrayElement(usb_confDescObjArray, c, usb_confDescObj);/*add it to the Array*/
|
|
/*fill the fields*/
|
|
env->SetByteField(usb_confDescObj, usb_confDescFID_bLength, conf_desc->bLength);
|
|
env->SetByteField(usb_confDescObj, usb_confDescFID_bDescriptorType, conf_desc->bDescriptorType);
|
|
env->SetShortField(usb_confDescObj, usb_confDescFID_wTotalLength, conf_desc->wTotalLength);
|
|
env->SetByteField(usb_confDescObj, usb_confDescFID_bNumInterfaces, conf_desc->bNumInterfaces);
|
|
env->SetByteField(usb_confDescObj, usb_confDescFID_bConfigurationValue, conf_desc->bConfigurationValue);
|
|
env->SetByteField(usb_confDescObj, usb_confDescFID_iConfiguration, conf_desc->iConfiguration);
|
|
env->SetByteField(usb_confDescObj, usb_confDescFID_bmAttributes, conf_desc->bmAttributes);
|
|
env->SetByteField(usb_confDescObj, usb_confDescFID_MaxPower, conf_desc->MaxPower);
|
|
env->SetIntField(usb_confDescObj, usb_confDescFID_extralen, conf_desc->extra_length);
|
|
if (conf_desc->extra) {
|
|
jbyteArray jbExtraDesc = to_byteArray(env, conf_desc->extra, conf_desc->extra_length);
|
|
env->SetObjectField(usb_confDescObj, usb_confDescFID_extra, jbExtraDesc);
|
|
} else {
|
|
env->SetObjectField(usb_confDescObj, usb_confDescFID_extra, NULL);
|
|
}
|
|
/*interface*/
|
|
usb_intObjArray = (jobjectArray) env->NewObjectArray(conf_desc->bNumInterfaces, usb_intClazz, NULL);
|
|
if (!usb_intObjArray) {
|
|
setLibusbJavaError("shared library error: Error NewObjectArray (usb_intObjArray)");
|
|
return NULL;
|
|
}
|
|
for (h = 0; h < conf_desc->bNumInterfaces; h++) {
|
|
#ifdef DEBUGON
|
|
printf("\t\t\tlibusb_get_device_list: interface %u \n", h);
|
|
#endif
|
|
|
|
if (conf_desc->interface == NULL) {
|
|
/* this shouldn't happen*/
|
|
printf("(*conf_desc)->usb_interface == NULL");
|
|
continue;
|
|
}
|
|
usb_intObj = env->NewObject(usb_intClazz, usb_intMid);
|
|
if (!usb_intObj) {
|
|
setLibusbJavaError("shared library error: Error NewObject (usb_intObj)");
|
|
return NULL;
|
|
}
|
|
env->SetObjectArrayElement(usb_intObjArray, h, usb_intObj);
|
|
env->SetIntField(usb_intObj, usb_intFID_num_altsetting, conf_desc->interface[h].num_altsetting);
|
|
// interface descriptor
|
|
usb_intDescObjArray = (jobjectArray) env->NewObjectArray( conf_desc->interface[h].num_altsetting, usb_intDescClazz, NULL);
|
|
if (!usb_intDescObjArray) {
|
|
setLibusbJavaError("shared library error: Error NewObjectArray (usb_intDescObjArray)");
|
|
return NULL;
|
|
}
|
|
for (a = 0; a < conf_desc->interface[h].num_altsetting; a++) {
|
|
#ifdef DEBUGON
|
|
printf("\t\t\t\tlibusb_get_device_list: interface descriptor %u \n", a);
|
|
#endif
|
|
if (conf_desc->interface[h].altsetting == NULL) {
|
|
// this shouldn't happen
|
|
printf("LibusbJava: libusb_get_device_list: (*conf_desc)->interface->altsetting == NULL\n");
|
|
continue;
|
|
}
|
|
usb_intDescObj = env->NewObject(usb_intDescClazz, usb_intDescMid);
|
|
if (!usb_intDescObj) {
|
|
setLibusbJavaError("shared library error: Error NewObject (usb_intDescObj)");
|
|
return NULL;
|
|
}
|
|
env->SetObjectArrayElement(usb_intDescObjArray, a, usb_intDescObj);
|
|
/*fill fields*/
|
|
env->SetByteField(usb_intDescObj, usb_intDescFID_bLength, conf_desc->interface[h].altsetting[a].bLength);
|
|
env->SetByteField(usb_intDescObj, usb_intDescFID_bDescriptorType, conf_desc->interface[h].altsetting[a].bDescriptorType);
|
|
env->SetByteField(usb_intDescObj, usb_intDescFID_bInterfaceNumber, conf_desc->interface[h].altsetting[a].bInterfaceNumber);
|
|
env->SetByteField(usb_intDescObj, usb_intDescFID_bAlternateSetting, conf_desc->interface[h].altsetting[a].bAlternateSetting);
|
|
env->SetByteField(usb_intDescObj, usb_intDescFID_bNumEndpoints, conf_desc->interface[h].altsetting[a].bNumEndpoints);
|
|
env->SetByteField(usb_intDescObj, usb_intDescFID_bInterfaceClass, conf_desc->interface[h].altsetting[a].bInterfaceClass);
|
|
env->SetByteField(usb_intDescObj, usb_intDescFID_bInterfaceSubClass, conf_desc->interface[h].altsetting[a].bInterfaceSubClass);
|
|
env->SetByteField(usb_intDescObj, usb_intDescFID_bInterfaceProtocol, conf_desc->interface[h].altsetting[a].bInterfaceProtocol);
|
|
env->SetByteField(usb_intDescObj, usb_intDescFID_iInterface, conf_desc->interface[h].altsetting[a].iInterface);
|
|
env->SetIntField(usb_intDescObj, usb_intDescFID_extralen, conf_desc->interface[h].altsetting[a].extra_length);
|
|
if (conf_desc->interface[h].altsetting[a].extra) {
|
|
jbyteArray jbExtraDesc = to_byteArray(env, conf_desc->interface[h].altsetting[a].extra, conf_desc->interface[h].altsetting[a].extra_length);
|
|
env->SetObjectField(usb_intDescObj, usb_intDescFID_extra, jbExtraDesc);
|
|
} else {
|
|
env->SetObjectField(usb_intDescObj, usb_intDescFID_extra, NULL);
|
|
}
|
|
/*endpoint descriptor*/
|
|
usb_epDescObjArray = (jobjectArray) env->NewObjectArray( conf_desc->interface[h].altsetting[a].bNumEndpoints, usb_epDescClazz, NULL);
|
|
if (!usb_epDescObjArray) {
|
|
setLibusbJavaError("shared library error: Error NewObjectArray (usb_epDescObjArray)");
|
|
return NULL;
|
|
}
|
|
for (e = 0; e < conf_desc->interface[h].altsetting[a].bNumEndpoints; e++) {
|
|
#ifdef DEBUGON
|
|
printf("\t\t\t\t\tLibusb_get_device_list: endpoint descriptor %u \n",e);
|
|
#endif
|
|
|
|
|
|
if (conf_desc->interface[h].altsetting[a].endpoint == NULL) {
|
|
printf( "LibusbJava: usb_get_busses: (*conf_desc)->interface->altsetting->endpoint == NULL\n");
|
|
return root_usb_devObj;
|
|
}
|
|
usb_epDescObj = env->NewObject(usb_epDescClazz, usb_epDescMid);
|
|
if (!usb_epDescObj) {
|
|
setLibusbJavaError("shared library error: Error NewObject (usb_epDescObj)");
|
|
return NULL;
|
|
}
|
|
env->SetObjectArrayElement(usb_epDescObjArray, e, usb_epDescObj);
|
|
env->SetByteField(usb_epDescObj, usb_epDescFID_bLength, conf_desc->interface[h].altsetting[a].endpoint[e].bLength);
|
|
env->SetByteField(usb_epDescObj, usb_epDescFID_bDescriptorType, conf_desc->interface[h].altsetting[a].endpoint[e].bDescriptorType);
|
|
env->SetByteField(usb_epDescObj, usb_epDescFID_bEndpointAddress, conf_desc->interface[h].altsetting[a].endpoint[e].bEndpointAddress);
|
|
env->SetByteField(usb_epDescObj, usb_epDescFID_bmAttributes, conf_desc->interface[h].altsetting[a].endpoint[e].bmAttributes);
|
|
env->SetShortField(usb_epDescObj, usb_epDescFID_wMaxPacketSize, conf_desc->interface[h].altsetting[a].endpoint[e].wMaxPacketSize);
|
|
env->SetByteField(usb_epDescObj, usb_epDescFID_bInterval, conf_desc->interface[h].altsetting[a].endpoint[e].bInterval);
|
|
env->SetByteField(usb_epDescObj, usb_epDescFID_bRefresh, conf_desc->interface[h].altsetting[a].endpoint[e].bRefresh);
|
|
env->SetByteField(usb_epDescObj, usb_epDescFID_bSynchAddress, conf_desc->interface[h].altsetting[a].endpoint[e].bSynchAddress);
|
|
env->SetIntField(usb_epDescObj, usb_epDescFID_extralen, conf_desc->interface[h].altsetting[a].endpoint[e].extra_length);
|
|
if (conf_desc->interface[h].altsetting[a].endpoint[e].extra) {
|
|
jbyteArray jbExtraDesc = to_byteArray(env, conf_desc->interface[h].altsetting[a].endpoint[e].extra, conf_desc->interface[h].altsetting[a].endpoint[e].extra_length);
|
|
env->SetObjectField(usb_epDescObj, usb_epDescFID_extra, jbExtraDesc);
|
|
} else {
|
|
env->SetObjectField(usb_epDescObj, usb_epDescFID_extra, NULL);
|
|
}
|
|
}
|
|
env->SetObjectField(usb_intDescObj, usb_intDescFID_endpoint, usb_epDescObjArray);
|
|
}
|
|
env->SetObjectField(usb_intObj, usb_intFID_altsetting, usb_intDescObjArray);
|
|
}
|
|
env->SetObjectField(usb_confDescObj, usb_confDescFID_interface_, usb_intObjArray);
|
|
libusb_free_config_descriptor(conf_desc);
|
|
}
|
|
if (res) {
|
|
env->SetLongField(usb_devObj, usb_devFID_devStructAddr, (jlong) 0);
|
|
continue;
|
|
}
|
|
env->SetObjectField(usb_devObj, usb_devFID_config, usb_confDescObjArray);
|
|
usb_devObj_prev = usb_devObj;
|
|
usb_devObj = usb_devObj_next;
|
|
|
|
}
|
|
//Eliminate empty last device
|
|
env->SetObjectField(usb_devObj_prev, usb_devFID_next, NULL);
|
|
|
|
// free(dev_desc);
|
|
libusb_free_device_list(devs, 0);
|
|
#ifdef DEBUGON
|
|
printf("libusb_get_device_list: done\n");
|
|
#endif
|
|
return root_usb_devObj;
|
|
}
|
|
|
|
/********************************************************************************************
|
|
* Class: ch_ntb_inf_libusbJava_LibusbJava1
|
|
* Method: libusb_get_bus_number
|
|
* Signature: (Lch/ntb/inf/libusbJava/Usb_Device;)S
|
|
********************************************************************************************/
|
|
JNIEXPORT jshort JNICALL Java_ch_ntb_inf_libusbJava_LibusbJava1_libusb_1get_1bus_1number( JNIEnv *env, jclass obj, jobject dev) {
|
|
clearLibusbJavaError();
|
|
libusb_device *libusb_dev = (libusb_device *) (long) env->GetLongField(dev, usb_devFID_devStructAddr);
|
|
return libusb_get_bus_number(libusb_dev);
|
|
}
|
|
|
|
/********************************************************************************************
|
|
* Class: ch_ntb_inf_libusbJava_LibusbJava1
|
|
* Method: libusb_get_max_iso_packet_size
|
|
* Signature: (Lch/ntb/inf/libusbJava/Usb_Device;S)I
|
|
********************************************************************************************/
|
|
JNIEXPORT jint
|
|
JNICALL Java_ch_ntb_inf_libusbJava_LibusbJava1_libusb_1get_1max_1iso_1packet_1size( JNIEnv *env, jclass obj, jobject dev, jshort epAddr) {
|
|
clearLibusbJavaError();
|
|
libusb_device *libusb_dev = (libusb_device *) (unsigned long) env->GetLongField(dev, usb_devFID_devStructAddr);
|
|
return libusb_get_max_iso_packet_size(libusb_dev, epAddr);
|
|
}
|
|
|
|
/********************************************************************************************
|
|
* Class: ch_ntb_inf_libusbJava_LibusbJava1
|
|
* Method: libusb_ref_device
|
|
* Signature: (Lch/ntb/inf/libusbJava/Usb_Device;)Lch/ntb/inf/libusbJava/Usb_Device;
|
|
********************************************************************************************/
|
|
JNIEXPORT jobject JNICALL Java_ch_ntb_inf_libusbJava_LibusbJava1_libusb_1ref_1device(JNIEnv *env, jclass obj, jobject dev) {
|
|
clearLibusbJavaError();
|
|
libusb_device *libusb_dev = (libusb_device *) (unsigned long) env->GetLongField(dev, usb_devFID_devStructAddr);
|
|
libusb_ref_device(libusb_dev);
|
|
return dev;
|
|
}
|
|
|
|
/********************************************************************************************
|
|
* Class: ch_ntb_inf_libusbJava_LibusbJava1
|
|
* Method: libusb_unref_device
|
|
* Signature: (Lch/ntb/inf/libusbJava/Usb_Device;)V
|
|
********************************************************************************************/
|
|
JNIEXPORT void JNICALL Java_ch_ntb_inf_libusbJava_LibusbJava1_libusb_1unref_1device(JNIEnv *env, jclass obj, jobject dev) {
|
|
clearLibusbJavaError();
|
|
libusb_device *libusb_dev = (libusb_device *) (unsigned long) env->GetLongField(dev,usb_devFID_devStructAddr);
|
|
libusb_unref_device(libusb_dev);
|
|
}
|
|
|
|
/********************************************************************************************
|
|
* Class: ch_ntb_inf_libusbJava_LibusbJava1
|
|
* Method: libusb_open
|
|
* Signature: (Lch/ntb/inf/libusbJava/Usb_Device;)J
|
|
********************************************************************************************/
|
|
JNIEXPORT jlong JNICALL Java_ch_ntb_inf_libusbJava_LibusbJava1_libusb_1open( JNIEnv *env, jclass obj, jobject dev) {
|
|
clearLibusbJavaError();
|
|
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 != 0)
|
|
{
|
|
ThrowLibusbError(env, res);
|
|
handle = NULL;
|
|
}
|
|
|
|
return (jlong)handle;
|
|
}
|
|
|
|
/********************************************************************************************
|
|
* Class: ch_ntb_inf_libusbJava_LibusbJava1
|
|
* Method: libusb_open_device_with_vid_pid
|
|
* Signature: (JII)J
|
|
********************************************************************************************/
|
|
JNIEXPORT jlong
|
|
JNICALL Java_ch_ntb_inf_libusbJava_LibusbJava1_libusb_1open_1device_1with_1vid_1pid(JNIEnv *env, jclass obj, jlong ctx, jint vendor_id, jint product_id) {
|
|
clearLibusbJavaError();
|
|
return (jlong) libusb_open_device_with_vid_pid((libusb_context*) (unsigned long) ctx, vendor_id, product_id);
|
|
}
|
|
|
|
/********************************************************************************************
|
|
* Class: ch_ntb_inf_libusbJava_LibusbJava1
|
|
* Method: libusb_close
|
|
* Signature: (J)V
|
|
********************************************************************************************/
|
|
JNIEXPORT void JNICALL Java_ch_ntb_inf_libusbJava_LibusbJava1_libusb_1close(JNIEnv *env, jclass obj, jlong dev_handle) {
|
|
clearLibusbJavaError();
|
|
libusb_close((libusb_device_handle*) (unsigned long) dev_handle);
|
|
}
|
|
|
|
/********************************************************************************************
|
|
* Class: ch_ntb_inf_libusbJava_LibusbJava1
|
|
* Method: libusb_get_device
|
|
* Signature: (J)Lch/ntb/inf/libusbJava/Usb_Device;
|
|
********************************************************************************************/
|
|
JNIEXPORT jobject JNICALL Java_ch_ntb_inf_libusbJava_LibusbJava1_libusb_1get_1device(JNIEnv *env, jclass obj, jlong handle) {
|
|
int res, a;
|
|
uint8_t c, h, e;
|
|
char filename[3];
|
|
clearLibusbJavaError();
|
|
libusb_config_descriptor *conf_desc;
|
|
struct libusb_device_descriptor dev_desc;
|
|
libusb_device *lib_dev = libusb_get_device((libusb_device_handle*) (unsigned long) handle);
|
|
|
|
/* objects*/
|
|
jobject usb_devObj, usb_devDescObj, usb_confDescObj, usb_intObj, usb_intDescObj, usb_epDescObj;
|
|
jobjectArray usb_confDescObjArray, usb_intObjArray, usb_intDescObjArray, usb_epDescObjArray;
|
|
|
|
/* create a new object for device*/
|
|
libusb_get_device_descriptor(lib_dev, &dev_desc);
|
|
usb_devObj = env->NewObject(usb_devClazz, usb_devMid);
|
|
if (!usb_devObj) {
|
|
setLibusbJavaError("shared library error: Error NewObject (usb_devObj)");
|
|
return NULL;
|
|
}
|
|
|
|
/*fill the fields of the object*/
|
|
env->SetObjectField(usb_devObj, usb_devFID_next, NULL);
|
|
env->SetObjectField(usb_devObj, usb_devFID_prev, NULL);
|
|
|
|
sprintf(filename, "%03d", libusb_get_device_address(lib_dev));
|
|
env->SetObjectField(usb_devObj, usb_devFID_filename, env->NewStringUTF(filename));/*like the compatibility Layer*/
|
|
env->SetByteField(usb_devObj, usb_devFID_devnum, libusb_get_device_address(lib_dev));
|
|
env->SetByteField(usb_devObj, usb_devFID_num_children, 0);/*Hardcoded to 0, like the compatibility Layer*/
|
|
env->SetObjectField(usb_devObj, usb_devFID_children, NULL);/*Hardcoded to NULL, like the compatibility Layer*/
|
|
env->SetLongField(usb_devObj, usb_devFID_devStructAddr,(jlong) lib_dev);
|
|
|
|
/*device Descriptor*/
|
|
usb_devDescObj = env->NewObject(usb_devDescClazz, usb_devDescMid);
|
|
if (!usb_devDescObj) {
|
|
setLibusbJavaError("shared library error: Error NewObject (usb_devDescObj)");
|
|
return NULL;
|
|
}
|
|
env->SetByteField(usb_devDescObj, usb_devDescFID_bLength, dev_desc.bLength);
|
|
env->SetByteField(usb_devDescObj, usb_devDescFID_bDescriptorType, dev_desc.bDescriptorType);
|
|
env->SetShortField(usb_devDescObj, usb_devDescFID_bcdUSB, dev_desc.bcdUSB);
|
|
env->SetByteField(usb_devDescObj, usb_devDescFID_bDeviceClass, dev_desc.bDeviceClass);
|
|
env->SetByteField(usb_devDescObj, usb_devDescFID_bDeviceSubClass, dev_desc.bDeviceSubClass);
|
|
env->SetByteField(usb_devDescObj, usb_devDescFID_bDeviceProtocol, dev_desc.bDeviceProtocol);
|
|
env->SetByteField(usb_devDescObj, usb_devDescFID_bMaxPacketSize0, dev_desc.bMaxPacketSize0);
|
|
env->SetShortField(usb_devDescObj, usb_devDescFID_idVendor, dev_desc.idVendor);
|
|
env->SetShortField(usb_devDescObj, usb_devDescFID_idProduct, dev_desc.idProduct);
|
|
env->SetShortField(usb_devDescObj, usb_devDescFID_bcdDevice, dev_desc.bcdDevice);
|
|
env->SetByteField(usb_devDescObj, usb_devDescFID_iManufacturer, dev_desc.iManufacturer);
|
|
env->SetByteField(usb_devDescObj, usb_devDescFID_iProduct, dev_desc.iProduct);
|
|
env->SetByteField(usb_devDescObj, usb_devDescFID_iSerialNumber, dev_desc.iSerialNumber);
|
|
env->SetByteField(usb_devDescObj, usb_devDescFID_bNumConfigurations, dev_desc.bNumConfigurations);
|
|
env->SetObjectField(usb_devDescObj, usb_devFID_descriptor, usb_devDescObj);
|
|
|
|
/*configuration descriptor*/
|
|
/*Loop through all of the configurations*/
|
|
usb_confDescObjArray = (jobjectArray) env->NewObjectArray(
|
|
dev_desc.bNumConfigurations, usb_confDescClazz, NULL);
|
|
if (!usb_confDescObjArray) {
|
|
setLibusbJavaError("shared library error: Error NewOjectArray");
|
|
return NULL;
|
|
}
|
|
for (c = 0; c < dev_desc.bNumConfigurations; c++) {
|
|
#ifdef DEBUGON
|
|
printf("\t\tlibusb_get_device: configuration %u \n", c);
|
|
#endif
|
|
res = libusb_get_config_descriptor(lib_dev, c, &conf_desc);
|
|
if (res) {
|
|
setLibusbJavaError("shared library error: read conf_desc failed");
|
|
return usb_devObj;
|
|
}
|
|
|
|
usb_confDescObj = env->NewObject(usb_confDescClazz, usb_confDescMid);
|
|
if (!usb_confDescObj) {
|
|
setLibusbJavaError("shared library error: Error NewObject (usb_confDescObj)");
|
|
return NULL;
|
|
}
|
|
env->SetObjectArrayElement(usb_confDescObjArray, c, usb_confDescObj);/*add it to the Array*/
|
|
/*fill the fields*/
|
|
env->SetByteField(usb_confDescObj, usb_confDescFID_bLength, conf_desc->bLength);
|
|
env->SetByteField(usb_confDescObj, usb_confDescFID_bDescriptorType, conf_desc->bDescriptorType);
|
|
env->SetShortField(usb_confDescObj, usb_confDescFID_wTotalLength, conf_desc->wTotalLength);
|
|
env->SetByteField(usb_confDescObj, usb_confDescFID_bNumInterfaces, conf_desc->bNumInterfaces);
|
|
env->SetByteField(usb_confDescObj, usb_confDescFID_bConfigurationValue, conf_desc->bConfigurationValue);
|
|
env->SetByteField(usb_confDescObj, usb_confDescFID_iConfiguration, conf_desc->iConfiguration);
|
|
env->SetByteField(usb_confDescObj, usb_confDescFID_bmAttributes, conf_desc->bmAttributes);
|
|
env->SetByteField(usb_confDescObj, usb_confDescFID_MaxPower, conf_desc->MaxPower);
|
|
env->SetIntField(usb_confDescObj, usb_confDescFID_extralen, conf_desc->extra_length);
|
|
if (conf_desc->extra) {
|
|
jbyteArray jbExtraDesc = to_byteArray(env, conf_desc->extra, conf_desc->extra_length);
|
|
env->SetObjectField(usb_confDescObj, usb_confDescFID_extra, jbExtraDesc);
|
|
} else {
|
|
env->SetObjectField(usb_confDescObj, usb_confDescFID_extra, NULL);
|
|
}
|
|
/*interface*/
|
|
usb_intObjArray = (jobjectArray) env->NewObjectArray(conf_desc->bNumInterfaces, usb_intClazz, NULL);
|
|
if (!usb_intObjArray) {
|
|
setLibusbJavaError("shared library error: Error NewObjectArray (usb_intObjArray)");
|
|
return NULL;
|
|
}
|
|
for (h = 0; h < conf_desc->bNumInterfaces; h++) {
|
|
#ifdef DEBUGON
|
|
printf("\t\t\tlibusb_get_device: interface %u \n", h);
|
|
#endif
|
|
|
|
if (conf_desc->interface == NULL) {
|
|
// this shouldn't happen
|
|
printf("(*conf_desc)->usb_interface == NULL");
|
|
continue;
|
|
}
|
|
usb_intObj = env->NewObject(usb_intClazz, usb_intMid);
|
|
if (!usb_intObj) {
|
|
setLibusbJavaError("shared library error: Error NewObject (usb_intObj)");
|
|
return NULL;
|
|
}
|
|
env->SetObjectArrayElement(usb_intObjArray, h, usb_intObj);
|
|
env->SetIntField(usb_intObj, usb_intFID_num_altsetting, conf_desc->interface[h].num_altsetting);
|
|
// interface descriptor
|
|
usb_intDescObjArray = (jobjectArray) env->NewObjectArray(conf_desc->interface[h].num_altsetting, usb_intDescClazz, NULL);
|
|
if (!usb_intDescObjArray) {
|
|
setLibusbJavaError("shared library error: Error NewObjectArray (usb_intDescObjArray)");
|
|
return NULL;
|
|
}
|
|
for (a = 0; a < conf_desc->interface[h].num_altsetting; a++) {
|
|
#ifdef DEBUGON
|
|
printf("\t\t\t\tlibusb_get_device: interface descriptor %u \n", a);
|
|
#endif
|
|
|
|
if (conf_desc->interface[h].altsetting == NULL) {
|
|
// this shouldn't happen
|
|
printf("LibusbJava: libusb_get_device_list: altsetting == NULL\n");
|
|
continue;
|
|
}
|
|
usb_intDescObj = env->NewObject(usb_intDescClazz, usb_intDescMid);
|
|
if (!usb_intDescObj) {
|
|
setLibusbJavaError("shared library error: Error NewObject (usb_intDescObj)");
|
|
return NULL;
|
|
}
|
|
env->SetObjectArrayElement(usb_intDescObjArray, a, usb_intDescObj);
|
|
/*fill fields*/
|
|
env->SetByteField(usb_intDescObj, usb_intDescFID_bLength, conf_desc->interface[h].altsetting[a].bLength);
|
|
env->SetByteField(usb_intDescObj, usb_intDescFID_bDescriptorType, conf_desc->interface[h].altsetting[a].bDescriptorType);
|
|
env->SetByteField(usb_intDescObj, usb_intDescFID_bInterfaceNumber, conf_desc->interface[h].altsetting[a].bInterfaceNumber);
|
|
env->SetByteField(usb_intDescObj, usb_intDescFID_bAlternateSetting, conf_desc->interface[h].altsetting[a].bAlternateSetting);
|
|
env->SetByteField(usb_intDescObj, usb_intDescFID_bNumEndpoints, conf_desc->interface[h].altsetting[a].bNumEndpoints);
|
|
env->SetByteField(usb_intDescObj, usb_intDescFID_bInterfaceClass, conf_desc->interface[h].altsetting[a].bInterfaceClass);
|
|
env->SetByteField(usb_intDescObj, usb_intDescFID_bInterfaceSubClass, conf_desc->interface[h].altsetting[a].bInterfaceSubClass);
|
|
env->SetByteField(usb_intDescObj, usb_intDescFID_bInterfaceProtocol, conf_desc->interface[h].altsetting[a].bInterfaceProtocol);
|
|
env->SetByteField(usb_intDescObj, usb_intDescFID_iInterface, conf_desc->interface[h].altsetting[a].iInterface);
|
|
env->SetIntField(usb_intDescObj, usb_intDescFID_extralen, conf_desc->interface[h].altsetting[a].extra_length);
|
|
if (conf_desc->interface[h].altsetting[a].extra) {
|
|
jbyteArray jbExtraDesc = to_byteArray(env, conf_desc->interface[h].altsetting[a].extra, conf_desc->interface[h].altsetting[a].extra_length);
|
|
env->SetObjectField(usb_intDescObj, usb_intDescFID_extra, jbExtraDesc);
|
|
} else {
|
|
env->SetObjectField(usb_intDescObj, usb_intDescFID_extra, NULL);
|
|
}
|
|
/*endpoint descriptor*/
|
|
usb_epDescObjArray = (jobjectArray) env->NewObjectArray(conf_desc->interface[h].altsetting[a].bNumEndpoints, usb_epDescClazz, NULL);
|
|
if (!usb_epDescObjArray) {
|
|
setLibusbJavaError("shared library error: Error NewObjectArray (usb_epDescObjArray)");
|
|
return NULL;
|
|
}
|
|
for (e = 0; e < conf_desc->interface[h].altsetting[a].bNumEndpoints; e++) {
|
|
#ifdef DEBUGON
|
|
printf("\t\t\t\t\tLibusb_get_device: endpoint descriptor %u \n", e);
|
|
#endif
|
|
|
|
if (conf_desc->interface[h].altsetting[a].endpoint == NULL) {
|
|
printf("LibusbJava: usb_get_busses: endpoint == NULL\n");
|
|
return usb_devObj;
|
|
}
|
|
usb_epDescObj = env->NewObject(usb_epDescClazz, usb_epDescMid);
|
|
if (!usb_epDescObj) {
|
|
setLibusbJavaError("shared library error: Error NewObject (usb_epDescObj)");
|
|
return NULL;
|
|
}
|
|
env->SetObjectArrayElement(usb_epDescObjArray, e, usb_epDescObj);
|
|
env->SetByteField(usb_epDescObj, usb_epDescFID_bLength, conf_desc->interface[h].altsetting[a].endpoint[e].bLength);
|
|
env->SetByteField(usb_epDescObj, usb_epDescFID_bDescriptorType, conf_desc->interface[h].altsetting[a].endpoint[e].bDescriptorType);
|
|
env->SetByteField(usb_epDescObj, usb_epDescFID_bEndpointAddress, conf_desc->interface[h].altsetting[a].endpoint[e].bEndpointAddress);
|
|
env->SetByteField(usb_epDescObj, usb_epDescFID_bmAttributes, conf_desc->interface[h].altsetting[a].endpoint[e].bmAttributes);
|
|
env->SetShortField(usb_epDescObj, usb_epDescFID_wMaxPacketSize, conf_desc->interface[h].altsetting[a].endpoint[e].wMaxPacketSize);
|
|
env->SetByteField(usb_epDescObj, usb_epDescFID_bInterval, conf_desc->interface[h].altsetting[a].endpoint[e].bInterval);
|
|
env->SetByteField(usb_epDescObj, usb_epDescFID_bRefresh, conf_desc->interface[h].altsetting[a].endpoint[e].bRefresh);
|
|
env->SetByteField(usb_epDescObj, usb_epDescFID_bSynchAddress, conf_desc->interface[h].altsetting[a].endpoint[e].bSynchAddress);
|
|
env->SetIntField(usb_epDescObj, usb_epDescFID_extralen, conf_desc->interface[h].altsetting[a].endpoint[e].extra_length);
|
|
if (conf_desc->interface[h].altsetting[a].endpoint[e].extra) {
|
|
jbyteArray jbExtraDesc = to_byteArray(env, conf_desc->interface[h].altsetting[a].endpoint[e].extra, conf_desc->interface[h].altsetting[a].endpoint[e].extra_length);
|
|
env->SetObjectField(usb_epDescObj, usb_epDescFID_extra, jbExtraDesc);
|
|
} else {
|
|
env->SetObjectField(usb_epDescObj, usb_epDescFID_extra, NULL);
|
|
}
|
|
}
|
|
env->SetObjectField(usb_intDescObj, usb_intDescFID_endpoint, usb_epDescObjArray);
|
|
}
|
|
env->SetObjectField(usb_intObj, usb_intFID_altsetting, usb_intDescObjArray);
|
|
}
|
|
env->SetObjectField(usb_confDescObj, usb_confDescFID_interface_, usb_intObjArray);
|
|
libusb_free_config_descriptor(conf_desc);
|
|
}
|
|
env->SetObjectField(usb_devObj, usb_devFID_config, usb_confDescObjArray);
|
|
|
|
#ifdef DEBUGON
|
|
printf("libusb_get_device: done\n");
|
|
#endif
|
|
return usb_devObj;
|
|
}
|
|
/********************************************************************************************
|
|
* Class: ch_ntb_inf_libusbJava_LibusbJava1
|
|
* Method: libusb_get_configuration
|
|
* Signature: (J)I
|
|
********************************************************************************************/
|
|
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();
|
|
libusb_result = libusb_get_configuration((libusb_device_handle*) (unsigned long) handle, &config);
|
|
|
|
if (libusb_result != 0) {
|
|
setLibusbJavaError("shared library error: get_configuration failed");
|
|
ThrowLibusbError(env, libusb_result);
|
|
config = 0;
|
|
}
|
|
|
|
return config;
|
|
}
|
|
|
|
/********************************************************************************************
|
|
* Class: ch_ntb_inf_libusbJava_LibusbJava1
|
|
* Method: libusb_set_configuration
|
|
* Signature: (JI)V
|
|
********************************************************************************************/
|
|
JNIEXPORT void JNICALL Java_ch_ntb_inf_libusbJava_LibusbJava1_libusb_1set_1configuration(JNIEnv *env, jclass obj, jlong handle, jint config) {
|
|
clearLibusbJavaError();
|
|
ThrowIfUnsuccessful(env, libusb_set_configuration((libusb_device_handle*) (unsigned long) handle, config));
|
|
}
|
|
|
|
/********************************************************************************************
|
|
* Class: ch_ntb_inf_libusbJava_LibusbJava1
|
|
* Method: libusb_claim_interface
|
|
* Signature: (JI)V
|
|
********************************************************************************************/
|
|
JNIEXPORT void JNICALL Java_ch_ntb_inf_libusbJava_LibusbJava1_libusb_1claim_1interface(JNIEnv *env, jclass obj, jlong handle, jint iNumber) {
|
|
clearLibusbJavaError();
|
|
ThrowIfUnsuccessful(env, libusb_claim_interface((libusb_device_handle*) (unsigned long) handle, iNumber));
|
|
}
|
|
|
|
/********************************************************************************************
|
|
* Class: ch_ntb_inf_libusbJava_LibusbJava1
|
|
* Method: libusb_release_interface
|
|
* Signature: (JI)V
|
|
********************************************************************************************/
|
|
JNIEXPORT void JNICALL Java_ch_ntb_inf_libusbJava_LibusbJava1_libusb_1release_1interface(JNIEnv *env, jclass obj, jlong handle, jint iNumber) {
|
|
clearLibusbJavaError();
|
|
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)V
|
|
********************************************************************************************/
|
|
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();
|
|
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)V
|
|
********************************************************************************************/
|
|
JNIEXPORT void JNICALL Java_ch_ntb_inf_libusbJava_LibusbJava1_libusb_1clear_1halt(JNIEnv *env, jclass obj, jlong handle, jshort ep) {
|
|
clearLibusbJavaError();
|
|
ThrowIfUnsuccessful(env, libusb_clear_halt((libusb_device_handle*) (unsigned long) handle, ep));
|
|
}
|
|
|
|
/********************************************************************************************
|
|
* Class: ch_ntb_inf_libusbJava_LibusbJava1
|
|
* Method: libusb_reset_device
|
|
* Signature: (J)V
|
|
********************************************************************************************/
|
|
JNIEXPORT void JNICALL Java_ch_ntb_inf_libusbJava_LibusbJava1_libusb_1reset_1device(JNIEnv *env, jclass obj, jlong handle) {
|
|
clearLibusbJavaError();
|
|
ThrowIfUnsuccessful(env, libusb_reset_device((libusb_device_handle*) (unsigned long) handle));
|
|
}
|
|
|
|
/********************************************************************************************
|
|
* Class: ch_ntb_inf_libusbJava_LibusbJava1
|
|
* Method: libusb_kernel_driver_active
|
|
* 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();
|
|
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)V
|
|
********************************************************************************************/
|
|
JNIEXPORT void JNICALL Java_ch_ntb_inf_libusbJava_LibusbJava1_libusb_1detach_1kernel_1driver(JNIEnv *env, jclass obj, jlong handle, jint iNumber) {
|
|
clearLibusbJavaError();
|
|
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)V
|
|
********************************************************************************************/
|
|
JNIEXPORT void JNICALL Java_ch_ntb_inf_libusbJava_LibusbJava1_libusb_1attach_1kernel_1driver(JNIEnv *env, jclass obj, jlong handle, jint iNumber) {
|
|
clearLibusbJavaError();
|
|
ThrowIfUnsuccessful(env, libusb_attach_kernel_driver((libusb_device_handle*) (unsigned long) handle, iNumber));
|
|
}
|
|
|
|
/********************************************************************************************
|
|
* Class: ch_ntb_inf_libusbJava_LibusbJava1
|
|
* Method: libusb_get_active_config_descriptor
|
|
* Signature: (Lch/ntb/inf/libusbJava/Usb_Device;)Lch/ntb/inf/libusbJava/Usb_Config_Descriptor;
|
|
********************************************************************************************/
|
|
JNIEXPORT jobject JNICALL Java_ch_ntb_inf_libusbJava_LibusbJava1_libusb_1get_1active_1config_1descriptor(JNIEnv *env, jclass obj, jobject dev) {
|
|
uint8_t a, e;
|
|
clearLibusbJavaError();
|
|
libusb_config_descriptor *conf_desc;
|
|
jobject usb_confDescObj, usb_intObj, usb_intDescObj, usb_epDescObj;
|
|
jobjectArray usb_intObjArray, usb_intDescObjArray, usb_epDescObjArray;
|
|
|
|
libusb_device *lib_dev = (libusb_device*) (unsigned long) env->GetLongField(dev, usb_devFID_devStructAddr);
|
|
if (libusb_get_active_config_descriptor(lib_dev, &conf_desc)) {
|
|
setLibusbJavaError("shared library error: get_configuration failed");
|
|
return NULL;
|
|
}
|
|
usb_confDescObj = env->NewObject(usb_confDescClazz, usb_confDescMid);
|
|
if (!usb_confDescObj) {
|
|
setLibusbJavaError("shared library error: Error NewObject (usb_confDescObj)");
|
|
return NULL;
|
|
}
|
|
/*fill the fields*/
|
|
env->SetByteField(usb_confDescObj, usb_confDescFID_bLength, conf_desc->bLength);
|
|
env->SetByteField(usb_confDescObj, usb_confDescFID_bDescriptorType, conf_desc->bDescriptorType);
|
|
env->SetShortField(usb_confDescObj, usb_confDescFID_wTotalLength, conf_desc->wTotalLength);
|
|
env->SetByteField(usb_confDescObj, usb_confDescFID_bNumInterfaces, conf_desc->bNumInterfaces);
|
|
env->SetByteField(usb_confDescObj, usb_confDescFID_bConfigurationValue, conf_desc->bConfigurationValue);
|
|
env->SetByteField(usb_confDescObj, usb_confDescFID_iConfiguration, conf_desc->iConfiguration);
|
|
env->SetByteField(usb_confDescObj, usb_confDescFID_bmAttributes, conf_desc->bmAttributes);
|
|
env->SetByteField(usb_confDescObj, usb_confDescFID_MaxPower, conf_desc->MaxPower);
|
|
env->SetIntField(usb_confDescObj, usb_confDescFID_extralen, conf_desc->extra_length);
|
|
if (conf_desc->extra) {
|
|
jbyteArray jbExtraDesc = to_byteArray(env, conf_desc->extra, conf_desc->extra_length);
|
|
env->SetObjectField(usb_confDescObj, usb_confDescFID_extra, jbExtraDesc);
|
|
} else {
|
|
env->SetObjectField(usb_confDescObj, usb_confDescFID_extra, NULL);
|
|
}
|
|
/*interface*/
|
|
usb_intObjArray = (jobjectArray) env->NewObjectArray(conf_desc->bNumInterfaces, usb_intClazz, NULL);
|
|
if (!usb_intObjArray) {
|
|
setLibusbJavaError("shared library error: Error NewObjectArray (usb_intObjArray)");
|
|
return NULL;
|
|
}
|
|
for (int i = 0; i < conf_desc->bNumInterfaces; i++) {
|
|
#ifdef DEBUGON
|
|
printf("\t\t\tlibusb_get_activ_config_descriptor: interface %u \n", i);
|
|
#endif
|
|
if (conf_desc->interface == NULL) {
|
|
// this shouldn't happen
|
|
printf("conf_des->interface == NULL");
|
|
continue;
|
|
}
|
|
usb_intObj = env->NewObject(usb_intClazz, usb_intMid);
|
|
if (!usb_intObj) {
|
|
setLibusbJavaError("shared library error: Error NewObject (usb_intObj)");
|
|
return NULL;
|
|
}
|
|
env->SetObjectArrayElement(usb_intObjArray, i, usb_intObj);
|
|
env->SetIntField(usb_intObj, usb_intFID_num_altsetting, conf_desc->interface[i].num_altsetting);
|
|
// interface descriptor
|
|
usb_intDescObjArray = (jobjectArray) env->NewObjectArray(conf_desc->interface[i].num_altsetting, usb_intDescClazz, NULL);
|
|
if (!usb_intDescObjArray) {
|
|
setLibusbJavaError("shared library error: Error NewObjectArray (usb_intDescObjArray)");
|
|
return NULL;
|
|
}
|
|
for (a = 0; a < conf_desc->interface[i].num_altsetting; a++) {
|
|
#ifdef DEBUGON
|
|
printf("\t\t\t\tlibusb_get__activ_config_descriptor: interface descriptor %u \n", a);
|
|
#endif
|
|
|
|
if (conf_desc->interface[i].altsetting == NULL) {
|
|
// this shouldn't happen
|
|
printf("LibusbJava: libusb_get__activ_config_descriptor: altsetting == NULL\n");
|
|
continue;
|
|
}
|
|
usb_intDescObj = env->NewObject(usb_intDescClazz, usb_intDescMid);
|
|
if (!usb_intDescObj) {
|
|
setLibusbJavaError("shared library error: Error NewObject (usb_intDescObj)");
|
|
return NULL;
|
|
}
|
|
env->SetObjectArrayElement(usb_intDescObjArray, a, usb_intDescObj);
|
|
/*fill fields*/
|
|
env->SetByteField(usb_intDescObj, usb_intDescFID_bLength, conf_desc->interface[i].altsetting[a].bLength);
|
|
env->SetByteField(usb_intDescObj, usb_intDescFID_bDescriptorType, conf_desc->interface[i].altsetting[a].bDescriptorType);
|
|
env->SetByteField(usb_intDescObj, usb_intDescFID_bInterfaceNumber, conf_desc->interface[i].altsetting[a].bInterfaceNumber);
|
|
env->SetByteField(usb_intDescObj, usb_intDescFID_bAlternateSetting, conf_desc->interface[i].altsetting[a].bAlternateSetting);
|
|
env->SetByteField(usb_intDescObj, usb_intDescFID_bNumEndpoints, conf_desc->interface[i].altsetting[a].bNumEndpoints);
|
|
env->SetByteField(usb_intDescObj, usb_intDescFID_bInterfaceClass, conf_desc->interface[i].altsetting[a].bInterfaceClass);
|
|
env->SetByteField(usb_intDescObj, usb_intDescFID_bInterfaceSubClass, conf_desc->interface[i].altsetting[a].bInterfaceSubClass);
|
|
env->SetByteField(usb_intDescObj, usb_intDescFID_bInterfaceProtocol, conf_desc->interface[i].altsetting[a].bInterfaceProtocol);
|
|
env->SetByteField(usb_intDescObj, usb_intDescFID_iInterface, conf_desc->interface[i].altsetting[a].iInterface);
|
|
env->SetIntField(usb_intDescObj, usb_intDescFID_extralen, conf_desc->interface[i].altsetting[a].extra_length);
|
|
if (conf_desc->interface[i].altsetting[a].extra) {
|
|
jbyteArray jbExtraDesc = to_byteArray(env, conf_desc->interface[i].altsetting[a].extra, conf_desc->interface[i].altsetting[a].extra_length);
|
|
env->SetObjectField(usb_intDescObj, usb_intDescFID_extra, jbExtraDesc);
|
|
} else {
|
|
env->SetObjectField(usb_intDescObj, usb_intDescFID_extra, NULL);
|
|
}
|
|
/*endpoint descriptor*/
|
|
usb_epDescObjArray = (jobjectArray) env->NewObjectArray(conf_desc->interface[i].altsetting[a].bNumEndpoints, usb_epDescClazz, NULL);
|
|
if (!usb_epDescObjArray) {
|
|
setLibusbJavaError("shared library error: Error NewObjectArray (usb_epDescObjArray)");
|
|
return NULL;
|
|
}
|
|
for (e = 0; e < conf_desc->interface[i].altsetting[a].bNumEndpoints; e++) {
|
|
#ifdef DEBUGON
|
|
printf("\t\t\t\t\tLibusb_get__activ_config_descriptor: endpoint descriptor %u \n", e);
|
|
#endif
|
|
if (conf_desc->interface[i].altsetting[a].endpoint == NULL) {
|
|
printf("LibusbJava: usb_get__activ_config_descriptor: endpoint == NULL\n");
|
|
return usb_confDescObj;
|
|
}
|
|
usb_epDescObj = env->NewObject(usb_epDescClazz, usb_epDescMid);
|
|
if (!usb_epDescObj) {
|
|
setLibusbJavaError("shared library error: Error NewObject (usb_epDescObj)");
|
|
return NULL;
|
|
}
|
|
env->SetObjectArrayElement(usb_epDescObjArray, e, usb_epDescObj);
|
|
env->SetByteField(usb_epDescObj, usb_epDescFID_bLength, conf_desc->interface[i].altsetting[a].endpoint[e].bLength);
|
|
env->SetByteField(usb_epDescObj, usb_epDescFID_bDescriptorType, conf_desc->interface[i].altsetting[a].endpoint[e].bDescriptorType);
|
|
env->SetByteField(usb_epDescObj, usb_epDescFID_bEndpointAddress, conf_desc->interface[i].altsetting[a].endpoint[e].bEndpointAddress);
|
|
env->SetByteField(usb_epDescObj, usb_epDescFID_bmAttributes, conf_desc->interface[i].altsetting[a].endpoint[e].bmAttributes);
|
|
env->SetShortField(usb_epDescObj, usb_epDescFID_wMaxPacketSize, conf_desc->interface[i].altsetting[a].endpoint[e].wMaxPacketSize);
|
|
env->SetByteField(usb_epDescObj, usb_epDescFID_bInterval, conf_desc->interface[i].altsetting[a].endpoint[e].bInterval);
|
|
env->SetByteField(usb_epDescObj, usb_epDescFID_bRefresh, conf_desc->interface[i].altsetting[a].endpoint[e].bRefresh);
|
|
env->SetByteField(usb_epDescObj, usb_epDescFID_bSynchAddress, conf_desc->interface[i].altsetting[a].endpoint[e].bSynchAddress);
|
|
env->SetIntField(usb_epDescObj, usb_epDescFID_extralen, conf_desc->interface[i].altsetting[a].endpoint[e].extra_length);
|
|
if (conf_desc->interface[i].altsetting[a].endpoint[e].extra) {
|
|
jbyteArray jbExtraDesc = to_byteArray(env, conf_desc->interface[i].altsetting[a].endpoint[e].extra, conf_desc->interface[i].altsetting[a].endpoint[e].extra_length);
|
|
env->SetObjectField(usb_epDescObj, usb_epDescFID_extra, jbExtraDesc);
|
|
} else {
|
|
env->SetObjectField(usb_epDescObj, usb_epDescFID_extra, NULL);
|
|
}
|
|
}
|
|
env->SetObjectField(usb_intDescObj, usb_intDescFID_endpoint, usb_epDescObjArray);
|
|
}
|
|
env->SetObjectField(usb_intObj, usb_intFID_altsetting, usb_intDescObjArray);
|
|
}
|
|
env->SetObjectField(usb_confDescObj, usb_confDescFID_interface_, usb_intObjArray);
|
|
libusb_free_config_descriptor(conf_desc);
|
|
|
|
return usb_confDescObj;
|
|
}
|
|
|
|
/********************************************************************************************
|
|
* Class: ch_ntb_inf_libusbJava_LibusbJava1
|
|
* Method: libusb_get_string_descriptor_ascii
|
|
* Signature: (JSI)Ljava/lang/String;
|
|
********************************************************************************************/
|
|
JNIEXPORT jstring JNICALL Java_ch_ntb_inf_libusbJava_LibusbJava1_libusb_1get_1string_1descriptor_1ascii( JNIEnv *env, jclass obj, jlong handle, jshort desc_index, jint length) {
|
|
jstring string;
|
|
int res = 0;
|
|
clearLibusbJavaError();
|
|
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)
|
|
{
|
|
data[res] = '\0';
|
|
string = env->NewStringUTF((const char*)data);
|
|
}
|
|
else
|
|
{
|
|
setLibusbJavaError("get_string_descriptor_ascii: retrieve String failed");
|
|
string = NULL;
|
|
ThrowLibusbError(env, res);
|
|
}
|
|
return string;
|
|
}
|
|
/********************************************************************************************
|
|
* Class: ch_ntb_inf_libusbJava_LibusbJava1
|
|
* Method: libusb_get_descriptor
|
|
* Signature: (JISI)[B
|
|
********************************************************************************************/
|
|
|
|
JNIEXPORT jbyteArray JNICALL Java_ch_ntb_inf_libusbJava_LibusbJava1_libusb_1get_1descriptor(
|
|
JNIEnv *env, jclass obj, jlong handle, jint desc_type,
|
|
jshort desc_index, jint size) {
|
|
|
|
clearLibusbJavaError();
|
|
int res;
|
|
unsigned char data[255];
|
|
|
|
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;
|
|
}
|
|
|
|
return to_byteArray(env, data, res);
|
|
}
|
|
/********************************************************************************************
|
|
* Class: ch_ntb_inf_libusbJava_LibusbJava1
|
|
* Method: libusb_get_string_descriptor
|
|
* Signature: (JSII)Ljava/lang/String;
|
|
********************************************************************************************/
|
|
JNIEXPORT jstring
|
|
JNICALL Java_ch_ntb_inf_libusbJava_LibusbJava1_libusb_1get_1string_1descriptor(JNIEnv *env, jclass obj, jlong handle, jshort desc_index, jint langid, jint size) {
|
|
clearLibusbJavaError();
|
|
int res;
|
|
jstring string;
|
|
unsigned char data[(int)size + 1];
|
|
|
|
res = libusb_get_string_descriptor((libusb_device_handle*) (unsigned long) handle, desc_index, langid, data, size);
|
|
|
|
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;
|
|
|
|
}
|
|
/********************************************************************************************
|
|
* Class: ch_ntb_inf_libusbJava_LibusbJava1
|
|
* Method: libusb_alloc_transfer
|
|
* Signature: (I)J
|
|
********************************************************************************************/
|
|
JNIEXPORT jlong JNICALL Java_ch_ntb_inf_libusbJava_LibusbJava1_libusb_1alloc_1transfer( JNIEnv *env, jclass obj, jint iso_packets) {
|
|
clearLibusbJavaError();
|
|
return (jlong) libusb_alloc_transfer(iso_packets);
|
|
}
|
|
|
|
/********************************************************************************************
|
|
* Class: ch_ntb_inf_libusbJava_LibusbJava1
|
|
* Method: libusb_free_transfer
|
|
* Signature: (J)V
|
|
********************************************************************************************/
|
|
JNIEXPORT void JNICALL Java_ch_ntb_inf_libusbJava_LibusbJava1_libusb_1free_1transfer( JNIEnv *env, jclass obj, jlong transfernumber) {
|
|
clearLibusbJavaError();
|
|
libusb_free_transfer((libusb_transfer*) (unsigned long) transfernumber);
|
|
}
|
|
|
|
/********************************************************************************************
|
|
* Class: ch_ntb_inf_libusbJava_LibusbJava1
|
|
* Method: libusb_submit_transfer
|
|
* Signature: (J)V
|
|
********************************************************************************************/
|
|
JNIEXPORT void JNICALL Java_ch_ntb_inf_libusbJava_LibusbJava1_libusb_1submit_1transfer(JNIEnv *env, jclass obj, jlong transfernumber) {
|
|
clearLibusbJavaError();
|
|
ThrowIfUnsuccessful(env, libusb_submit_transfer((libusb_transfer*) (unsigned long) transfernumber));
|
|
}
|
|
|
|
/********************************************************************************************
|
|
* Class: ch_ntb_inf_libusbJava_LibusbJava1
|
|
* Method: libusb_cancel_transfer
|
|
* Signature: (J)V
|
|
********************************************************************************************/
|
|
JNIEXPORT void JNICALL Java_ch_ntb_inf_libusbJava_LibusbJava1_libusb_1cancel_1transfer(JNIEnv *env, jclass obj, jlong transfernumber) {
|
|
clearLibusbJavaError();
|
|
ThrowIfUnsuccessful(env, libusb_cancel_transfer((libusb_transfer*) (unsigned long) transfernumber));
|
|
}
|
|
/********************************************************************************************
|
|
* Class: ch_ntb_inf_libusbJava_LibusbJava1
|
|
* Method: libusb_control_transfer_get_data
|
|
* Signature: (J)[B
|
|
********************************************************************************************/
|
|
JNIEXPORT jbyteArray JNICALL Java_ch_ntb_inf_libusbJava_LibusbJava1_libusb_1control_1transfer_1get_1data(JNIEnv *env, jclass obj, jlong transfernumber) {
|
|
clearLibusbJavaError();
|
|
unsigned char *data;
|
|
libusb_transfer* trans = (libusb_transfer*) (unsigned long) transfernumber;
|
|
|
|
if (trans == NULL)
|
|
return NULL;
|
|
|
|
data = libusb_control_transfer_get_data(trans);
|
|
return to_byteArray(env, data, trans->actual_length - LIBUSB_CONTROL_SETUP_SIZE );
|
|
}
|
|
|
|
/*********************************************************************************************
|
|
* Class: ch_ntb_inf_libusbJava_LibusbJava1
|
|
* Method: libusb_control_transfer_get_setup
|
|
* Signature: (J)[B
|
|
********************************************************************************************/
|
|
JNIEXPORT jbyteArray JNICALL Java_ch_ntb_inf_libusbJava_LibusbJava1_libusb_1control_1transfer_1get_1setup(JNIEnv *env, jclass obj, jlong transfernumber) {
|
|
clearLibusbJavaError();
|
|
unsigned char *data;
|
|
libusb_transfer* trans = (libusb_transfer*) (unsigned long) transfernumber;
|
|
|
|
if (trans == NULL) {
|
|
return NULL;
|
|
}
|
|
|
|
data = (unsigned char*)libusb_control_transfer_get_setup(trans);
|
|
|
|
return to_byteArray(env, data, 8);
|
|
}
|
|
/********************************************************************************************
|
|
* Class: ch_ntb_inf_libusbJava_LibusbJava1
|
|
* Method: libusb_fill_control_setup
|
|
* Signature: (IIIII)[B
|
|
********************************************************************************************/
|
|
JNIEXPORT jbyteArray JNICALL Java_ch_ntb_inf_libusbJava_LibusbJava1_libusb_1fill_1control_1setup(JNIEnv *env, jclass obj, jint bmRequestType, jint bRequest, jint wValue, jint wIndex, jint wLength) {
|
|
clearLibusbJavaError();
|
|
unsigned char setup[8];
|
|
|
|
libusb_fill_control_setup(setup, bmRequestType, bRequest, wValue, wIndex, wLength);
|
|
|
|
return to_byteArray(env, setup, 8);
|
|
}
|
|
|
|
/********************************************************************************************
|
|
* Class: ch_ntb_inf_libusbJava_LibusbJava1
|
|
* Method: libusb_fill_control_transfer
|
|
* Signature: (JJ[BI)V
|
|
********************************************************************************************/
|
|
JNIEXPORT void JNICALL Java_ch_ntb_inf_libusbJava_LibusbJava1_libusb_1fill_1control_1transfer(JNIEnv *env, jclass obj, jlong transfernumber, jlong handle, jbyteArray buffer, jint timeout) {
|
|
clearLibusbJavaError();
|
|
jbyte *byteArrayElements = env->GetByteArrayElements(buffer, NULL);
|
|
libusb_fill_control_transfer((libusb_transfer*) (unsigned long) transfernumber,(libusb_device_handle*) (unsigned long) handle,(unsigned char*) byteArrayElements, transfer_callback, env,(unsigned int) timeout);
|
|
env->ReleaseByteArrayElements(buffer, byteArrayElements, 0);
|
|
}
|
|
|
|
/********************************************************************************************
|
|
* Class: ch_ntb_inf_libusbJava_LibusbJava1
|
|
* Method: libusb_fill_bulk_transfer
|
|
* Signature: (JJB[BII)V
|
|
********************************************************************************************/
|
|
JNIEXPORT void JNICALL Java_ch_ntb_inf_libusbJava_LibusbJava1_libusb_1fill_1bulk_1transfer(JNIEnv *env, jclass obj, jlong transfernumber, jlong handle, jbyte endpoint, jbyteArray buffer, jint length, jint timeout) {
|
|
clearLibusbJavaError();
|
|
jbyte *byteArrayElements = env->GetByteArrayElements(buffer, NULL);
|
|
libusb_fill_bulk_transfer((libusb_transfer*) (unsigned long) transfernumber,(libusb_device_handle*) (unsigned long) handle, endpoint,(unsigned char*) byteArrayElements, length, transfer_callback, env,(unsigned int) timeout);
|
|
env->ReleaseByteArrayElements(buffer, byteArrayElements, 0);
|
|
}
|
|
|
|
/********************************************************************************************
|
|
* Class: ch_ntb_inf_libusbJava_LibusbJava1
|
|
* Method: libusb_fill_interrupt_transfer
|
|
* Signature: (JJB[BII)V
|
|
********************************************************************************************/
|
|
JNIEXPORT void JNICALL Java_ch_ntb_inf_libusbJava_LibusbJava1_libusb_1fill_1interrupt_1transfer(JNIEnv *env, jclass obj, jlong transfernumber, jlong handle,jbyte endpoint, jbyteArray buffer, jint length, jint timeout) {
|
|
clearLibusbJavaError();
|
|
jbyte *byteArrayElements = env->GetByteArrayElements(buffer, NULL);
|
|
libusb_fill_interrupt_transfer((libusb_transfer*) (unsigned long) transfernumber,(libusb_device_handle*) (unsigned long) handle, endpoint,(unsigned char*) byteArrayElements, length, transfer_callback, env, timeout);
|
|
env->ReleaseByteArrayElements(buffer, byteArrayElements, 0);
|
|
}
|
|
|
|
/********************************************************************************************
|
|
* Class: ch_ntb_inf_libusbJava_LibusbJava1
|
|
* Method: libusb_fill_iso_transfer
|
|
* Signature: (JJB[BIII)V
|
|
********************************************************************************************/
|
|
JNIEXPORT void JNICALL Java_ch_ntb_inf_libusbJava_LibusbJava1_libusb_1fill_1iso_1transfer(JNIEnv *env, jclass obj, jlong transfernumber, jlong handle, jbyte endpoint, jbyteArray buffer, jint length, jint num_iso_packets, jint timeout) {
|
|
clearLibusbJavaError();
|
|
jbyte *byteArrayElements = env->GetByteArrayElements(buffer, NULL);
|
|
libusb_fill_iso_transfer((libusb_transfer*) (unsigned long) transfernumber, (libusb_device_handle*) (unsigned long) handle, endpoint, (unsigned char*) byteArrayElements, length, num_iso_packets, transfer_callback, env, timeout);
|
|
env->ReleaseByteArrayElements(buffer, byteArrayElements, 0);
|
|
}
|
|
|
|
/********************************************************************************************
|
|
* Class: ch_ntb_inf_libusbJava_LibusbJava1
|
|
* Method: libusb_set_iso_packet_lengths
|
|
* Signature: (JI)V
|
|
********************************************************************************************/
|
|
JNIEXPORT void JNICALL Java_ch_ntb_inf_libusbJava_LibusbJava1_libusb_1set_1iso_1packet_1lengths(JNIEnv *env, jclass obj, jlong transfernumber, jint length) {
|
|
clearLibusbJavaError();
|
|
libusb_set_iso_packet_lengths((libusb_transfer*) (unsigned long) transfernumber, length);
|
|
}
|
|
|
|
/********************************************************************************************
|
|
* Class: ch_ntb_inf_libusbJava_LibusbJava1
|
|
* Method: libusb_get_iso_packet_buffer
|
|
* Signature: (JI)[B
|
|
********************************************************************************************/
|
|
|
|
JNIEXPORT jbyteArray JNICALL Java_ch_ntb_inf_libusbJava_LibusbJava1_libusb_1get_1iso_1packet_1buffer(JNIEnv *env, jclass obj, jlong transfernumber, jint packet) {
|
|
clearLibusbJavaError();
|
|
int size = 0;
|
|
unsigned char *data = NULL;
|
|
libusb_transfer* transfer = (libusb_transfer*) (unsigned long) transfernumber;
|
|
|
|
if (transfer == NULL) {
|
|
setLibusbJavaError("libusb_get_iso_packet_buffer: ilegal transfernumber");
|
|
return NULL;
|
|
}
|
|
|
|
if (packet < transfer->num_iso_packets) {
|
|
size = transfer->iso_packet_desc[packet].actual_length;
|
|
}
|
|
|
|
data = libusb_get_iso_packet_buffer((libusb_transfer*) (unsigned long) transfernumber, packet);
|
|
if (data == NULL) {
|
|
setLibusbJavaError("libusb_get_iso_packet_buffer: packet does not exist");
|
|
return NULL;
|
|
}
|
|
|
|
return to_byteArray(env, data, size);
|
|
}
|
|
|
|
/********************************************************************************************
|
|
* Class: ch_ntb_inf_libusbJava_LibusbJava1
|
|
* Method: libusb_get_iso_packet_buffer_simple
|
|
* Signature: (JI)[B
|
|
********************************************************************************************/
|
|
JNIEXPORT jbyteArray JNICALL Java_ch_ntb_inf_libusbJava_LibusbJava1_libusb_1get_1iso_1packet_1buffer_1simple(JNIEnv *env, jclass obj, jlong transfernumber, jint packet) {
|
|
clearLibusbJavaError();
|
|
int size = 0;
|
|
unsigned char *data = NULL;
|
|
libusb_transfer* transfer = (libusb_transfer*) (unsigned long) transfernumber;
|
|
|
|
if (transfer == NULL) {
|
|
setLibusbJavaError("libusb_get_iso_packet_buffer_simple: ilegal transfernumber");
|
|
return NULL;
|
|
}
|
|
|
|
if (packet < transfer->num_iso_packets) {
|
|
size = transfer->iso_packet_desc[packet].actual_length;
|
|
}
|
|
|
|
data = libusb_get_iso_packet_buffer_simple((libusb_transfer*) (unsigned long) transfernumber, packet);
|
|
|
|
if (data == NULL) {
|
|
setLibusbJavaError("libusb_get_iso_packet_buffer_simple: packet does not exist");
|
|
return NULL;
|
|
}
|
|
|
|
return to_byteArray(env, data, size);
|
|
}
|
|
|
|
/********************************************************************************************
|
|
* Class: ch_ntb_inf_libusbJava_LibusbJava1
|
|
* Method: libusb_try_lock_events
|
|
* Signature: (J)I
|
|
********************************************************************************************/
|
|
JNIEXPORT jint JNICALL Java_ch_ntb_inf_libusbJava_LibusbJava1_libusb_1try_1lock_1events(JNIEnv *env, jclass obj, jlong ctx) {
|
|
clearLibusbJavaError();
|
|
return libusb_try_lock_events((libusb_context*) (unsigned long) ctx);
|
|
// return libusb_try_lock_events(NULL);
|
|
}
|
|
|
|
/********************************************************************************************
|
|
* Class: ch_ntb_inf_libusbJava_LibusbJava1
|
|
* Method: libusb_lock_events
|
|
* Signature: (J)V
|
|
********************************************************************************************/
|
|
JNIEXPORT void JNICALL Java_ch_ntb_inf_libusbJava_LibusbJava1_libusb_1lock_1events(JNIEnv *env, jclass obj, jlong ctx) {
|
|
libusb_lock_events((libusb_context*) (unsigned long) ctx);
|
|
// libusb_lock_events(NULL);
|
|
}
|
|
|
|
/********************************************************************************************
|
|
* Class: ch_ntb_inf_libusbJava_LibusbJava1
|
|
* Method: libusb_unlock_events
|
|
* Signature: (J)V
|
|
********************************************************************************************/
|
|
JNIEXPORT void JNICALL Java_ch_ntb_inf_libusbJava_LibusbJava1_libusb_1unlock_1events(JNIEnv *env, jclass obj, jlong ctx) {
|
|
clearLibusbJavaError();
|
|
libusb_unlock_events((libusb_context*) (unsigned long) ctx);
|
|
}
|
|
|
|
/********************************************************************************************
|
|
* Class: ch_ntb_inf_libusbJava_LibusbJava1
|
|
* Method: libusb_event_handling_ok
|
|
* Signature: (J)I
|
|
********************************************************************************************/
|
|
JNIEXPORT jint JNICALL Java_ch_ntb_inf_libusbJava_LibusbJava1_libusb_1event_1handling_1ok(JNIEnv *env, jclass obj, jlong ctx) {
|
|
clearLibusbJavaError();
|
|
return libusb_event_handling_ok((libusb_context*) (unsigned long) ctx);
|
|
}
|
|
|
|
/********************************************************************************************
|
|
* Class: ch_ntb_inf_libusbJava_LibusbJava1
|
|
* Method: libusb_event_handler_active
|
|
* Signature: (J)I
|
|
********************************************************************************************/
|
|
JNIEXPORT jint JNICALL Java_ch_ntb_inf_libusbJava_LibusbJava1_libusb_1event_1handler_1active(JNIEnv *env, jclass obj, jlong ctx) {
|
|
clearLibusbJavaError();
|
|
return libusb_event_handler_active((libusb_context*) (unsigned long) ctx);
|
|
}
|
|
|
|
/********************************************************************************************
|
|
* Class: ch_ntb_inf_libusbJava_LibusbJava1
|
|
* Method: libusb_lock_event_waiters
|
|
* Signature: (J)V
|
|
********************************************************************************************/
|
|
JNIEXPORT void JNICALL Java_ch_ntb_inf_libusbJava_LibusbJava1_libusb_1lock_1event_1waiters(JNIEnv *env, jclass obj, jlong ctx) {
|
|
clearLibusbJavaError();
|
|
libusb_lock_event_waiters((libusb_context*) (unsigned long) ctx);
|
|
}
|
|
|
|
/********************************************************************************************
|
|
* Class: ch_ntb_inf_libusbJava_LibusbJava1
|
|
* Method: libusb_unlock_event_waiters
|
|
* Signature: (J)V
|
|
********************************************************************************************/
|
|
JNIEXPORT void JNICALL Java_ch_ntb_inf_libusbJava_LibusbJava1_libusb_1unlock_1event_1waiters(JNIEnv *env, jclass obj, jlong ctx) {
|
|
clearLibusbJavaError();
|
|
libusb_unlock_event_waiters((libusb_context*) (unsigned long) ctx);
|
|
}
|
|
|
|
/********************************************************************************************
|
|
* Class: ch_ntb_inf_libusbJava_LibusbJava1
|
|
* Method: libusb_wait_for_event
|
|
* Signature: (JJ)I
|
|
********************************************************************************************/
|
|
JNIEXPORT jint JNICALL Java_ch_ntb_inf_libusbJava_LibusbJava1_libusb_1wait_1for_1event(JNIEnv *env, jclass obj, jlong ctx, jlong timevalue) {
|
|
clearLibusbJavaError();
|
|
if (timevalue) {
|
|
timeval tv;
|
|
tv.tv_sec = timevalue;
|
|
tv.tv_usec = 0;
|
|
return libusb_wait_for_event((libusb_context*) (unsigned long) ctx, &tv);
|
|
}
|
|
return libusb_wait_for_event((libusb_context*) (unsigned long) ctx, NULL);
|
|
}
|
|
|
|
/********************************************************************************************
|
|
* Class: ch_ntb_inf_libusbJava_LibusbJava1
|
|
* Method: libusb_handle_events_timeout
|
|
* Signature: (JJ)V
|
|
********************************************************************************************/
|
|
JNIEXPORT void JNICALL Java_ch_ntb_inf_libusbJava_LibusbJava1_libusb_1handle_1events_1timeout(JNIEnv *env, jclass obj, jlong ctx, jlong timevalue) {
|
|
clearLibusbJavaError();
|
|
if (timevalue != 0)
|
|
{
|
|
timeval tv;
|
|
tv.tv_sec = timevalue;
|
|
tv.tv_usec = 0;
|
|
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));
|
|
}
|
|
}
|
|
|
|
/********************************************************************************************
|
|
* Class: ch_ntb_inf_libusbJava_LibusbJava1
|
|
* Method: libusb_handle_events
|
|
* Signature: (J)V
|
|
********************************************************************************************/
|
|
JNIEXPORT void JNICALL Java_ch_ntb_inf_libusbJava_LibusbJava1_libusb_1handle_1events(JNIEnv *env, jclass obj, jlong ctx) {
|
|
clearLibusbJavaError();
|
|
ThrowIfUnsuccessful(env, libusb_handle_events((libusb_context*) (unsigned long) ctx));
|
|
}
|
|
|
|
/********************************************************************************************
|
|
* Class: ch_ntb_inf_libusbJava_LibusbJava1
|
|
* Method: libusb_handle_events_locked
|
|
* Signature: (JJ)V
|
|
********************************************************************************************/
|
|
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;
|
|
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));
|
|
}
|
|
}
|
|
|
|
/********************************************************************************************
|
|
* Class: ch_ntb_inf_libusbJava_LibusbJava1
|
|
* Method: libusb_pollfds_handle_timeouts
|
|
* Signature: (J)I
|
|
********************************************************************************************/
|
|
JNIEXPORT jint JNICALL Java_ch_ntb_inf_libusbJava_LibusbJava1_libusb_1pollfds_1handle_1timeouts(JNIEnv *env, jclass obj, jlong ctx) {
|
|
clearLibusbJavaError();
|
|
return libusb_pollfds_handle_timeouts((libusb_context*) (unsigned long) ctx);
|
|
}
|
|
|
|
/********************************************************************************************
|
|
* Class: ch_ntb_inf_libusbJava_LibusbJava1
|
|
* Method: libusb_get_next_timeout
|
|
* Signature: (J)I
|
|
********************************************************************************************/
|
|
JNIEXPORT jint JNICALL Java_ch_ntb_inf_libusbJava_LibusbJava1_libusb_1get_1next_1timeout(JNIEnv *env, jclass obj, jlong ctx) {
|
|
clearLibusbJavaError();
|
|
int res;
|
|
timeval 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)
|
|
{
|
|
res = tv.tv_sec;
|
|
}
|
|
else if (res == 0) {
|
|
res = -1;
|
|
}
|
|
else
|
|
{
|
|
ThrowLibusbError(env, res);
|
|
res = -2;
|
|
}
|
|
|
|
return res;
|
|
}
|
|
|
|
/********************************************************************************************
|
|
* Class: ch_ntb_inf_libusbJava_LibusbJava1
|
|
* Method: libusb_set_pollfd_notifiers
|
|
* Signature: (JZ)V
|
|
********************************************************************************************/
|
|
JNIEXPORT void JNICALL Java_ch_ntb_inf_libusbJava_LibusbJava1_libusb_1set_1pollfd_1notifiers(JNIEnv *env, jclass obj, jlong ctx, jboolean remove) {
|
|
clearLibusbJavaError();
|
|
if (remove)
|
|
{
|
|
libusb_set_pollfd_notifiers((libusb_context*) (unsigned long) ctx, NULL, NULL, env);
|
|
}
|
|
else
|
|
{
|
|
libusb_set_pollfd_notifiers((libusb_context*) (unsigned long) ctx, fd_added_callback, fd_removed_callback, env);
|
|
}
|
|
}
|
|
|
|
/********************************************************************************************
|
|
* Class: ch_ntb_inf_libusbJava_LibusbJava1
|
|
* Method: libusb_get_pollfds
|
|
* Signature: (J)[Lch/ntb/inf/libusbJava/Libusb_pollfd;
|
|
********************************************************************************************/
|
|
JNIEXPORT jobjectArray JNICALL Java_ch_ntb_inf_libusbJava_LibusbJava1_libusb_1get_1pollfds(JNIEnv *env, jclass obj, jlong ctx) {
|
|
clearLibusbJavaError();
|
|
int count = 0;
|
|
jobjectArray pollfdArray;
|
|
jobject pollfdObj;
|
|
const libusb_pollfd **fdList;
|
|
|
|
fdList = libusb_get_pollfds((libusb_context*) (unsigned long) ctx);
|
|
if (fdList == NULL) {
|
|
return NULL;
|
|
}
|
|
/*determine the length of the list*/
|
|
while (fdList[count]) {
|
|
count++;
|
|
}
|
|
pollfdArray = (jobjectArray) env->NewObjectArray(count, usb_pollfd_clazz, NULL);
|
|
if (!pollfdArray) {
|
|
setLibusbJavaError("libusb_get_pollfds: error NewObjectArry (pollfdArray");
|
|
return NULL;
|
|
}
|
|
|
|
for (int i = 0; i < count; i++) {
|
|
pollfdObj = env->NewObject(usb_pollfd_clazz, usb_pollfd_Mid);
|
|
if (!pollfdObj) {
|
|
setLibusbJavaError("libusb_get_pollfds: Error NewObject (pollfdObj)");
|
|
return NULL;
|
|
}
|
|
env->SetObjectArrayElement(pollfdArray, i, pollfdObj);
|
|
env->SetIntField(pollfdObj, usb_pollfdFID_fd, fdList[i]->fd);
|
|
env->SetShortField(pollfdObj, usb_pollfdFID_events, fdList[i]->events);
|
|
}
|
|
return pollfdArray;
|
|
}
|
|
|
|
/********************************************************************************************
|
|
* Class: ch_ntb_inf_libusbJava_LibusbJava1
|
|
* Method: libusb_control_transfer
|
|
* Signature: (JIIII[BII)I
|
|
********************************************************************************************/
|
|
JNIEXPORT jint JNICALL Java_ch_ntb_inf_libusbJava_LibusbJava1_libusb_1control_1transfer(JNIEnv *env, jclass obj, jlong handle, jint bmRequestType, jint bRequest, jint wValue, jint wIndex, jbyteArray buffer, jint wLength, jint timeout) {
|
|
clearLibusbJavaError();
|
|
int res;
|
|
unsigned char* data;
|
|
data = (unsigned char*) env->GetByteArrayElements(buffer, NULL);
|
|
res = libusb_control_transfer((libusb_device_handle*) (unsigned long) handle, bmRequestType, bRequest, wValue, wIndex, data, wLength, timeout);
|
|
env->ReleaseByteArrayElements(buffer, (jbyte*) data, 0);
|
|
|
|
return res;
|
|
}
|
|
|
|
/********************************************************************************************
|
|
* Class: ch_ntb_inf_libusbJava_LibusbJava1
|
|
* Method: libusb_bulk_transfer
|
|
* Signature: (JB[BII)I
|
|
********************************************************************************************/
|
|
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 libusb_result = 0;
|
|
int bytes_transferred = 0;
|
|
unsigned char* data = (unsigned char*) env->GetByteArrayElements(buffer, NULL);
|
|
|
|
libusb_result = libusb_bulk_transfer((libusb_device_handle*) (unsigned long) handle, endpoint, data, length, &bytes_transferred, timeout);
|
|
env->ReleaseByteArrayElements(buffer, (jbyte*) data, 0);
|
|
|
|
if (libusb_result != 0)
|
|
{
|
|
ThrowLibusbError(env, libusb_result);
|
|
bytes_transferred = 0;
|
|
}
|
|
|
|
return bytes_transferred;
|
|
}
|
|
|
|
/********************************************************************************************
|
|
* Class: ch_ntb_inf_libusbJava_LibusbJava1
|
|
* Method: libusb_interrupt_transfer
|
|
* Signature: (JB[BII)I
|
|
********************************************************************************************/
|
|
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 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 (libusb_result != 0)
|
|
{
|
|
ThrowLibusbError(env, libusb_result);
|
|
bytes_transferred = 0;
|
|
}
|
|
|
|
return bytes_transferred;
|
|
}
|
|
|
|
/********************************************************************************************
|
|
* Class: ch_ntb_inf_libusbJava_LibusbJava1
|
|
* Method: libusb_strerror
|
|
* Signature: ()Ljava/lang/String;
|
|
********************************************************************************************/
|
|
JNIEXPORT jstring JNICALL Java_ch_ntb_inf_libusbJava_LibusbJava1_libusb_1strerror(JNIEnv *env, jclass obj) {
|
|
char *str = "Libusb-1.0 Error";
|
|
|
|
/* check for LibusbJava specific errors first*/
|
|
if (libusbJavaError != NULL) {
|
|
str = libusbJavaError;
|
|
clearLibusbJavaError();
|
|
}
|
|
|
|
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
|
|
*
|
|
********************************************************************************************/
|
|
static void LIBUSB_CALL transfer_callback(struct libusb_transfer *transfer) {
|
|
|
|
((JNIEnv*) transfer->user_data)->CallVoidMethod(usb_cb_clazz,
|
|
usb_transfer_cb_Mid);
|
|
}
|
|
|
|
/********************************************************************************************
|
|
* Class: LibusbJava_1_0.cpp
|
|
* Method: fd_added_callback
|
|
*
|
|
********************************************************************************************/
|
|
static void LIBUSB_CALL fd_added_callback(int fd, short events, void *user_data) {
|
|
|
|
((JNIEnv*) user_data)->CallVoidMethod(usb_cb_clazz, usb_fd_added_cb_Mid,
|
|
(jint) fd);
|
|
}
|
|
|
|
/********************************************************************************************
|
|
* Class: LibusbJava_1_0.cpp
|
|
* Method: fd_removed_callback
|
|
*
|
|
********************************************************************************************/
|
|
static void LIBUSB_CALL fd_removed_callback(int fd, void *user_data) {
|
|
|
|
((JNIEnv*) user_data)->CallVoidMethod(usb_cb_clazz, usb_fd_removed_cb_Mid,
|
|
(jint) fd);
|
|
}
|
|
|
|
/*! \brief Turns a memory section into a java byte array that can be returned to the java
|
|
* environment.
|
|
*
|
|
* \param env Environment to create the array for
|
|
* \param data Pointer to the data to be put in the array
|
|
* \param len [bytes] Length of the data to be put into the array
|
|
*
|
|
* \return The pointer to the newly created byte array. NULL if an error occured
|
|
*
|
|
* \note If NULL is returned, #libusbJavaError is set to a matching error string.
|
|
*/
|
|
static __inline jbyteArray JNICALL to_byteArray(JNIEnv *env, const void *data, size_t len)
|
|
{
|
|
jbyteArray result = env->NewByteArray(len);
|
|
|
|
if (result != NULL) {
|
|
/* Using SetByteArrayRegion, we avoid that the JNI layer first copies the data already
|
|
* available in the array in our space just to overwrite them. As we just allocated the
|
|
* byte aray with a length of "len", the set operation can never fail. The check for an
|
|
* exception can be omitted. */
|
|
env->SetByteArrayRegion(result, 0, len, (const signed char *)data);
|
|
#if 0 /* No need to check for exceptions here... */
|
|
if (env->ExceptionOccurred()){
|
|
setLibusbJavaError("to_byteArray: unable to copy data to array");
|
|
env->DeleteLocalRef(result);
|
|
result = NULL;
|
|
}
|
|
#endif
|
|
}
|
|
else {
|
|
setLibusbJavaError("to_byteArray: out of memory");
|
|
}
|
|
|
|
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, "<init>", "(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;
|
|
}
|