Skip to content

Commit 1efbcf0

Browse files
committed
move setReadQueue to UsbSerialPort interface
1 parent 90246e5 commit 1efbcf0

File tree

5 files changed

+62
-46
lines changed

5 files changed

+62
-46
lines changed

usbSerialForAndroid/src/androidTest/java/com/hoho/android/usbserial/DeviceTest.java

+25-23
Original file line numberDiff line numberDiff line change
@@ -1207,52 +1207,54 @@ class CountingUsbRequest extends UsbRequest {
12071207
@Override public Object getClientData() { count += 1; return super.getClientData(); }
12081208
}
12091209

1210-
usb.open(EnumSet.of(UsbWrapper.OpenCloseFlags.NO_IOMANAGER_THREAD));
1211-
int len = usb.serialPort.getReadEndpoint().getMaxPacketSize();
1212-
usb.close();
12131210
CommonUsbSerialPortWrapper.setReadQueueRequestSupplier(usb.serialPort, CountingUsbRequest::new);
1214-
CommonUsbSerialPort port = (CommonUsbSerialPort) usb.serialPort;
1215-
1216-
port.setReadQueue(2, len);
1211+
usb.serialPort.setReadQueue(2, 0);
1212+
assertEquals(0, usb.serialPort.getReadQueueBufferSize());
12171213
usb.open(EnumSet.of(UsbWrapper.OpenCloseFlags.NO_IOMANAGER_START));
1218-
usb.setParameters(115200, 8, 1, UsbSerialPort.PARITY_NONE);
1219-
telnet.setParameters(115200, 8, 1, UsbSerialPort.PARITY_NONE);
1220-
assertEquals(2, port.getReadQueueBufferCount());
1214+
int len = usb.serialPort.getReadEndpoint().getMaxPacketSize();
1215+
assertEquals(len, usb.serialPort.getReadQueueBufferSize());
1216+
assertEquals(2, usb.serialPort.getReadQueueBufferCount());
12211217
assertEquals(4, usb.ioManager.getReadQueueBufferCount()); // not set at port yet
12221218
assertThrows(IllegalStateException.class, () -> usb.ioManager.setReadQueue(1)); // cannot reduce bufferCount
12231219
usb.ioManager.setReadQueue(2);
12241220
usb.ioManager.start();
1225-
port.setReadQueue(4, len);
1221+
usb.serialPort.setReadQueue(3, 0);
1222+
usb.serialPort.setReadQueue(3, len);
1223+
usb.ioManager.setReadQueue(4);
12261224

