mirror of
https://github.com/mik3y/usb-serial-for-android.git
synced 2026-08-12 17:03:06 +00:00
implement async read for all devices
This commit is contained in:
+15
-15
@@ -191,23 +191,23 @@ public class Ch34xSerialDriver implements UsbSerialDriver {
|
||||
} finally {
|
||||
request.close();
|
||||
}
|
||||
}
|
||||
|
||||
final int numBytesRead;
|
||||
synchronized (mReadBufferLock) {
|
||||
int readAmt = Math.min(dest.length, mReadBuffer.length);
|
||||
numBytesRead = mConnection.bulkTransfer(mReadEndpoint, mReadBuffer, readAmt,
|
||||
timeoutMillis);
|
||||
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;
|
||||
} else {
|
||||
final int numBytesRead;
|
||||
synchronized (mReadBufferLock) {
|
||||
int readAmt = Math.min(dest.length, mReadBuffer.length);
|
||||
numBytesRead = mConnection.bulkTransfer(mReadEndpoint, mReadBuffer, readAmt,
|
||||
timeoutMillis);
|
||||
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, numBytesRead);
|
||||
}
|
||||
System.arraycopy(mReadBuffer, 0, dest, 0, numBytesRead);
|
||||
return numBytesRead;
|
||||
}
|
||||
return numBytesRead;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+44
-13
@@ -26,9 +26,12 @@ import android.hardware.usb.UsbDevice;
|
||||
import android.hardware.usb.UsbDeviceConnection;
|
||||
import android.hardware.usb.UsbEndpoint;
|
||||
import android.hardware.usb.UsbInterface;
|
||||
import android.hardware.usb.UsbRequest;
|
||||
import android.os.Build;
|
||||
import android.util.Log;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
@@ -101,11 +104,13 @@ public class Cp21xxSerialDriver implements UsbSerialDriver {
|
||||
private static final int CONTROL_WRITE_DTR = 0x0100;
|
||||
private static final int CONTROL_WRITE_RTS = 0x0200;
|
||||
|
||||
private final boolean mEnableAsyncReads;
|
||||
private UsbEndpoint mReadEndpoint;
|
||||
private UsbEndpoint mWriteEndpoint;
|
||||
|
||||
public Cp21xxSerialPort(UsbDevice device, int portNumber) {
|
||||
super(device, portNumber);
|
||||
mEnableAsyncReads = (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -179,21 +184,47 @@ public class Cp21xxSerialDriver implements UsbSerialDriver {
|
||||
|
||||
@Override
|
||||
public int read(byte[] dest, int timeoutMillis) throws IOException {
|
||||
final int numBytesRead;
|
||||
synchronized (mReadBufferLock) {
|
||||
int readAmt = Math.min(dest.length, mReadBuffer.length);
|
||||
numBytesRead = mConnection.bulkTransfer(mReadEndpoint, mReadBuffer, readAmt,
|
||||
timeoutMillis);
|
||||
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;
|
||||
if (mEnableAsyncReads) {
|
||||
final UsbRequest request = new UsbRequest();
|
||||
try {
|
||||
request.initialize(mConnection, mReadEndpoint);
|
||||
final ByteBuffer buf = ByteBuffer.wrap(dest);
|
||||
if (!request.queue(buf, dest.length)) {
|
||||
throw new IOException("Error queueing request.");
|
||||
}
|
||||
|
||||
final UsbRequest response = mConnection.requestWait();
|
||||
if (response == null) {
|
||||
throw new IOException("Null response");
|
||||
}
|
||||
|
||||
final int nread = buf.position();
|
||||
if (nread > 0) {
|
||||
//Log.d(TAG, HexDump.dumpHexString(dest, 0, Math.min(32, dest.length)));
|
||||
return nread;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
} finally {
|
||||
request.close();
|
||||
}
|
||||
System.arraycopy(mReadBuffer, 0, dest, 0, numBytesRead);
|
||||
} else {
|
||||
final int numBytesRead;
|
||||
synchronized (mReadBufferLock) {
|
||||
int readAmt = Math.min(dest.length, mReadBuffer.length);
|
||||
numBytesRead = mConnection.bulkTransfer(mReadEndpoint, mReadBuffer, readAmt,
|
||||
timeoutMillis);
|
||||
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, numBytesRead);
|
||||
}
|
||||
return numBytesRead;
|
||||
}
|
||||
return numBytesRead;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+39
-8
@@ -32,10 +32,13 @@ import android.hardware.usb.UsbDevice;
|
||||
import android.hardware.usb.UsbDeviceConnection;
|
||||
import android.hardware.usb.UsbEndpoint;
|
||||
import android.hardware.usb.UsbInterface;
|
||||
import android.hardware.usb.UsbRequest;
|
||||
import android.os.Build;
|
||||
import android.util.Log;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
@@ -109,6 +112,7 @@ public class ProlificSerialDriver implements UsbSerialDriver {
|
||||
|
||||
private int mDeviceType = DEVICE_TYPE_HX;
|
||||
|
||||
private final boolean mEnableAsyncReads;
|
||||
private UsbEndpoint mReadEndpoint;
|
||||
private UsbEndpoint mWriteEndpoint;
|
||||
private UsbEndpoint mInterruptEndpoint;
|
||||
@@ -126,6 +130,7 @@ public class ProlificSerialDriver implements UsbSerialDriver {
|
||||
|
||||
public ProlificSerialPort(UsbDevice device, int portNumber) {
|
||||
super(device, portNumber);
|
||||
mEnableAsyncReads = (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -368,15 +373,41 @@ public class ProlificSerialDriver implements UsbSerialDriver {
|
||||
|
||||
@Override
|
||||
public int read(byte[] dest, int timeoutMillis) throws IOException {
|
||||
synchronized (mReadBufferLock) {
|
||||
int readAmt = Math.min(dest.length, mReadBuffer.length);
|
||||
int numBytesRead = mConnection.bulkTransfer(mReadEndpoint, mReadBuffer,
|
||||
readAmt, timeoutMillis);
|
||||
if (numBytesRead < 0) {
|
||||
return 0;
|
||||
if (mEnableAsyncReads) {
|
||||
final UsbRequest request = new UsbRequest();
|
||||
try {
|
||||
request.initialize(mConnection, mReadEndpoint);
|
||||
final ByteBuffer buf = ByteBuffer.wrap(dest);
|
||||
if (!request.queue(buf, dest.length)) {
|
||||
throw new IOException("Error queueing request.");
|
||||
}
|
||||
|
||||
final UsbRequest response = mConnection.requestWait();
|
||||
if (response == null) {
|
||||
throw new IOException("Null response");
|
||||
}
|
||||
|
||||
final int nread = buf.position();
|
||||
if (nread > 0) {
|
||||
//Log.d(TAG, HexDump.dumpHexString(dest, 0, Math.min(32, dest.length)));
|
||||
return nread;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
} finally {
|
||||
request.close();
|
||||
}
|
||||
} else {
|
||||
synchronized (mReadBufferLock) {
|
||||
int readAmt = Math.min(dest.length, mReadBuffer.length);
|
||||
int numBytesRead = mConnection.bulkTransfer(mReadEndpoint, mReadBuffer,
|
||||
readAmt, timeoutMillis);
|
||||
if (numBytesRead < 0) {
|
||||
return 0;
|
||||
}
|
||||
System.arraycopy(mReadBuffer, 0, dest, 0, numBytesRead);
|
||||
return numBytesRead;
|
||||
}
|
||||
System.arraycopy(mReadBuffer, 0, dest, 0, numBytesRead);
|
||||
return numBytesRead;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
-1
@@ -120,7 +120,6 @@ public class SerialInputOutputManager implements Runnable {
|
||||
* called, or until a driver exception is raised.
|
||||
*
|
||||
* NOTE(mikey): Uses inefficient read/write-with-timeout.
|
||||
* TODO(mikey): Read asynchronously with {@link UsbRequest#queue(ByteBuffer, int)}
|
||||
*/
|
||||
@Override
|
||||
public void run() {
|
||||
|
||||
Reference in New Issue
Block a user