8

I am fairly new to Android Development and i have recently been exploring Usb Host.

Would anyone be able to tell me how to use Bulk Transfer so that i can see what an external camera sees but instead show it on my tablet?

Camera : Canon Powershot A1300 Tablet : Iconia A200

I have looked around stack overflow and some other forums but have not yet been able to find a good explanation on how to use Bulk Transfer or what constants to use as parameters for retrieving certain data.

I am able to see the endpoints and set up a connection with the external camera but I do not know where to go from here.

Any help is deeply appreciated.

Rachael
  • 1,965
  • 4
  • 29
  • 55

1 Answers1

16

The USB Host APIs in Android are fairly thin, by which I mean once you have gone beyond enumerating the interfaces/endpoints and creating a connection it doesn't do much more to assist you. You are then in the realm of communicating with raw USB data transfers, the format of which depend on the device class your camera represents. Your request is somewhat a can of worms, so I will do my best to provide helpful resources.

Unfortunately, storage and media devices are not the simplest device classes to interpret, so it may be difficult if you are just getting your feet wet on USB in general. The best advice I can give is to take a look at the device class specs for the interface class your camera reports (most are either Mass Storage or MTP), which can be found here: http://www.usb.org/developers/devclass_docs

The spec document will enumerate the commands you need to use to communicate with the device. I would also recommend checking out USB In a Nutshell, which does a great job of pointing out how USB requests are constructed in general, which can help you map what you see in a the spec docs to the parameters found in the methods of UsbDeviceConnection: http://www.beyondlogic.org/usbnutshell/usb1.shtml

There will likely be a handful of control commands you need to send to "endpoint 0" initially to set up the camera, and then the remaining transfers will likely take place over the bulk endpoints.

In Android terms, control requests can only be sent synchronously using UsbDeviceConnection.controlTransfer(), meaning this method blocks until the transfer is complete. The parameters that fill in this method are found in the spec docs for your device class.

Requests on bulk endpoints can be sent synchronously via UsbDeviceConnection.bulkTransfer() OR asynchronously using a UsbRequest instance. With UsbRequest you can queue a transfer and then later check back (via UsbDeviceConnection.requestWait()) for the results.

I have some examples on my Github page in using the host APIs to do some basic interrupt and control transfers to get information like device descriptors. Perhaps some of that will be helpful to you as well: https://github.com/devunwired/accessory-samples


With regards to your question about the USB example code:

The request made in this code is just a generic "Get Configuration Descriptor" request that all USB devices must respond to (it's a core command, not class-specific). In fact, its the request where the Android APIs get the information you can query for interfaces and endpoints. The field values come from the Core USB Specification (this command specifically is defined at section 9.4.3 and 9.6.3 in the 3.0 spec): http://www.usb.org/developers/docs/ or a more helpful description you can find from USB in a Nutshell, which has a little more discussion: http://www.beyondlogic.org/usbnutshell/usb5.shtml#ConfigurationDescriptors

The length is somewhat arbitrary, this tells the driver how many bytes to read or write. Most USB host drivers will first query the device descriptor, which includes a field telling the host the Max Packet Size the device supports, and then will use that size as the length for future requests. A full-featured driver would probably make this command and then check the length bytes first (the wTotalLength field of the descriptor) to see if the buffer was large enough, and modify/resend if not. In the example, I just chose 64 for simplicity because that is the "maximum" Max Packet Size the protocol defines as supportable.

Again, then making requests of the specific data your device has to offer, those commands will be found in the specific class document, not the core specification.

devunwired
  • 62,780
  • 12
  • 127
  • 139
  • I have peeked around the beyondlogic site before and had a little trouble interpreting a lot of it and wasn't able to find a relation to the android part of it. I found that the device is considered to be public static final int USB_CLASS_STILL_IMAGE I will delve into the spec pdf now and see what i can find! Thanks again, (hopefully I won't get stuck!) – dave sunderland Dec 22 '12 at 15:16
  • I am having a little trouble finding the usefulness of the standard device requests since they all seem to just give metadata for the device. Am I reading this incorrectly? I jotted down the class,subclass, and protocol codes and the respective endpoint data but have yet to discover any relevant command for sending what the camera sees to the device. – dave sunderland Dec 22 '12 at 16:33
  • This information is what you will find included in the device class specification documents. Still Image is listed on the site I linked, or here is a direct link to that class document. Specifically, Section 7 talks about the workflow for working with the image capture: http://www.usb.org/developers/devclass_docs/usb_still_img10.pdf – devunwired Dec 24 '12 at 03:50
  • Devunwired, looking again at your source code for USB https://github.com/devunwired/accessory-samples/blob/master/UsbMonitor/src/com/example/UsbMonitor/USBActivity.java Where did you find the length, value, and buffer etc for this specific command of getDeviceStatus ? This seems to be the last piece of my puzzle, thank you for your direction and links thus far! – dave sunderland Dec 29 '12 at 16:56
  • I've updated the answer with some more information in this regard. – devunwired Dec 30 '12 at 22:26
  • Hi @Devunwired I have tried your library https://github.com/androidthings/sample-usbenum. It works for me when I try to connect the External USB device with Tablet. However, I am getting only the max length of the data. Can you help me how can I get the data instead of length? – Janmejoy Jul 03 '19 at 10:36