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

FTDI read() now waits until timeout

previously returned after periodic FTDI status response (default 16 msec)
This commit is contained in:
kai-morich 2020-09-05 12:00:37 +02:00
parent 80e8eb8a60
commit 6f4cd0313c
3 changed files with 38 additions and 26 deletions

View File

@ -1101,9 +1101,6 @@ public class DeviceTest {
@Test @Test
public void writeAsync() throws Exception { public void writeAsync() throws Exception {
if (usb.serialDriver instanceof FtdiSerialDriver)
return; // periodically sends status messages, so does not block here
byte[] data, buf = new byte[]{1}; byte[] data, buf = new byte[]{1};
// w/o timeout: write delayed until something is read // w/o timeout: write delayed until something is read
@ -1134,20 +1131,18 @@ public class DeviceTest {
@Test @Test
public void readTimeout() throws Exception { public void readTimeout() throws Exception {
if (usb.serialDriver instanceof FtdiSerialDriver)
return; // periodically sends status messages, so does not block here
final Boolean[] closed = {Boolean.FALSE}; final Boolean[] closed = {Boolean.FALSE};
Runnable closeThread = new Runnable() { Runnable closeThread = new Runnable() {
@Override @Override
public void run() { public void run() {
try { try {
Thread.sleep(100); Thread.sleep(100);
} catch (InterruptedException e) { } catch (InterruptedException e) {
e.printStackTrace(); e.printStackTrace();
} }
usb.close(); usb.close();
closed[0] = true; closed[0] = true;
} }
}; };
@ -1155,19 +1150,22 @@ public class DeviceTest {
usb.setParameters(19200, 8, 1, UsbSerialPort.PARITY_NONE); usb.setParameters(19200, 8, 1, UsbSerialPort.PARITY_NONE);
telnet.setParameters(19200, 8, 1, UsbSerialPort.PARITY_NONE); telnet.setParameters(19200, 8, 1, UsbSerialPort.PARITY_NONE);
byte[] buf = new byte[]{1}; byte[] writeBuf = new byte[]{1};
byte[] readBuf = new byte[1];
if (usb.serialDriver instanceof FtdiSerialDriver)
readBuf = new byte[3]; // include space for 2 header bytes
int len,i,j; int len,i,j;
long time; long time;
// w/o timeout // w/o timeout
telnet.write(buf); telnet.write(writeBuf);
len = usb.serialPort.read(buf, 0); // not blocking because data is available len = usb.serialPort.read(readBuf, 0); // not blocking because data is available
assertEquals(1, len); assertEquals(1, len);
time = System.currentTimeMillis(); time = System.currentTimeMillis();
closed[0] = false; closed[0] = false;
Executors.newSingleThreadExecutor().submit(closeThread); Executors.newSingleThreadExecutor().submit(closeThread);
len = usb.serialPort.read(buf, 0); // blocking until close() len = usb.serialPort.read(readBuf, 0); // blocking until close()
assertEquals(0, len); assertEquals(0, len);
assertTrue(System.currentTimeMillis()-time >= 100); assertTrue(System.currentTimeMillis()-time >= 100);
// wait for usbClose // wait for usbClose
@ -1185,7 +1183,7 @@ public class DeviceTest {
int longTimeout = 1000; int longTimeout = 1000;
int shortTimeout = 10; int shortTimeout = 10;
time = System.currentTimeMillis(); time = System.currentTimeMillis();
len = usb.serialPort.read(buf, shortTimeout); len = usb.serialPort.read(readBuf, shortTimeout);
assertEquals(0, len); assertEquals(0, len);
assertTrue(System.currentTimeMillis()-time < 100); assertTrue(System.currentTimeMillis()-time < 100);
@ -1193,9 +1191,10 @@ public class DeviceTest {
time = System.currentTimeMillis(); time = System.currentTimeMillis();
for(i=0; i<50; i++) { for(i=0; i<50; i++) {
Thread.sleep(10); Thread.sleep(10);
telnet.write(buf); telnet.write(writeBuf);
Log.d(TAG,"telnet write 1");
for(j=0; j<20; j++) { for(j=0; j<20; j++) {
len = usb.serialPort.read(buf, shortTimeout); len = usb.serialPort.read(readBuf, shortTimeout);
if (len > 0) if (len > 0)
break; break;
} }

View File

@ -158,15 +158,12 @@ public abstract class CommonUsbSerialPort implements UsbSerialPort {
} }
nread = buf.position(); nread = buf.position();
} }
if (nread > 0) { if (nread > 0)
return readFilter(dest, nread); return nread;
} else { else
return 0; return 0;
}
} }
protected int readFilter(final byte[] buffer, int len) throws IOException { return len; }
@Override @Override
public int write(final byte[] src, final int timeout) throws IOException { public int write(final byte[] src, final int timeout) throws IOException {
int offset = 0; int offset = 0;

View File

@ -136,7 +136,22 @@ public class FtdiSerialDriver implements UsbSerialDriver {
} }
@Override @Override
protected int readFilter(byte[] buffer, int totalBytesRead) throws IOException { public int read(final byte[] dest, final int timeout) throws IOException {
int nread;
if (timeout != 0) {
long endTime = System.currentTimeMillis() + timeout;
do {
nread = super.read(dest, Math.max(1, (int)(endTime - System.currentTimeMillis())));
} while (nread == READ_HEADER_LENGTH && System.currentTimeMillis() < endTime);
} else {
do {
nread = super.read(dest, timeout);
} while (nread == READ_HEADER_LENGTH);
}
return readFilter(dest, nread);
}
private int readFilter(byte[] buffer, int totalBytesRead) throws IOException {
final int maxPacketSize = mReadEndpoint.getMaxPacketSize(); final int maxPacketSize = mReadEndpoint.getMaxPacketSize();
int destPos = 0; int destPos = 0;
for(int srcPos = 0; srcPos < totalBytesRead; srcPos += maxPacketSize) { for(int srcPos = 0; srcPos < totalBytesRead; srcPos += maxPacketSize) {
@ -146,6 +161,7 @@ public class FtdiSerialDriver implements UsbSerialDriver {
System.arraycopy(buffer, srcPos + READ_HEADER_LENGTH, buffer, destPos, length); System.arraycopy(buffer, srcPos + READ_HEADER_LENGTH, buffer, destPos, length);
destPos += length; destPos += length;
} }
//Log.d(TAG, "read filter " + totalBytesRead + " -> " + destPos);
return destPos; return destPos;
} }