mirror of
				https://github.com/mik3y/usb-serial-for-android
				synced 2025-10-31 10:27:27 +00:00 
			
		
		
		
	move setReadQueue to UsbSerialPort interface
This commit is contained in:
		
							parent
							
								
									90246e5c7b
								
							
						
					
					
						commit
						1efbcf0a38
					
				| @ -1207,52 +1207,54 @@ public class DeviceTest { | |||||||
|             @Override public Object getClientData() { count += 1; return super.getClientData(); } |             @Override public Object getClientData() { count += 1; return super.getClientData(); } | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         usb.open(EnumSet.of(UsbWrapper.OpenCloseFlags.NO_IOMANAGER_THREAD)); |  | ||||||
|         int len = usb.serialPort.getReadEndpoint().getMaxPacketSize(); |  | ||||||
|         usb.close(); |  | ||||||
|         CommonUsbSerialPortWrapper.setReadQueueRequestSupplier(usb.serialPort, CountingUsbRequest::new); |         CommonUsbSerialPortWrapper.setReadQueueRequestSupplier(usb.serialPort, CountingUsbRequest::new); | ||||||
|         CommonUsbSerialPort port = (CommonUsbSerialPort) usb.serialPort; |         usb.serialPort.setReadQueue(2, 0); | ||||||
| 
 |         assertEquals(0, usb.serialPort.getReadQueueBufferSize()); | ||||||
|         port.setReadQueue(2, len); |  | ||||||
|         usb.open(EnumSet.of(UsbWrapper.OpenCloseFlags.NO_IOMANAGER_START)); |         usb.open(EnumSet.of(UsbWrapper.OpenCloseFlags.NO_IOMANAGER_START)); | ||||||
|         usb.setParameters(115200, 8, 1, UsbSerialPort.PARITY_NONE); |         int len = usb.serialPort.getReadEndpoint().getMaxPacketSize(); | ||||||
|         telnet.setParameters(115200, 8, 1, UsbSerialPort.PARITY_NONE); |         assertEquals(len, usb.serialPort.getReadQueueBufferSize()); | ||||||
|         assertEquals(2, port.getReadQueueBufferCount()); |         assertEquals(2, usb.serialPort.getReadQueueBufferCount()); | ||||||
|         assertEquals(4, usb.ioManager.getReadQueueBufferCount()); // not set at port yet |         assertEquals(4, usb.ioManager.getReadQueueBufferCount()); // not set at port yet | ||||||
|         assertThrows(IllegalStateException.class, () -> usb.ioManager.setReadQueue(1)); // cannot reduce bufferCount |         assertThrows(IllegalStateException.class, () -> usb.ioManager.setReadQueue(1)); // cannot reduce bufferCount | ||||||
|         usb.ioManager.setReadQueue(2); |         usb.ioManager.setReadQueue(2); | ||||||
|         usb.ioManager.start(); |         usb.ioManager.start(); | ||||||
|         port.setReadQueue(4, len); |         usb.serialPort.setReadQueue(3, 0); | ||||||
|  |         usb.serialPort.setReadQueue(3, len); | ||||||
|  |         usb.ioManager.setReadQueue(4); | ||||||
| 
 | 
 | ||||||
|  |         usb.setParameters(115200, 8, 1, UsbSerialPort.PARITY_NONE); | ||||||
|  |         telnet.setParameters(115200, 8, 1, UsbSerialPort.PARITY_NONE); | ||||||
|         // linux kernel does round-robin |         // linux kernel does round-robin | ||||||
|         LinkedList<UsbRequest> requests = CommonUsbSerialPortWrapper.getReadQueueRequests(usb.serialPort); |         LinkedList<UsbRequest> requests = CommonUsbSerialPortWrapper.getReadQueueRequests(usb.serialPort); | ||||||
|         assertNotNull(requests); |         assertNotNull(requests); | ||||||
|         for (int i=0; i<16; i++) { |         for (int i=0; i<4*4; i++) { | ||||||
|             telnet.write(new byte[1]); |             telnet.write(new byte[1]); | ||||||
|             usb.read(1); |             usb.read(1); | ||||||
|         } |         } | ||||||
|         List<Integer> requestCounts; |  | ||||||
|         if(usb.serialDriver instanceof FtdiSerialDriver) { |  | ||||||
|         for (UsbRequest request : requests) { |         for (UsbRequest request : requests) { | ||||||
|             int count = ((CountingUsbRequest)request).count; |             int count = ((CountingUsbRequest)request).count; | ||||||
|  |             if(usb.serialDriver instanceof FtdiSerialDriver) { | ||||||
|                 assertTrue(String.valueOf(count), count >= 4); |                 assertTrue(String.valueOf(count), count >= 4); | ||||||
|             } |  | ||||||
|             } else { |             } else { | ||||||
|             requestCounts = requests.stream().map(r -> ((CountingUsbRequest)r).count).collect(Collectors.toList()); |                 assertEquals(String.valueOf(count), 4, count); | ||||||
|             assertThat(requestCounts, equalTo(Arrays.asList(4, 4, 4, 4))); |             } | ||||||
|         } |         } | ||||||
|         usb.ioManager.setReadQueue(6); |         usb.ioManager.setReadQueue(6); | ||||||
|         for (int i=0; i<18; i++) { |         for (int i=0; i<3*6; i++) { | ||||||
|             telnet.write(new byte[1]); |             telnet.write(new byte[1]); | ||||||
|             usb.read(1); |             usb.read(1); | ||||||
|         } |         } | ||||||
|         requestCounts = requests.stream().map(r -> ((CountingUsbRequest)r).count).collect(Collectors.toList()); |         for (UsbRequest request : requests) { | ||||||
|         if(!(usb.serialDriver instanceof FtdiSerialDriver)) { |             int count = ((CountingUsbRequest)request).count; | ||||||
|             assertThat(requestCounts, equalTo(Arrays.asList(7, 7, 7, 7, 3, 3))); |             if(usb.serialDriver instanceof FtdiSerialDriver) { | ||||||
|  |                 assertTrue(String.valueOf(count), count >= 3); | ||||||
|  |             } else { | ||||||
|  |                 assertTrue(String.valueOf(count), count == 7 || count == 3); | ||||||
|  |             } | ||||||
|         } |         } | ||||||
|         usb.close(); |         usb.close(); | ||||||
|         usb.open(EnumSet.of(UsbWrapper.OpenCloseFlags.NO_IOMANAGER_START)); |         usb.open(EnumSet.of(UsbWrapper.OpenCloseFlags.NO_IOMANAGER_START)); | ||||||
|         port.setReadQueue(8, len); |         usb.serialPort.setReadQueue(8, len); | ||||||
|         assertThrows(IllegalStateException.class, () -> usb.serialPort.read(new byte[len], 1) ); // cannot use timeout != 0 |         assertThrows(IllegalStateException.class, () -> usb.serialPort.read(new byte[len], 1) ); // cannot use timeout != 0 | ||||||
|         assertThrows(IllegalStateException.class, () -> usb.serialPort.read(new byte[4], 0) ); // cannot use different length |         assertThrows(IllegalStateException.class, () -> usb.serialPort.read(new byte[4], 0) ); // cannot use different length | ||||||
|         assertThrows(IllegalStateException.class, () -> usb.ioManager.start()); // cannot reduce bufferCount |         assertThrows(IllegalStateException.class, () -> usb.ioManager.start()); // cannot reduce bufferCount | ||||||
|  | |||||||
| @ -117,24 +117,24 @@ public abstract class CommonUsbSerialPort implements UsbSerialPort { | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** |     @Override | ||||||
|      * for applications doing permanent read() with timeout=0, multiple buffers can be |  | ||||||
|      * used to copy next data from Linux kernel, while the current data is processed. |  | ||||||
|      * @param bufferCount number of buffers to use for readQueue |  | ||||||
|      *                    disabled with 0 |  | ||||||
|      * @param bufferSize size of each buffer |  | ||||||
|      */ |  | ||||||
|     public void setReadQueue(int bufferCount, int bufferSize) { |     public void setReadQueue(int bufferCount, int bufferSize) { | ||||||
|         if (bufferCount < 0) { |         if (bufferCount < 0) { | ||||||
|             throw new IllegalArgumentException("Invalid bufferCount"); |             throw new IllegalArgumentException("Invalid bufferCount"); | ||||||
|         } |         } | ||||||
|         if (bufferCount > 0 && bufferSize <= 0) { |         if (bufferSize < 0) { | ||||||
|             throw new IllegalArgumentException("Invalid bufferSize"); |             throw new IllegalArgumentException("Invalid bufferSize"); | ||||||
|         } |         } | ||||||
|         if(isOpen()) { |         if(isOpen()) { | ||||||
|             if (bufferCount < mReadQueueBufferCount) { |             if (bufferCount < mReadQueueBufferCount) { | ||||||
|                 throw new IllegalStateException("Cannot reduce bufferCount when port is open"); |                 throw new IllegalStateException("Cannot reduce bufferCount when port is open"); | ||||||
|             } |             } | ||||||
|  |             if (bufferSize == 0) { | ||||||
|  |                 bufferSize = mReadEndpoint.getMaxPacketSize(); | ||||||
|  |             } | ||||||
|  |             if (mReadQueueBufferSize == 0) { | ||||||
|  |                 mReadQueueBufferSize = mReadEndpoint.getMaxPacketSize(); | ||||||
|  |             } | ||||||
|             if (mReadQueueBufferCount != 0 && bufferSize != mReadQueueBufferSize) { |             if (mReadQueueBufferCount != 0 && bufferSize != mReadQueueBufferSize) { | ||||||
|                 throw new IllegalStateException("Cannot change bufferSize when port is open"); |                 throw new IllegalStateException("Cannot change bufferSize when port is open"); | ||||||
|             } |             } | ||||||
| @ -156,7 +156,9 @@ public abstract class CommonUsbSerialPort implements UsbSerialPort { | |||||||
|         mReadQueueBufferSize = bufferSize; |         mReadQueueBufferSize = bufferSize; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     @Override | ||||||
|     public int getReadQueueBufferCount() { return mReadQueueBufferCount; } |     public int getReadQueueBufferCount() { return mReadQueueBufferCount; } | ||||||
|  |     @Override | ||||||
|     public int getReadQueueBufferSize() { return mReadQueueBufferSize; } |     public int getReadQueueBufferSize() { return mReadQueueBufferSize; } | ||||||
| 
 | 
 | ||||||
|     private boolean useReadQueue() { return mReadQueueBufferCount != 0; } |     private boolean useReadQueue() { return mReadQueueBufferCount != 0; } | ||||||
|  | |||||||
| @ -104,6 +104,23 @@ public interface UsbSerialPort extends Closeable { | |||||||
|      */ |      */ | ||||||
|     String getSerial(); |     String getSerial(); | ||||||
| 
 | 
 | ||||||
|  |     /** | ||||||
|  |      * Applications doing permanent {@link #read} with timeout=0 can reduce data loss likelihood | ||||||
|  |      * at high baud rate and continuous data transfer by using multiple buffers to copy next data | ||||||
|  |      * from Linux kernel, while the current data is processed. | ||||||
|  |      * When enabled, {@link #read} can not be called with timeout!=0 or different buffer size. | ||||||
|  |      * | ||||||
|  |      * @param bufferCount number of buffers to use for readQueue. | ||||||
|  |      *                    Use 0 to disable. | ||||||
|  |      * @param bufferSize size of each buffer. | ||||||
|  |      *                   Use 0 for optimal size (= getReadEndpoint().getMaxPacketSize()). | ||||||
|  |      * @throws IllegalStateException if port is open and buffer count should be lowered or | ||||||
|  |      *                               buffer size should be changed. | ||||||
|  |      */ | ||||||
|  |     void setReadQueue(int bufferCount, int bufferSize); | ||||||
|  |     int getReadQueueBufferCount(); | ||||||
|  |     int getReadQueueBufferSize(); | ||||||
|  | 
 | ||||||
|     /** |     /** | ||||||
|      * Opens and initializes the port. Upon success, caller must ensure that |      * Opens and initializes the port. Upon success, caller must ensure that | ||||||
|      * {@link #close()} is eventually called. |      * {@link #close()} is eventually called. | ||||||
|  | |||||||
| @ -39,7 +39,8 @@ public class SerialInputOutputManager { | |||||||
| 
 | 
 | ||||||
|     private int mReadTimeout = 0; |     private int mReadTimeout = 0; | ||||||
|     private int mWriteTimeout = 0; |     private int mWriteTimeout = 0; | ||||||
|     private int mReadQueueBufferCount; // = READ_QUEUE_BUFFER_COUNT |     private int mReadQueueBufferCount = READ_QUEUE_BUFFER_COUNT; | ||||||
|  |     //       no mReadQueueBufferSize, using mReadBuffer.size instead | ||||||
| 
 | 
 | ||||||
|     private final Object mReadBufferLock = new Object(); |     private final Object mReadBufferLock = new Object(); | ||||||
|     private final Object mWriteBufferLock = new Object(); |     private final Object mWriteBufferLock = new Object(); | ||||||
| @ -68,8 +69,6 @@ public class SerialInputOutputManager { | |||||||
|     public SerialInputOutputManager(UsbSerialPort serialPort) { |     public SerialInputOutputManager(UsbSerialPort serialPort) { | ||||||
|         mSerialPort = serialPort; |         mSerialPort = serialPort; | ||||||
|         mReadBuffer = ByteBuffer.allocate(serialPort.getReadEndpoint().getMaxPacketSize()); |         mReadBuffer = ByteBuffer.allocate(serialPort.getReadEndpoint().getMaxPacketSize()); | ||||||
|         mReadQueueBufferCount = serialPort instanceof CommonUsbSerialPort ? READ_QUEUE_BUFFER_COUNT : 0; |  | ||||||
|         //readQueueBufferSize fixed to getMaxPacketSize() |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public SerialInputOutputManager(UsbSerialPort serialPort, Listener listener) { |     public SerialInputOutputManager(UsbSerialPort serialPort, Listener listener) { | ||||||
| @ -150,17 +149,16 @@ public class SerialInputOutputManager { | |||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|      * Set read queue. Set buffer size before. |      * Set read queue, similar to {@link UsbSerialPort#setReadQueue} | ||||||
|      * @param bufferCount number of buffers to use for readQueue |      * except buffer size to be set before with {@link #setReadBufferSize}. | ||||||
|  |      * | ||||||
|  |      * @param bufferCount number of buffers to use for readQueue, | ||||||
|      *                    disable with value 0, |      *                    disable with value 0, | ||||||
|      *                    default enabled as value 4 (READ_QUEUE_BUFFER_COUNT) |      *                    default enabled as value 4 (READ_QUEUE_BUFFER_COUNT) | ||||||
|      */ |      */ | ||||||
|     public void setReadQueue(int bufferCount) { |     public void setReadQueue(int bufferCount) { | ||||||
|         if (!(mSerialPort instanceof CommonUsbSerialPort)) { |         mSerialPort.setReadQueue(bufferCount, getReadBufferSize()); | ||||||
|             throw new IllegalArgumentException("only for CommonUsbSerialPort based drivers"); |         mReadQueueBufferCount = bufferCount; // only store if set ok | ||||||
|         } |  | ||||||
|         mReadQueueBufferCount = bufferCount; |  | ||||||
|         ((CommonUsbSerialPort) mSerialPort).setReadQueue(getReadQueueBufferCount(), getReadBufferSize()); |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public int getReadQueueBufferCount() { return mReadQueueBufferCount; } |     public int getReadQueueBufferCount() { return mReadQueueBufferCount; } | ||||||
| @ -179,9 +177,7 @@ public class SerialInputOutputManager { | |||||||
|      * start SerialInputOutputManager in separate threads |      * start SerialInputOutputManager in separate threads | ||||||
|      */ |      */ | ||||||
|     public void start() { |     public void start() { | ||||||
|         if(mSerialPort instanceof CommonUsbSerialPort) { |         mSerialPort.setReadQueue(mReadQueueBufferCount, getReadBufferSize()); | ||||||
|             ((CommonUsbSerialPort) mSerialPort).setReadQueue(mReadQueueBufferCount, getReadBufferSize()); |  | ||||||
|         } |  | ||||||
|         if(mState.compareAndSet(State.STOPPED, State.STARTING)) { |         if(mState.compareAndSet(State.STOPPED, State.STARTING)) { | ||||||
|             mStartuplatch = new CountDownLatch(2); |             mStartuplatch = new CountDownLatch(2); | ||||||
|             new Thread(this::runRead, this.getClass().getSimpleName() + "_read").start(); |             new Thread(this::runRead, this.getClass().getSimpleName() + "_read").start(); | ||||||
|  | |||||||
| @ -71,9 +71,8 @@ public class CommonUsbSerialPortTest { | |||||||
| 
 | 
 | ||||||
|         // set before open |         // set before open | ||||||
|         port.setReadQueue(0, 0); |         port.setReadQueue(0, 0); | ||||||
|         port.setReadQueue(0, -1); |  | ||||||
|         assertThrows(IllegalArgumentException.class, () -> port.setReadQueue(-1, 1)); |         assertThrows(IllegalArgumentException.class, () -> port.setReadQueue(-1, 1)); | ||||||
|         assertThrows(IllegalArgumentException.class, () -> port.setReadQueue(1, 0)); |         assertThrows(IllegalArgumentException.class, () -> port.setReadQueue(1, -1)); | ||||||
|         port.setReadQueue(2, 256); |         port.setReadQueue(2, 256); | ||||||
|         assertNull(port.mReadQueueRequests); |         assertNull(port.mReadQueueRequests); | ||||||
| 
 | 
 | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user