diff --git a/usbSerialForAndroid/src/main/java/com/hoho/android/usbserial/driver/CdcAcmSerialDriver.java b/usbSerialForAndroid/src/main/java/com/hoho/android/usbserial/driver/CdcAcmSerialDriver.java index 88e297c..8efccd7 100644 --- a/usbSerialForAndroid/src/main/java/com/hoho/android/usbserial/driver/CdcAcmSerialDriver.java +++ b/usbSerialForAndroid/src/main/java/com/hoho/android/usbserial/driver/CdcAcmSerialDriver.java @@ -26,11 +26,9 @@ import android.hardware.usb.UsbDevice; import android.hardware.usb.UsbDeviceConnection; import android.hardware.usb.UsbEndpoint; import android.hardware.usb.UsbInterface; -import android.hardware.usb.UsbRequest; import android.util.Log; import java.io.IOException; -import java.nio.ByteBuffer; import java.util.Collections; import java.util.LinkedHashMap; import java.util.List; @@ -50,7 +48,6 @@ public class CdcAcmSerialDriver implements UsbSerialDriver { private final UsbDevice mDevice; private final UsbSerialPort mPort; - private UsbRequest mUsbRequest; public CdcAcmSerialDriver(UsbDevice device) { mDevice = device; @@ -73,8 +70,6 @@ public class CdcAcmSerialDriver implements UsbSerialDriver { private UsbInterface mDataInterface; private UsbEndpoint mControlEndpoint; - private UsbEndpoint mReadEndpoint; - private UsbEndpoint mWriteEndpoint; private int mControlIndex; @@ -266,78 +261,6 @@ public class CdcAcmSerialDriver implements UsbSerialDriver { } } - @Override - public int read(byte[] dest, int timeoutMillis) throws IOException { - if(mConnection == null) { - throw new IOException("Connection closed"); - } - final UsbRequest request = new UsbRequest(); - try { - request.initialize(mConnection, mReadEndpoint); - final ByteBuffer buf = ByteBuffer.wrap(dest); - if (!request.queue(buf, dest.length)) { - throw new IOException("Error queueing request"); - } - mUsbRequest = request; - final UsbRequest response = mConnection.requestWait(); - synchronized (this) { - mUsbRequest = null; - } - if (response == null) { - throw new IOException("Null response"); - } - - final int nread = buf.position(); - if (nread > 0) { - //Log.d(TAG, HexDump.dumpHexString(dest, 0, Math.min(32, dest.length))); - return nread; - } else { - return 0; - } - } finally { - mUsbRequest = null; - request.close(); - } - } - - @Override - public int write(byte[] src, int timeoutMillis) throws IOException { - // TODO(mikey): Nearly identical to FtdiSerial write. Refactor. - int offset = 0; - - if(mConnection == null) { - throw new IOException("Connection closed"); - } - while (offset < src.length) { - final int writeLength; - final int amtWritten; - - synchronized (mWriteBufferLock) { - final byte[] writeBuffer; - - writeLength = Math.min(src.length - offset, mWriteBuffer.length); - if (offset == 0) { - writeBuffer = src; - } else { - // bulkTransfer does not support offsets, make a copy. - System.arraycopy(src, offset, mWriteBuffer, 0, writeLength); - writeBuffer = mWriteBuffer; - } - - amtWritten = mConnection.bulkTransfer(mWriteEndpoint, writeBuffer, writeLength, - timeoutMillis); - } - if (amtWritten <= 0) { - throw new IOException("Error writing " + writeLength - + " bytes at offset " + offset + " length=" + src.length); - } - - Log.d(TAG, "Wrote amt=" + amtWritten + " attempted=" + writeLength); - offset += amtWritten; - } - return offset; - } - @Override public void setParameters(int baudRate, int dataBits, int stopBits, int parity) throws IOException { if(baudRate <= 0) { diff --git a/usbSerialForAndroid/src/main/java/com/hoho/android/usbserial/driver/Ch34xSerialDriver.java b/usbSerialForAndroid/src/main/java/com/hoho/android/usbserial/driver/Ch34xSerialDriver.java index 0c21001..c6870b8 100644 --- a/usbSerialForAndroid/src/main/java/com/hoho/android/usbserial/driver/Ch34xSerialDriver.java +++ b/usbSerialForAndroid/src/main/java/com/hoho/android/usbserial/driver/Ch34xSerialDriver.java @@ -25,11 +25,8 @@ import android.hardware.usb.UsbDevice; import android.hardware.usb.UsbDeviceConnection; import android.hardware.usb.UsbEndpoint; import android.hardware.usb.UsbInterface; -import android.hardware.usb.UsbRequest; -import android.util.Log; import java.io.IOException; -import java.nio.ByteBuffer; import java.util.Collections; import java.util.LinkedHashMap; import java.util.List; @@ -83,10 +80,6 @@ public class Ch34xSerialDriver implements UsbSerialDriver { private boolean dtr = false; private boolean rts = false; - private UsbEndpoint mReadEndpoint; - private UsbEndpoint mWriteEndpoint; - private UsbRequest mUsbRequest; - public Ch340SerialPort(UsbDevice device, int portNumber) { super(device, portNumber); } @@ -155,78 +148,6 @@ public class Ch34xSerialDriver implements UsbSerialDriver { } } - - @Override - public int read(byte[] dest, int timeoutMillis) throws IOException { - if(mConnection == null) { - throw new IOException("Connection closed"); - } - final UsbRequest request = new UsbRequest(); - try { - request.initialize(mConnection, mReadEndpoint); - final ByteBuffer buf = ByteBuffer.wrap(dest); - if (!request.queue(buf, dest.length)) { - throw new IOException("Error queueing request"); - } - mUsbRequest = request; - final UsbRequest response = mConnection.requestWait(); - synchronized (this) { - mUsbRequest = null; - } - if (response == null) { - throw new IOException("Null response"); - } - - final int nread = buf.position(); - if (nread > 0) { - //Log.d(TAG, HexDump.dumpHexString(dest, 0, Math.min(32, dest.length))); - return nread; - } else { - return 0; - } - } finally { - mUsbRequest = null; - request.close(); - } - } - - @Override - public int write(byte[] src, int timeoutMillis) throws IOException { - int offset = 0; - - if(mConnection == null) { - throw new IOException("Connection closed"); - } - while (offset < src.length) { - final int writeLength; - final int amtWritten; - - synchronized (mWriteBufferLock) { - final byte[] writeBuffer; - - writeLength = Math.min(src.length - offset, mWriteBuffer.length); - if (offset == 0) { - writeBuffer = src; - } else { - // bulkTransfer does not support offsets, make a copy. - System.arraycopy(src, offset, mWriteBuffer, 0, writeLength); - writeBuffer = mWriteBuffer; - } - - amtWritten = mConnection.bulkTransfer(mWriteEndpoint, writeBuffer, writeLength, - timeoutMillis); - } - if (amtWritten <= 0) { - throw new IOException("Error writing " + writeLength - + " bytes at offset " + offset + " length=" + src.length); - } - - Log.d(TAG, "Wrote amt=" + amtWritten + " attempted=" + writeLength); - offset += amtWritten; - } - return offset; - } - private int controlOut(int request, int value, int index) { final int REQTYPE_HOST_TO_DEVICE = 0x41; return mConnection.controlTransfer(REQTYPE_HOST_TO_DEVICE, request, diff --git a/usbSerialForAndroid/src/main/java/com/hoho/android/usbserial/driver/CommonUsbSerialPort.java b/usbSerialForAndroid/src/main/java/com/hoho/android/usbserial/driver/CommonUsbSerialPort.java index 8323535..cc9797c 100644 --- a/usbSerialForAndroid/src/main/java/com/hoho/android/usbserial/driver/CommonUsbSerialPort.java +++ b/usbSerialForAndroid/src/main/java/com/hoho/android/usbserial/driver/CommonUsbSerialPort.java @@ -23,8 +23,12 @@ package com.hoho.android.usbserial.driver; import android.hardware.usb.UsbDevice; import android.hardware.usb.UsbDeviceConnection; +import android.hardware.usb.UsbEndpoint; +import android.hardware.usb.UsbRequest; +import android.util.Log; import java.io.IOException; +import java.nio.ByteBuffer; /** * A base class shared by several driver implementations. @@ -33,16 +37,19 @@ import java.io.IOException; */ public abstract class CommonUsbSerialPort implements UsbSerialPort { - public static final int DEFAULT_WRITE_BUFFER_SIZE = 16 * 1024; + private static final String TAG = CommonUsbSerialPort.class.getSimpleName(); + private static final int DEFAULT_WRITE_BUFFER_SIZE = 16 * 1024; protected final UsbDevice mDevice; protected final int mPortNumber; // non-null when open() protected UsbDeviceConnection mConnection = null; + protected UsbEndpoint mReadEndpoint; + protected UsbEndpoint mWriteEndpoint; + protected UsbRequest mUsbRequest; protected final Object mWriteBufferLock = new Object(); - /** Internal write buffer. Guarded by {@link #mWriteBufferLock}. */ protected byte[] mWriteBuffer; @@ -52,7 +59,7 @@ public abstract class CommonUsbSerialPort implements UsbSerialPort { mWriteBuffer = new byte[DEFAULT_WRITE_BUFFER_SIZE]; } - + @Override public String toString() { return String.format("<%s device_name=%s device_id=%s port_number=%s>", @@ -105,10 +112,76 @@ public abstract class CommonUsbSerialPort implements UsbSerialPort { public abstract void close() throws IOException; @Override - public abstract int read(final byte[] dest, final int timeoutMillis) throws IOException; + public int read(final byte[] dest, final int timeoutMillis) throws IOException { + if(mConnection == null) { + throw new IOException("Connection closed"); + } + final UsbRequest request = new UsbRequest(); + try { + request.initialize(mConnection, mReadEndpoint); + final ByteBuffer buf = ByteBuffer.wrap(dest); + if (!request.queue(buf, dest.length)) { + throw new IOException("Error queueing request"); + } + mUsbRequest = request; + final UsbRequest response = mConnection.requestWait(); + synchronized (this) { + mUsbRequest = null; + } + if (response == null) { + throw new IOException("Null response"); + } + final int nread = buf.position(); + if (nread > 0) { + return readFilter(dest, nread); + } else { + return 0; + } + } finally { + mUsbRequest = null; + request.close(); + } + } + + protected int readFilter(final byte[] buffer, int len) throws IOException { return len; } @Override - public abstract int write(final byte[] src, final int timeoutMillis) throws IOException; + public int write(final byte[] src, final int timeoutMillis) throws IOException { + int offset = 0; + + if(mConnection == null) { + throw new IOException("Connection closed"); + } + while (offset < src.length) { + final int writeLength; + final int amtWritten; + + synchronized (mWriteBufferLock) { + final byte[] writeBuffer; + + writeLength = Math.min(src.length - offset, mWriteBuffer.length); + if (offset == 0) { + writeBuffer = src; + } else { + // bulkTransfer does not support offsets, make a copy. + System.arraycopy(src, offset, mWriteBuffer, 0, writeLength); + writeBuffer = mWriteBuffer; + } + + amtWritten = mConnection.bulkTransfer(mWriteEndpoint, writeBuffer, writeLength, + timeoutMillis); + } + if (amtWritten <= 0) { + throw new IOException("Error writing " + writeLength + + " bytes at offset " + offset + " length=" + src.length); + } + + Log.d(TAG, "Wrote amt=" + amtWritten + " attempted=" + writeLength); + offset += amtWritten; + } + return offset; + } + @Override public abstract void setParameters(int baudRate, int dataBits, int stopBits, int parity) throws IOException; diff --git a/usbSerialForAndroid/src/main/java/com/hoho/android/usbserial/driver/Cp21xxSerialDriver.java b/usbSerialForAndroid/src/main/java/com/hoho/android/usbserial/driver/Cp21xxSerialDriver.java index 4b84ca2..a148b43 100644 --- a/usbSerialForAndroid/src/main/java/com/hoho/android/usbserial/driver/Cp21xxSerialDriver.java +++ b/usbSerialForAndroid/src/main/java/com/hoho/android/usbserial/driver/Cp21xxSerialDriver.java @@ -26,11 +26,8 @@ import android.hardware.usb.UsbDevice; import android.hardware.usb.UsbDeviceConnection; import android.hardware.usb.UsbEndpoint; import android.hardware.usb.UsbInterface; -import android.hardware.usb.UsbRequest; -import android.util.Log; import java.io.IOException; -import java.nio.ByteBuffer; import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; @@ -106,10 +103,6 @@ public class Cp21xxSerialDriver implements UsbSerialDriver { private static final int CONTROL_WRITE_DTR = 0x0100; private static final int CONTROL_WRITE_RTS = 0x0200; - private UsbEndpoint mReadEndpoint; - private UsbEndpoint mWriteEndpoint; - private UsbRequest mUsbRequest; - // second port of Cp2105 has limited baudRate, dataBits, stopBits, parity // unsupported baudrate returns error at controlTransfer(), other parameters are silently ignored private boolean mIsRestrictedPort; @@ -195,77 +188,6 @@ public class Cp21xxSerialDriver implements UsbSerialDriver { } } - @Override - public int read(byte[] dest, int timeoutMillis) throws IOException { - if(mConnection == null) { - throw new IOException("Connection closed"); - } - final UsbRequest request = new UsbRequest(); - try { - request.initialize(mConnection, mReadEndpoint); - final ByteBuffer buf = ByteBuffer.wrap(dest); - if (!request.queue(buf, dest.length)) { - throw new IOException("Error queueing request"); - } - mUsbRequest = request; - final UsbRequest response = mConnection.requestWait(); - synchronized (this) { - mUsbRequest = null; - } - if (response == null) { - throw new IOException("Null response"); - } - - final int nread = buf.position(); - if (nread > 0) { - //Log.d(TAG, HexDump.dumpHexString(dest, 0, Math.min(32, dest.length))); - return nread; - } else { - return 0; - } - } finally { - mUsbRequest = null; - request.close(); - } - } - - @Override - public int write(byte[] src, int timeoutMillis) throws IOException { - int offset = 0; - - if(mConnection == null) { - throw new IOException("Connection closed"); - } - while (offset < src.length) { - final int writeLength; - final int amtWritten; - - synchronized (mWriteBufferLock) { - final byte[] writeBuffer; - - writeLength = Math.min(src.length - offset, mWriteBuffer.length); - if (offset == 0) { - writeBuffer = src; - } else { - // bulkTransfer does not support offsets, make a copy. - System.arraycopy(src, offset, mWriteBuffer, 0, writeLength); - writeBuffer = mWriteBuffer; - } - - amtWritten = mConnection.bulkTransfer(mWriteEndpoint, writeBuffer, writeLength, - timeoutMillis); - } - if (amtWritten <= 0) { - throw new IOException("Error writing " + writeLength - + " bytes at offset " + offset + " length=" + src.length); - } - - Log.d(TAG, "Wrote amt=" + amtWritten + " attempted=" + writeLength); - offset += amtWritten; - } - return offset; - } - private void setBaudRate(int baudRate) throws IOException { byte[] data = new byte[] { (byte) ( baudRate & 0xff), diff --git a/usbSerialForAndroid/src/main/java/com/hoho/android/usbserial/driver/FtdiSerialDriver.java b/usbSerialForAndroid/src/main/java/com/hoho/android/usbserial/driver/FtdiSerialDriver.java index 2a90a04..e0162c3 100644 --- a/usbSerialForAndroid/src/main/java/com/hoho/android/usbserial/driver/FtdiSerialDriver.java +++ b/usbSerialForAndroid/src/main/java/com/hoho/android/usbserial/driver/FtdiSerialDriver.java @@ -24,12 +24,9 @@ package com.hoho.android.usbserial.driver; import android.hardware.usb.UsbConstants; import android.hardware.usb.UsbDevice; import android.hardware.usb.UsbDeviceConnection; -import android.hardware.usb.UsbEndpoint; -import android.hardware.usb.UsbRequest; import android.util.Log; import java.io.IOException; -import java.nio.ByteBuffer; import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; @@ -196,31 +193,32 @@ public class FtdiSerialDriver implements UsbSerialDriver { /** * Filter FTDI status bytes from buffer - * @param src The source buffer (which contains status bytes) - * @param dest The destination buffer to write the status bytes into (can be src) + * @param buffer The source buffer (which contains status bytes) + * buffer The destination buffer to write the status bytes into (can be src) * @param totalBytesRead Number of bytes read to src - * @param maxPacketSize The USB endpoint max packet size * @return The number of payload bytes */ - private final int filterStatusBytes(byte[] src, byte[] dest, int totalBytesRead, int maxPacketSize) { + @Override + protected int readFilter(byte[] buffer, int totalBytesRead) throws IOException { + if (totalBytesRead < MODEM_STATUS_HEADER_LENGTH) { + throw new IOException("Expected at least " + MODEM_STATUS_HEADER_LENGTH + " bytes"); + } + int maxPacketSize = mReadEndpoint.getMaxPacketSize(); final int packetsCount = (totalBytesRead + maxPacketSize -1 )/ maxPacketSize; for (int packetIdx = 0; packetIdx < packetsCount; ++packetIdx) { final int count = (packetIdx == (packetsCount - 1)) ? totalBytesRead - packetIdx * maxPacketSize - MODEM_STATUS_HEADER_LENGTH : maxPacketSize - MODEM_STATUS_HEADER_LENGTH; if (count > 0) { - System.arraycopy(src, - packetIdx * maxPacketSize + MODEM_STATUS_HEADER_LENGTH, - dest, - packetIdx * (maxPacketSize - MODEM_STATUS_HEADER_LENGTH), - count); + System.arraycopy(buffer, packetIdx * maxPacketSize + MODEM_STATUS_HEADER_LENGTH, + buffer, packetIdx * (maxPacketSize - MODEM_STATUS_HEADER_LENGTH), + count); } } - - return totalBytesRead - (packetsCount * 2); + return totalBytesRead - (packetsCount * 2); } - public void reset() throws IOException { + void reset() throws IOException { // TODO(mikey): autodetect. mType = DeviceType.TYPE_R; if(mDevice.getInterfaceCount() > 1) { @@ -252,6 +250,12 @@ public class FtdiSerialDriver implements UsbSerialDriver { } else { throw new IOException("Error claiming interface " + mPortNumber); } + if (mDevice.getInterface(mPortNumber).getEndpointCount() < 2) { + throw new IOException("Insufficient number of endpoints (" + + mDevice.getInterface(mPortNumber).getEndpointCount() + ")"); + } + mReadEndpoint = mDevice.getInterface(mPortNumber).getEndpoint(0); + mWriteEndpoint = mDevice.getInterface(mPortNumber).getEndpoint(1); reset(); opened = true; } finally { @@ -276,75 +280,6 @@ public class FtdiSerialDriver implements UsbSerialDriver { } } - @Override - public int read(byte[] dest, int timeoutMillis) throws IOException { - if(mConnection == null) { - throw new IOException("Connection closed"); - } - final UsbEndpoint endpoint = mDevice.getInterface(mPortNumber).getEndpoint(0); - final UsbRequest request = new UsbRequest(); - final ByteBuffer buf = ByteBuffer.wrap(dest); - try { - request.initialize(mConnection, endpoint); - if (!request.queue(buf, dest.length)) { - throw new IOException("Error queueing request"); - } - - final UsbRequest response = mConnection.requestWait(); - if (response == null) { - throw new IOException("Null response"); - } - } finally { - request.close(); - } - - final int totalBytesRead = buf.position(); - if (totalBytesRead < MODEM_STATUS_HEADER_LENGTH) { - throw new IOException("Expected at least " + MODEM_STATUS_HEADER_LENGTH + " bytes"); - } - - return filterStatusBytes(dest, dest, totalBytesRead, endpoint.getMaxPacketSize()); - } - - @Override - public int write(byte[] src, int timeoutMillis) throws IOException { - if(mConnection == null) { - throw new IOException("Connection closed"); - } - final UsbEndpoint endpoint = mDevice.getInterface(mPortNumber).getEndpoint(1); - int offset = 0; - - while (offset < src.length) { - final int writeLength; - final int amtWritten; - - synchronized (mWriteBufferLock) { - final byte[] writeBuffer; - - writeLength = Math.min(src.length - offset, mWriteBuffer.length); - if (offset == 0) { - writeBuffer = src; - } else { - // bulkTransfer does not support offsets, make a copy. - System.arraycopy(src, offset, mWriteBuffer, 0, writeLength); - writeBuffer = mWriteBuffer; - } - - amtWritten = mConnection.bulkTransfer(endpoint, writeBuffer, writeLength, - timeoutMillis); - } - - if (amtWritten <= 0) { - throw new IOException("Error writing " + writeLength - + " bytes at offset " + offset + " length=" + src.length); - } - - Log.d(TAG, "Wrote amtWritten=" + amtWritten + " attempted=" + writeLength); - offset += amtWritten; - } - return offset; - } - private int setBaudRate(int baudRate) throws IOException { long[] vals = convertBaudrate(baudRate); long actualBaudrate = vals[0]; diff --git a/usbSerialForAndroid/src/main/java/com/hoho/android/usbserial/driver/ProlificSerialDriver.java b/usbSerialForAndroid/src/main/java/com/hoho/android/usbserial/driver/ProlificSerialDriver.java index 29d5f0f..ba084ad 100644 --- a/usbSerialForAndroid/src/main/java/com/hoho/android/usbserial/driver/ProlificSerialDriver.java +++ b/usbSerialForAndroid/src/main/java/com/hoho/android/usbserial/driver/ProlificSerialDriver.java @@ -32,12 +32,10 @@ import android.hardware.usb.UsbDevice; import android.hardware.usb.UsbDeviceConnection; import android.hardware.usb.UsbEndpoint; import android.hardware.usb.UsbInterface; -import android.hardware.usb.UsbRequest; import android.util.Log; import java.io.IOException; import java.lang.reflect.Method; -import java.nio.ByteBuffer; import java.util.Collections; import java.util.LinkedHashMap; import java.util.List; @@ -111,8 +109,6 @@ public class ProlificSerialDriver implements UsbSerialDriver { private int mDeviceType = DEVICE_TYPE_HX; - private UsbEndpoint mReadEndpoint; - private UsbEndpoint mWriteEndpoint; private UsbEndpoint mInterruptEndpoint; private int mControlLinesValue = 0; @@ -370,74 +366,6 @@ public class ProlificSerialDriver implements UsbSerialDriver { } } - @Override - public int read(byte[] dest, int timeoutMillis) throws IOException { - if(mConnection == null) { - throw new IOException("Connection closed"); - } - final UsbRequest request = new UsbRequest(); - try { - request.initialize(mConnection, mReadEndpoint); - final ByteBuffer buf = ByteBuffer.wrap(dest); - if (!request.queue(buf, dest.length)) { - throw new IOException("Error queueing request"); - } - - final UsbRequest response = mConnection.requestWait(); - if (response == null) { - throw new IOException("Null response"); - } - - final int nread = buf.position(); - if (nread > 0) { - //Log.d(TAG, HexDump.dumpHexString(dest, 0, Math.min(32, dest.length))); - return nread; - } else { - return 0; - } - } finally { - request.close(); - } - } - - @Override - public int write(byte[] src, int timeoutMillis) throws IOException { - int offset = 0; - - if(mConnection == null) { - throw new IOException("Connection closed"); - } - while (offset < src.length) { - final int writeLength; - final int amtWritten; - - synchronized (mWriteBufferLock) { - final byte[] writeBuffer; - - writeLength = Math.min(src.length - offset, mWriteBuffer.length); - if (offset == 0) { - writeBuffer = src; - } else { - // bulkTransfer does not support offsets, make a copy. - System.arraycopy(src, offset, mWriteBuffer, 0, writeLength); - writeBuffer = mWriteBuffer; - } - - amtWritten = mConnection.bulkTransfer(mWriteEndpoint, - writeBuffer, writeLength, timeoutMillis); - } - - if (amtWritten <= 0) { - throw new IOException("Error writing " + writeLength - + " bytes at offset " + offset + " length=" - + src.length); - } - - offset += amtWritten; - } - return offset; - } - @Override public void setParameters(int baudRate, int dataBits, int stopBits, int parity) throws IOException { if ((mBaudRate == baudRate) && (mDataBits == dataBits)