From 03563c765d8b0ab3689c91b2b533c68e11650577 Mon Sep 17 00:00:00 2001 From: Mike Beattie Date: Tue, 28 Aug 2012 17:35:11 +1200 Subject: [PATCH] altosdroid: Add new "TelemetryReader" class to handle Telemetry * Add MSG_TELEMETRY messages to both AltosDroid and TelemetryService to handle passing of AltosState object all the way back to the UI. * Remove linkedblockinglist from TelemetryService * (MSG_TELEMETRY is a rename of MSG_INCOMING_TELEM in AltosDroid) * commented code in case statement inside AltosDroind - won't work with the objects it is currently passed. * Add new "MSG_DEVCONFIG" message to AltosDroid - allows TelemetryService to pass information about the connected device back to the UI. Signed-off-by: Mike Beattie --- .../altusmetrum/AltosDroid/AltosDroid.java | 14 ++-- .../AltosDroid/TelemetryReader.java | 75 +++++++++++++++++++ .../AltosDroid/TelemetryService.java | 23 ++++-- 3 files changed, 100 insertions(+), 12 deletions(-) create mode 100644 altosdroid/src/org/altusmetrum/AltosDroid/TelemetryReader.java diff --git a/altosdroid/src/org/altusmetrum/AltosDroid/AltosDroid.java b/altosdroid/src/org/altusmetrum/AltosDroid/AltosDroid.java index 33da9346..cf982eac 100644 --- a/altosdroid/src/org/altusmetrum/AltosDroid/AltosDroid.java +++ b/altosdroid/src/org/altusmetrum/AltosDroid/AltosDroid.java @@ -60,8 +60,9 @@ public class AltosDroid extends Activity { // Message types sent from the TelemetryService Handler public static final int MSG_STATE_CHANGE = 1; public static final int MSG_DEVNAME = 2; - public static final int MSG_INCOMING_TELEM = 3; - public static final int MSG_TOAST = 4; + public static final int MSG_TOAST = 3; + public static final int MSG_DEVCONFIG = 4; + public static final int MSG_TELEMETRY = 5; // Intent request codes private static final int REQUEST_CONNECT_DEVICE = 1; @@ -111,11 +112,12 @@ public class AltosDroid extends Activity { break; } break; - case MSG_INCOMING_TELEM: - byte[] buf = (byte[]) msg.obj; + case MSG_DEVCONFIG: + case MSG_TELEMETRY: + //byte[] buf = (byte[]) msg.obj; // construct a string from the buffer - String telem = new String(buf); - ad.mSerialView.append(telem); + //String telem = new String(buf); + //ad.mSerialView.append(telem); break; case MSG_DEVNAME: // save the connected device's name diff --git a/altosdroid/src/org/altusmetrum/AltosDroid/TelemetryReader.java b/altosdroid/src/org/altusmetrum/AltosDroid/TelemetryReader.java new file mode 100644 index 00000000..bfa5db5c --- /dev/null +++ b/altosdroid/src/org/altusmetrum/AltosDroid/TelemetryReader.java @@ -0,0 +1,75 @@ +package org.altusmetrum.AltosDroid; + +import java.text.*; +import java.io.*; +import java.util.concurrent.*; +import android.util.Log; +import android.os.Handler; + +import org.altusmetrum.AltosLib.*; + + +public class TelemetryReader extends Thread { + + private static final String TAG = "TelemetryReader"; + + int crc_errors; + + Handler handler; + + AltosLink link; + AltosRecord previous; + + LinkedBlockingQueue telem; + + public AltosRecord read() throws ParseException, AltosCRCException, InterruptedException, IOException { + AltosLine l = telem.take(); + if (l.line == null) + throw new IOException("IO error"); + AltosRecord next = AltosTelemetry.parse(l.line, previous); + previous = next; + return next; + } + + public void close() { + previous = null; + link.remove_monitor(telem); + link = null; + telem.clear(); + telem = null; + } + + public void run() { + AltosState state = null; + + try { + for (;;) { + try { + AltosRecord record = read(); + if (record == null) + break; + state = new AltosState(record, state); + + handler.obtainMessage(TelemetryService.MSG_TELEMETRY, state).sendToTarget(); + } catch (ParseException pp) { + Log.e(TAG, String.format("Parse error: %d \"%s\"", pp.getErrorOffset(), pp.getMessage())); + } catch (AltosCRCException ce) { + ++crc_errors; + } + } + } catch (InterruptedException ee) { + } catch (IOException ie) { + } finally { + close(); + } + } + + public TelemetryReader (AltosLink in_link, Handler in_handler) { + link = in_link; + handler = in_handler; + + previous = null; + telem = new LinkedBlockingQueue(); + link.add_monitor(telem); + } +} diff --git a/altosdroid/src/org/altusmetrum/AltosDroid/TelemetryService.java b/altosdroid/src/org/altusmetrum/AltosDroid/TelemetryService.java index a1b1915a..42198b6b 100644 --- a/altosdroid/src/org/altusmetrum/AltosDroid/TelemetryService.java +++ b/altosdroid/src/org/altusmetrum/AltosDroid/TelemetryService.java @@ -19,7 +19,6 @@ package org.altusmetrum.AltosDroid; import java.lang.ref.WeakReference; import java.util.ArrayList; -import java.util.concurrent.LinkedBlockingQueue; import android.app.Notification; //import android.app.NotificationManager; @@ -36,7 +35,7 @@ import android.os.RemoteException; import android.util.Log; import android.widget.Toast; -import org.altusmetrum.AltosLib.*; +//import org.altusmetrum.AltosLib.*; public class TelemetryService extends Service { @@ -49,6 +48,7 @@ public class TelemetryService extends Service { static final int MSG_CONNECTED = 4; static final int MSG_CONNECT_FAILED = 5; static final int MSG_DISCONNECTED = 6; + static final int MSG_TELEMETRY = 7; public static final int STATE_NONE = 0; public static final int STATE_READY = 1; @@ -67,8 +67,9 @@ public class TelemetryService extends Service { // Name of the connected device private BluetoothDevice device = null; private AltosBluetooth mAltosBluetooth = null; + private TelemetryReader mTelemetryReader = null; + private int state = STATE_NONE; - LinkedBlockingQueue telem; // Handler of incoming messages from clients. static class IncomingHandler extends Handler { @@ -101,7 +102,6 @@ public class TelemetryService extends Service { case MSG_CONNECTED: if (D) Log.d(TAG, "Connected to device"); s.connected(); - s.mAltosBluetooth.add_monitor(s.telem); break; case MSG_CONNECT_FAILED: if (D) Log.d(TAG, "Connection failed... retrying"); @@ -111,6 +111,9 @@ public class TelemetryService extends Service { if (D) Log.d(TAG, "Disconnected from " + s.device.getName()); s.stopAltosBluetooth(); break; + case MSG_TELEMETRY: + s.sendMessageToClients(Message.obtain(null, AltosDroid.MSG_TELEMETRY, msg.obj)); + break; default: super.handleMessage(msg); } @@ -130,13 +133,20 @@ public class TelemetryService extends Service { private void stopAltosBluetooth() { if (D) Log.i(TAG, "Stopping BT"); setState(STATE_READY); + if (mTelemetryReader != null) { + mTelemetryReader.interrupt(); + try { + mTelemetryReader.join(); + } catch (InterruptedException e) { + } + mTelemetryReader = null; + } if (mAltosBluetooth != null) { if (D) Log.i(TAG, "Closing AltosBluetooth"); mAltosBluetooth.close(); mAltosBluetooth = null; } device = null; - telem.clear(); } private void startAltosBluetooth() { @@ -160,6 +170,8 @@ public class TelemetryService extends Service { private void connected() { sendMessageToClients(Message.obtain(null, AltosDroid.MSG_DEVNAME, device.getName())); setState(STATE_CONNECTED); + mTelemetryReader = new TelemetryReader(mAltosBluetooth, mHandler); + mTelemetryReader.start(); } @@ -168,7 +180,6 @@ public class TelemetryService extends Service { // Create a reference to the NotificationManager so that we can update our notifcation text later //mNM = (NotificationManager)getSystemService(NOTIFICATION_SERVICE); - telem = new LinkedBlockingQueue(); setState(STATE_READY); } -- 2.30.2