From b15b9c6cd0e8d83ec12a868c10cf184217f51309 Mon Sep 17 00:00:00 2001
From: Christof Arnosti <charno@charno.ch>
Date: Sun, 8 Mar 2020 15:25:55 +0100
Subject: usb-serial-for-android: Implement timeout-handling

Since the Android USB stack and subsequently the usb-serial-for-android
driver have problems with read-timeouts, the read-timeout is now
implemented in AndroidSerial.java. Also, DC_STATUS_TIMEOUT is returned
if there are less bytes returned than expected.

Different chipsets seem to behave differently with
usb-serial-for-android. On CP210x the read blocks until there is some
data here, but on FTDI the chip seems to return whatever is currently in
the buffer (so 0 bytes if the buffer is empty). This different behaviour
should be mitigated by the changes by this commit.

Signed-off-by: Christof Arnosti <charno@charno.ch>
---
 .../src/org/subsurfacedivelog/mobile/AndroidSerial.java      | 12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)

(limited to 'android-mobile/src/org/subsurfacedivelog')

diff --git a/android-mobile/src/org/subsurfacedivelog/mobile/AndroidSerial.java b/android-mobile/src/org/subsurfacedivelog/mobile/AndroidSerial.java
index 59b8dc9e9..1193b0ceb 100644
--- a/android-mobile/src/org/subsurfacedivelog/mobile/AndroidSerial.java
+++ b/android-mobile/src/org/subsurfacedivelog/mobile/AndroidSerial.java
@@ -19,6 +19,7 @@ import java.util.Queue;
 import java.util.List;
 import java.util.LinkedList;
 import java.lang.Math;
+import java.util.Date;
 
 public class AndroidSerial {
 
@@ -221,17 +222,20 @@ public class AndroidSerial {
 			Log.d(TAG, "read length: " + data.length);
 
 			int toReadFromHwLength = data.length - readBuffer.size();
-
 			int arraylength = (toReadFromHwLength % 64) != 0 ? toReadFromHwLength + (64 - (toReadFromHwLength % 64)): toReadFromHwLength; // use blocks of 64 for reading
 
-			// When we don't have enough in the buffer, try to read from HW
-			if (toReadFromHwLength > 0) {
+			long startTime =  (new Date()).getTime();
+
+			// while we don't have enough in the buffer, try to read from HW until there is enough or timeout is reached.
+			while (toReadFromHwLength > 0 && (startTime + timeout > (new Date()).getTime() || timeout == 0)) {
 				// Read and append to buffer
 				byte[] readFromHwData = new byte[arraylength];
-				int actuallyReadFromHwLength = usbSerialPort.read(readFromHwData, 0); // With this it works... But the timeout is ignored! Fix this!
+				int actuallyReadFromHwLength = usbSerialPort.read(readFromHwData, 0); // This behaves differently on different chipsets. CP210x blocks, FTDI seems to return instantly.
 				for (int i = 0; i < actuallyReadFromHwLength; i++ ) {
 					readBuffer.add(readFromHwData[i]);
 				}
+				toReadFromHwLength = data.length - readBuffer.size();
+				arraylength = (toReadFromHwLength % 64) != 0 ? toReadFromHwLength + (64 - (toReadFromHwLength % 64)): toReadFromHwLength; // use blocks of 64 for reading
 			}
 
 			//Log.d(TAG, "read buffer: " + printQueue(readBuffer));
-- 
cgit v1.2.3-70-g09d2