mirror of
https://github.com/mik3y/usb-serial-for-android
synced 2025-09-02 05:31:34 +00:00
write + purge tests, remove unused read buffer code
This commit is contained in:
parent
5c6748e1b8
commit
e1b62cf675
@ -25,6 +25,7 @@ import android.util.Log;
|
|||||||
|
|
||||||
import com.hoho.android.usbserial.driver.CdcAcmSerialDriver;
|
import com.hoho.android.usbserial.driver.CdcAcmSerialDriver;
|
||||||
import com.hoho.android.usbserial.driver.Ch34xSerialDriver;
|
import com.hoho.android.usbserial.driver.Ch34xSerialDriver;
|
||||||
|
import com.hoho.android.usbserial.driver.CommonUsbSerialPort;
|
||||||
import com.hoho.android.usbserial.driver.Cp21xxSerialDriver;
|
import com.hoho.android.usbserial.driver.Cp21xxSerialDriver;
|
||||||
import com.hoho.android.usbserial.driver.FtdiSerialDriver;
|
import com.hoho.android.usbserial.driver.FtdiSerialDriver;
|
||||||
import com.hoho.android.usbserial.driver.ProbeTable;
|
import com.hoho.android.usbserial.driver.ProbeTable;
|
||||||
@ -222,6 +223,33 @@ public class DeviceTest implements SerialInputOutputManager.Listener {
|
|||||||
telnetClient = null;
|
telnetClient = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class TestBuffer {
|
||||||
|
private byte[] buf;
|
||||||
|
private int len;
|
||||||
|
|
||||||
|
private TestBuffer(int length) {
|
||||||
|
len = 0;
|
||||||
|
buf = new byte[length];
|
||||||
|
int i=0;
|
||||||
|
int j=0;
|
||||||
|
for(j=0; j<length/16; j++)
|
||||||
|
for(int k=0; k<16; k++)
|
||||||
|
buf[i++]=(byte)j;
|
||||||
|
while(i<length)
|
||||||
|
buf[i++]=(byte)j;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean testRead(byte[] data) {
|
||||||
|
assertNotEquals(0, data.length);
|
||||||
|
assertTrue("got " + (len+data.length) +" bytes", (len+data.length) <= buf.length);
|
||||||
|
for(int j=0; j<data.length; j++)
|
||||||
|
assertEquals("at pos "+(len+j), (byte)((len+j)/16), data[j]);
|
||||||
|
len += data.length;
|
||||||
|
//Log.d(TAG, "read " + len);
|
||||||
|
return len == buf.length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// wait full time
|
// wait full time
|
||||||
private byte[] telnetRead() throws Exception {
|
private byte[] telnetRead() throws Exception {
|
||||||
return telnetRead(-1);
|
return telnetRead(-1);
|
||||||
@ -229,7 +257,7 @@ public class DeviceTest implements SerialInputOutputManager.Listener {
|
|||||||
|
|
||||||
private byte[] telnetRead(int expectedLength) throws Exception {
|
private byte[] telnetRead(int expectedLength) throws Exception {
|
||||||
long end = System.currentTimeMillis() + TELNET_READ_WAIT;
|
long end = System.currentTimeMillis() + TELNET_READ_WAIT;
|
||||||
ByteBuffer buf = ByteBuffer.allocate(8192);
|
ByteBuffer buf = ByteBuffer.allocate(65536);
|
||||||
while(System.currentTimeMillis() < end) {
|
while(System.currentTimeMillis() < end) {
|
||||||
if(telnetReadStream.available() > 0) {
|
if(telnetReadStream.available() > 0) {
|
||||||
buf.put((byte) telnetReadStream.read());
|
buf.put((byte) telnetReadStream.read());
|
||||||
@ -337,14 +365,11 @@ public class DeviceTest implements SerialInputOutputManager.Listener {
|
|||||||
} else {
|
} else {
|
||||||
byte[] b1 = new byte[256];
|
byte[] b1 = new byte[256];
|
||||||
while (System.currentTimeMillis() < end) {
|
while (System.currentTimeMillis() < end) {
|
||||||
int len = usbSerialPort.read(b1, USB_READ_WAIT / 10);
|
int len = usbSerialPort.read(b1, USB_READ_WAIT);
|
||||||
if (len > 0) {
|
if (len > 0)
|
||||||
buf.put(b1, 0, len);
|
buf.put(b1, 0, len);
|
||||||
} else {
|
if (expectedLength >= 0 && buf.position() >= expectedLength)
|
||||||
if (expectedLength >= 0 && buf.position() >= expectedLength)
|
break;
|
||||||
break;
|
|
||||||
Thread.sleep(1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
byte[] data = new byte[buf.position()];
|
byte[] data = new byte[buf.position()];
|
||||||
@ -907,6 +932,85 @@ public class DeviceTest implements SerialInputOutputManager.Listener {
|
|||||||
assertEquals(availableDrivers.get(0).getClass(), usbSerialDriver.getClass());
|
assertEquals(availableDrivers.get(0).getClass(), usbSerialDriver.getClass());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void writeTimeout() throws Exception {
|
||||||
|
usbOpen(true);
|
||||||
|
usbParameters(115200, 8, 1, UsbSerialPort.PARITY_NONE);
|
||||||
|
telnetParameters(115200, 8, 1, UsbSerialPort.PARITY_NONE);
|
||||||
|
|
||||||
|
// Basically all devices have a UsbEndpoint.getMaxPacketSize() 64. When the timeout
|
||||||
|
// in usbSerialPort.write() is reached, some packets have been written and the rest
|
||||||
|
// is discarded. bulkTransfer() does not return the number written so far, but -1.
|
||||||
|
// With 115200 baud and 1/2 second timeout, typical values are:
|
||||||
|
// ch340 6080 of 6144
|
||||||
|
// pl2302 5952 of 6144
|
||||||
|
// cp2102 6400 of 7168
|
||||||
|
// cp2105 6272 of 7168
|
||||||
|
// ft232 5952 of 6144
|
||||||
|
// ft2232 9728 of 10240
|
||||||
|
// arduino 128 of 144
|
||||||
|
int timeout = 500;
|
||||||
|
int len = 0;
|
||||||
|
int startLen = 1024;
|
||||||
|
int step = 1024;
|
||||||
|
int minLen = 4069;
|
||||||
|
int maxLen = 12288;
|
||||||
|
int bufferSize = 997;
|
||||||
|
TestBuffer buf = new TestBuffer(len);
|
||||||
|
if(usbSerialDriver instanceof CdcAcmSerialDriver) {
|
||||||
|
startLen = 16;
|
||||||
|
step = 16;
|
||||||
|
minLen = 128;
|
||||||
|
maxLen = 256;
|
||||||
|
bufferSize = 31;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
for (len = startLen; len < maxLen; len += step) {
|
||||||
|
buf = new TestBuffer(len);
|
||||||
|
Log.d(TAG, "write buffer size " + len);
|
||||||
|
usbSerialPort.write(buf.buf, timeout);
|
||||||
|
while (!buf.testRead(telnetRead(-1)))
|
||||||
|
;
|
||||||
|
}
|
||||||
|
fail("write timeout expected between " + minLen + " and " + maxLen + ", is " + len);
|
||||||
|
} catch (IOException e) {
|
||||||
|
Log.d(TAG, "usbWrite failed", e);
|
||||||
|
while (true) {
|
||||||
|
byte[] data = telnetRead(-1);
|
||||||
|
if (data.length == 0) break;
|
||||||
|
if (buf.testRead(data)) break;
|
||||||
|
}
|
||||||
|
Log.d(TAG, "received " + buf.len + " of " + len + " bytes of failing usbWrite");
|
||||||
|
assertTrue("write timeout expected between " + minLen + " and " + maxLen + ", is " + len, len > minLen);
|
||||||
|
}
|
||||||
|
|
||||||
|
// With smaller writebuffer, the timeout is used per bulkTransfer.
|
||||||
|
// Should further calls only use the remaining timout?
|
||||||
|
((CommonUsbSerialPort) usbSerialPort).setWriteBufferSize(bufferSize);
|
||||||
|
len = maxLen;
|
||||||
|
buf = new TestBuffer(len);
|
||||||
|
Log.d(TAG, "write buffer size " + len);
|
||||||
|
usbSerialPort.write(buf.buf, timeout);
|
||||||
|
while (!buf.testRead(telnetRead(-1)))
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void writeFragments() throws Exception {
|
||||||
|
usbOpen(true);
|
||||||
|
usbParameters(115200, 8, 1, UsbSerialPort.PARITY_NONE);
|
||||||
|
telnetParameters(115200, 8, 1, UsbSerialPort.PARITY_NONE);
|
||||||
|
|
||||||
|
((CommonUsbSerialPort) usbSerialPort).setWriteBufferSize(12);
|
||||||
|
((CommonUsbSerialPort) usbSerialPort).setWriteBufferSize(12); // keeps last buffer
|
||||||
|
TestBuffer buf = new TestBuffer(256);
|
||||||
|
usbSerialPort.write(buf.buf, 5000);
|
||||||
|
while (!buf.testRead(telnetRead(-1)))
|
||||||
|
;
|
||||||
|
// todo: deduplicate write method, use bulkTransfer with offset
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
// provoke data loss, when data is not read fast enough
|
// provoke data loss, when data is not read fast enough
|
||||||
public void readBufferOverflow() throws Exception {
|
public void readBufferOverflow() throws Exception {
|
||||||
@ -1077,6 +1181,7 @@ public class DeviceTest implements SerialInputOutputManager.Listener {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void purgeHwBuffers() throws Exception {
|
public void purgeHwBuffers() throws Exception {
|
||||||
|
// purge write buffer
|
||||||
// 2400 is slowest baud rate for isCp21xxRestrictedPort
|
// 2400 is slowest baud rate for isCp21xxRestrictedPort
|
||||||
usbOpen(true);
|
usbOpen(true);
|
||||||
usbParameters(2400, 8, 1, UsbSerialPort.PARITY_NONE);
|
usbParameters(2400, 8, 1, UsbSerialPort.PARITY_NONE);
|
||||||
@ -1085,9 +1190,8 @@ public class DeviceTest implements SerialInputOutputManager.Listener {
|
|||||||
for(int i=0; i<buf.length; i++) buf[i]='a';
|
for(int i=0; i<buf.length; i++) buf[i]='a';
|
||||||
StringBuilder data = new StringBuilder();
|
StringBuilder data = new StringBuilder();
|
||||||
|
|
||||||
// purge send buffer
|
|
||||||
usbWrite(buf);
|
usbWrite(buf);
|
||||||
Thread.sleep(50); // ~ 12 characters
|
Thread.sleep(50); // ~ 12 bytes
|
||||||
boolean purged = usbSerialPort.purgeHwBuffers(true, false);
|
boolean purged = usbSerialPort.purgeHwBuffers(true, false);
|
||||||
usbWrite("bcd".getBytes());
|
usbWrite("bcd".getBytes());
|
||||||
Thread.sleep(50);
|
Thread.sleep(50);
|
||||||
@ -1101,7 +1205,32 @@ public class DeviceTest implements SerialInputOutputManager.Listener {
|
|||||||
else
|
else
|
||||||
assertEquals(data.length(), buf.length + 3);
|
assertEquals(data.length(), buf.length + 3);
|
||||||
|
|
||||||
// todo: purge receive buffer
|
// purge read buffer
|
||||||
|
usbClose();
|
||||||
|
usbOpen(false);
|
||||||
|
usbParameters(19200, 8, 1, UsbSerialPort.PARITY_NONE);
|
||||||
|
telnetParameters(19200, 8, 1, UsbSerialPort.PARITY_NONE);
|
||||||
|
telnetWrite("x".getBytes());
|
||||||
|
Thread.sleep(10); // ~ 20 bytes
|
||||||
|
purged = usbSerialPort.purgeHwBuffers(false, true);
|
||||||
|
Log.d(TAG, "purged = " + purged);
|
||||||
|
telnetWrite("y".getBytes());
|
||||||
|
Thread.sleep(10); // ~ 20 bytes
|
||||||
|
if(purged) {
|
||||||
|
if(usbSerialDriver instanceof Cp21xxSerialDriver) { // only working on some devices/ports
|
||||||
|
if(isCp21xxRestrictedPort) {
|
||||||
|
assertThat(usbRead(2), equalTo("xy".getBytes())); // cp2105/1
|
||||||
|
} else if(usbSerialDriver.getPorts().size() > 1) {
|
||||||
|
assertThat(usbRead(1), equalTo("y".getBytes())); // cp2105/0
|
||||||
|
} else {
|
||||||
|
assertThat(usbRead(2), equalTo("xy".getBytes())); // cp2102
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
assertThat(usbRead(1), equalTo("y".getBytes()));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
assertThat(usbRead(2), equalTo("xy".getBytes()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -31,9 +31,8 @@ import java.io.IOException;
|
|||||||
*
|
*
|
||||||
* @author mike wakerly (opensource@hoho.com)
|
* @author mike wakerly (opensource@hoho.com)
|
||||||
*/
|
*/
|
||||||
abstract class CommonUsbSerialPort implements UsbSerialPort {
|
public abstract class CommonUsbSerialPort implements UsbSerialPort {
|
||||||
|
|
||||||
public static final int DEFAULT_READ_BUFFER_SIZE = 16 * 1024;
|
|
||||||
public static final int DEFAULT_WRITE_BUFFER_SIZE = 16 * 1024;
|
public static final int DEFAULT_WRITE_BUFFER_SIZE = 16 * 1024;
|
||||||
|
|
||||||
protected final UsbDevice mDevice;
|
protected final UsbDevice mDevice;
|
||||||
@ -42,12 +41,8 @@ abstract class CommonUsbSerialPort implements UsbSerialPort {
|
|||||||
// non-null when open()
|
// non-null when open()
|
||||||
protected UsbDeviceConnection mConnection = null;
|
protected UsbDeviceConnection mConnection = null;
|
||||||
|
|
||||||
protected final Object mReadBufferLock = new Object();
|
|
||||||
protected final Object mWriteBufferLock = 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}. */
|
/** Internal write buffer. Guarded by {@link #mWriteBufferLock}. */
|
||||||
protected byte[] mWriteBuffer;
|
protected byte[] mWriteBuffer;
|
||||||
|
|
||||||
@ -55,7 +50,6 @@ abstract class CommonUsbSerialPort implements UsbSerialPort {
|
|||||||
mDevice = device;
|
mDevice = device;
|
||||||
mPortNumber = portNumber;
|
mPortNumber = portNumber;
|
||||||
|
|
||||||
mReadBuffer = new byte[DEFAULT_READ_BUFFER_SIZE];
|
|
||||||
mWriteBuffer = new byte[DEFAULT_WRITE_BUFFER_SIZE];
|
mWriteBuffer = new byte[DEFAULT_WRITE_BUFFER_SIZE];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -89,21 +83,6 @@ abstract class CommonUsbSerialPort implements UsbSerialPort {
|
|||||||
return mConnection.getSerial();
|
return mConnection.getSerial();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 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
|
* 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.
|
* stack for write operations. Most users should not need to change this.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user