From daab45d14d39f5bea82d3b06b4c48eb4a85b680a Mon Sep 17 00:00:00 2001 From: James Cotton <peabody124@gmail.com> Date: Mon, 13 Aug 2012 01:07:09 -0500 Subject: [PATCH] AndroidGCS HID: Go back to a read and write thread but now use synchronous bultTransfer for write which gets rid of the segfaults with running two asynchronous transfers. --- .../androidgcs/telemetry/HidUAVTalk.java | 98 ++++++++++++------- 1 file changed, 64 insertions(+), 34 deletions(-) diff --git a/androidgcs/src/org/openpilot/androidgcs/telemetry/HidUAVTalk.java b/androidgcs/src/org/openpilot/androidgcs/telemetry/HidUAVTalk.java index a074e79ca..9cb2d8be7 100644 --- a/androidgcs/src/org/openpilot/androidgcs/telemetry/HidUAVTalk.java +++ b/androidgcs/src/org/openpilot/androidgcs/telemetry/HidUAVTalk.java @@ -28,7 +28,7 @@ import android.util.Log; public class HidUAVTalk extends TelemetryTask { private static final String TAG = HidUAVTalk.class.getSimpleName(); - public static final int LOGLEVEL = 0; + public static final int LOGLEVEL = 1; public static final boolean DEBUG = LOGLEVEL > 2; public static final boolean WARN = LOGLEVEL > 1; public static final boolean ERROR = LOGLEVEL > 0; @@ -57,9 +57,10 @@ public class HidUAVTalk extends TelemetryTask { private UsbInterface usbInterface = null; private TalkInputStream inTalkStream; private TalkOutputStream outTalkStream; - private UsbRequest writeRequest = null; + private final UsbRequest writeRequest = null; private UsbRequest readRequest = null; - private Thread readWriteThread; + private Thread readThread; + private Thread writeThread; private boolean readPending = false; private boolean writePending = false; @@ -78,9 +79,15 @@ public class HidUAVTalk extends TelemetryTask { super.disconnect(); try { - if(readWriteThread != null) { - readWriteThread.join(); - readWriteThread = null; + if(readThread != null) { + readThread.interrupt(); // Make sure not blocking for data + readThread.join(); + readThread = null; + } + if(writeThread != null) { + writeThread.interrupt(); + writeThread.join(); + writeThread = null; } } catch (InterruptedException e) { e.printStackTrace(); @@ -91,13 +98,6 @@ public class HidUAVTalk extends TelemetryTask { readRequest.close(); readRequest = null; } - - if (writeRequest != null) { - writeRequest.cancel(); - writeRequest.close(); - writeRequest = null; - } - } @Override @@ -293,9 +293,6 @@ public class HidUAVTalk extends TelemetryTask { readRequest = new UsbRequest(); readRequest.initialize(usbDeviceConnection, usbEndpointRead); - writeRequest = new UsbRequest(); - writeRequest.initialize(usbDeviceConnection, usbEndpointWrite); - inTalkStream = new TalkInputStream(); outTalkStream = new TalkOutputStream(); inStream = inTalkStream; @@ -307,31 +304,39 @@ public class HidUAVTalk extends TelemetryTask { } }); - readWriteThread = new Thread(new Runnable() { + readThread = new Thread(new Runnable() { @Override public void run() { - // Enqueue the first read queueRead(); - while (!shutdown) { - // If there are no request - - // Enqueue requests appropriately first UsbRequest returned = usbDeviceConnection.requestWait(); if (returned == readRequest) { if (DEBUG) Log.d(TAG, "Received read request"); readData(); - } else if (returned == writeRequest) { - if (DEBUG) Log.d(TAG, "Received write completed request"); - writePending = false; - sendData(); - } + } else + Log.e(TAG, "Received unknown USB response"); } } - }, "HID Read Write"); - readWriteThread.start(); + }, "HID Read"); + readThread.start(); + + writeThread = new Thread(new Runnable() { + @Override + public void run() { + if (DEBUG) Log.d(TAG, "Starting HID write thread"); + while(!shutdown) { + try { + sendDataSynchronous(); + } catch (InterruptedException e) { + break; + } + } + if (DEBUG) Log.d(TAG, "Ending HID write thread"); + } + }, "HID Write"); + writeThread.start(); return true; } @@ -402,6 +407,7 @@ public class HidUAVTalk extends TelemetryTask { } } + /** * Send a packet if data is available */ @@ -426,6 +432,21 @@ public class HidUAVTalk extends TelemetryTask { } } + /** + * Send a packet if data is available + * @throws InterruptedException + */ + public void sendDataSynchronous() throws InterruptedException { + + ByteBuffer packet = outTalkStream.getHIDpacketBlocking(); + if (packet != null) { + if (DEBUG) Log.d(TAG, "sendDataSynchronous() Writing to device()"); + + if (usbDeviceConnection.bulkTransfer(usbEndpointWrite, packet.array(), MAX_HID_PACKET_SIZE, 1000) < 0) + Log.e(TAG, "Failed to perform bult write"); + } + } + /*********** Helper classes for telemetry streams ************/ class TalkOutputStream extends OutputStream { @@ -433,6 +454,20 @@ public class HidUAVTalk extends TelemetryTask { // and ByteFifo.put(byte []) ByteFifo data = new ByteFifo(); + /** + * Blocks until data is available and then returns a properly formatted HID packet + */ + public ByteBuffer getHIDpacketBlocking() throws InterruptedException { + synchronized(data) { + if (data.remaining() == 0) + data.wait(); + return getHIDpacket(); + } + } + + /** + * Gets data from the ByteFifo in a properly formatted HID packet + */ public ByteBuffer getHIDpacket() { ByteBuffer packet = null; synchronized(data) { @@ -461,9 +496,6 @@ public class HidUAVTalk extends TelemetryTask { data.put((byte) oneByte); data.notify(); } - - // If there is not a write request queued, add one - sendData(); } @Override @@ -475,8 +507,6 @@ public class HidUAVTalk extends TelemetryTask { data.put(b); data.notify(); } - - sendData(); } };