diff --git a/usbSerialForAndroid/src/androidTest/java/com/hoho/android/usbserial/CrossoverTest.java b/usbSerialForAndroid/src/androidTest/java/com/hoho/android/usbserial/CrossoverTest.java index 89e2018..07b2f9c 100644 --- a/usbSerialForAndroid/src/androidTest/java/com/hoho/android/usbserial/CrossoverTest.java +++ b/usbSerialForAndroid/src/androidTest/java/com/hoho/android/usbserial/CrossoverTest.java @@ -14,6 +14,7 @@ import android.util.Log; import com.hoho.android.usbserial.driver.UsbSerialDriver; import com.hoho.android.usbserial.driver.UsbSerialPort; import com.hoho.android.usbserial.driver.UsbSerialProber; +import com.hoho.android.usbserial.util.TestBuffer; import com.hoho.android.usbserial.util.UsbWrapper; import org.junit.Before; @@ -24,12 +25,14 @@ import org.junit.rules.TestWatcher; import org.junit.runner.Description; import org.junit.runner.RunWith; +import java.io.IOException; import java.util.EnumSet; import java.util.List; import static org.hamcrest.CoreMatchers.equalTo; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.assertNull; import static org.junit.Assert.assertThat; import static org.junit.Assert.fail; import static org.junit.Assume.assumeTrue; @@ -160,4 +163,53 @@ public class CrossoverTest { usb2.close(); } + @Test + public void concurrent() throws Exception { + // 115200 baud ~= 11kB/sec => ~1.5 second test duration with 16kB tbuf + // concurrent (+ blocking) write calls as tbuf larger than any buffer size returned by UsbWrapper.getWriteSizes() + // concurrent read calls in IoManager threads + TestBuffer tbuf1 = new TestBuffer(16*1024); + TestBuffer tbuf2 = new TestBuffer(16*1024); + + class WriteRunnable implements Runnable { + public WriteRunnable(int port) { this.port = port; } + private final int port; + Exception exc; + @Override + public void run() { + byte[] buf = new byte[1024]; + try { + for(int i=0; i 0); @@ -967,7 +916,7 @@ public class DeviceTest { if(usb.serialDriver instanceof Cp21xxSerialDriver && usb.serialDriver.getPorts().size() == 1) purge = false; // purge is blocking - int[] writeSizes = getWriteSizes(); + int[] writeSizes = usb.getWriteSizes(); int writePacketSize = writeSizes[0]; int writeBufferSize = writeSizes[1]; int purgeTimeout = 250; diff --git a/usbSerialForAndroid/src/androidTest/java/com/hoho/android/usbserial/util/TestBuffer.java b/usbSerialForAndroid/src/androidTest/java/com/hoho/android/usbserial/util/TestBuffer.java new file mode 100644 index 0000000..95bca8b --- /dev/null +++ b/usbSerialForAndroid/src/androidTest/java/com/hoho/android/usbserial/util/TestBuffer.java @@ -0,0 +1,32 @@ +package com.hoho.android.usbserial.util; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.assertTrue; + +public class TestBuffer { + public final byte[] buf; + public int len; + + public 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; + } + + public 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; + } +} diff --git a/usbSerialForAndroid/src/androidTest/java/com/hoho/android/usbserial/util/UsbWrapper.java b/usbSerialForAndroid/src/androidTest/java/com/hoho/android/usbserial/util/UsbWrapper.java index 5bf114d..3eab1ec 100644 --- a/usbSerialForAndroid/src/androidTest/java/com/hoho/android/usbserial/util/UsbWrapper.java +++ b/usbSerialForAndroid/src/androidTest/java/com/hoho/android/usbserial/util/UsbWrapper.java @@ -12,7 +12,11 @@ import android.net.Uri; import android.util.Log; import com.hoho.android.usbserial.driver.CdcAcmSerialDriver; +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.FtdiSerialDriver; +import com.hoho.android.usbserial.driver.ProlificSerialDriver; import com.hoho.android.usbserial.driver.UsbSerialDriver; import com.hoho.android.usbserial.driver.UsbSerialPort; @@ -246,15 +250,40 @@ public class UsbWrapper implements SerialInputOutputManager.Listener { } } + // return [write packet size, write buffer size(s)] + public int[] getWriteSizes() { + if (serialDriver instanceof Cp21xxSerialDriver) { + if (serialDriver.getPorts().size() == 1) return new int[]{64, 576}; + else if (serialPort.getPortNumber() == 0) return new int[]{64, 320}; + else return new int[]{32, 128, 160}; // write buffer size detection is unreliable + } else if (serialDriver instanceof Ch34xSerialDriver) { + return new int[]{32, 64}; + } else if (serialDriver instanceof ProlificSerialDriver) { + return new int[]{64, 256}; + } else if (serialDriver instanceof FtdiSerialDriver) { + switch (serialDriver.getPorts().size()) { + case 1: return new int[]{64, 128}; + case 2: return new int[]{512, 4096}; + case 4: return new int[]{512, 2048}; + default: return null; + } + } else if (serialDriver instanceof CdcAcmSerialDriver) { + return new int[]{64, 128}; + } else { + return null; + } + } + + @Override public void onNewData(byte[] data) { long now = System.currentTimeMillis(); if(readTime == 0) readTime = now; if(data.length > 64) { - Log.d(TAG, "usb read: time+=" + String.format("%-3d",now- readTime) + " len=" + String.format("%-4d",data.length) + " data=" + new String(data, 0, 32) + "..." + new String(data, data.length-32, 32)); + Log.d(TAG, "usb " + devicePort + " read: time+=" + String.format("%-3d",now- readTime) + " len=" + String.format("%-4d",data.length) + " data=" + new String(data, 0, 32) + "..." + new String(data, data.length-32, 32)); } else { - Log.d(TAG, "usb read: time+=" + String.format("%-3d",now- readTime) + " len=" + String.format("%-4d",data.length) + " data=" + new String(data)); + Log.d(TAG, "usb " + devicePort + " read: time+=" + String.format("%-3d",now- readTime) + " len=" + String.format("%-4d",data.length) + " data=" + new String(data)); } readTime = now;