Android USB Host API: bulk transfer buffer size

syntagma picture syntagma · Jun 5, 2012 · Viewed 17.8k times · Source

I am writing software to communicate between tablet (Motorola Xoom with Android version 4.0.3 and Kernel version 2.6.39.4) and a peripheral device using USB Host API provided by Android. I use only two types of communication:

  • control: controlTransfer(int requestType, int request, int value, int index, byte[] buffer, int length, int timeout)
  • bulk: bulkTransfer(UsbEndpoint endpoint, byte[] buffer, int length, int timeout)

Control transfer works fine, but I have a problem with bulk transfer. I can use only 32768 as a size of the buffer for bulkTransfer function. It is not possible to use less or more. I know that I cannot use more because of the limit of the buffer pipe (size: 32769 bytes).

This peripheral device streams data which is not correctly read by bulkTranfer function. I suppose that some data is lost.

I find this: In Linux If a process attempts to read from an empty pipe (buffer), then read(2) will block until data is available. If a process attempts to write to a full pipe , then write(2) blocks until sufficient data has been read from the pipe to allow the write to complete.

And based on that, my explanation of the problem is that some data is not written to pipe (buffer) because of blocking flag made by write(2) function. Am I correct? If this is true I could change pipe buffer.

  1. My first solution for this problem is greater buffer. For kernel >= 2.6.35, you can change the size of a pipe with fcntl(fd, F_SETPIPE_SZ, size) but how can I find fd (file descriptor) for USB pipes?
  2. Second option is to use ulimit -p SIZE but parameter p for my kernel is not for pipe but process.

Has anyone faced the same problem, any solutions?

Answer

FabianCook picture FabianCook · Jun 13, 2012

You should get a USB data analyzer, Im using this one: http://www.ellisys.com/products/usbex200/index.php

Using something like this really helped me when I was doing the same type of thing, what I found was that you had to do some type of while loop.

For my device I had 64 bytes of data coming in packets to me, the packet would be two control bytes and 62 for data, so for my transfer I had to do something like

StringBuilder sb = new StringBuilder();
while(bulkTransfer(UsbEndpoint endpoint, byte[] buffer, int length, int timeout) > 2){
    for(int i = 2; i < buffer.length(); i++){
        sb.append((char) buffer[i]);
    }
}

something a long these lines worked good for me, i had exactly the same issue and this is how I fixed it. I have more information if you need it. Just comment :). I know this was really frustrating for me to. Im using an Acer Iconia A500 with Android 4.0.3 btw


Transferring larger amounts of data USB

Transferring data USB