]> sigrok.org Git - sigrok-util.git/blame - cross-compile/android/libusb-1.0.patch
sigrok-fwextract-dreamsourcelab-dslogic: Download v0.98 firmware
[sigrok-util.git] / cross-compile / android / libusb-1.0.patch
CommitLineData
13b2dfdc
MC
1diff -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
4@@ -36,6 +36,14 @@
5
6 #include "libusbi.h"
7
8+#ifndef TIMESPEC_TO_TIMEVAL
9+#define TIMESPEC_TO_TIMEVAL(tv, ts) \
10+ do { \
11+ (tv)->tv_sec = (ts)->tv_sec; \
12+ (tv)->tv_usec = (ts)->tv_nsec / 1000; \
13+ } while (0)
14+#endif
15+
16 /**
17 * \page io Synchronous and asynchronous device I/O
18 *
c8cf030a
MC
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
21@@ -37,11 +37,31 @@
e1dbb76d
MC
22 #include <sys/types.h>
23 #include <sys/utsname.h>
24 #include <unistd.h>
25+#ifdef __ANDROID__
26+#include <jni.h>
27+#endif
28
29 #include "libusb.h"
30 #include "libusbi.h"
31 #include "linux_usbfs.h"
32
33+#ifdef __ANDROID__
34+static JavaVM *g_jvm = NULL;
35+static jclass usb_helper_class;
c8cf030a 36+static jclass usb_event_listener_class;
e1dbb76d 37+static jmethodID usb_helper_open_mid;
c8cf030a
MC
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;
e1dbb76d 42+static int usb_helper_open(const char *pathname, int flags);
c8cf030a
MC
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);
e1dbb76d
MC
48+#endif
49+
50 /* sysfs vs usbfs:
51 * opening a usbfs node causes the device to be resumed, so we attempt to
52 * avoid this during enumeration.
c8cf030a 53@@ -193,6 +213,11 @@
e1dbb76d
MC
54 snprintf(path, PATH_MAX, "%s/%03d/%03d",
55 usbfs_path, dev->bus_number, dev->device_address);
56
57+#ifdef __ANDROID__
58+ if (g_jvm)
59+ fd = usb_helper_open(path, mode);
60+ else
61+#endif
62 fd = open(path, mode);
63 if (fd != -1)
64 return fd; /* Success */
c8cf030a
MC
65@@ -369,6 +394,13 @@
66 struct stat statbuf;
67 int r;
68
69+#ifdef __ANDROID__
70+ if (g_jvm) {
71+ usbfs_path = "/dev/bus/usb";
72+ sysfs_can_relate_devices = 0;
73+ sysfs_has_descriptors = 0;
74+ } else
75+#endif
76 usbfs_path = find_usbfs_path();
77 if (!usbfs_path) {
78 usbi_err(ctx, "could not find usbfs");
79@@ -467,6 +499,10 @@
80
81 static int linux_start_event_monitor(void)
82 {
83+#ifdef __ANDROID__
84+ if (g_jvm)
85+ return usb_helper_start_event_monitor();
86+#endif
87 #if defined(USE_UDEV)
88 return linux_udev_start_event_monitor();
89 #else
90@@ -476,6 +512,10 @@
91
92 static int linux_stop_event_monitor(void)
93 {
94+#ifdef __ANDROID__
95+ if (g_jvm)
96+ return usb_helper_stop_event_monitor();
97+#endif
98 #if defined(USE_UDEV)
99 return linux_udev_stop_event_monitor();
100 #else
101@@ -489,6 +529,11 @@
102
103 usbi_mutex_static_lock(&linux_hotplug_lock);
104
105+#ifdef __ANDROID__
106+ if (g_jvm)
107+ ret = usb_helper_scan_devices(ctx);
108+ else
109+#endif
110 #if defined(USE_UDEV)
111 ret = linux_udev_scan_devices(ctx);
112 #else
113@@ -502,6 +547,11 @@
114
115 static void op_hotplug_poll(void)
116 {
117+#ifdef __ANDROID__
118+ if (g_jvm)
119+ usb_helper_hotplug_poll();
120+ else
121+#endif
122 #if defined(USE_UDEV)
123 linux_udev_hotplug_poll();
124 #else
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 */
129+#ifdef __ANDROID__
130+ if (g_jvm)
131+ dev->port_number = dev->device_address;
132+#endif
133 return LIBUSB_SUCCESS;
134 }
135
136@@ -2693,3 +2747,262 @@
e1dbb76d
MC
137 .transfer_priv_size = sizeof(struct linux_transfer_priv),
138 .add_iso_packet_size = 0,
139 };
140+
141+#ifdef __ANDROID__
142+jint JNI_OnLoad(JavaVM *vm, void *reserved)
143+{
c8cf030a
MC
144+ static JNINativeMethod jni_method = {
145+ "onUsbDeviceAction",
146+ "(Ljava/lang/String;Z)V",
147+ (void*)usb_helper_on_usb_device_action
148+ };
149+
e1dbb76d
MC
150+ JNIEnv* env;
151+ g_jvm = vm;
152+ if ((*vm)->GetEnv(vm, (void **)&env, JNI_VERSION_1_6) != JNI_OK) {
153+ return -1;
154+ }
155+
156+ jclass helper = (*env)->FindClass(env, "org/sigrok/androidutils/UsbHelper");
c8cf030a 157+ jclass event_listener = (*env)->FindClass(env, "org/sigrok/androidutils/UsbEventListenerStub");
e1dbb76d 158+
c8cf030a 159+ if (helper && event_listener) {
e1dbb76d
MC
160+
161+ usb_helper_class = (jclass)(*env)->NewGlobalRef(env, helper);
162+
163+ usb_helper_open_mid = (*env)->GetStaticMethodID(env, helper, "open",
164+ "(Ljava/lang/String;I)I");
c8cf030a
MC
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",
168+ "()V");
169+ usb_helper_scan_devices_mid = (*env)->GetStaticMethodID(env, helper, "scanDevices",
170+ "()[Ljava/lang/String;");
e1dbb76d
MC
171+ (*env)->DeleteLocalRef(env, helper);
172+
c8cf030a
MC
173+ usb_event_listener_class = (jclass)(*env)->NewGlobalRef(env, event_listener);
174+ usb_event_listener_init_mid = (*env)->GetMethodID(env, event_listener, "<init>",
175+ "()V");
176+ if ((*env)->RegisterNatives(env, event_listener, &jni_method, 1) < 0) {
177+ if ((*env)->ExceptionCheck(env)) {
178+ (*env)->ExceptionClear(env);
179+ }
180+ g_jvm = NULL;
181+ }
182+
183+ (*env)->DeleteLocalRef(env, event_listener);
184+
e1dbb76d
MC
185+ } else {
186+ if ((*env)->ExceptionCheck(env)) {
187+ (*env)->ExceptionClear(env);
188+ }
189+ g_jvm = NULL;
190+ }
191+
192+ return JNI_VERSION_1_6;
193+}
194+
195+void JNI_OnUnload(JavaVM *vm, void *reserved)
196+{
197+ JNIEnv* env;
198+ if ((*vm)->GetEnv(vm, (void **)&env, JNI_VERSION_1_6) != JNI_OK) {
199+ return;
200+ }
201+
202+ jclass helper = usb_helper_class;
c8cf030a 203+ jclass event_listener = usb_event_listener_class;
e1dbb76d 204+ usb_helper_class = NULL;
c8cf030a 205+ usb_event_listener_class = NULL;
e1dbb76d
MC
206+ if (helper)
207+ (*env)->DeleteGlobalRef(env, helper);
c8cf030a
MC
208+ if (event_listener) {
209+ (*env)->UnregisterNatives(env, event_listener);
210+ (*env)->DeleteGlobalRef(env, event_listener);
211+ }
e1dbb76d
MC
212+ g_jvm = NULL;
213+}
214+
215+static int usb_helper_open(const char *pathname, int flags)
216+{
217+ JNIEnv* env;
218+ int res;
219+ jint st;
220+ int do_detach = 0;
221+
222+ if (g_jvm == NULL) {
223+ return -1;
224+ }
225+ st = (*g_jvm)->GetEnv(g_jvm, (void **)&env, JNI_VERSION_1_6);
226+
227+ if (st == JNI_EDETACHED) {
228+ st = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
229+ do_detach = 1;
230+ }
231+
232+ if (st != JNI_OK) {
233+ return -1;
234+ }
235+
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);
239+
240+ if (do_detach) {
241+ (*g_jvm)->DetachCurrentThread(g_jvm);
242+ }
243+
c8cf030a
MC
244+ if (res >= 0) {
245+ /* Rewind so that descriptors can be read */
246+ lseek(res, SEEK_SET, 0);
247+ }
248+
249+ return res;
250+}
251+
252+static int usb_helper_start_event_monitor(void)
253+{
254+ JNIEnv* env;
255+ jint st;
256+ int do_detach = 0;
257+ int res = 0;
258+ jobject usb_event_listener;
259+
260+ if (g_jvm == NULL) {
261+ return LIBUSB_ERROR_OTHER;
262+ }
263+ st = (*g_jvm)->GetEnv(g_jvm, (void **)&env, JNI_VERSION_1_6);
264+
265+ if (st == JNI_EDETACHED) {
266+ st = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
267+ do_detach = 1;
268+ }
269+
270+ if (st != JNI_OK) {
271+ return LIBUSB_ERROR_OTHER;
272+ }
273+
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;
277+ else {
278+ (*env)->CallStaticVoidMethod(env, usb_helper_class, usb_helper_start_event_monitor_mid, usb_event_listener);
279+ (*env)->DeleteLocalRef(env, usb_event_listener);
280+ }
281+
282+ if (do_detach) {
283+ (*g_jvm)->DetachCurrentThread(g_jvm);
284+ }
285+
286+ return res;
287+}
288+
289+static int usb_helper_stop_event_monitor(void)
290+{
291+ JNIEnv* env;
292+ jint st;
293+ int do_detach = 0;
294+
295+ if (g_jvm == NULL) {
296+ return LIBUSB_ERROR_OTHER;
297+ }
298+ st = (*g_jvm)->GetEnv(g_jvm, (void **)&env, JNI_VERSION_1_6);
299+
300+ if (st == JNI_EDETACHED) {
301+ st = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
302+ do_detach = 1;
303+ }
304+
305+ if (st != JNI_OK) {
306+ return LIBUSB_ERROR_OTHER;
307+ }
308+
309+ (*env)->CallStaticVoidMethod(env, usb_helper_class, usb_helper_stop_event_monitor_mid);
310+
311+ if (do_detach) {
312+ (*g_jvm)->DetachCurrentThread(g_jvm);
313+ }
314+
315+ return 0;
316+}
317+
318+static int usb_helper_scan_devices (struct libusb_context *ctx)
319+{
320+ JNIEnv* env;
321+ int res = 0;
322+ jint st;
323+ int do_detach = 0;
324+
325+ if (g_jvm == NULL) {
326+ return LIBUSB_ERROR_OTHER;
327+ }
328+ st = (*g_jvm)->GetEnv(g_jvm, (void **)&env, JNI_VERSION_1_6);
329+
330+ if (st == JNI_EDETACHED) {
331+ st = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
332+ do_detach = 1;
333+ }
334+
335+ if (st != JNI_OK) {
336+ return LIBUSB_ERROR_OTHER;
337+ }
338+
339+ jobject arr = (*env)->CallStaticObjectMethod(env, usb_helper_class, usb_helper_scan_devices_mid);
340+
341+ if (arr == NULL)
342+ res = LIBUSB_ERROR_OTHER;
343+ else {
344+ jsize i, len = (*env)->GetArrayLength(env, arr);
345+ for (i=0; i<len; i++) {
346+ jobject str = (*env)->GetObjectArrayElement(env, arr, i);
347+ if (str) {
348+ const char *ustr = (*env)->GetStringUTFChars(env, str, NULL);
349+ if (ustr) {
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);
355+ }
356+ (*env)->ReleaseStringUTFChars(env, str, ustr);
357+ } else
358+ res = LIBUSB_ERROR_OTHER;
359+ (*env)->DeleteLocalRef(env, str);
360+ } else
361+ res = LIBUSB_ERROR_OTHER;
362+ if (res)
363+ break;
364+ }
365+ (*env)->DeleteLocalRef(env, arr);
366+ }
367+
368+ if (do_detach) {
369+ (*g_jvm)->DetachCurrentThread(g_jvm);
370+ }
371+
e1dbb76d
MC
372+ return res;
373+}
c8cf030a
MC
374+
375+static void usb_helper_hotplug_poll(void)
376+{
377+}
378+
379+static void usb_helper_on_usb_device_action(JNIEnv *env, jobject self, jstring name, jboolean removed)
380+{
381+ usbi_mutex_static_lock(&linux_hotplug_lock);
382+ if (name) {
383+ const char *ustr = (*env)->GetStringUTFChars(env, name, NULL);
384+ if (ustr) {
385+ unsigned busnum, devaddr;
386+ if (2 == sscanf(ustr, "/dev/bus/usb/%u/%u",
387+ &busnum, &devaddr)) {
388+ if (removed)
389+ linux_device_disconnected(busnum, devaddr, NULL);
390+ else
391+ linux_hotplug_enumerate(busnum, devaddr, NULL);
392+ }
393+ (*env)->ReleaseStringUTFChars(env, name, ustr);
394+ }
395+ }
396+ usbi_mutex_static_unlock(&linux_hotplug_lock);
397+}
e1dbb76d 398+#endif