From aaa3bd5d586db1c11e6978413654fa2a4d494286 Mon Sep 17 00:00:00 2001 From: schlaepfer Date: Thu, 9 Mar 2006 07:06:41 +0000 Subject: [PATCH] - only load references once (flag) - interrupt read/write corrected - log messages updated - text header inserted git-svn-id: https://svn.code.sf.net/p/libusbjava/code/trunk@109 94ad28fe-ef68-46b1-9651-e7ae4fcf1c4c --- libusbdll/.cdtproject | 15 -- libusbdll/LibusbWin.cpp | 373 +++++++++++++++++++++------------------- libusbdll/LibusbWin.dll | Bin 37716 -> 40995 bytes 3 files changed, 193 insertions(+), 195 deletions(-) diff --git a/libusbdll/.cdtproject b/libusbdll/.cdtproject index 60a6b94..384716e 100644 --- a/libusbdll/.cdtproject +++ b/libusbdll/.cdtproject @@ -53,23 +53,8 @@ - - -make - -cleanDll -false -true - - -make - -testExe -false -true - make diff --git a/libusbdll/LibusbWin.cpp b/libusbdll/LibusbWin.cpp index f54e968..596d793 100644 --- a/libusbdll/LibusbWin.cpp +++ b/libusbdll/LibusbWin.cpp @@ -1,3 +1,11 @@ +/* + * 2005/2006 + * Interstate University of Applied Sciences of Technology Buchs NTB + * Computer Science Laboratory, inf.ntb.ch + * Andreas Schläpfer, aschlaepfer@ntb.ch + * + */ + #include #include #include @@ -9,10 +17,54 @@ // global bus (updated when usb_get_busses() is called) struct usb_bus *busses; -// device class -jclass usb_devClazz; -// usb_device.devnum -jfieldID usb_devFID_devnum; + +// global flag for loading all class, method and field ID references +int java_references_loaded = 0; + +// class references +jclass usb_busClazz, usb_devClazz, usb_devDescClazz, usb_confDescClazz, \ + usb_intClazz, usb_intDescClazz, usb_epDescClazz; + +// method ID references +jmethodID usb_busMid, usb_devMid, usb_devDescMid, usb_confDescMid, \ + usb_intMid, usb_intDescMid, usb_epDescMid; + +// field ID references +// usb_bus +jfieldID usb_busFID_next, usb_busFID_prev, usb_busFID_dirname, \ + usb_busFID_devices, usb_busFID_location, usb_busFID_root_dev; +// usb_device +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_deviceDescriptor +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 +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 +jfieldID usb_intFID_altsetting, usb_intFID_num_altsetting; +// usb_intDesc +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 +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; /* * Class: ch_ntb_usb_LibusbWin @@ -55,174 +107,133 @@ JNIEXPORT jint JNICALL Java_ch_ntb_usb_LibusbWin_usb_1find_1devices JNIEXPORT jobject JNICALL Java_ch_ntb_usb_LibusbWin_usb_1get_1busses (JNIEnv *env, jobject obj) { - // classes - jclass usb_busClazz, /*usb_devClazz,*/ usb_devDescClazz, usb_confDescClazz, \ - usb_intClazz, usb_intDescClazz, usb_epDescClazz; - // method IDs - jmethodID usb_busMid, usb_devMid, usb_devDescMid, usb_confDescMid, \ - usb_intMid, usb_intDescMid, usb_epDescMid; - // usb_bus - jfieldID usb_busFID_next, usb_busFID_prev, usb_busFID_dirname, \ - usb_busFID_devices, usb_busFID_location, usb_busFID_root_dev; - // usb_device - 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_deviceDescriptor - 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 - 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 - jfieldID usb_intFID_altsetting, usb_intFID_num_altsetting; - // usb_intDesc - 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 - 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; - - // find classes and field ids - // usb_bus - usb_busClazz = env->FindClass("ch/ntb/usb/Usb_Bus"); - if (usb_busClazz == NULL) { return NULL; /* exception thrown */ } - usb_busMid = env->GetMethodID(usb_busClazz, "","()V"); - if (usb_busMid == NULL) { return NULL; } + + // only load class, method and field ID references once + if (!java_references_loaded) { + // find classes and field ids + // usb_bus + usb_busClazz = env->FindClass("ch/ntb/usb/Usb_Bus"); + if (usb_busClazz == NULL) { return NULL; /* exception thrown */ } + usb_busMid = env->GetMethodID(usb_busClazz, "","()V"); + if (usb_busMid == NULL) { return NULL; } - usb_busFID_next = env->GetFieldID(usb_busClazz, "next", "Lch/ntb/usb/Usb_Bus;"); - usb_busFID_prev = env->GetFieldID(usb_busClazz, "prev", "Lch/ntb/usb/Usb_Bus;"); - usb_busFID_dirname = env->GetFieldID(usb_busClazz, "dirname", "Ljava/lang/String;"); - usb_busFID_devices = env->GetFieldID(usb_busClazz, "devices", "Lch/ntb/usb/Usb_Device;"); - usb_busFID_location = env->GetFieldID(usb_busClazz, "location", "J"); - usb_busFID_root_dev = env->GetFieldID(usb_busClazz, "root_dev", "Lch/ntb/usb/Usb_Device;"); + usb_busFID_next = env->GetFieldID(usb_busClazz, "next", "Lch/ntb/usb/Usb_Bus;"); + usb_busFID_prev = env->GetFieldID(usb_busClazz, "prev", "Lch/ntb/usb/Usb_Bus;"); + usb_busFID_dirname = env->GetFieldID(usb_busClazz, "dirname", "Ljava/lang/String;"); + usb_busFID_devices = env->GetFieldID(usb_busClazz, "devices", "Lch/ntb/usb/Usb_Device;"); + usb_busFID_location = env->GetFieldID(usb_busClazz, "location", "J"); + usb_busFID_root_dev = env->GetFieldID(usb_busClazz, "root_dev", "Lch/ntb/usb/Usb_Device;"); + + // usb_device + usb_devClazz = env->FindClass("ch/ntb/usb/Usb_Device"); + if (usb_devClazz == NULL) { return NULL; /* exception thrown */ } + usb_devMid = env->GetMethodID(usb_devClazz, "","()V"); + if (usb_devMid == NULL) { return NULL; } + + usb_devFID_next = env->GetFieldID(usb_devClazz, "next", "Lch/ntb/usb/Usb_Device;"); + usb_devFID_prev = env->GetFieldID(usb_devClazz, "prev", "Lch/ntb/usb/Usb_Device;"); + usb_devFID_filename = env->GetFieldID(usb_devClazz, "filename", "Ljava/lang/String;"); + usb_devFID_bus = env->GetFieldID(usb_devClazz, "bus", "Lch/ntb/usb/Usb_Bus;"); + usb_devFID_descriptor = env->GetFieldID(usb_devClazz, "descriptor", "Lch/ntb/usb/Usb_Device_Descriptor;"); + usb_devFID_config = env->GetFieldID(usb_devClazz, "config", "[Lch/ntb/usb/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/usb/Usb_Device;"); - // usb_device - usb_devClazz = env->FindClass("ch/ntb/usb/Usb_Device"); - if (usb_devClazz == NULL) { return NULL; /* exception thrown */ } - usb_devMid = env->GetMethodID(usb_devClazz, "","()V"); - if (usb_devMid == NULL) { return NULL; } + // usb_device_descriptor + usb_devDescClazz = env->FindClass("ch/ntb/usb/Usb_Device_Descriptor"); + if (usb_devDescClazz == NULL) { return NULL; /* exception thrown */ } + usb_devDescMid = env->GetMethodID(usb_devDescClazz, "","()V"); + if (usb_devDescMid == NULL) { return NULL; } - usb_devFID_next = env->GetFieldID(usb_devClazz, "next", "Lch/ntb/usb/Usb_Device;"); - usb_devFID_prev = env->GetFieldID(usb_devClazz, "prev", "Lch/ntb/usb/Usb_Device;"); - usb_devFID_filename = env->GetFieldID(usb_devClazz, "filename", "Ljava/lang/String;"); - usb_devFID_bus = env->GetFieldID(usb_devClazz, "bus", "Lch/ntb/usb/Usb_Bus;"); - usb_devFID_descriptor = env->GetFieldID(usb_devClazz, "descriptor", "Lch/ntb/usb/Usb_Device_Descriptor;"); - usb_devFID_config = env->GetFieldID(usb_devClazz, "config", "[Lch/ntb/usb/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/usb/Usb_Device;"); + 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"); + // usb_configuration_descriptor + usb_confDescClazz = env->FindClass("ch/ntb/usb/Usb_Config_Descriptor"); + if (usb_confDescClazz == NULL) { return NULL; /* exception thrown */ } + usb_confDescMid = env->GetMethodID(usb_confDescClazz, "","()V"); + if (usb_confDescMid == NULL) { return NULL; } - // usb_device_descriptor - usb_devDescClazz = env->FindClass("ch/ntb/usb/Usb_Device_Descriptor"); - if (usb_devDescClazz == NULL) { return NULL; /* exception thrown */ } - usb_devDescMid = env->GetMethodID(usb_devDescClazz, "","()V"); - if (usb_devDescMid == 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/usb/Usb_Interface;"); + usb_confDescFID_extra = env->GetFieldID(usb_confDescClazz, "extra", "Lch/ntb/usb/Usb_Config_Descriptor;"); + usb_confDescFID_extralen = env->GetFieldID(usb_confDescClazz, "extralen", "I"); - 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"); + // usb_interface + usb_intClazz = env->FindClass("ch/ntb/usb/Usb_Interface"); + if (usb_intClazz == NULL) { return NULL; /* exception thrown */ } + usb_intMid = env->GetMethodID(usb_intClazz, "","()V"); + if (usb_intMid == NULL) { return NULL; } + usb_intFID_altsetting = env->GetFieldID(usb_intClazz, "altsetting", "[Lch/ntb/usb/Usb_Interface_Descriptor;"); + usb_intFID_num_altsetting = env->GetFieldID(usb_intClazz, "num_altsetting", "I"); - // usb_configuration_descriptor - usb_confDescClazz = env->FindClass("ch/ntb/usb/Usb_Config_Descriptor"); - if (usb_confDescClazz == NULL) { return NULL; /* exception thrown */ } - usb_confDescMid = env->GetMethodID(usb_confDescClazz, "","()V"); - if (usb_confDescMid == NULL) { return NULL; } + // usb_interface_descriptor + usb_intDescClazz = env->FindClass("ch/ntb/usb/Usb_Interface_Descriptor"); + if (usb_intDescClazz == NULL) { return NULL; /* exception thrown */ } + usb_intDescMid = env->GetMethodID(usb_intDescClazz, "","()V"); + if (usb_intDescMid == 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/usb/Usb_Interface;"); - usb_confDescFID_extra = env->GetFieldID(usb_confDescClazz, "extra", "Lch/ntb/usb/Usb_Config_Descriptor;"); - usb_confDescFID_extralen = env->GetFieldID(usb_confDescClazz, "extralen", "I"); + 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/usb/Usb_Endpoint_Descriptor;"); + usb_intDescFID_extra = env->GetFieldID(usb_intDescClazz, "extra", "Lch/ntb/usb/Usb_Interface_Descriptor;"); + usb_intDescFID_extralen = env->GetFieldID(usb_intDescClazz, "extralen", "I"); - // usb_interface - usb_intClazz = env->FindClass("ch/ntb/usb/Usb_Interface"); - if (usb_intClazz == NULL) { return NULL; /* exception thrown */ } - usb_intMid = env->GetMethodID(usb_intClazz, "","()V"); - if (usb_intMid == NULL) { return NULL; } + // usb_endpoint_descriptor + usb_epDescClazz = env->FindClass("ch/ntb/usb/Usb_Endpoint_Descriptor"); + if (usb_epDescClazz == NULL) { return NULL; /* exception thrown */ } + usb_epDescMid = env->GetMethodID(usb_epDescClazz, "","()V"); + if (usb_epDescMid == NULL) { return NULL; } - usb_intFID_altsetting = env->GetFieldID(usb_intClazz, "altsetting", "[Lch/ntb/usb/Usb_Interface_Descriptor;"); - usb_intFID_num_altsetting = env->GetFieldID(usb_intClazz, "num_altsetting", "I"); - - // usb_interface_descriptor - usb_intDescClazz = env->FindClass("ch/ntb/usb/Usb_Interface_Descriptor"); - if (usb_intDescClazz == NULL) { return NULL; /* exception thrown */ } - usb_intDescMid = env->GetMethodID(usb_intDescClazz, "","()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/usb/Usb_Endpoint_Descriptor;"); - usb_intDescFID_extra = env->GetFieldID(usb_intDescClazz, "extra", "Lch/ntb/usb/Usb_Interface_Descriptor;"); - usb_intDescFID_extralen = env->GetFieldID(usb_intDescClazz, "extralen", "I"); - - // usb_endpoint_descriptor - usb_epDescClazz = env->FindClass("ch/ntb/usb/Usb_Endpoint_Descriptor"); - if (usb_epDescClazz == NULL) { return NULL; /* exception thrown */ } - usb_epDescMid = env->GetMethodID(usb_epDescClazz, "","()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", "Lch/ntb/usb/Usb_Endpoint_Descriptor;"); - usb_epDescFID_extralen = env->GetFieldID(usb_epDescClazz, "extralen", "I"); + 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", "Lch/ntb/usb/Usb_Endpoint_Descriptor;"); + usb_epDescFID_extralen = env->GetFieldID(usb_epDescClazz, "extralen", "I"); +#ifdef DEBUGON + printf("usb_get_busses: Field initialization done (1)\n"); +#endif + } //************************************************************************// -#ifdef DEBUGON - printf("usb_get_busses: Field initialization done (1)\n"); -#endif - struct usb_device *dev; struct usb_bus *bus; - + busses = usb_get_busses(); bus = busses; if (!bus){ @@ -247,13 +258,13 @@ JNIEXPORT jobject JNICALL Java_ch_ntb_usb_LibusbWin_usb_1get_1busses while (bus){ #ifdef DEBUGON - printf("\tusb_get_busses: bus %x (2)\n", bus); + printf("\tusb_get_busses: bus %x (3)\n", bus); #endif // create a new object for every bus if (!usb_busObj) { usb_busObj = env->NewObject(usb_busClazz, usb_busMid); - if (!usb_busObj) { printf("Error NewObject 1\n"); return NULL; } + if (!usb_busObj) { printf("Error NewObject (usb_busObj)\n"); return NULL; } main_usb_busObj = usb_busObj; } @@ -261,7 +272,7 @@ JNIEXPORT jobject JNICALL Java_ch_ntb_usb_LibusbWin_usb_1get_1busses usb_busObj_next = NULL; if (bus->next){ usb_busObj_next = env->NewObject(usb_busClazz, usb_busMid); - if (!usb_busObj_next) { printf("Error NewObject 2\n"); return NULL; } + if (!usb_busObj_next) { printf("Error NewObject (usb_busObj_next)\n"); return NULL; } } env->SetObjectField(usb_busObj, usb_busFID_next, usb_busObj_next); env->SetObjectField(usb_busObj, usb_busFID_prev, usb_busObj_prev); @@ -275,19 +286,19 @@ JNIEXPORT jobject JNICALL Java_ch_ntb_usb_LibusbWin_usb_1get_1busses while (dev){ #ifdef DEBUGON - printf("\tusb_get_busses: dev %x (3)\n", dev); + printf("\tusb_get_busses: dev %x (4)\n", dev); #endif // create a new object for every device if (!usb_devObj){ usb_devObj = env->NewObject(usb_devClazz, usb_devMid); - if (!usb_devObj) { printf("Error NewObject 3\n"); return NULL; } + if (!usb_devObj) { printf("Error NewObject (usb_devObj)\n"); return NULL; } main_usb_devObj = usb_devObj; } // fill the fields of the object usb_devObj_next = NULL; if (dev->next){ usb_devObj_next = env->NewObject(usb_devClazz, usb_devMid); - if (!usb_devObj_next) { printf("Error NewObject 4\n"); return NULL; } + if (!usb_devObj_next) { printf("Error NewObject (usb_devObj_next)\n"); return NULL; } } env->SetObjectField(usb_devObj, usb_devFID_next, usb_devObj_next); env->SetObjectField(usb_devObj, usb_devFID_prev, usb_devObj_prev); @@ -298,7 +309,7 @@ JNIEXPORT jobject JNICALL Java_ch_ntb_usb_LibusbWin_usb_1get_1busses // device descriptor usb_devDescObj = env->NewObject(usb_devDescClazz, usb_devDescMid); - if (!usb_devDescObj) { printf("Error NewObject 5\n"); return NULL; } + if (!usb_devDescObj) { printf("Error NewObject (usb_devDescObj)\n"); return NULL; } env->SetByteField(usb_devDescObj, usb_devDescFID_bLength, dev->descriptor.bLength); env->SetByteField(usb_devDescObj, usb_devDescFID_bDescriptorType, dev->descriptor.bDescriptorType); env->SetShortField(usb_devDescObj, usb_devDescFID_bcdUSB, dev->descriptor.bcdUSB); @@ -321,15 +332,16 @@ JNIEXPORT jobject JNICALL Java_ch_ntb_usb_LibusbWin_usb_1get_1busses if (!usb_confDescObjArray) { printf("Error NewObject 6\n"); return NULL; } for (int c = 0; c < dev->descriptor.bNumConfigurations; c++){ #ifdef DEBUGON - printf("\t\tusb_get_busses: configuration %x (4)\n", c); + printf("\t\tusb_get_busses: configuration %x (5)\n", c); #endif if (dev->config == NULL) { + // this shouldn't happen, but it did occasionally (maybe this is (or probably was) a libusb bug) printf("dev->config == NULL\n"); return main_usb_busObj; } usb_confDescObj = env->NewObject(usb_confDescClazz, usb_confDescMid); - if (!usb_confDescObj) { printf("Error NewObject 7\n"); return NULL; } + if (!usb_confDescObj) { printf("Error NewObject (usb_confDescObj)\n"); return NULL; } env->SetObjectArrayElement(usb_confDescObjArray, c, usb_confDescObj); env->SetByteField(usb_confDescObj, usb_confDescFID_bLength, dev->config[c].bLength); env->SetByteField(usb_confDescObj, usb_confDescFID_bDescriptorType, dev->config[c].bDescriptorType); @@ -348,34 +360,36 @@ JNIEXPORT jobject JNICALL Java_ch_ntb_usb_LibusbWin_usb_1get_1busses } // interface usb_intObjArray = env->NewObjectArray(dev->config[c].bNumInterfaces, usb_intClazz, NULL); - if (!usb_intObjArray) { printf("Error NewObject 8\n"); return NULL; } + if (!usb_intObjArray) { printf("Error NewObject (usb_intObjArray)\n"); return NULL; } for (int i = 0; i < dev->config[c].bNumInterfaces; i++){ #ifdef DEBUGON - printf("\t\t\tusb_get_busses: interface %x (5)\n", i); + printf("\t\t\tusb_get_busses: interface %x (6)\n", i); #endif if (dev->config[c].interface == NULL) { + // this shouldn't happen printf("dev->config[c].interface == NULL\n"); return main_usb_busObj; } usb_intObj = env->NewObject(usb_intClazz, usb_intMid); - if (!usb_intObj) { printf("Error NewObject 9\n"); return NULL; } + if (!usb_intObj) { printf("Error NewObject (usb_intObj)\n"); return NULL; } env->SetObjectArrayElement(usb_intObjArray, i, usb_intObj); env->SetIntField(usb_intObj, usb_intFID_num_altsetting, dev->config[c].interface[i].num_altsetting); // interface descriptor usb_intDescObjArray = env->NewObjectArray(dev->config[c].interface[i].num_altsetting, usb_intDescClazz, NULL); - if (!usb_intDescObjArray) { printf("Error NewObject 10\n"); return NULL; } + if (!usb_intDescObjArray) { printf("Error NewObject (usb_intDescObjArray)\n"); return NULL; } for (int a = 0; a < dev->config[c].interface[i].num_altsetting; a++){ #ifdef DEBUGON - printf("\t\t\t\tusb_get_busses: interface descriptor %x (6)\n", a); + printf("\t\t\t\tusb_get_busses: interface descriptor %x (7)\n", a); #endif if (dev->config[c].interface[i].altsetting == NULL) { + // this shouldn't happen printf("dev->config[c].interface[i].altsetting == NULL\n"); return main_usb_busObj; } usb_intDescObj = env->NewObject(usb_intDescClazz, usb_intDescMid); - if (!usb_intDescObj) { printf("Error NewObject 11\n"); return NULL; } + if (!usb_intDescObj) { printf("Error NewObject (usb_intDescObj)\n"); return NULL; } env->SetObjectArrayElement(usb_intDescObjArray, a, usb_intDescObj); env->SetByteField(usb_intDescObj, usb_intDescFID_bLength, dev->config[c].interface[i].altsetting[a].bLength); env->SetByteField(usb_intDescObj, usb_intDescFID_bDescriptorType, dev->config[c].interface[i].altsetting[a].bDescriptorType); @@ -395,10 +409,10 @@ JNIEXPORT jobject JNICALL Java_ch_ntb_usb_LibusbWin_usb_1get_1busses env->SetObjectField(usb_intDescObj, usb_intDescFID_extra, NULL); // endpoint descriptor usb_epDescObjArray = env->NewObjectArray(dev->config[c].interface[i].altsetting[a].bNumEndpoints, usb_epDescClazz, NULL); - if (!usb_epDescObjArray) { printf("Error NewObject 12\n"); return NULL; } + if (!usb_epDescObjArray) { printf("Error NewObject (usb_epDescObjArray)\n"); return NULL; } for (int e = 0; e < dev->config[c].interface[i].altsetting[a].bNumEndpoints; e++){ #ifdef DEBUGON - printf("\t\t\t\t\tusb_get_busses: endpoint descriptor %x (7)\n", e); + printf("\t\t\t\t\tusb_get_busses: endpoint descriptor %x (8)\n", e); #endif if (dev->config[c].interface[i].altsetting[a].endpoint == NULL) { printf("dev->config[c].interface[i].altsetting[a].endpoint == NULL\n"); @@ -406,7 +420,7 @@ JNIEXPORT jobject JNICALL Java_ch_ntb_usb_LibusbWin_usb_1get_1busses } usb_epDescObj = env->NewObject(usb_epDescClazz, usb_epDescMid); - if (!usb_epDescObj) { printf("Error NewObject 13\n"); return NULL; } + if (!usb_epDescObj) { printf("Error NewObject (usb_epDescObj)\n"); return NULL; } env->SetObjectArrayElement(usb_epDescObjArray, e, usb_epDescObj); env->SetByteField(usb_epDescObj, usb_epDescFID_bLength, dev->config[c].interface[i].altsetting[a].endpoint[e].bLength); env->SetByteField(usb_epDescObj, usb_epDescFID_bDescriptorType, dev->config[c].interface[i].altsetting[a].endpoint[e].bDescriptorType); @@ -639,10 +653,9 @@ JNIEXPORT jint JNICALL Java_ch_ntb_usb_LibusbWin_usb_1bulk_1write JNIEXPORT jint JNICALL Java_ch_ntb_usb_LibusbWin_usb_1bulk_1read (JNIEnv *env, jobject obj, jint dev_handle, jint ep, jbyteArray jbytes, jint size, jint timeout) { - char *bytes = (char *) malloc(size*sizeof(char)); + char *bytes = (char *) malloc(size * sizeof(char)); int retVal = usb_bulk_read((usb_dev_handle *) dev_handle, ep, bytes, size, timeout); if (!bytes) { return retVal; } - // jbytes = env->NewByteArray(size); env->SetByteArrayRegion(jbytes, 0, size, (jbyte *) bytes); free(bytes); return retVal; @@ -668,11 +681,11 @@ JNIEXPORT jint JNICALL Java_ch_ntb_usb_LibusbWin_usb_1interrupt_1write JNIEXPORT jint JNICALL Java_ch_ntb_usb_LibusbWin_usb_1interrupt_1read (JNIEnv *env, jobject obj, jint dev_handle, jint ep, jbyteArray jbytes, jint size, jint timeout) { - jbyte *bytes; - int retVal = usb_interrupt_write((usb_dev_handle *) dev_handle, ep, (char *) bytes, size, timeout); - if (bytes) { return retVal; } - jbytes = env->NewByteArray(size); - env->SetByteArrayRegion(jbytes, 0, size, bytes); + char *bytes = (char *) malloc(size * sizeof(char)); + int retVal = usb_interrupt_write((usb_dev_handle *) dev_handle, ep, bytes, size, timeout); + if (!bytes) { return retVal; } + env->SetByteArrayRegion(jbytes, 0, size, (jbyte *) bytes); + free(bytes); return retVal; } diff --git a/libusbdll/LibusbWin.dll b/libusbdll/LibusbWin.dll index 102cc879bdab22eb2fac588363e3025ecadc7971..bff7e5fb2382b52b0e5294c931f7df9a7bab285b 100644 GIT binary patch literal 40995 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
xUJHXL4@Z(9aX+7rio@#kVH&n*%*(8t7f& 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
0Iq~I2!$tg`JTb1O8yEr=iq)cNbg#+EC`byNzfI z>w*}xoFjutjg!>ym9=w2A>Ue0(BI+jjCdLxE~$~xgPH{ftsjTqWQ4=5F7FjaG?aMn z#`?H$coeniahMgk;B8|&)<%pG*08}rM|vz~RZggyw>IJ*LzB;_DJ>3bMfF{stHw~Y z#;hnMhlL`PQX^Xvx3uX-Ps7bENm5O>%_7`twvAzJqr+>IoHmz9VVRm(9xbIDcJJLC z{z!Wl>d<`#O=-YQDjfFtex6PX>vT$PZfSHSxiJ>dEY<3sk6SHmPtpVS9?)H^e6=_Y(gqENn;j z;qczwjMk5L9>Ip2liIp;nJjV(Rhn{3^b|>XlyuX??xaenV`sfxILY3Ic7xQkc~a!v zD#|;)YOTguYK|neKD>QJ&5Rg(_vCvf#~f}r#<^?pSpv9(Ap=*Ic~!8h*%$P-vge5g5`V<#^>+K| zqZ8gxPiG|1;rFulRPcp~kfMKaWmYf{j^OPTFMR=nzCYm&WAQ|Qh8T>beiQ?XJKKCc z!HBm9gY|BFx`kU}_;3a-W*4u$k2Cc!{KaAAb;xBY47}tB-TD($9(3X3=cmmuJ;8q%MP?r)~?PvCP z`0nlsp}3mEYr_$Lhj+C<6h>>!eZ!-0@0y@yqg;-x8KN#Ml?zVc7UK$NTq=b>&0tnj zMHbI(g-axf`cp$EEd6C`m~}v{*6;k#1^xCejR*;l_n^^mV~b zeArLKMLfoay~Ykm-#Jl^lH+{XM7~k0Ez^jpXTL~!c^FJ}QjKSzgDQl+c@1{?TKyq! zThO;E%qj_!ruI?n%FyDgF1R;!Xt z7{JW0Py>-Hg$e-*Mn+qHo8I^@x{^ik?4qty4>K^d4U{+hh%YdPt3% R7IkCyOek4RWrFhj_%9Ppe$D^@