1
0
mirror of https://github.com/mik3y/usb-serial-for-android synced 2025-06-08 00:16:13 +00:00

Merge pull request #170 from kai-morich/ftdi-async

enable async read for FTDI + prevent loss of last packet if full
This commit is contained in:
kai-morich 2019-10-04 16:49:03 +02:00 committed by GitHub
commit eb2de17af8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -26,6 +26,7 @@ import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbDeviceConnection; import android.hardware.usb.UsbDeviceConnection;
import android.hardware.usb.UsbEndpoint; import android.hardware.usb.UsbEndpoint;
import android.hardware.usb.UsbRequest; import android.hardware.usb.UsbRequest;
import android.os.Build;
import android.util.Log; import android.util.Log;
import com.hoho.android.usbserial.util.HexDump; import com.hoho.android.usbserial.util.HexDump;
@ -190,10 +191,11 @@ public class FtdiSerialDriver implements UsbSerialDriver {
* since it gives no indication of number of bytes read. Set this to * since it gives no indication of number of bytes read. Set this to
* {@code true} on platforms where it is fixed. * {@code true} on platforms where it is fixed.
*/ */
private static final boolean ENABLE_ASYNC_READS = false; private final boolean mEnableAsyncReads;
public FtdiSerialPort(UsbDevice device, int portNumber) { public FtdiSerialPort(UsbDevice device, int portNumber) {
super(device, portNumber); super(device, portNumber);
mEnableAsyncReads = (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1);
} }
@Override @Override
@ -210,10 +212,10 @@ public class FtdiSerialDriver implements UsbSerialDriver {
* @return The number of payload bytes * @return The number of payload bytes
*/ */
private final int filterStatusBytes(byte[] src, byte[] dest, int totalBytesRead, int maxPacketSize) { private final int filterStatusBytes(byte[] src, byte[] dest, int totalBytesRead, int maxPacketSize) {
final int packetsCount = totalBytesRead / maxPacketSize + (totalBytesRead % maxPacketSize == 0 ? 0 : 1); final int packetsCount = (totalBytesRead + maxPacketSize -1 )/ maxPacketSize;
for (int packetIdx = 0; packetIdx < packetsCount; ++packetIdx) { for (int packetIdx = 0; packetIdx < packetsCount; ++packetIdx) {
final int count = (packetIdx == (packetsCount - 1)) final int count = (packetIdx == (packetsCount - 1))
? (totalBytesRead % maxPacketSize) - MODEM_STATUS_HEADER_LENGTH ? totalBytesRead - packetIdx * maxPacketSize - MODEM_STATUS_HEADER_LENGTH
: maxPacketSize - MODEM_STATUS_HEADER_LENGTH; : maxPacketSize - MODEM_STATUS_HEADER_LENGTH;
if (count > 0) { if (count > 0) {
System.arraycopy(src, System.arraycopy(src,
@ -280,33 +282,30 @@ public class FtdiSerialDriver implements UsbSerialDriver {
public int read(byte[] dest, int timeoutMillis) throws IOException { public int read(byte[] dest, int timeoutMillis) throws IOException {
final UsbEndpoint endpoint = mDevice.getInterface(0).getEndpoint(0); final UsbEndpoint endpoint = mDevice.getInterface(0).getEndpoint(0);
if (ENABLE_ASYNC_READS) { if (mEnableAsyncReads) {
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(); final UsbRequest request = new UsbRequest();
request.initialize(mConnection, endpoint);
final ByteBuffer buf = ByteBuffer.wrap(dest); final ByteBuffer buf = ByteBuffer.wrap(dest);
if (!request.queue(buf, readAmt)) { try {
throw new IOException("Error queueing request."); 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 UsbRequest response = mConnection.requestWait(); final int totalBytesRead = buf.position();
if (response == null) { if (totalBytesRead < MODEM_STATUS_HEADER_LENGTH) {
throw new IOException("Null response"); throw new IOException("Expected at least " + MODEM_STATUS_HEADER_LENGTH + " bytes");
} }
final int payloadBytesRead = buf.position() - MODEM_STATUS_HEADER_LENGTH; return filterStatusBytes(dest, dest, totalBytesRead, endpoint.getMaxPacketSize());
if (payloadBytesRead > 0) {
Log.d(TAG, HexDump.dumpHexString(dest, 0, Math.min(32, dest.length)));
return payloadBytesRead;
} else {
return 0;
}
} else { } else {
final int totalBytesRead; final int totalBytesRead;