1 diff -urp libusb-1.0.9.orig/libusb/io.c libusb-1.0.9/libusb/io.c
2 --- libusb-1.0.9.orig/libusb/io.c 2013-08-28 14:33:15.000000000 +0200
3 +++ libusb-1.0.9/libusb/io.c 2013-08-28 14:31:25.000000000 +0200
8 +#ifndef TIMESPEC_TO_TIMEVAL
9 +#define TIMESPEC_TO_TIMEVAL(tv, ts) \
11 + (tv)->tv_sec = (ts)->tv_sec; \
12 + (tv)->tv_usec = (ts)->tv_nsec / 1000; \
17 * \page io Synchronous and asynchronous device I/O
19 --- libusb-1.0.19.orig/libusb/os/linux_usbfs.c 2014-05-30 11:18:28.000000000 +0200
20 +++ libusb-1.0.19/libusb/os/linux_usbfs.c 2016-11-26 15:38:21.199383120 +0100
22 #include <sys/types.h>
23 #include <sys/utsname.h>
31 #include "linux_usbfs.h"
34 +static JavaVM *g_jvm = NULL;
35 +static jclass usb_helper_class;
36 +static jclass usb_event_listener_class;
37 +static jmethodID usb_helper_open_mid;
38 +static jmethodID usb_helper_start_event_monitor_mid;
39 +static jmethodID usb_helper_stop_event_monitor_mid;
40 +static jmethodID usb_helper_scan_devices_mid;
41 +static jmethodID usb_event_listener_init_mid;
42 +static int usb_helper_open(const char *pathname, int flags);
43 +static int usb_helper_start_event_monitor(void);
44 +static int usb_helper_stop_event_monitor(void);
45 +static int usb_helper_scan_devices (struct libusb_context *ctx);
46 +static void usb_helper_hotplug_poll(void);
47 +static void usb_helper_on_usb_device_action(JNIEnv *env, jobject self, jstring name, jboolean removed);
51 * opening a usbfs node causes the device to be resumed, so we attempt to
52 * avoid this during enumeration.
54 snprintf(path, PATH_MAX, "%s/%03d/%03d",
55 usbfs_path, dev->bus_number, dev->device_address);
59 + fd = usb_helper_open(path, mode);
62 fd = open(path, mode);
64 return fd; /* Success */
71 + usbfs_path = "/dev/bus/usb";
72 + sysfs_can_relate_devices = 0;
73 + sysfs_has_descriptors = 0;
76 usbfs_path = find_usbfs_path();
78 usbi_err(ctx, "could not find usbfs");
81 static int linux_start_event_monitor(void)
85 + return usb_helper_start_event_monitor();
88 return linux_udev_start_event_monitor();
92 static int linux_stop_event_monitor(void)
96 + return usb_helper_stop_event_monitor();
99 return linux_udev_stop_event_monitor();
103 usbi_mutex_static_lock(&linux_hotplug_lock);
107 + ret = usb_helper_scan_devices(ctx);
110 #if defined(USE_UDEV)
111 ret = linux_udev_scan_devices(ctx);
115 static void op_hotplug_poll(void)
119 + usb_helper_hotplug_poll();
122 #if defined(USE_UDEV)
123 linux_udev_hotplug_poll();
125 @@ -994,6 +1044,10 @@
126 /* XXX -- can we figure out the topology when using usbfs? */
127 if (NULL == sysfs_dir || 0 == strncmp(sysfs_dir, "usb", 3)) {
128 /* either using usbfs or finding the parent of a root hub */
131 + dev->port_number = dev->device_address;
133 return LIBUSB_SUCCESS;
136 @@ -2693,3 +2747,262 @@
137 .transfer_priv_size = sizeof(struct linux_transfer_priv),
138 .add_iso_packet_size = 0,
142 +jint JNI_OnLoad(JavaVM *vm, void *reserved)
144 + static JNINativeMethod jni_method = {
145 + "onUsbDeviceAction",
146 + "(Ljava/lang/String;Z)V",
147 + (void*)usb_helper_on_usb_device_action
152 + if ((*vm)->GetEnv(vm, (void **)&env, JNI_VERSION_1_6) != JNI_OK) {
156 + jclass helper = (*env)->FindClass(env, "org/sigrok/androidutils/UsbHelper");
157 + jclass event_listener = (*env)->FindClass(env, "org/sigrok/androidutils/UsbEventListenerStub");
159 + if (helper && event_listener) {
161 + usb_helper_class = (jclass)(*env)->NewGlobalRef(env, helper);
163 + usb_helper_open_mid = (*env)->GetStaticMethodID(env, helper, "open",
164 + "(Ljava/lang/String;I)I");
165 + usb_helper_start_event_monitor_mid = (*env)->GetStaticMethodID(env, helper, "startEventMonitor",
166 + "(Lorg/sigrok/androidutils/UsbEventListener;)V");
167 + usb_helper_stop_event_monitor_mid = (*env)->GetStaticMethodID(env, helper, "stopEventMonitor",
169 + usb_helper_scan_devices_mid = (*env)->GetStaticMethodID(env, helper, "scanDevices",
170 + "()[Ljava/lang/String;");
171 + (*env)->DeleteLocalRef(env, helper);
173 + usb_event_listener_class = (jclass)(*env)->NewGlobalRef(env, event_listener);
174 + usb_event_listener_init_mid = (*env)->GetMethodID(env, event_listener, "<init>",
176 + if ((*env)->RegisterNatives(env, event_listener, &jni_method, 1) < 0) {
177 + if ((*env)->ExceptionCheck(env)) {
178 + (*env)->ExceptionClear(env);
183 + (*env)->DeleteLocalRef(env, event_listener);
186 + if ((*env)->ExceptionCheck(env)) {
187 + (*env)->ExceptionClear(env);
192 + return JNI_VERSION_1_6;
195 +void JNI_OnUnload(JavaVM *vm, void *reserved)
198 + if ((*vm)->GetEnv(vm, (void **)&env, JNI_VERSION_1_6) != JNI_OK) {
202 + jclass helper = usb_helper_class;
203 + jclass event_listener = usb_event_listener_class;
204 + usb_helper_class = NULL;
205 + usb_event_listener_class = NULL;
207 + (*env)->DeleteGlobalRef(env, helper);
208 + if (event_listener) {
209 + (*env)->UnregisterNatives(env, event_listener);
210 + (*env)->DeleteGlobalRef(env, event_listener);
215 +static int usb_helper_open(const char *pathname, int flags)
222 + if (g_jvm == NULL) {
225 + st = (*g_jvm)->GetEnv(g_jvm, (void **)&env, JNI_VERSION_1_6);
227 + if (st == JNI_EDETACHED) {
228 + st = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
232 + if (st != JNI_OK) {
236 + jstring string = (*env)->NewStringUTF(env, pathname);
237 + res = (*env)->CallStaticIntMethod(env, usb_helper_class, usb_helper_open_mid, string, (jint)flags);
238 + (*env)->DeleteLocalRef(env, string);
241 + (*g_jvm)->DetachCurrentThread(g_jvm);
245 + /* Rewind so that descriptors can be read */
246 + lseek(res, SEEK_SET, 0);
252 +static int usb_helper_start_event_monitor(void)
258 + jobject usb_event_listener;
260 + if (g_jvm == NULL) {
261 + return LIBUSB_ERROR_OTHER;
263 + st = (*g_jvm)->GetEnv(g_jvm, (void **)&env, JNI_VERSION_1_6);
265 + if (st == JNI_EDETACHED) {
266 + st = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
270 + if (st != JNI_OK) {
271 + return LIBUSB_ERROR_OTHER;
274 + usb_event_listener = (*env)->NewObject(env, usb_event_listener_class, usb_event_listener_init_mid);
275 + if (usb_event_listener == NULL)
276 + res = LIBUSB_ERROR_OTHER;
278 + (*env)->CallStaticVoidMethod(env, usb_helper_class, usb_helper_start_event_monitor_mid, usb_event_listener);
279 + (*env)->DeleteLocalRef(env, usb_event_listener);
283 + (*g_jvm)->DetachCurrentThread(g_jvm);
289 +static int usb_helper_stop_event_monitor(void)
295 + if (g_jvm == NULL) {
296 + return LIBUSB_ERROR_OTHER;
298 + st = (*g_jvm)->GetEnv(g_jvm, (void **)&env, JNI_VERSION_1_6);
300 + if (st == JNI_EDETACHED) {
301 + st = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
305 + if (st != JNI_OK) {
306 + return LIBUSB_ERROR_OTHER;
309 + (*env)->CallStaticVoidMethod(env, usb_helper_class, usb_helper_stop_event_monitor_mid);
312 + (*g_jvm)->DetachCurrentThread(g_jvm);
318 +static int usb_helper_scan_devices (struct libusb_context *ctx)
325 + if (g_jvm == NULL) {
326 + return LIBUSB_ERROR_OTHER;
328 + st = (*g_jvm)->GetEnv(g_jvm, (void **)&env, JNI_VERSION_1_6);
330 + if (st == JNI_EDETACHED) {
331 + st = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
335 + if (st != JNI_OK) {
336 + return LIBUSB_ERROR_OTHER;
339 + jobject arr = (*env)->CallStaticObjectMethod(env, usb_helper_class, usb_helper_scan_devices_mid);
342 + res = LIBUSB_ERROR_OTHER;
344 + jsize i, len = (*env)->GetArrayLength(env, arr);
345 + for (i=0; i<len; i++) {
346 + jobject str = (*env)->GetObjectArrayElement(env, arr, i);
348 + const char *ustr = (*env)->GetStringUTFChars(env, str, NULL);
350 + unsigned busnum, devaddr;
351 + if (2 != sscanf(ustr, "/dev/bus/usb/%u/%u",
352 + &busnum, &devaddr) ||
353 + linux_enumerate_device(ctx, busnum, devaddr, NULL)) {
354 + usbi_dbg("failed to enumerate device %s", ustr);
356 + (*env)->ReleaseStringUTFChars(env, str, ustr);
358 + res = LIBUSB_ERROR_OTHER;
359 + (*env)->DeleteLocalRef(env, str);
361 + res = LIBUSB_ERROR_OTHER;
365 + (*env)->DeleteLocalRef(env, arr);
369 + (*g_jvm)->DetachCurrentThread(g_jvm);
375 +static void usb_helper_hotplug_poll(void)
379 +static void usb_helper_on_usb_device_action(JNIEnv *env, jobject self, jstring name, jboolean removed)
381 + usbi_mutex_static_lock(&linux_hotplug_lock);
383 + const char *ustr = (*env)->GetStringUTFChars(env, name, NULL);
385 + unsigned busnum, devaddr;
386 + if (2 == sscanf(ustr, "/dev/bus/usb/%u/%u",
387 + &busnum, &devaddr)) {
389 + linux_device_disconnected(busnum, devaddr, NULL);
391 + linux_hotplug_enumerate(busnum, devaddr, NULL);
393 + (*env)->ReleaseStringUTFChars(env, name, ustr);
396 + usbi_mutex_static_unlock(&linux_hotplug_lock);