Always use async read, as bulkTransfer can cause data loss. Increase API version to 17 because async read only works reliably since Android 4.2 (http://b.android.com/28023)
This commit is contained in:
parent
e527afdf35
commit
0d48ed04e7
|
@ -3,7 +3,7 @@
|
||||||
This is a driver library for communication with Arduinos and other USB serial hardware on
|
This is a driver library for communication with Arduinos and other USB serial hardware on
|
||||||
Android, using the
|
Android, using the
|
||||||
[Android USB Host API](http://developer.android.com/guide/topics/connectivity/usb/host.html)
|
[Android USB Host API](http://developer.android.com/guide/topics/connectivity/usb/host.html)
|
||||||
available on Android 3.1+.
|
available since Android 3.1 and asynchronous interrupt transfer working reliably since Android 4.2
|
||||||
|
|
||||||
No root access, ADK, or special kernel drivers are required; all drivers are implemented in
|
No root access, ADK, or special kernel drivers are required; all drivers are implemented in
|
||||||
Java. You get a raw serial port with `read()`, `write()`, and other basic
|
Java. You get a raw serial port with `read()`, `write()`, and other basic
|
||||||
|
|
|
@ -6,7 +6,7 @@ buildscript {
|
||||||
google()
|
google()
|
||||||
}
|
}
|
||||||
dependencies {
|
dependencies {
|
||||||
classpath 'com.android.tools.build:gradle:3.2.1'
|
classpath 'com.android.tools.build:gradle:3.3.0'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#Sun Nov 11 09:16:07 CET 2018
|
#Sun Feb 03 09:37:03 CET 2019
|
||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-all.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.1-all.zip
|
||||||
|
|
|
@ -5,7 +5,7 @@ android {
|
||||||
buildToolsVersion '28.0.3'
|
buildToolsVersion '28.0.3'
|
||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
minSdkVersion 14
|
minSdkVersion 17
|
||||||
targetSdkVersion 28
|
targetSdkVersion 28
|
||||||
|
|
||||||
testInstrumentationRunner "android.test.InstrumentationTestRunner"
|
testInstrumentationRunner "android.test.InstrumentationTestRunner"
|
||||||
|
|
|
@ -7,7 +7,7 @@ android {
|
||||||
buildToolsVersion '28.0.3'
|
buildToolsVersion '28.0.3'
|
||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
minSdkVersion 14
|
minSdkVersion 17
|
||||||
targetSdkVersion 28
|
targetSdkVersion 28
|
||||||
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,7 +27,6 @@ import android.hardware.usb.UsbDeviceConnection;
|
||||||
import android.hardware.usb.UsbEndpoint;
|
import android.hardware.usb.UsbEndpoint;
|
||||||
import android.hardware.usb.UsbInterface;
|
import android.hardware.usb.UsbInterface;
|
||||||
import android.hardware.usb.UsbRequest;
|
import android.hardware.usb.UsbRequest;
|
||||||
import android.os.Build;
|
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
@ -69,7 +68,6 @@ public class CdcAcmSerialDriver implements UsbSerialDriver {
|
||||||
|
|
||||||
class CdcAcmSerialPort extends CommonUsbSerialPort {
|
class CdcAcmSerialPort extends CommonUsbSerialPort {
|
||||||
|
|
||||||
private final boolean mEnableAsyncReads;
|
|
||||||
private UsbInterface mControlInterface;
|
private UsbInterface mControlInterface;
|
||||||
private UsbInterface mDataInterface;
|
private UsbInterface mDataInterface;
|
||||||
|
|
||||||
|
@ -92,7 +90,6 @@ public class CdcAcmSerialDriver implements UsbSerialDriver {
|
||||||
|
|
||||||
public CdcAcmSerialPort(UsbDevice device, int portNumber) {
|
public CdcAcmSerialPort(UsbDevice device, int portNumber) {
|
||||||
super(device, portNumber);
|
super(device, portNumber);
|
||||||
mEnableAsyncReads = (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -118,13 +115,6 @@ public class CdcAcmSerialDriver implements UsbSerialDriver {
|
||||||
openInterface();
|
openInterface();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mEnableAsyncReads) {
|
|
||||||
Log.d(TAG, "Async reads enabled");
|
|
||||||
} else {
|
|
||||||
Log.d(TAG, "Async reads disabled.");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
opened = true;
|
opened = true;
|
||||||
} finally {
|
} finally {
|
||||||
if (!opened) {
|
if (!opened) {
|
||||||
|
@ -269,51 +259,29 @@ public class CdcAcmSerialDriver implements UsbSerialDriver {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int read(byte[] dest, int timeoutMillis) throws IOException {
|
public int read(byte[] dest, int timeoutMillis) throws IOException {
|
||||||
if (mEnableAsyncReads) {
|
final UsbRequest request = new UsbRequest();
|
||||||
final UsbRequest request = new UsbRequest();
|
try {
|
||||||
try {
|
|
||||||
request.initialize(mConnection, mReadEndpoint);
|
request.initialize(mConnection, mReadEndpoint);
|
||||||
final ByteBuffer buf = ByteBuffer.wrap(dest);
|
final ByteBuffer buf = ByteBuffer.wrap(dest);
|
||||||
if (!request.queue(buf, dest.length)) {
|
if (!request.queue(buf, dest.length)) {
|
||||||
throw new IOException("Error queueing request.");
|
throw new IOException("Error queueing request.");
|
||||||
}
|
}
|
||||||
|
|
||||||
final UsbRequest response = mConnection.requestWait();
|
final UsbRequest response = mConnection.requestWait();
|
||||||
if (response == null) {
|
if (response == null) {
|
||||||
throw new IOException("Null response");
|
throw new IOException("Null response");
|
||||||
}
|
}
|
||||||
|
|
||||||
final int nread = buf.position();
|
final int nread = buf.position();
|
||||||
if (nread > 0) {
|
if (nread > 0) {
|
||||||
//Log.d(TAG, HexDump.dumpHexString(dest, 0, Math.min(32, dest.length)));
|
//Log.d(TAG, HexDump.dumpHexString(dest, 0, Math.min(32, dest.length)));
|
||||||
return nread;
|
return nread;
|
||||||
} else {
|
} else {
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
} 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
|
|
||||||
if (timeoutMillis == Integer.MAX_VALUE) {
|
|
||||||
// Hack: Special case "~infinite timeout" as an error.
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
System.arraycopy(mReadBuffer, 0, dest, 0, numBytesRead);
|
} finally {
|
||||||
|
request.close();
|
||||||
}
|
}
|
||||||
return numBytesRead;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -26,7 +26,6 @@ import android.hardware.usb.UsbDeviceConnection;
|
||||||
import android.hardware.usb.UsbEndpoint;
|
import android.hardware.usb.UsbEndpoint;
|
||||||
import android.hardware.usb.UsbInterface;
|
import android.hardware.usb.UsbInterface;
|
||||||
import android.hardware.usb.UsbRequest;
|
import android.hardware.usb.UsbRequest;
|
||||||
import android.os.Build;
|
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
@ -84,14 +83,12 @@ public class Ch34xSerialDriver implements UsbSerialDriver {
|
||||||
private boolean dtr = false;
|
private boolean dtr = false;
|
||||||
private boolean rts = false;
|
private boolean rts = false;
|
||||||
|
|
||||||
private final Boolean mEnableAsyncReads;
|
|
||||||
private UsbEndpoint mReadEndpoint;
|
private UsbEndpoint mReadEndpoint;
|
||||||
private UsbEndpoint mWriteEndpoint;
|
private UsbEndpoint mWriteEndpoint;
|
||||||
private UsbRequest mUsbRequest;
|
private UsbRequest mUsbRequest;
|
||||||
|
|
||||||
public Ch340SerialPort(UsbDevice device, int portNumber) {
|
public Ch340SerialPort(UsbDevice device, int portNumber) {
|
||||||
super(device, portNumber);
|
super(device, portNumber);
|
||||||
mEnableAsyncReads = (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -127,12 +124,6 @@ public class Ch34xSerialDriver implements UsbSerialDriver {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mEnableAsyncReads) {
|
|
||||||
Log.d(TAG, "Async reads enabled");
|
|
||||||
} else {
|
|
||||||
Log.d(TAG, "Async reads disabled.");
|
|
||||||
}
|
|
||||||
|
|
||||||
initialize();
|
initialize();
|
||||||
setBaudRate(DEFAULT_BAUD_RATE);
|
setBaudRate(DEFAULT_BAUD_RATE);
|
||||||
|
|
||||||
|
@ -153,12 +144,10 @@ public class Ch34xSerialDriver implements UsbSerialDriver {
|
||||||
if (mConnection == null) {
|
if (mConnection == null) {
|
||||||
throw new IOException("Already closed");
|
throw new IOException("Already closed");
|
||||||
}
|
}
|
||||||
synchronized (mEnableAsyncReads) {
|
synchronized (this) {
|
||||||
if (mUsbRequest != null)
|
if (mUsbRequest != null)
|
||||||
mUsbRequest.cancel();
|
mUsbRequest.cancel();
|
||||||
}
|
}
|
||||||
// TODO: nothing sended on close, maybe needed?
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
mConnection.close();
|
mConnection.close();
|
||||||
} finally {
|
} finally {
|
||||||
|
@ -169,50 +158,32 @@ public class Ch34xSerialDriver implements UsbSerialDriver {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int read(byte[] dest, int timeoutMillis) throws IOException {
|
public int read(byte[] dest, int timeoutMillis) throws IOException {
|
||||||
if (mEnableAsyncReads) {
|
final UsbRequest request = new UsbRequest();
|
||||||
final UsbRequest request = new UsbRequest();
|
try {
|
||||||
try {
|
request.initialize(mConnection, mReadEndpoint);
|
||||||
request.initialize(mConnection, mReadEndpoint);
|
final ByteBuffer buf = ByteBuffer.wrap(dest);
|
||||||
final ByteBuffer buf = ByteBuffer.wrap(dest);
|
if (!request.queue(buf, dest.length)) {
|
||||||
if (!request.queue(buf, dest.length)) {
|
throw new IOException("Error queueing request.");
|
||||||
throw new IOException("Error queueing request.");
|
}
|
||||||
}
|
mUsbRequest = request;
|
||||||
mUsbRequest = request;
|
final UsbRequest response = mConnection.requestWait();
|
||||||
final UsbRequest response = mConnection.requestWait();
|
synchronized (this) {
|
||||||
synchronized (mEnableAsyncReads) {
|
|
||||||
mUsbRequest = null;
|
|
||||||
}
|
|
||||||
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 {
|
|
||||||
mUsbRequest = null;
|
mUsbRequest = null;
|
||||||
request.close();
|
|
||||||
}
|
}
|
||||||
} else {
|
if (response == null) {
|
||||||
final int numBytesRead;
|
throw new IOException("Null response");
|
||||||
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;
|
|
||||||
|
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 {
|
||||||
|
mUsbRequest = null;
|
||||||
|
request.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,6 @@ import android.hardware.usb.UsbDeviceConnection;
|
||||||
import android.hardware.usb.UsbEndpoint;
|
import android.hardware.usb.UsbEndpoint;
|
||||||
import android.hardware.usb.UsbInterface;
|
import android.hardware.usb.UsbInterface;
|
||||||
import android.hardware.usb.UsbRequest;
|
import android.hardware.usb.UsbRequest;
|
||||||
import android.os.Build;
|
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
@ -107,7 +106,6 @@ public class Cp21xxSerialDriver implements UsbSerialDriver {
|
||||||
private static final int CONTROL_WRITE_DTR = 0x0100;
|
private static final int CONTROL_WRITE_DTR = 0x0100;
|
||||||
private static final int CONTROL_WRITE_RTS = 0x0200;
|
private static final int CONTROL_WRITE_RTS = 0x0200;
|
||||||
|
|
||||||
private final Boolean mEnableAsyncReads;
|
|
||||||
private UsbEndpoint mReadEndpoint;
|
private UsbEndpoint mReadEndpoint;
|
||||||
private UsbEndpoint mWriteEndpoint;
|
private UsbEndpoint mWriteEndpoint;
|
||||||
private UsbRequest mUsbRequest;
|
private UsbRequest mUsbRequest;
|
||||||
|
@ -118,7 +116,6 @@ public class Cp21xxSerialDriver implements UsbSerialDriver {
|
||||||
|
|
||||||
public Cp21xxSerialPort(UsbDevice device, int portNumber) {
|
public Cp21xxSerialPort(UsbDevice device, int portNumber) {
|
||||||
super(device, portNumber);
|
super(device, portNumber);
|
||||||
mEnableAsyncReads = (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -180,13 +177,16 @@ public class Cp21xxSerialDriver implements UsbSerialDriver {
|
||||||
if (mConnection == null) {
|
if (mConnection == null) {
|
||||||
throw new IOException("Already closed");
|
throw new IOException("Already closed");
|
||||||
}
|
}
|
||||||
synchronized (mEnableAsyncReads) {
|
synchronized (this) {
|
||||||
if(mUsbRequest != null) {
|
if(mUsbRequest != null) {
|
||||||
mUsbRequest.cancel();
|
mUsbRequest.cancel();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
setConfigSingle(SILABSER_IFC_ENABLE_REQUEST_CODE, UART_DISABLE);
|
setConfigSingle(SILABSER_IFC_ENABLE_REQUEST_CODE, UART_DISABLE);
|
||||||
|
} catch (Exception ignored)
|
||||||
|
{}
|
||||||
|
try {
|
||||||
mConnection.close();
|
mConnection.close();
|
||||||
} finally {
|
} finally {
|
||||||
mConnection = null;
|
mConnection = null;
|
||||||
|
@ -195,50 +195,32 @@ public class Cp21xxSerialDriver implements UsbSerialDriver {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int read(byte[] dest, int timeoutMillis) throws IOException {
|
public int read(byte[] dest, int timeoutMillis) throws IOException {
|
||||||
if (mEnableAsyncReads) {
|
final UsbRequest request = new UsbRequest();
|
||||||
final UsbRequest request = new UsbRequest();
|
try {
|
||||||
try {
|
request.initialize(mConnection, mReadEndpoint);
|
||||||
request.initialize(mConnection, mReadEndpoint);
|
final ByteBuffer buf = ByteBuffer.wrap(dest);
|
||||||
final ByteBuffer buf = ByteBuffer.wrap(dest);
|
if (!request.queue(buf, dest.length)) {
|
||||||
if (!request.queue(buf, dest.length)) {
|
throw new IOException("Error queueing request.");
|
||||||
throw new IOException("Error queueing request.");
|
}
|
||||||
}
|
mUsbRequest = request;
|
||||||
mUsbRequest = request;
|
final UsbRequest response = mConnection.requestWait();
|
||||||
final UsbRequest response = mConnection.requestWait();
|
synchronized (this) {
|
||||||
synchronized (mEnableAsyncReads) {
|
|
||||||
mUsbRequest = null;
|
|
||||||
}
|
|
||||||
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 {
|
|
||||||
mUsbRequest = null;
|
mUsbRequest = null;
|
||||||
request.close();
|
|
||||||
}
|
}
|
||||||
} else {
|
if (response == null) {
|
||||||
final int numBytesRead;
|
throw new IOException("Null response");
|
||||||
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;
|
|
||||||
|
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 {
|
||||||
|
mUsbRequest = null;
|
||||||
|
request.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,6 @@ import android.hardware.usb.UsbDevice;
|
||||||
import android.hardware.usb.UsbDeviceConnection;
|
import android.hardware.usb.UsbDeviceConnection;
|
||||||
import android.hardware.usb.UsbEndpoint;
|
import android.hardware.usb.UsbEndpoint;
|
||||||
import android.hardware.usb.UsbRequest;
|
import android.hardware.usb.UsbRequest;
|
||||||
import android.os.Build;
|
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
@ -186,16 +185,8 @@ public class FtdiSerialDriver implements UsbSerialDriver {
|
||||||
|
|
||||||
private int mIndex = 0;
|
private int mIndex = 0;
|
||||||
|
|
||||||
/**
|
|
||||||
* Due to http://b.android.com/28023 , we cannot use UsbRequest async reads
|
|
||||||
* since it gives no indication of number of bytes read. Set this to
|
|
||||||
* {@code true} on platforms where it is fixed.
|
|
||||||
*/
|
|
||||||
private final boolean mEnableAsyncReads;
|
|
||||||
|
|
||||||
public FtdiSerialPort(UsbDevice device, int portNumber) {
|
public FtdiSerialPort(UsbDevice device, int portNumber) {
|
||||||
super(device, portNumber);
|
super(device, portNumber);
|
||||||
mEnableAsyncReads = (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -286,46 +277,28 @@ public class FtdiSerialDriver implements UsbSerialDriver {
|
||||||
@Override
|
@Override
|
||||||
public int read(byte[] dest, int timeoutMillis) throws IOException {
|
public int read(byte[] dest, int timeoutMillis) throws IOException {
|
||||||
final UsbEndpoint endpoint = mDevice.getInterface(mPortNumber).getEndpoint(0);
|
final UsbEndpoint endpoint = mDevice.getInterface(mPortNumber).getEndpoint(0);
|
||||||
|
final UsbRequest request = new UsbRequest();
|
||||||
if (mEnableAsyncReads) {
|
final ByteBuffer buf = ByteBuffer.wrap(dest);
|
||||||
final UsbRequest request = new UsbRequest();
|
try {
|
||||||
final ByteBuffer buf = ByteBuffer.wrap(dest);
|
request.initialize(mConnection, endpoint);
|
||||||
try {
|
if (!request.queue(buf, dest.length)) {
|
||||||
request.initialize(mConnection, endpoint);
|
throw new IOException("Error queueing request.");
|
||||||
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");
|
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
request.close();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
final int totalBytesRead = buf.position();
|
final UsbRequest response = mConnection.requestWait();
|
||||||
if (totalBytesRead < MODEM_STATUS_HEADER_LENGTH) {
|
if (response == null) {
|
||||||
throw new IOException("Expected at least " + MODEM_STATUS_HEADER_LENGTH + " bytes");
|
throw new IOException("Null response");
|
||||||
}
|
|
||||||
|
|
||||||
return filterStatusBytes(dest, dest, totalBytesRead, endpoint.getMaxPacketSize());
|
|
||||||
|
|
||||||
} else {
|
|
||||||
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");
|
|
||||||
}
|
|
||||||
|
|
||||||
return filterStatusBytes(mReadBuffer, dest, totalBytesRead, endpoint.getMaxPacketSize());
|
|
||||||
}
|
}
|
||||||
|
} finally {
|
||||||
|
request.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final int totalBytesRead = buf.position();
|
||||||
|
if (totalBytesRead < MODEM_STATUS_HEADER_LENGTH) {
|
||||||
|
throw new IOException("Expected at least " + MODEM_STATUS_HEADER_LENGTH + " bytes");
|
||||||
|
}
|
||||||
|
|
||||||
|
return filterStatusBytes(dest, dest, totalBytesRead, endpoint.getMaxPacketSize());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -33,7 +33,6 @@ import android.hardware.usb.UsbDeviceConnection;
|
||||||
import android.hardware.usb.UsbEndpoint;
|
import android.hardware.usb.UsbEndpoint;
|
||||||
import android.hardware.usb.UsbInterface;
|
import android.hardware.usb.UsbInterface;
|
||||||
import android.hardware.usb.UsbRequest;
|
import android.hardware.usb.UsbRequest;
|
||||||
import android.os.Build;
|
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
@ -112,7 +111,6 @@ public class ProlificSerialDriver implements UsbSerialDriver {
|
||||||
|
|
||||||
private int mDeviceType = DEVICE_TYPE_HX;
|
private int mDeviceType = DEVICE_TYPE_HX;
|
||||||
|
|
||||||
private final boolean mEnableAsyncReads;
|
|
||||||
private UsbEndpoint mReadEndpoint;
|
private UsbEndpoint mReadEndpoint;
|
||||||
private UsbEndpoint mWriteEndpoint;
|
private UsbEndpoint mWriteEndpoint;
|
||||||
private UsbEndpoint mInterruptEndpoint;
|
private UsbEndpoint mInterruptEndpoint;
|
||||||
|
@ -130,7 +128,6 @@ public class ProlificSerialDriver implements UsbSerialDriver {
|
||||||
|
|
||||||
public ProlificSerialPort(UsbDevice device, int portNumber) {
|
public ProlificSerialPort(UsbDevice device, int portNumber) {
|
||||||
super(device, portNumber);
|
super(device, portNumber);
|
||||||
mEnableAsyncReads = (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -373,41 +370,28 @@ public class ProlificSerialDriver implements UsbSerialDriver {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int read(byte[] dest, int timeoutMillis) throws IOException {
|
public int read(byte[] dest, int timeoutMillis) throws IOException {
|
||||||
if (mEnableAsyncReads) {
|
final UsbRequest request = new UsbRequest();
|
||||||
final UsbRequest request = new UsbRequest();
|
try {
|
||||||
try {
|
request.initialize(mConnection, mReadEndpoint);
|
||||||
request.initialize(mConnection, mReadEndpoint);
|
final ByteBuffer buf = ByteBuffer.wrap(dest);
|
||||||
final ByteBuffer buf = ByteBuffer.wrap(dest);
|
if (!request.queue(buf, dest.length)) {
|
||||||
if (!request.queue(buf, dest.length)) {
|
throw new IOException("Error queueing request.");
|
||||||
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) {
|
final UsbRequest response = mConnection.requestWait();
|
||||||
int readAmt = Math.min(dest.length, mReadBuffer.length);
|
if (response == null) {
|
||||||
int numBytesRead = mConnection.bulkTransfer(mReadEndpoint, mReadBuffer,
|
throw new IOException("Null response");
|
||||||
readAmt, timeoutMillis);
|
|
||||||
if (numBytesRead < 0) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
System.arraycopy(mReadBuffer, 0, dest, 0, numBytesRead);
|
|
||||||
return numBytesRead;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue