9
votes

I am trying to communicate with USB device from Android-based smartphone via OTG. I was able to communicate with my device using Android USB Host API. The problem of USB Host API solution is performance (single bulk transfer bounded by 16384 bytes).

The libusb can perform larger requests and now I am trying to integrate it using Android NDK. I succeeded to compile libusb sources for Android and even initUSB(), but libusb_open(dev, &dev_handle) returns -3 (Access denied).

How can I pass the file descriptor

int fd = connection.getFileDescriptor()

to libusb after getting USB_PERMISSION under Android USB Host API and get USB device access under libusb?

2
try this libusb fork github.com/martinmarinov/rtl_tcp_andro-/tree/master/jni/…. it has open2(, int fd) function for this4ntoine
vote to get good explanation from android team: code.google.com/p/android/issues/detail?id=564504ntoine

2 Answers

5
votes

This is what you are looking for.
https://github.com/kuldeepdhaka/libusb/tree/android-open2
just compile it and drop it in. :)
see the "How To for Android" section for full usage.

i made all the required modification to libusb (and im also using it).
It has SELinux fix for "Android 5.0"+ too.

2
votes

See also https://github.com/libusb/libusb/wiki/Android which now discusses android a little bit. Here is the quote from the proposed readme change (2021-02):

Runtime Permissions:
--------------------

The Runtime Permissions on Android can be transfered from Java to Native over the following approach:
 Java:
  // obtaining the Usb Permissions over the android.hardware.usb.UsbManager class
  usbManager = (UsbManager) getSystemService(Context.USB_SERVICE);
  HashMap<String, UsbDevice> deviceList = usbManager.getDeviceList();
  for (UsbDevice usbDevice : deviceList.values()) {   usbManager.requestPermission(usbDevice, mPermissionIntent); }
  // get the native FileDescriptor of the UsbDevice and transfer it to Native over JNI or JNA
  UsbDeviceConnection usbDeviceConnection = usbManager.openDevice(camDevice);
  int fileDescriptor = usbDeviceConnection.getFileDescriptor();
  // JNA sample method: 
  JNA.INSTANCE.set_the_native_Descriptor(fileDescriptor);  
 Native:
  // Initialize LibUsb on Android
  set_the_native_Descriptor(int fileDescriptor) {
   libusb_context *ctx;
   libusb_device_handle *devh;
   libusb_set_option(&ctx, LIBUSB_OPTION_WEAK_AUTHORITY, NULL);        // important for Android
   libusb_init(&ctx);
   libusb_wrap_sys_device(NULL, (intptr_t)fileDescriptor, &devh);

   //  From this point you can regulary use all LibUsb functions as usual.
  }