kopia lustrzana https://github.com/mik3y/usb-serial-for-android
rodzic
880c0070cb
commit
1db6c393a8
|
@ -169,16 +169,23 @@ public abstract class CommonUsbSerialPort implements UsbSerialPort {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int read(final byte[] dest, final int timeout) throws IOException {
|
public int read(final byte[] dest, final int timeout) throws IOException {
|
||||||
return read(dest, timeout, true);
|
if(dest.length <= 0) {
|
||||||
|
throw new IllegalArgumentException("Read buffer too small");
|
||||||
|
}
|
||||||
|
return read(dest, dest.length, timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected int read(final byte[] dest, final int timeout, boolean testConnection) throws IOException {
|
@Override
|
||||||
|
public int read(final byte[] dest, final int length, final int timeout) throws IOException {return read(dest, length, timeout, true);}
|
||||||
|
|
||||||
|
protected int read(final byte[] dest, int length, final int timeout, boolean testConnection) throws IOException {
|
||||||
if(mConnection == null || mUsbRequest == null) {
|
if(mConnection == null || mUsbRequest == null) {
|
||||||
throw new IOException("Connection closed");
|
throw new IOException("Connection closed");
|
||||||
}
|
}
|
||||||
if(dest.length <= 0) {
|
if(length <= 0) {
|
||||||
throw new IllegalArgumentException("Read buffer to small");
|
throw new IllegalArgumentException("Read length too small");
|
||||||
}
|
}
|
||||||
|
length = Math.min(length, dest.length);
|
||||||
final int nread;
|
final int nread;
|
||||||
if (timeout != 0) {
|
if (timeout != 0) {
|
||||||
// bulkTransfer will cause data loss with short timeout + high baud rates + continuous transfer
|
// bulkTransfer will cause data loss with short timeout + high baud rates + continuous transfer
|
||||||
|
@ -190,7 +197,7 @@ public abstract class CommonUsbSerialPort implements UsbSerialPort {
|
||||||
// /system/lib64/libandroid_runtime.so (android_hardware_UsbDeviceConnection_request_wait(_JNIEnv*, _jobject*, long)+84)
|
// /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
|
// data loss / crashes were observed with timeout up to 200 msec
|
||||||
long endTime = testConnection ? MonotonicClock.millis() + timeout : 0;
|
long endTime = testConnection ? MonotonicClock.millis() + timeout : 0;
|
||||||
int readMax = Math.min(dest.length, MAX_READ_SIZE);
|
int readMax = Math.min(length, MAX_READ_SIZE);
|
||||||
nread = mConnection.bulkTransfer(mReadEndpoint, dest, readMax, timeout);
|
nread = mConnection.bulkTransfer(mReadEndpoint, dest, readMax, timeout);
|
||||||
// Android error propagation is improvable:
|
// Android error propagation is improvable:
|
||||||
// nread == -1 can be: timeout, connection lost, buffer to small, ???
|
// nread == -1 can be: timeout, connection lost, buffer to small, ???
|
||||||
|
@ -198,8 +205,8 @@ public abstract class CommonUsbSerialPort implements UsbSerialPort {
|
||||||
testConnection();
|
testConnection();
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
final ByteBuffer buf = ByteBuffer.wrap(dest);
|
final ByteBuffer buf = ByteBuffer.wrap(dest, 0, length);
|
||||||
if (!mUsbRequest.queue(buf, dest.length)) {
|
if (!mUsbRequest.queue(buf, length)) {
|
||||||
throw new IOException("Queueing USB request failed");
|
throw new IOException("Queueing USB request failed");
|
||||||
}
|
}
|
||||||
final UsbRequest response = mConnection.requestWait();
|
final UsbRequest response = mConnection.requestWait();
|
||||||
|
@ -217,14 +224,18 @@ public abstract class CommonUsbSerialPort implements UsbSerialPort {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void write(final byte[] src, final int timeout) throws IOException {
|
public void write(byte[] src, int timeout) throws IOException {write(src, src.length, timeout);}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void write(final byte[] src, int length, final int timeout) throws IOException {
|
||||||
int offset = 0;
|
int offset = 0;
|
||||||
final long endTime = (timeout == 0) ? 0 : (MonotonicClock.millis() + timeout);
|
final long endTime = (timeout == 0) ? 0 : (MonotonicClock.millis() + timeout);
|
||||||
|
length = Math.min(length, src.length);
|
||||||
|
|
||||||
if(mConnection == null) {
|
if(mConnection == null) {
|
||||||
throw new IOException("Connection closed");
|
throw new IOException("Connection closed");
|
||||||
}
|
}
|
||||||
while (offset < src.length) {
|
while (offset < length) {
|
||||||
int requestTimeout;
|
int requestTimeout;
|
||||||
final int requestLength;
|
final int requestLength;
|
||||||
final int actualLength;
|
final int actualLength;
|
||||||
|
@ -235,7 +246,7 @@ public abstract class CommonUsbSerialPort implements UsbSerialPort {
|
||||||
if (mWriteBuffer == null) {
|
if (mWriteBuffer == null) {
|
||||||
mWriteBuffer = new byte[mWriteEndpoint.getMaxPacketSize()];
|
mWriteBuffer = new byte[mWriteEndpoint.getMaxPacketSize()];
|
||||||
}
|
}
|
||||||
requestLength = Math.min(src.length - offset, mWriteBuffer.length);
|
requestLength = Math.min(length - offset, mWriteBuffer.length);
|
||||||
if (offset == 0) {
|
if (offset == 0) {
|
||||||
writeBuffer = src;
|
writeBuffer = src;
|
||||||
} else {
|
} else {
|
||||||
|
@ -257,7 +268,7 @@ public abstract class CommonUsbSerialPort implements UsbSerialPort {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
Log.d(TAG, "Wrote " + actualLength + "/" + requestLength + " offset " + offset + "/" + src.length + " timeout " + requestTimeout);
|
Log.d(TAG, "Wrote " + actualLength + "/" + requestLength + " offset " + offset + "/" + length + " timeout " + requestTimeout);
|
||||||
}
|
}
|
||||||
if (actualLength <= 0) {
|
if (actualLength <= 0) {
|
||||||
if (timeout != 0 && MonotonicClock.millis() >= endTime) {
|
if (timeout != 0 && MonotonicClock.millis() >= endTime) {
|
||||||
|
@ -265,7 +276,7 @@ public abstract class CommonUsbSerialPort implements UsbSerialPort {
|
||||||
ex.bytesTransferred = offset;
|
ex.bytesTransferred = offset;
|
||||||
throw ex;
|
throw ex;
|
||||||
} else {
|
} else {
|
||||||
throw new IOException("Error writing " + requestLength + " bytes at offset " + offset + " of total " + src.length);
|
throw new IOException("Error writing " + requestLength + " bytes at offset " + offset + " of total " + length);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
offset += actualLength;
|
offset += actualLength;
|
||||||
|
|
|
@ -139,24 +139,37 @@ public class FtdiSerialDriver implements UsbSerialDriver {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int read(final byte[] dest, final int timeout) throws IOException {
|
public int read(final byte[] dest, final int timeout) throws IOException
|
||||||
|
{
|
||||||
if(dest.length <= READ_HEADER_LENGTH) {
|
if(dest.length <= READ_HEADER_LENGTH) {
|
||||||
throw new IllegalArgumentException("Read buffer to small");
|
throw new IllegalArgumentException("Read buffer too small");
|
||||||
// could allocate larger buffer, including space for 2 header bytes, but this would
|
// 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
|
// 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.
|
// data transfer at high baud rates when buffers are fully filled.
|
||||||
}
|
}
|
||||||
|
return read(dest, dest.length, timeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int read(final byte[] dest, int length, final int timeout) throws IOException {
|
||||||
|
if(length <= READ_HEADER_LENGTH) {
|
||||||
|
throw new IllegalArgumentException("Read length too 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.
|
||||||
|
}
|
||||||
|
length = Math.min(length, dest.length);
|
||||||
int nread;
|
int nread;
|
||||||
if (timeout != 0) {
|
if (timeout != 0) {
|
||||||
long endTime = MonotonicClock.millis() + timeout;
|
long endTime = MonotonicClock.millis() + timeout;
|
||||||
do {
|
do {
|
||||||
nread = super.read(dest, Math.max(1, (int)(endTime - MonotonicClock.millis())), false);
|
nread = super.read(dest, length, Math.max(1, (int)(endTime - MonotonicClock.millis())), false);
|
||||||
} while (nread == READ_HEADER_LENGTH && MonotonicClock.millis() < endTime);
|
} while (nread == READ_HEADER_LENGTH && MonotonicClock.millis() < endTime);
|
||||||
if(nread <= 0 && MonotonicClock.millis() < endTime)
|
if(nread <= 0 && MonotonicClock.millis() < endTime)
|
||||||
testConnection();
|
testConnection();
|
||||||
} else {
|
} else {
|
||||||
do {
|
do {
|
||||||
nread = super.read(dest, timeout);
|
nread = super.read(dest, length, timeout);
|
||||||
} while (nread == READ_HEADER_LENGTH);
|
} while (nread == READ_HEADER_LENGTH);
|
||||||
}
|
}
|
||||||
return readFilter(dest, nread);
|
return readFilter(dest, nread);
|
||||||
|
|
|
@ -122,6 +122,17 @@ public interface UsbSerialPort extends Closeable {
|
||||||
*/
|
*/
|
||||||
int read(final byte[] dest, final int timeout) throws IOException;
|
int read(final byte[] dest, final int timeout) throws IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads bytes with specified length into the destination buffer.
|
||||||
|
*
|
||||||
|
* @param dest the destination byte buffer
|
||||||
|
* @param length the maximum length of the data to read
|
||||||
|
* @param timeout the timeout for reading in milliseconds, 0 is infinite
|
||||||
|
* @return the actual number of bytes read
|
||||||
|
* @throws IOException if an error occurred during reading
|
||||||
|
*/
|
||||||
|
int read(final byte[] dest, int length, final int timeout) throws IOException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Writes as many bytes as possible from the source buffer.
|
* Writes as many bytes as possible from the source buffer.
|
||||||
*
|
*
|
||||||
|
@ -133,6 +144,18 @@ public interface UsbSerialPort extends Closeable {
|
||||||
*/
|
*/
|
||||||
void write(final byte[] src, final int timeout) throws IOException;
|
void write(final byte[] src, final int timeout) throws IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes bytes with specified length from the source buffer.
|
||||||
|
*
|
||||||
|
* @param src the source byte buffer
|
||||||
|
* @param length the length of the data to write
|
||||||
|
* @param timeout the timeout for writing in milliseconds, 0 is infinite
|
||||||
|
* @throws SerialTimeoutException if timeout reached before sending all data.
|
||||||
|
* ex.bytesTransferred may contain bytes transferred
|
||||||
|
* @throws IOException if an error occurred during writing
|
||||||
|
*/
|
||||||
|
void write(final byte[] src, int length, final int timeout) throws IOException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets various serial port parameters.
|
* Sets various serial port parameters.
|
||||||
*
|
*
|
||||||
|
|
Ładowanie…
Reference in New Issue