mirror of
				https://github.com/mik3y/usb-serial-for-android
				synced 2025-10-31 02:17:23 +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