kopia lustrzana https://github.com/mik3y/usb-serial-for-android
read with timeout now throws error on connection lost, e.g. device disconnected
and similar connection lost detection for prolific input control linespull/330/head v3.1.0
rodzic
c53c3ed0ae
commit
26999e3626
|
@ -1660,18 +1660,27 @@ public class DeviceTest {
|
|||
purged = false;
|
||||
}
|
||||
usb.deviceConnection.close();
|
||||
try {
|
||||
try { // only Prolific driver has early exit if nothing changed
|
||||
usb.setParameters(115200, 8, 1, UsbSerialPort.PARITY_NONE);
|
||||
if(!(usb.serialDriver instanceof ProlificSerialDriver))
|
||||
fail("setParameters error expected");
|
||||
} catch (IOException ignored) {
|
||||
}
|
||||
try {
|
||||
usb.setParameters(57600, 8, 1, UsbSerialPort.PARITY_NONE);
|
||||
fail("setParameters error expected");
|
||||
} catch (IOException ignored) {
|
||||
}
|
||||
try {
|
||||
usb.write("x".getBytes());
|
||||
fail("write error expected");
|
||||
} catch (IOException ignored) {
|
||||
}
|
||||
usb.serialPort.read(buf, 1000); // bulkTransfer returns -1 on timeout and error, so no exception thrown here
|
||||
try {
|
||||
usb.serialPort.read(buf, 1000);
|
||||
fail("read error expected");
|
||||
} catch (IOException ignored) {
|
||||
}
|
||||
try {
|
||||
usb.serialPort.read(buf, 0);
|
||||
fail("read error expected");
|
||||
|
@ -1683,16 +1692,17 @@ public class DeviceTest {
|
|||
} catch (IOException ignored) {
|
||||
}
|
||||
try {
|
||||
if(usb.serialDriver instanceof ProlificSerialDriver)
|
||||
Thread.sleep(600); // wait for background thread
|
||||
usb.serialPort.getRI();
|
||||
if(!(usb.serialDriver instanceof ProlificSerialDriver))
|
||||
fail("getRI error expected");
|
||||
fail("getRI error expected");
|
||||
} catch (IOException ignored) {
|
||||
} catch (UnsupportedOperationException ignored) {
|
||||
}
|
||||
if(purged) {
|
||||
try {
|
||||
usb.serialPort.purgeHwBuffers(true, true);
|
||||
fail("setRts error expected");
|
||||
fail("purgeHwBuffers error expected");
|
||||
} catch (IOException ignored) {
|
||||
}
|
||||
}
|
||||
|
|
|
@ -129,13 +129,27 @@ public abstract class CommonUsbSerialPort implements UsbSerialPort {
|
|||
|
||||
protected abstract void closeInt();
|
||||
|
||||
/**
|
||||
* use simple USB request supported by all devices to test if connection is still valid
|
||||
*/
|
||||
protected void testConnection() throws IOException {
|
||||
byte[] buf = new byte[2];
|
||||
int len = mConnection.controlTransfer(0x80 /*DEVICE*/, 0 /*GET_STATUS*/, 0, 0, buf, buf.length, 200);
|
||||
if(len < 0)
|
||||
throw new IOException("USB get_status request failed");
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read(final byte[] dest, final int timeout) throws IOException {
|
||||
return read(dest, timeout, true);
|
||||
}
|
||||
|
||||
protected int read(final byte[] dest, final int timeout, boolean testConnection) throws IOException {
|
||||
if(mConnection == null) {
|
||||
throw new IOException("Connection closed");
|
||||
}
|
||||
if(dest.length <= 0) {
|
||||
throw new IllegalArgumentException("read buffer to small");
|
||||
throw new IllegalArgumentException("Read buffer to small");
|
||||
}
|
||||
final int nread;
|
||||
if (timeout != 0) {
|
||||
|
@ -147,8 +161,12 @@ public abstract class CommonUsbSerialPort implements UsbSerialPort {
|
|||
// /system/lib64/libusbhost.so (usb_request_wait+192)
|
||||
// /system/lib64/libandroid_runtime.so (android_hardware_UsbDeviceConnection_request_wait(_JNIEnv*, _jobject*, long)+84)
|
||||
// data loss / crashes were observed with timeout up to 200 msec
|
||||
long endTime = testConnection ? System.currentTimeMillis() + timeout : 0;
|
||||
int readMax = Math.min(dest.length, MAX_READ_SIZE);
|
||||
nread = mConnection.bulkTransfer(mReadEndpoint, dest, readMax, timeout);
|
||||
// Android error propagation is improvable, nread == -1 can be: timeout, connection lost, buffer undersized, ...
|
||||
if(nread == -1 && testConnection && System.currentTimeMillis() < endTime)
|
||||
testConnection();
|
||||
|
||||
} else {
|
||||
final ByteBuffer buf = ByteBuffer.wrap(dest);
|
||||
|
|
|
@ -138,7 +138,7 @@ public class FtdiSerialDriver implements UsbSerialDriver {
|
|||
@Override
|
||||
public int read(final byte[] dest, final int timeout) throws IOException {
|
||||
if(dest.length <= READ_HEADER_LENGTH) {
|
||||
throw new IllegalArgumentException("read buffer to small");
|
||||
throw new IllegalArgumentException("Read buffer to small");
|
||||
// could allocate larger buffer, including space for 2 header bytes, but this would
|
||||
// result in buffers not being 64 byte aligned any more, causing data loss at continuous
|
||||
// data transfer at high baud rates when buffers are fully filled.
|
||||
|
@ -147,11 +147,13 @@ public class FtdiSerialDriver implements UsbSerialDriver {
|
|||
if (timeout != 0) {
|
||||
long endTime = System.currentTimeMillis() + timeout;
|
||||
do {
|
||||
nread = super.read(dest, Math.max(1, (int)(endTime - System.currentTimeMillis())));
|
||||
nread = super.read(dest, Math.max(1, (int)(endTime - System.currentTimeMillis())), false);
|
||||
} while (nread == READ_HEADER_LENGTH && System.currentTimeMillis() < endTime);
|
||||
if(nread <= 0 && System.currentTimeMillis() < endTime)
|
||||
testConnection();
|
||||
} else {
|
||||
do {
|
||||
nread = super.read(dest, timeout);
|
||||
nread = super.read(dest, timeout, false);
|
||||
} while (nread == READ_HEADER_LENGTH);
|
||||
}
|
||||
return readFilter(dest, nread);
|
||||
|
|
|
@ -184,10 +184,10 @@ public class ProlificSerialDriver implements UsbSerialDriver {
|
|||
try {
|
||||
while (!mStopReadStatusThread) {
|
||||
byte[] buffer = new byte[STATUS_BUFFER_SIZE];
|
||||
int readBytesCount = mConnection.bulkTransfer(mInterruptEndpoint,
|
||||
buffer,
|
||||
STATUS_BUFFER_SIZE,
|
||||
500);
|
||||
long endTime = System.currentTimeMillis() + 500;
|
||||
int readBytesCount = mConnection.bulkTransfer(mInterruptEndpoint, buffer, STATUS_BUFFER_SIZE, 500);
|
||||
if(readBytesCount == -1 && System.currentTimeMillis() < endTime)
|
||||
testConnection();
|
||||
if (readBytesCount > 0) {
|
||||
if (readBytesCount == STATUS_BUFFER_SIZE) {
|
||||
mStatus = buffer[STATUS_BYTE_IDX] & 0xff;
|
||||
|
|
Ładowanie…
Reference in New Issue