Android USB Host Communication
I hate to answer my own question but... I got it figured out. I was just mixing up my reads and writes. Additionally the device didn't like the '\n' I was using at the end of my commands. It appears to get along with '\r' much better.
I ended up using android's bulkTransfer for reads and writes. My writes looked like this.
try { device.getWriter().write(command + "\r"); device.getWriter().flush(); } catch (IOException e) { throw new RuntimeException(e); }
And my overridden write method for my BufferedWriter:
@Override
public void write(char[] buf, int offset, int count) throws IOException { byte[] buffer = new String(buf, offset, count).getBytes(Charset.forName("US-ASCII")); int byteCount = connection.bulkTransfer(endpoint, buffer, buffer.length, TIMEOUT); }
The reads were similar:
char[] buffer = new char[BUF_SIZE]; try { BufferedReader reader = device.getReader(); int readBytes = reader.read(buffer); Log.d(TAG, "BYTES READ: " + readBytes); } catch (IOException e) { throw new RuntimeException(e); } String strBuf = new String(buffer).trim(); if (DEBUG) { Log.d(TAG, "Read: " + strBuf); }
And:
@Override public int read(char[] buf, int offset, int count) throws IOException { byte[] buffer = new byte[count]; int byteCount = connection.bulkTransfer(endpoint, buffer, buffer.length, TIMEOUT); if (byteCount < 0) { throw new IOException(); } char[] charBuffer = new String(buffer, Charset.forName("US-ASCII")).toCharArray(); System.arraycopy(charBuffer, 0, buf, offset, byteCount); return byteCount; }
This was all just kicked off in a thread like so:
new Thread() { @Overridepublic void run() { String command = "go"; write(command); while (true) { String coords = read(); }}}.start();
Obviously this is just the comm stuff and I'll need to now do something with it (put it in a Service that can report back to a top level UI Activity using a handler). But this part of it is figured out.
A huge thank you to the folks who are working on rosjava (http://code.google.com/p/rosjava/)... They have put together a lot of great projects and their code was very helpful.
Adding my device class to help clarify things.
import com.google.common.base.Preconditions;import android.hardware.usb.UsbConstants;import android.hardware.usb.UsbDeviceConnection;import android.hardware.usb.UsbEndpoint;import android.hardware.usb.UsbInterface;import android.util.Log;import java.io.BufferedReader;import java.io.BufferedWriter;/* This class represents a USB device that supports the adb protocol. */public class BKDevice {// private static final int TIMEOUT = 3000;private final UsbDeviceConnection usbDeviceConnection;private final BufferedReader reader;private final BufferedWriter writer;public static final String TAG = "AcmDevice";public BKDevice(UsbDeviceConnection usbDeviceConnection, UsbInterface usbInterface) { Preconditions.checkState(usbDeviceConnection.claimInterface( usbInterface, true)); this.usbDeviceConnection = usbDeviceConnection; UsbEndpoint epOut = null; UsbEndpoint epIn = null; // look for our bulk endpoints for (int i = 0; i < usbInterface.getEndpointCount(); i++) { UsbEndpoint ep = usbInterface.getEndpoint(i); Log.d(TAG, "EP " + i + ": " + ep.getType()); if (ep.getType() == UsbConstants.USB_ENDPOINT_XFER_BULK) { if (ep.getDirection() == UsbConstants.USB_DIR_OUT) { epOut = ep; } else if (ep.getDirection() == UsbConstants.USB_DIR_IN) { epIn = ep; } } } if (epOut == null || epIn == null) { throw new IllegalArgumentException("Not all endpoints found."); } BKReader acmReader = new BKReader(usbDeviceConnection, epIn); BKWriter acmWriter = new BKWriter(usbDeviceConnection, epOut); reader = new BufferedReader(acmReader); writer = new BufferedWriter(acmWriter);}public BufferedReader getReader() { return reader;}public BufferedWriter getWriter() { return writer;}}
Adding BKReader code:
import android.hardware.usb.UsbDeviceConnection;import android.hardware.usb.UsbEndpoint;import android.util.Log;import java.io.IOException;import java.io.Reader;import java.nio.charset.Charset;public class BKReader extends Reader { private static final int TIMEOUT = 1000; private final UsbDeviceConnection connection; private final UsbEndpoint endpoint; public BKReader(UsbDeviceConnection connection, UsbEndpoint endpoint) { this.connection = connection; this.endpoint = endpoint; } @Override public int read(char[] buf, int offset, int count) throws IOException { byte[] buffer = new byte[count]; int byteCount = connection.bulkTransfer(endpoint, buffer, buffer.length, TIMEOUT); if (byteCount < 0) { throw new IOException(); } char[] charBuffer = new String(buffer, Charset.forName("US-ASCII")).toCharArray(); System.arraycopy(charBuffer, 0, buf, offset, byteCount); return byteCount; } @Override public void close() throws IOException { }}