Increase default read/write buffer sizes; allow tuning.
This commit is contained in:
parent
c5e9955b01
commit
b328f3cbc9
|
@ -1,7 +1,6 @@
|
|||
package com.hoho.android.usbserial.driver;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
|
@ -21,8 +20,6 @@ public class CdcAcmSerialDriver extends UsbSerialDriver {
|
|||
|
||||
private final String TAG = CdcAcmSerialDriver.class.getSimpleName();
|
||||
|
||||
private final byte[] mReadBuffer = new byte[4096];
|
||||
|
||||
private UsbInterface mControlInterface;
|
||||
private UsbInterface mDataInterface;
|
||||
|
||||
|
@ -96,47 +93,55 @@ public class CdcAcmSerialDriver extends UsbSerialDriver {
|
|||
|
||||
@Override
|
||||
public int read(byte[] dest, int timeoutMillis) throws IOException {
|
||||
int readAmt = Math.min(dest.length, mReadBuffer.length);
|
||||
readAmt = Math.min(readAmt, mReadEndpoint.getMaxPacketSize());
|
||||
final int transferred = mConnection.bulkTransfer(mReadEndpoint, mReadBuffer, readAmt,
|
||||
timeoutMillis);
|
||||
|
||||
if (transferred < 0) {
|
||||
// This sucks: we get -1 on timeout, not 0 as preferred.
|
||||
// We *should* use UsbRequest, except it has a bug/api oversight
|
||||
// where there is no way to determine the number of bytes read
|
||||
// in response :\ -- http://b.android.com/28023
|
||||
return 0;
|
||||
final int numBytesRead;
|
||||
synchronized (mReadBufferLock) {
|
||||
int readAmt = Math.min(dest.length, mReadBuffer.length);
|
||||
readAmt = Math.min(readAmt, mReadEndpoint.getMaxPacketSize());
|
||||
numBytesRead = mConnection.bulkTransfer(mReadEndpoint, mReadBuffer, readAmt,
|
||||
timeoutMillis);
|
||||
if (numBytesRead < 0) {
|
||||
// This sucks: we get -1 on timeout, not 0 as preferred.
|
||||
// We *should* use UsbRequest, except it has a bug/api oversight
|
||||
// where there is no way to determine the number of bytes read
|
||||
// in response :\ -- http://b.android.com/28023
|
||||
return 0;
|
||||
}
|
||||
System.arraycopy(mReadBuffer, 0, dest, 0, numBytesRead);
|
||||
}
|
||||
System.arraycopy(mReadBuffer, 0, dest, 0, transferred);
|
||||
return transferred;
|
||||
return numBytesRead;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int write(byte[] src, int timeoutMillis) throws IOException {
|
||||
// TODO(mikey): Nearly identical to FtdiSerial write. Refactor.
|
||||
int offset = 0;
|
||||
final int chunksize = mWriteEndpoint.getMaxPacketSize();
|
||||
|
||||
while (offset < src.length) {
|
||||
final byte[] writeBuffer;
|
||||
final int writeLength;
|
||||
final int amtWritten;
|
||||
|
||||
// bulkTransfer does not support offsets; make a copy if necessary.
|
||||
writeLength = Math.min(src.length - offset, chunksize);
|
||||
if (offset == 0) {
|
||||
writeBuffer = src;
|
||||
} else {
|
||||
writeBuffer = Arrays.copyOfRange(src, offset, offset + writeLength);
|
||||
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);
|
||||
}
|
||||
|
||||
final int amt = mConnection.bulkTransfer(mWriteEndpoint, writeBuffer, writeLength,
|
||||
timeoutMillis);
|
||||
if (amt <= 0) {
|
||||
if (amtWritten <= 0) {
|
||||
throw new IOException("Error writing " + writeLength
|
||||
+ " bytes at offset " + offset + " length=" + src.length);
|
||||
}
|
||||
Log.d(TAG, "Wrote amt=" + amt + " attempted=" + writeBuffer.length);
|
||||
offset += amt;
|
||||
|
||||
Log.d(TAG, "Wrote amt=" + amtWritten + " attempted=" + writeLength);
|
||||
offset += amtWritten;
|
||||
}
|
||||
return offset;
|
||||
}
|
||||
|
|
|
@ -22,7 +22,6 @@ package com.hoho.android.usbserial.driver;
|
|||
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.Arrays;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
|
@ -38,8 +37,8 @@ import com.hoho.android.usbserial.util.HexDump;
|
|||
/**
|
||||
* A {@link UsbSerialDriver} implementation for a variety of FTDI devices
|
||||
* <p>
|
||||
* This driver is based on <a
|
||||
* href="http://www.intra2net.com/en/developer/libftdi">libftdi</a>, and is
|
||||
* This driver is based on
|
||||
* <a href="http://www.intra2net.com/en/developer/libftdi">libftdi</a>, and is
|
||||
* copyright and subject to the following terms:
|
||||
*
|
||||
* <pre>
|
||||
|
@ -142,11 +141,6 @@ public class FtdiSerialDriver extends UsbSerialDriver {
|
|||
public static final int FTDI_DEVICE_IN_REQTYPE =
|
||||
UsbConstants.USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_IN;
|
||||
|
||||
/**
|
||||
* Size of chunks, used in {@link #write(byte[], int)}.
|
||||
*/
|
||||
private static final int WRITE_CHUNKSIZE = 4096;
|
||||
|
||||
/**
|
||||
* Length of the modem status header, transmitted with every read.
|
||||
*/
|
||||
|
@ -156,8 +150,6 @@ public class FtdiSerialDriver extends UsbSerialDriver {
|
|||
|
||||
private DeviceType mType;
|
||||
|
||||
private final byte[] mReadBuffer = new byte[4096];
|
||||
|
||||
/**
|
||||
* FTDI chip types.
|
||||
*/
|
||||
|
@ -228,10 +220,15 @@ public class FtdiSerialDriver extends UsbSerialDriver {
|
|||
|
||||
@Override
|
||||
public int read(byte[] dest, int timeoutMillis) throws IOException {
|
||||
final int readAmt = Math.min(dest.length, mReadBuffer.length);
|
||||
final UsbEndpoint endpoint = mDevice.getInterface(0).getEndpoint(0);
|
||||
|
||||
if (ENABLE_ASYNC_READS) {
|
||||
final int readAmt;
|
||||
synchronized (mReadBufferLock) {
|
||||
// mReadBuffer is only used for maximum read size.
|
||||
readAmt = Math.min(dest.length, mReadBuffer.length);
|
||||
}
|
||||
|
||||
final UsbRequest request = new UsbRequest();
|
||||
request.initialize(mConnection, endpoint);
|
||||
|
||||
|
@ -245,27 +242,32 @@ public class FtdiSerialDriver extends UsbSerialDriver {
|
|||
throw new IOException("Null response");
|
||||
}
|
||||
|
||||
final int nread = buf.position() - MODEM_STATUS_HEADER_LENGTH;
|
||||
if (nread > 0) {
|
||||
final int payloadBytesRead = buf.position() - MODEM_STATUS_HEADER_LENGTH;
|
||||
if (payloadBytesRead > 0) {
|
||||
Log.d(TAG, HexDump.dumpHexString(dest, 0, Math.min(32, dest.length)));
|
||||
return nread;
|
||||
return payloadBytesRead;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
final int transferred = mConnection.bulkTransfer(endpoint, mReadBuffer, readAmt,
|
||||
timeoutMillis);
|
||||
if (transferred < MODEM_STATUS_HEADER_LENGTH) {
|
||||
final int totalBytesRead;
|
||||
|
||||
synchronized (mReadBufferLock) {
|
||||
final int readAmt = Math.min(dest.length, mReadBuffer.length);
|
||||
totalBytesRead = mConnection.bulkTransfer(endpoint, mReadBuffer,
|
||||
readAmt, timeoutMillis);
|
||||
}
|
||||
|
||||
if (totalBytesRead < MODEM_STATUS_HEADER_LENGTH) {
|
||||
throw new IOException("Expected at least " + MODEM_STATUS_HEADER_LENGTH + " bytes");
|
||||
}
|
||||
|
||||
final int nread = transferred - MODEM_STATUS_HEADER_LENGTH;
|
||||
if (nread > 0) {
|
||||
System.arraycopy(mReadBuffer, MODEM_STATUS_HEADER_LENGTH, dest, 0, nread);
|
||||
final int payloadBytesRead = totalBytesRead - MODEM_STATUS_HEADER_LENGTH;
|
||||
if (payloadBytesRead > 0) {
|
||||
System.arraycopy(mReadBuffer, MODEM_STATUS_HEADER_LENGTH, dest, 0, payloadBytesRead);
|
||||
}
|
||||
return nread;
|
||||
return payloadBytesRead;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -274,25 +276,32 @@ public class FtdiSerialDriver extends UsbSerialDriver {
|
|||
int offset = 0;
|
||||
|
||||
while (offset < src.length) {
|
||||
final byte[] writeBuffer;
|
||||
final int writeLength;
|
||||
final int amtWritten;
|
||||
|
||||
// bulkTransfer does not support offsets; make a copy if necessary.
|
||||
writeLength = Math.min(src.length - offset, WRITE_CHUNKSIZE);
|
||||
if (offset == 0) {
|
||||
writeBuffer = src;
|
||||
} else {
|
||||
writeBuffer = Arrays.copyOfRange(src, offset, offset + writeLength);
|
||||
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);
|
||||
}
|
||||
|
||||
final int amt = mConnection.bulkTransfer(endpoint, writeBuffer, writeLength,
|
||||
timeoutMillis);
|
||||
if (amt <= 0) {
|
||||
if (amtWritten <= 0) {
|
||||
throw new IOException("Error writing " + writeLength
|
||||
+ " bytes at offset " + offset + " length=" + src.length);
|
||||
}
|
||||
Log.d(TAG, "Wrote amt=" + amt + " attempted=" + writeBuffer.length);
|
||||
offset += amt;
|
||||
|
||||
Log.d(TAG, "Wrote amtWritten=" + amtWritten + " attempted=" + writeLength);
|
||||
offset += amtWritten;
|
||||
}
|
||||
return offset;
|
||||
}
|
||||
|
|
|
@ -32,12 +32,27 @@ import android.hardware.usb.UsbDeviceConnection;
|
|||
*/
|
||||
public abstract class UsbSerialDriver {
|
||||
|
||||
public static final int DEFAULT_READ_BUFFER_SIZE = 16 * 1024;
|
||||
public static final int DEFAULT_WRITE_BUFFER_SIZE = 16 * 1024;
|
||||
|
||||
protected final UsbDevice mDevice;
|
||||
protected final UsbDeviceConnection mConnection;
|
||||
|
||||
protected final Object mReadBufferLock = new Object();
|
||||
protected final Object mWriteBufferLock = new Object();
|
||||
|
||||
/** Internal read buffer. Guarded by {@link #mReadBufferLock}. */
|
||||
protected byte[] mReadBuffer;
|
||||
|
||||
/** Internal write buffer. Guarded by {@link #mWriteBufferLock}. */
|
||||
protected byte[] mWriteBuffer;
|
||||
|
||||
public UsbSerialDriver(UsbDevice device, UsbDeviceConnection connection) {
|
||||
mDevice = device;
|
||||
mConnection = connection;
|
||||
|
||||
mReadBuffer = new byte[DEFAULT_READ_BUFFER_SIZE];
|
||||
mWriteBuffer = new byte[DEFAULT_WRITE_BUFFER_SIZE];
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -93,4 +108,34 @@ public abstract class UsbSerialDriver {
|
|||
return mDevice;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the size of the internal buffer used to exchange data with the USB
|
||||
* stack for read operations. Most users should not need to change this.
|
||||
*
|
||||
* @param bufferSize the size in bytes
|
||||
*/
|
||||
public final void setReadBufferSize(int bufferSize) {
|
||||
synchronized (mReadBufferLock) {
|
||||
if (bufferSize == mReadBuffer.length) {
|
||||
return;
|
||||
}
|
||||
mReadBuffer = new byte[bufferSize];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the size of the internal buffer used to exchange data with the USB
|
||||
* stack for write operations. Most users should not need to change this.
|
||||
*
|
||||
* @param bufferSize the size in bytes
|
||||
*/
|
||||
public final void setWriteBufferSize(int bufferSize) {
|
||||
synchronized (mWriteBufferLock) {
|
||||
if (bufferSize == mWriteBuffer.length) {
|
||||
return;
|
||||
}
|
||||
mWriteBuffer = new byte[bufferSize];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue