++ if (res >= 0) {
++ /* Rewind so that descriptors can be read */
++ lseek(res, SEEK_SET, 0);
++ }
++
++ return res;
++}
++
++static int usb_helper_start_event_monitor(void)
++{
++ JNIEnv* env;
++ jint st;
++ int do_detach = 0;
++ int res = 0;
++ jobject usb_event_listener;
++
++ if (g_jvm == NULL) {
++ return LIBUSB_ERROR_OTHER;
++ }
++ st = (*g_jvm)->GetEnv(g_jvm, (void **)&env, JNI_VERSION_1_6);
++
++ if (st == JNI_EDETACHED) {
++ st = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
++ do_detach = 1;
++ }
++
++ if (st != JNI_OK) {
++ return LIBUSB_ERROR_OTHER;
++ }
++
++ usb_event_listener = (*env)->NewObject(env, usb_event_listener_class, usb_event_listener_init_mid);
++ if (usb_event_listener == NULL)
++ res = LIBUSB_ERROR_OTHER;
++ else {
++ (*env)->CallStaticVoidMethod(env, usb_helper_class, usb_helper_start_event_monitor_mid, usb_event_listener);
++ (*env)->DeleteLocalRef(env, usb_event_listener);
++ }
++
++ if (do_detach) {
++ (*g_jvm)->DetachCurrentThread(g_jvm);
++ }
++
++ return res;
++}
++
++static int usb_helper_stop_event_monitor(void)
++{
++ JNIEnv* env;
++ jint st;
++ int do_detach = 0;
++
++ if (g_jvm == NULL) {
++ return LIBUSB_ERROR_OTHER;
++ }
++ st = (*g_jvm)->GetEnv(g_jvm, (void **)&env, JNI_VERSION_1_6);
++
++ if (st == JNI_EDETACHED) {
++ st = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
++ do_detach = 1;
++ }
++
++ if (st != JNI_OK) {
++ return LIBUSB_ERROR_OTHER;
++ }
++
++ (*env)->CallStaticVoidMethod(env, usb_helper_class, usb_helper_stop_event_monitor_mid);
++
++ if (do_detach) {
++ (*g_jvm)->DetachCurrentThread(g_jvm);
++ }
++
++ return 0;
++}
++
++static int usb_helper_scan_devices (struct libusb_context *ctx)
++{
++ JNIEnv* env;
++ int res = 0;
++ jint st;
++ int do_detach = 0;
++
++ if (g_jvm == NULL) {
++ return LIBUSB_ERROR_OTHER;
++ }
++ st = (*g_jvm)->GetEnv(g_jvm, (void **)&env, JNI_VERSION_1_6);
++
++ if (st == JNI_EDETACHED) {
++ st = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
++ do_detach = 1;
++ }
++
++ if (st != JNI_OK) {
++ return LIBUSB_ERROR_OTHER;
++ }
++
++ jobject arr = (*env)->CallStaticObjectMethod(env, usb_helper_class, usb_helper_scan_devices_mid);
++
++ if (arr == NULL)
++ res = LIBUSB_ERROR_OTHER;
++ else {
++ jsize i, len = (*env)->GetArrayLength(env, arr);
++ for (i=0; i<len; i++) {
++ jobject str = (*env)->GetObjectArrayElement(env, arr, i);
++ if (str) {
++ const char *ustr = (*env)->GetStringUTFChars(env, str, NULL);
++ if (ustr) {
++ unsigned busnum, devaddr;
++ if (2 != sscanf(ustr, "/dev/bus/usb/%u/%u",
++ &busnum, &devaddr) ||
++ linux_enumerate_device(ctx, busnum, devaddr, NULL)) {
++ usbi_dbg("failed to enumerate device %s", ustr);
++ }
++ (*env)->ReleaseStringUTFChars(env, str, ustr);
++ } else
++ res = LIBUSB_ERROR_OTHER;
++ (*env)->DeleteLocalRef(env, str);
++ } else
++ res = LIBUSB_ERROR_OTHER;
++ if (res)
++ break;
++ }
++ (*env)->DeleteLocalRef(env, arr);
++ }
++
++ if (do_detach) {
++ (*g_jvm)->DetachCurrentThread(g_jvm);
++ }
++