1225+
usb.setParameters(115200, 8, 1, UsbSerialPort.PARITY_NONE);
1226+
telnet.setParameters(115200, 8, 1, UsbSerialPort.PARITY_NONE);
12271227
// linux kernel does round-robin
12281228
LinkedList<UsbRequest> requests = CommonUsbSerialPortWrapper.getReadQueueRequests(usb.serialPort);
12291229
assertNotNull(requests);
1230-
for (int i=0; i<16; i++) {
1230+
for (int i=0; i<4*4; i++) {
12311231
telnet.write(new byte[1]);
12321232
usb.read(1);
12331233
}
1234-
List<Integer> requestCounts;
1235-
if(usb.serialDriver instanceof FtdiSerialDriver) {
1236-
for (UsbRequest request : requests) {
1237-
int count = ((CountingUsbRequest)request).count;
1234+
for (UsbRequest request : requests) {
1235+
int count = ((CountingUsbRequest)request).count;
1236+
if(usb.serialDriver instanceof FtdiSerialDriver) {
12381237
assertTrue(String.valueOf(count), count >= 4);
1238+
} else {
1239+
assertEquals(String.valueOf(count), 4, count);
12391240
}
1240-
} else {
1241-
requestCounts = requests.stream().map(r -> ((CountingUsbRequest)r).count).collect(Collectors.toList());
1242-
assertThat(requestCounts, equalTo(Arrays.asList(4, 4, 4, 4)));
12431241
}
12441242
usb.ioManager.setReadQueue(6);
1245-
for (int i=0; i<18; i++) {
1243+
for (int i=0; i<3*6; i++) {
12461244
telnet.write(new byte[1]);
12471245
usb.read(1);
12481246
}
1249-
requestCounts = requests.stream().map(r -> ((CountingUsbRequest)r).count).collect(Collectors.toList());
1250-
if(!(usb.serialDriver instanceof FtdiSerialDriver)) {
1251-
assertThat(requestCounts, equalTo(Arrays.asList(7, 7, 7, 7, 3, 3)));
1247+
for (UsbRequest request : requests) {
1248+
int count = ((CountingUsbRequest)request).count;
1249+
if(usb.serialDriver instanceof FtdiSerialDriver) {
1250+
assertTrue(String.valueOf(count), count >= 3);
1251+
} else {
1252+
assertTrue(String.valueOf(count), count == 7 || count == 3);
1253+
}
12521254
}
12531255
usb.close();
12541256
usb.open(EnumSet.of(UsbWrapper.OpenCloseFlags.NO_IOMANAGER_START));
1255-
port.setReadQueue(8, len);
1257+
usb.serialPort.setReadQueue(8, len);
12561258
assertThrows(IllegalStateException.class, () -> usb.serialPort.read(new byte[len], 1) ); // cannot use timeout != 0
12571259
assertThrows(IllegalStateException.class, () -> usb.serialPort.read(new byte[4], 0) ); // cannot use different length
12581260
assertThrows(IllegalStateException.class, () -> usb.ioManager.start()); // cannot reduce bufferCount

usbSerialForAndroid/src/main/java/com/hoho/android/usbserial/driver/CommonUsbSerialPort.java

+10-8
Original file line numberDiff line numberDiff line change
@@ -117,24 +117,24 @@ public final void setWriteBufferSize(int bufferSize) {
117117
}
118118
}
119119

120-
/**
121-
* for applications doing permanent read() with timeout=0, multiple buffers can be
122-
* used to copy next data from Linux kernel, while the current data is processed.
123-
* @param bufferCount number of buffers to use for readQueue
124-
* disabled with 0
125-
* @param bufferSize size of each buffer
126-
*/
120+
@Override
127121
public void setReadQueue(int bufferCount, int bufferSize) {
128122
if (bufferCount < 0) {
129123
throw new IllegalArgumentException("Invalid bufferCount");
130124
}
131-
if (bufferCount > 0 && bufferSize <= 0) {
125+
if (bufferSize < 0) {
132126
throw new IllegalArgumentException("Invalid bufferSize");
133127
}
134128
if(isOpen()) {
135129
if (bufferCount < mReadQueueBufferCount) {
136130
throw new IllegalStateException("Cannot reduce bufferCount when port is open");
137131
}
132+
if (bufferSize == 0) {
133+
bufferSize = mReadEndpoint.getMaxPacketSize();
134+
}
135+
if (mReadQueueBufferSize == 0) {
136+
mReadQueueBufferSize = mReadEndpoint.getMaxPacketSize();
137+
}
138138
if (mReadQueueBufferCount != 0 && bufferSize != mReadQueueBufferSize) {
139139
throw new IllegalStateException("Cannot change bufferSize when port is open");
140140
}
@@ -156,7 +156,9 @@ public void setReadQueue(int bufferCount, int bufferSize) {
156156
mReadQueueBufferSize = bufferSize;
157157
}
158158

159+
@Override
159160
public int getReadQueueBufferCount() { return mReadQueueBufferCount; }
161+
@Override
160162
public int getReadQueueBufferSize() { return mReadQueueBufferSize; }
161163

162164
private boolean useReadQueue() { return mReadQueueBufferCount != 0; }

usbSerialForAndroid/src/main/java/com/hoho/android/usbserial/driver/UsbSerialPort.java

+17
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,23 @@ enum FlowControl { NONE, RTS_CTS, DTR_DSR, XON_XOFF, XON_XOFF_INLINE }
104104
*/
105105
String getSerial();
106106

107+
/**
108+
* Applications doing permanent {@link #read} with timeout=0 can reduce data loss likelihood
109+
* at high baud rate and continuous data transfer by using multiple buffers to copy next data
110+
* from Linux kernel, while the current data is processed.
111+
* When enabled, {@link #read} can not be called with timeout!=0 or different buffer size.
112+
*
113+
* @param bufferCount number of buffers to use for readQueue.
114+
* Use 0 to disable.
115+
* @param bufferSize size of each buffer.
116+
* Use 0 for optimal size (= getReadEndpoint().getMaxPacketSize()).
117+
* @throws IllegalStateException if port is open and buffer count should be lowered or
118+
* buffer size should be changed.
119+
*/
120+
void setReadQueue(int bufferCount, int bufferSize);
121+
int getReadQueueBufferCount();
122+
int getReadQueueBufferSize();
123+
107124
/**
108125
* Opens and initializes the port. Upon success, caller must ensure that
109126
* {@link #close()} is eventually called.

usbSerialForAndroid/src/main/java/com/hoho/android/usbserial/util/SerialInputOutputManager.java

+9-13
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,8 @@ public enum State {
3939

4040
private int mReadTimeout = 0;
4141
private int mWriteTimeout = 0;
42-
private int mReadQueueBufferCount; // = READ_QUEUE_BUFFER_COUNT
42+
private int mReadQueueBufferCount = READ_QUEUE_BUFFER_COUNT;
43+
// no mReadQueueBufferSize, using mReadBuffer.size instead
4344

4445
private final Object mReadBufferLock = new Object();
4546
private final Object mWriteBufferLock = new Object();
@@ -68,8 +69,6 @@ public interface Listener {
6869
public SerialInputOutputManager(UsbSerialPort serialPort) {
6970
mSerialPort = serialPort;
7071
mReadBuffer = ByteBuffer.allocate(serialPort.getReadEndpoint().getMaxPacketSize());
71-
mReadQueueBufferCount = serialPort instanceof CommonUsbSerialPort ? READ_QUEUE_BUFFER_COUNT : 0;
72-
//readQueueBufferSize fixed to getMaxPacketSize()
7372
}
7473

7574
public SerialInputOutputManager(UsbSerialPort serialPort, Listener listener) {
@@ -150,17 +149,16 @@ public int getWriteBufferSize() {
150149
}
151150

152151
/**
153-
* Set read queue. Set buffer size before.
154-
* @param bufferCount number of buffers to use for readQueue
152+
* Set read queue, similar to {@link UsbSerialPort#setReadQueue}
153+
* except buffer size to be set before with {@link #setReadBufferSize}.
154+
*
155+
* @param bufferCount number of buffers to use for readQueue,
155156
* disable with value 0,
156157
* default enabled as value 4 (READ_QUEUE_BUFFER_COUNT)
157158
*/
158159
public void setReadQueue(int bufferCount) {
159-
if (!(mSerialPort instanceof CommonUsbSerialPort)) {
160-
throw new IllegalArgumentException("only for CommonUsbSerialPort based drivers");
161-
}
162-
mReadQueueBufferCount = bufferCount;
163-
((CommonUsbSerialPort) mSerialPort).setReadQueue(getReadQueueBufferCount(), getReadBufferSize());
160+
mSerialPort.setReadQueue(bufferCount, getReadBufferSize());
161+
mReadQueueBufferCount = bufferCount; // only store if set ok
164162
}
165163

166164
public int getReadQueueBufferCount() { return mReadQueueBufferCount; }
@@ -179,9 +177,7 @@ public void writeAsync(byte[] data) {
179177
* start SerialInputOutputManager in separate threads
180178
*/
181179
public void start() {
182-
if(mSerialPort instanceof CommonUsbSerialPort) {
183-
((CommonUsbSerialPort) mSerialPort).setReadQueue(mReadQueueBufferCount, getReadBufferSize());
184-
}
180+
mSerialPort.setReadQueue(mReadQueueBufferCount, getReadBufferSize());
185181
if(mState.compareAndSet(State.STOPPED, State.STARTING)) {
186182
mStartuplatch = new CountDownLatch(2);
187183
new Thread(this::runRead, this.getClass().getSimpleName() + "_read").start();

usbSerialForAndroid/src/test/java/com/hoho/android/usbserial/driver/CommonUsbSerialPortTest.java

+1-2
Original file line numberDiff line numberDiff line change
@@ -71,9 +71,8 @@ public void readQueue() throws Exception {
7171

7272
// set before open
7373
port.setReadQueue(0, 0);
74-
port.setReadQueue(0, -1);
7574
assertThrows(IllegalArgumentException.class, () -> port.setReadQueue(-1, 1));
76-
assertThrows(IllegalArgumentException.class, () -> port.setReadQueue(1, 0));
75+
assertThrows(IllegalArgumentException.class, () -> port.setReadQueue(1, -1));
7776
port.setReadQueue(2, 256);
7877
assertNull(port.mReadQueueRequests);
7978

0 commit comments

Comments
 (0)