6

I am currently trying to find a way to handle USB data transfer on an isochronous endpoint on my Android 3.2 tablet (Host Mode supported). After writing some prototype code, I noticed that in the constants file for USB_ENDPOINT_XFER_ISOC states that "Isochronous endpoint type (currently not supported)".

Is this possible without rooting the device? If so how would I go about doing this?

Ideally I was hoping to stay within the java API, but if this is possible only via the NDK I would have to pursue that instead. I also understand that there might be some USB bandwidth issues based on the following post: User mode USB isochronous transfer from device-to-host

Community
  • 1
  • 1
glyph5
  • 121
  • 1
  • 4

3 Answers3

7

I have written a Java class for USB isochronous data transfer under Android (or Linux): UsbIso

It uses JNA to access the USBFS API via IOCTL calls.

Christian d'Heureuse
  • 5,090
  • 1
  • 32
  • 28
  • Can you tell me how to determine what value to provide as `altSetting` for the function `setInterface`? – JellicleCat May 17 '16 at 22:09
  • 1
    @JellicleCat You can use `lsusb -v -d xxxx:xxxx` (Linux) or `USBView` (Windows) to list the device descriptor of your USB device. There you find the AlternateSetting values supported by the device. If you have Android 5.0 or newer, you can use UsbInterface.getAlternateSetting(). – Christian d'Heureuse May 18 '16 at 17:59
  • Thank you. I wonder if you could provide any advice on the "Device or resource busy" error message I get when trying to instantiate `UsbIso`. I have written up the details of this problem as a separate thread: http://stackoverflow.com/questions/37356148/android-app-device-or-resource-busy-when-accessing-usb-device-via-jna – JellicleCat May 20 '16 at 21:30
  • @Christian d'Heureuse, I am facing issue " com/sun/jna/android-arm/libjnidispatch.so) not found in resource path (.)" in above library integration. can you please help – Parth Apr 04 '17 at 12:54
  • 1
    @Parth You have to extract libjnidispatch.so from [android-arm.jar](https://github.com/java-native-access/jna/raw/master/lib/native/android-arm.jar) and add it to your Android project. – Christian d'Heureuse Apr 04 '17 at 19:22
  • Thanks @Christian d'Heureuse for solution. but after integrating program runs fine , but when i am trying to read data from external device (using connection.bulkTransfer() ) at that time this function retuning " -1" – Parth Apr 05 '17 at 10:31
  • Can you please explain steps how can i read. data from external device after calling setinterface()in Usblso. It will help me to debug issue. thanks in advance. – Parth Apr 05 '17 at 13:04
  • 1
    @Parth You can't use `bulkTransfer()` with isochronous endpoints. If you have a device that supports bulk transfers, you don't need `UsbIso`. But if you want to read from an isochronous endpoint, you have to use `UsbIso.getRequest()`. The steps are described in the API docs of `UsbIso` and `UsbIso.Request`. – Christian d'Heureuse Apr 05 '17 at 23:15
  • Thanks but still i am not clear.According to document Request req = usbIso.reapRequest(true) after that ".. process received data ...", here i have query regrading processing the data. from where i can get data . here i am getting request object, so from that object how can i get byte[] data? – Parth Apr 06 '17 at 04:47
  • if i use getPacketData (int packetNo, byte[] buf, int len); to retrieve data from external device, then how i can get parameters to pass in this function.? – Parth Apr 06 '17 at 05:03
  • @Parth getPacketCount() and getPacketActualLength(). – Christian d'Heureuse Apr 06 '17 at 20:59
  • @Christiand'Heureuse can you provide sample code for the use of UsbIso ? I see you have used it for usb webcams. Can you give code of one of the programs that you wrote for usb webcams ? – WSS Jun 07 '17 at 20:58
  • @user1917769 No, sorry, my code for accessing USB cameras is not yet ready for publication. I had to work on other things. I will probably finish and publish it some time in the future. – Christian d'Heureuse Jun 07 '17 at 21:29
  • I can't make it work in Android devices with arm64-v8a architectures. Almost all the ioctl's calls work properly but the one in reapRequest method (USBDEVFS_REAPURB), which returns error 14 (bad address), only in 64 bit architectures. I guess that the problem is in the PointerByReference, but I have no clue of how to solve it. Can you help me? – moictab Jul 18 '19 at 06:21
  • 1
    @moictab Peter Stoiber and Matthias Bläsing have modified UsbIso to work in 64 bit environments: [UsbIso64](https://github.com/Peter-St/Android-UVC-Camera/tree/master/app/src/main/java/humer/uvc_camera/UsbIso64) – Christian d'Heureuse Aug 04 '19 at 13:19
6

You "can" do it without root, I believe.

You'll need to do it all using some native C code interfacing with the USB device using USBFS. The big issue comes from the lack of documentation of linux's usbfs. Basically everything has to be done through ioctls. That said you do open a device as you would normally from Java. Then you pass the file descriptor from the USBDeviceConnection

Add to that you will need to parse all the USB descriptors yourself. You can get at them, again from the USBDeviceConnection. Jumping from descriptor to descriptor is simple finding the documentation for what each descriptor means is a MASSIVE headache but you can find most of the documentation on www.usb.org.

I've written most of the code that is required to do the parsing for audio devices and I got all the way up to trying to submit an isochronous transfer and then started getting errors.

After switching to libusb I discovered that the problem, in my case, was because the audio device also had HID controllers and the default driver was atatching to those and stealing all the bandwidth away from the isochronous transfer. Had I known this earlier I might have persevered with the non-root non-libusb method. As it was I did get isochronous transfers working through lib usb but it required a rooted device :(

At some point I'll go back to it.

In summary, I'm pretty sure its possible but its not gonna be easy!!

Goz
  • 61,365
  • 24
  • 124
  • 204
1

you can find a runnable Solution of the UsbIso 64 bit on my git hub repo: https://github.com/Peter-St/Android-UVC-Camera/tree/master/app/src/main/java/humer/uvc_camera/UsbIso64

You need all 5 files of the UsbIso64 folder and can use the USBIso like following:

USBIso usbIso64 = new USBIso(camDeviceConnection.getFileDescriptor(), packetsPerRequest, maxPacketSize, (byte) camStreamingEndpoint.getAddress());
usbIso64.preallocateRequests(activeUrbs);

usbdevice_fs_util.setInterface(camDeviceConnection.getFileDescriptor(), camStreamingInterface.getId(), altSetting);
usbIso64.submitUrbs();
// While loop //
USBIso.Request req = usbIso64.reapRequest(true);
req.initialize();
req.submit();

You can use this version of UsbIso with 32 and 64 bit devices.

So far,

Peter