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
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.
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!!
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
Related
I want to send and recevice data between .NET application and Android Device by using USB. However, due to the security concerns, I do not desire to use Android Debug Bridge (USB debugging).
Is there any possible way to send and receive data from Android Device to my .NET application on computer by using USB ?
Thanks in advance.
There are many ways to skin this particular cat, let me name two:
Simple message files via MTP. Pro: Easiest to implement and widest possible client support. Con: High latency. Good, if you have few requests with a bigish payload each.
USB networking via CDC-ECM. Pro: Allows easy extension to full networking. Con: Not so broad client suppoort. Good, if you have full control over the hardware.
The prevalent problem is, that the fragmentation of Android allows you to assume only a very low baseline.
I do recommend, that you revisit the encrypted network connection option: It should be quite trivial to create a minimal network consisting only of the Android device and a single partner - e.g. by pluging a WLAN access point directly into a secondary network interface of the workstation - and by being associated to a special WLAN you make sure, that the device at this point is not connected to a different WLAN or mobile network.
This will not only be easiest, but also give you the best starting point if you want to upgrade to a broader network later on.
I am trying to use the android host api for USB storage. I have many doubts regarding same.
What all things are possible using host api. I want to see the content of USB and if possible so the normal file operation. I didnt find any documentation help regarding this.
I am able to claimInterface using UsbDeviceConnection class API but I'm unable to understand how the bulkTransfer works so if anyone can guide me or give some reference I will try myself.
I tried reading the USB specification also, I understood how bulkTransfer works at USB level but unable to relate how android/java file operations are possible using bulkTransfer which using UsbEndpoint not the File Descriptor.
Thanks in Advance !!
The Android USB Host APIs do not include USB Mass Storage filesystem code, nor as of this writing in 2014 will "stock" Android mount a USB Mass Storage volume at operating system level.
To access a USB Mass Storage device using the stock Android USB Host APIs, you must therefore implement in your Application code both the necessary raw-USB operations to achieve block-level device access, and the appropriate filesystem logic itself. Needless to say, the details of such are of a complexity beyond the scope of an answer here, but you could start by studying documentation or existing implementations of USB Mass Storage drivers and filesystem drivers for other platforms.
It appears the situation in Android 6 may be different, and access via the USB host apis to something that version recognizes as a storage device might even no longer be permitted. Those targeting Android 6+ may need to look elsewhere, but older devices will remain in use for some time.
I am trying to use the Android USB Host API in order to achieve native USB speeds (on the order of Mbps). I've seen some examples online that use some constants to set up baud rates of 9600. However, I would like to use bulk transfers and control transfers (as necessary, I'm not really sure about how these work, and which constants to use) in order to achieve native USB speeds. Is there any way to do this, and if so, does anyone have some sample code that they would be willing to share? Thanks!
Note: I've also rooted my Android Nexus 7 tablet just in case. I figured that since apps like StickMount need root access, root might be necessary to achieve native USB speeds.
I know that the latest versions of Android (Honeycomb and ICS) have support for joysticks and gamepads.
Guitar Hero (and Garage Band) controllers are essentially USB HID devices, right?
So my question:
Is that possible to receive data (button clicks) from the Guitar Hero (or Rock Band) controllers on Android device?
Would the Android understand it as a gamepad input?
P.S. all I need is to detect in my game the input from those five buttons on the plastic guitar fret.
A good starting point would be to review the linux source code for Frets On Fire, which supports some of the Guitar Hero controllers.
Frets on Fire: SourceForge
SVN: https://fretsonfire.svn.sourceforge.net/svnroot/fretsonfire
It looks like it would be difficult to universally support all controllers, from different platforms. Each console has it's own protocol, but it does look like JoyStick to keyboard emulation is possible on the PC with the PS3 controller. There is a config file for the PS3 controller on the second link that may be helpful, it's for JoyToKey (which isn't open source), but some of the values in the config may help you.
Hey this is a really cool idea. start here:
http://developer.android.com/guide/topics/usb/host.html
Then, check out this sample:
http://developer.android.com/resources/samples/USB/MissileLauncher/index.html
in that sample, there is a method named setDevice(UsbDevice device)
If I were implementing this, I would start with a duplicate of the MissileLauncher project, and modify this setDevice method. I would log everything I could possible find about the UsbDevice device and try experimenting with these conditionals in the setDevice method:
if (ep.getType() != UsbConstants.USB_ENDPOINT_XFER_INT) {
...
if (intf.getEndpointCount() != 1) {
While the MissileLauncher uses this type and this endpointCount, it is very likely the garageband controller will have different values
ALSO
check out the run method to see an example of back and forth communication
DISCLAIMER: I have no idea if this will work. I've also seen blogs stating this cannot be done.
My guess is it should detect data. This is even possible on existing Android devices - but it is not Android Market friendly.
To accomplish this on non-4.0 devices you must provide an alternative power source to the usb port. Usually this can be done with a cheap usb hub that leaks power. The device also must be rooted. Once this is complete you need to create an interface to the device shell to launch a native language like C outside of your Dalvik VM. Use your C to bind to the appropriate socket and you should be able to bus data back and forth. You may also need to compile a kernel module to give driver support.
Like I said this is a complete hack for device below 4.0. But it is possible.
What classes are available for Android platform to communicate (in/out) with external MIDI device? I have HTC Desire smartphone, it has USB port, I'd assume it is possible to connect it to a MIDI synthesizer, using standard USB cable + [Type A -> Mini A] converter. I'd like to write a MIDI sequencer app that would be able to record MIDI stream from the synthesizer and then play it back later.
Short answer: None. Slightly longer answer: On the HTC Desire there is no built-in support for USB host mode (which you need, since the usb-midi adapter would be the USB client).
(Android 3.1 does have some support for USB Host mode, but that's not available for the HTC Desire)
If you're not afraid of a soldering iron, you could go the midi-over-bluetooth route: http://nettoyeur.noisepages.com/2011/01/midi-over-bluetooth-part-iii-new-hardware/
Much has changed on this front. The following library allows for MIDI i/o with a USB OTG adapter on API 12+:
https://github.com/kshoji/USB-MIDI-Driver
It's far from perfect, and in my testing, pretty crashy, but it should at least be a good starting point for someone looking for the relevant classes.
As #edovino said, you need USB host mode, and then drivers.
If you don't mind rooting around your phone, and the hardware supports it, you do have some options. Check out this link: http://sven.killig.de/android/N1/2.2/usb_host/
This guy was able to get audio, video, keyboard, and some other stuff working. He includes audio/MIDI drivers.
Yes, as pointed above, it is not feasible using the phone because it does not provide USB-host capability. I have been working religiously over the past few months to make an XY-controller for my synthesizer so that I can transmit controller values to use for performances. I reckon, that is what you want to do with additional functionality.
Bluetooth is definitely an option and if you look up for libpd, Peter Brinkmann himself has addressed this issue and acknowledged that Bluetooth dongles for MIDI are not far away.
WiFi is also something one may be willing to look at. Using rtpMIDI, we can create sessions on the PC side of things and use just about any WiFI enabled MIDI device to transmit/receive data. IF you are looking to control software synthesizers using a phone, this seems ideal. TouchDAW and TouchOSC, applications on android, make use of this feature.
With the USB-Android driver, the only problem I see is no support for isochronous transfers using USB host. So, we cannot guarantee latency deterministic. But, considering no other bus accessories attached, the performance seems pretty decent in my tests.