mirror of
				https://github.com/mik3y/usb-serial-for-android
				synced 2025-10-31 02:17:23 +00:00 
			
		
		
		
	Increase default read/write buffer sizes; allow tuning.
This commit is contained in:
		
							parent
							
								
									c5e9955b01
								
							
						
					
					
						commit
						b328f3cbc9
					
				| @ -1,7 +1,6 @@ | ||||
| package com.hoho.android.usbserial.driver; | ||||
| 
 | ||||
| import java.io.IOException; | ||||
| import java.util.Arrays; | ||||
| import java.util.LinkedHashMap; | ||||
| import java.util.Map; | ||||
| 
 | ||||
| @ -21,8 +20,6 @@ public class CdcAcmSerialDriver extends UsbSerialDriver { | ||||
| 
 | ||||
|     private final String TAG = CdcAcmSerialDriver.class.getSimpleName(); | ||||
| 
 | ||||
|     private final byte[] mReadBuffer = new byte[4096]; | ||||
| 
 | ||||
|     private UsbInterface mControlInterface; | ||||
|     private UsbInterface mDataInterface; | ||||
| 
 | ||||
| @ -96,47 +93,55 @@ public class CdcAcmSerialDriver extends UsbSerialDriver { | ||||
| 
 | ||||
|     @Override | ||||
|     public int read(byte[] dest, int timeoutMillis) throws IOException { | ||||
|         final int numBytesRead; | ||||
|         synchronized (mReadBufferLock) { | ||||
|             int readAmt = Math.min(dest.length, mReadBuffer.length); | ||||
|             readAmt = Math.min(readAmt, mReadEndpoint.getMaxPacketSize()); | ||||
|         final int transferred = mConnection.bulkTransfer(mReadEndpoint, mReadBuffer, readAmt, | ||||
|             numBytesRead = mConnection.bulkTransfer(mReadEndpoint, mReadBuffer, readAmt, | ||||
|                     timeoutMillis); | ||||
| 
 | ||||
|         if (transferred < 0) { | ||||
|             if (numBytesRead < 0) { | ||||
|                 // This sucks: we get -1 on timeout, not 0 as preferred. | ||||
|                 // We *should* use UsbRequest, except it has a bug/api oversight | ||||
|                 // where there is no way to determine the number of bytes read | ||||
|                 // in response :\ -- http://b.android.com/28023 | ||||
|                 return 0; | ||||
|             } | ||||
|         System.arraycopy(mReadBuffer, 0, dest, 0, transferred); | ||||
|         return transferred; | ||||
|             System.arraycopy(mReadBuffer, 0, dest, 0, numBytesRead); | ||||
|         } | ||||
|         return numBytesRead; | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public int write(byte[] src, int timeoutMillis) throws IOException { | ||||
|         // TODO(mikey): Nearly identical to FtdiSerial write. Refactor. | ||||
|         int offset = 0; | ||||
|         final int chunksize = mWriteEndpoint.getMaxPacketSize(); | ||||
| 
 | ||||
|         while (offset < src.length) { | ||||
|             final byte[] writeBuffer; | ||||
|             final int writeLength; | ||||
|             final int amtWritten; | ||||
| 
 | ||||
|             // bulkTransfer does not support offsets; make a copy if necessary. | ||||
|             writeLength = Math.min(src.length - offset, chunksize); | ||||
|             synchronized (mWriteBufferLock) { | ||||
|                 final byte[] writeBuffer; | ||||
| 
 | ||||
|                 writeLength = Math.min(src.length - offset, mWriteBuffer.length); | ||||
|                 if (offset == 0) { | ||||
|                     writeBuffer = src; | ||||
|                 } else { | ||||
|                 writeBuffer = Arrays.copyOfRange(src, offset, offset + writeLength); | ||||
|                     // bulkTransfer does not support offsets, make a copy. | ||||
|                     System.arraycopy(src, offset, mWriteBuffer, 0, writeLength); | ||||
|                     writeBuffer = mWriteBuffer; | ||||
|                 } | ||||
| 
 | ||||
|             final int amt = mConnection.bulkTransfer(mWriteEndpoint, writeBuffer, writeLength, | ||||
|                 amtWritten = mConnection.bulkTransfer(mWriteEndpoint, writeBuffer, writeLength, | ||||
|                         timeoutMillis); | ||||
|             if (amt <= 0) { | ||||
|             } | ||||
|             if (amtWritten <= 0) { | ||||
|                 throw new IOException("Error writing " + writeLength | ||||
|                         + " bytes at offset " + offset + " length=" + src.length); | ||||
|             } | ||||
|             Log.d(TAG, "Wrote amt=" + amt + " attempted=" + writeBuffer.length); | ||||
|             offset += amt; | ||||
| 
 | ||||
|             Log.d(TAG, "Wrote amt=" + amtWritten + " attempted=" + writeLength); | ||||
|             offset += amtWritten; | ||||
|         } | ||||
|         return offset; | ||||
|     } | ||||
|  | ||||
| @ -22,7 +22,6 @@ package com.hoho.android.usbserial.driver; | ||||
| 
 | ||||
| import java.io.IOException; | ||||
| import java.nio.ByteBuffer; | ||||
| import java.util.Arrays; | ||||
| import java.util.LinkedHashMap; | ||||
| import java.util.Map; | ||||
| 
 | ||||
| @ -38,8 +37,8 @@ import com.hoho.android.usbserial.util.HexDump; | ||||
| /** | ||||
|  * A {@link UsbSerialDriver} implementation for a variety of FTDI devices | ||||
|  * <p> | ||||
|  * This driver is based on <a | ||||
|  * href="http://www.intra2net.com/en/developer/libftdi">libftdi</a>, and is | ||||
|  * This driver is based on | ||||
|  * <a href="http://www.intra2net.com/en/developer/libftdi">libftdi</a>, and is | ||||
|  * copyright and subject to the following terms: | ||||
|  * | ||||
|  * <pre> | ||||
| @ -142,11 +141,6 @@ public class FtdiSerialDriver extends UsbSerialDriver { | ||||
|     public static final int FTDI_DEVICE_IN_REQTYPE = | ||||
|             UsbConstants.USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_IN; | ||||
| 
 | ||||
|     /** | ||||
|      * Size of chunks, used in {@link #write(byte[], int)}. | ||||
|      */ | ||||
|     private static final int WRITE_CHUNKSIZE = 4096; | ||||
| 
 | ||||
|     /** | ||||
|      * Length of the modem status header, transmitted with every read. | ||||
|      */ | ||||
| @ -156,8 +150,6 @@ public class FtdiSerialDriver extends UsbSerialDriver { | ||||
| 
 | ||||
|     private DeviceType mType; | ||||
| 
 | ||||
|     private final byte[] mReadBuffer = new byte[4096]; | ||||
| 
 | ||||
|     /** | ||||
|      * FTDI chip types. | ||||
|      */ | ||||
| @ -228,10 +220,15 @@ public class FtdiSerialDriver extends UsbSerialDriver { | ||||
| 
 | ||||
|     @Override | ||||
|     public int read(byte[] dest, int timeoutMillis) throws IOException { | ||||
|         final int readAmt = Math.min(dest.length, mReadBuffer.length); | ||||
|         final UsbEndpoint endpoint = mDevice.getInterface(0).getEndpoint(0); | ||||
| 
 | ||||
|         if (ENABLE_ASYNC_READS) { | ||||
|             final int readAmt; | ||||
|             synchronized (mReadBufferLock) { | ||||
|                 // mReadBuffer is only used for maximum read size. | ||||
|                 readAmt = Math.min(dest.length, mReadBuffer.length); | ||||
|             } | ||||
| 
 | ||||
|             final UsbRequest request = new UsbRequest(); | ||||
|             request.initialize(mConnection, endpoint); | ||||
| 
 | ||||
| @ -245,27 +242,32 @@ public class FtdiSerialDriver extends UsbSerialDriver { | ||||
|                 throw new IOException("Null response"); | ||||
|             } | ||||
| 
 | ||||
|             final int nread = buf.position() - MODEM_STATUS_HEADER_LENGTH; | ||||
|             if (nread > 0) { | ||||
|             final int payloadBytesRead = buf.position() - MODEM_STATUS_HEADER_LENGTH; | ||||
|             if (payloadBytesRead > 0) { | ||||
|                 Log.d(TAG, HexDump.dumpHexString(dest, 0, Math.min(32, dest.length))); | ||||
|                 return nread; | ||||
|                 return payloadBytesRead; | ||||
|             } else { | ||||
|                 return 0; | ||||
|             } | ||||
|         } else { | ||||
|             final int transferred = mConnection.bulkTransfer(endpoint, mReadBuffer, readAmt, | ||||
|                     timeoutMillis); | ||||
|             if (transferred < MODEM_STATUS_HEADER_LENGTH) { | ||||
|             final int totalBytesRead; | ||||
| 
 | ||||
|             synchronized (mReadBufferLock) { | ||||
|                 final int readAmt = Math.min(dest.length, mReadBuffer.length); | ||||
|                 totalBytesRead = mConnection.bulkTransfer(endpoint, mReadBuffer, | ||||
|                         readAmt, timeoutMillis); | ||||
|             } | ||||
| 
 | ||||
|             if (totalBytesRead < MODEM_STATUS_HEADER_LENGTH) { | ||||
|                 throw new IOException("Expected at least " + MODEM_STATUS_HEADER_LENGTH + " bytes"); | ||||
|             } | ||||
| 
 | ||||
|             final int nread = transferred - MODEM_STATUS_HEADER_LENGTH; | ||||
|             if (nread > 0) { | ||||
|                 System.arraycopy(mReadBuffer, MODEM_STATUS_HEADER_LENGTH, dest, 0, nread); | ||||
|             final int payloadBytesRead = totalBytesRead - MODEM_STATUS_HEADER_LENGTH; | ||||
|             if (payloadBytesRead > 0) { | ||||
|                 System.arraycopy(mReadBuffer, MODEM_STATUS_HEADER_LENGTH, dest, 0, payloadBytesRead); | ||||
|             } | ||||
|             return nread; | ||||
|             return payloadBytesRead; | ||||
|         } | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
| @ -274,25 +276,32 @@ public class FtdiSerialDriver extends UsbSerialDriver { | ||||
|         int offset = 0; | ||||
| 
 | ||||
|         while (offset < src.length) { | ||||
|             final byte[] writeBuffer; | ||||
|             final int writeLength; | ||||
|             final int amtWritten; | ||||
| 
 | ||||
|             // bulkTransfer does not support offsets; make a copy if necessary. | ||||
|             writeLength = Math.min(src.length - offset, WRITE_CHUNKSIZE); | ||||
|             synchronized (mWriteBufferLock) { | ||||
|                 final byte[] writeBuffer; | ||||
| 
 | ||||
|                 writeLength = Math.min(src.length - offset, mWriteBuffer.length); | ||||
|                 if (offset == 0) { | ||||
|                     writeBuffer = src; | ||||
|                 } else { | ||||
|                 writeBuffer = Arrays.copyOfRange(src, offset, offset + writeLength); | ||||
|                     // bulkTransfer does not support offsets, make a copy. | ||||
|                     System.arraycopy(src, offset, mWriteBuffer, 0, writeLength); | ||||
|                     writeBuffer = mWriteBuffer; | ||||
|                 } | ||||
| 
 | ||||
|             final int amt = mConnection.bulkTransfer(endpoint, writeBuffer, writeLength, | ||||
|                 amtWritten = mConnection.bulkTransfer(endpoint, writeBuffer, writeLength, | ||||
|                         timeoutMillis); | ||||
|             if (amt <= 0) { | ||||
|             } | ||||
| 
 | ||||
|             if (amtWritten <= 0) { | ||||
|                 throw new IOException("Error writing " + writeLength | ||||
|                         + " bytes at offset " + offset + " length=" + src.length); | ||||
|             } | ||||
|             Log.d(TAG, "Wrote amt=" + amt + " attempted=" + writeBuffer.length); | ||||
|             offset += amt; | ||||
| 
 | ||||
|             Log.d(TAG, "Wrote amtWritten=" + amtWritten + " attempted=" + writeLength); | ||||
|             offset += amtWritten; | ||||
|         } | ||||
|         return offset; | ||||
|     } | ||||
|  | ||||
| @ -32,12 +32,27 @@ import android.hardware.usb.UsbDeviceConnection; | ||||
|  */ | ||||
| public abstract class UsbSerialDriver { | ||||
| 
 | ||||
|     public static final int DEFAULT_READ_BUFFER_SIZE = 16 * 1024; | ||||
|     public static final int DEFAULT_WRITE_BUFFER_SIZE = 16 * 1024; | ||||
| 
 | ||||
|     protected final UsbDevice mDevice; | ||||
|     protected final UsbDeviceConnection mConnection; | ||||
| 
 | ||||
|     protected final Object mReadBufferLock = 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}. */ | ||||
|     protected byte[] mWriteBuffer; | ||||
| 
 | ||||
|     public UsbSerialDriver(UsbDevice device, UsbDeviceConnection connection) { | ||||
|         mDevice = device; | ||||
|         mConnection = connection; | ||||
| 
 | ||||
|         mReadBuffer = new byte[DEFAULT_READ_BUFFER_SIZE]; | ||||
|         mWriteBuffer = new byte[DEFAULT_WRITE_BUFFER_SIZE]; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
| @ -93,4 +108,34 @@ public abstract class UsbSerialDriver { | ||||
|         return mDevice; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * 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 | ||||
|      * stack for write operations.  Most users should not need to change this. | ||||
|      * | ||||
|      * @param bufferSize the size in bytes | ||||
|      */ | ||||
|     public final void setWriteBufferSize(int bufferSize) { | ||||
|         synchronized (mWriteBufferLock) { | ||||
|             if (bufferSize == mWriteBuffer.length) { | ||||
|                 return; | ||||
|             } | ||||
|             mWriteBuffer = new byte[bufferSize]; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
| } | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user